ReactOS  0.4.14-dev-50-g13bb5e2
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 = sizeof(user)/sizeof(WCHAR);
155  if(!GetUserNameW(user, &user_len))
156  return FALSE;
157  user_len--;
158 
159  len = sizeof(cookie_prefix)/sizeof(WCHAR) + 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 + sizeof(cookie_prefix)/sizeof(WCHAR);
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 
228 static void delete_cookie(cookie_t *cookie)
229 {
230  list_remove(&cookie->entry);
231 
232  heap_free(cookie->name);
233  heap_free(cookie->data);
234  heap_free(cookie);
235 }
236 
238 {
239  cookie_t *new_cookie;
240 
241  new_cookie = heap_alloc(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  new_cookie->name = heap_strndupW(name.str, name.len);
251  new_cookie->data = heap_strndupW(data.str, data.len);
252  if(!new_cookie->name || !new_cookie->data) {
253  delete_cookie(new_cookie);
254  return NULL;
255  }
256 
257  return new_cookie;
258 }
259 
261 {
262  cookie_t *iter;
263 
264  LIST_FOR_EACH_ENTRY(iter, &container->cookie_list, cookie_t, entry) {
265  if(strlenW(iter->name) == name.len && !strncmpiW(iter->name, name.str, name.len))
266  return iter;
267  }
268 
269  return NULL;
270 }
271 
273 {
274  TRACE("Adding %s=%s to %s\n", debugstr_w(new_cookie->name), debugstr_w(new_cookie->data),
275  debugstr_w(container->cookie_url));
276 
277  list_add_tail(&container->cookie_list, &new_cookie->entry);
278  new_cookie->container = container;
279 }
280 
282 {
283  cookie_t *old_cookie;
284 
285  old_cookie = find_cookie(container, substrz(new_cookie->name));
286  if(old_cookie)
287  delete_cookie(old_cookie);
288 
289  add_cookie(container, new_cookie);
290 }
291 
293 {
294  return path.len >= container->path.len && !strncmpiW(container->path.str, path.str, container->path.len);
295 }
296 
298 {
300  cookie_container_t *cookie_container;
301  cookie_t *new_cookie;
302  HANDLE cookie;
303  char *str = NULL, *pbeg, *pend;
304  DWORD size, flags;
305  WCHAR *name, *data;
306  FILETIME expiry, create, time;
307 
308  cookie_container = get_cookie_container(domain, path, TRUE);
309  if(!cookie_container)
310  return FALSE;
311 
312  size = 0;
313  RetrieveUrlCacheEntryStreamW(cookie_container->cookie_url, NULL, &size, FALSE, 0);
315  return TRUE;
316  info = heap_alloc(size);
317  if(!info)
318  return FALSE;
319  cookie = RetrieveUrlCacheEntryStreamW(cookie_container->cookie_url, info, &size, FALSE, 0);
320  size = info->dwSizeLow;
321  heap_free(info);
322  if(!cookie)
323  return FALSE;
324 
325  if(!(str = heap_alloc(size+1)) || !ReadUrlCacheEntryStream(cookie, 0, str, &size, 0)) {
326  UnlockUrlCacheEntryStream(cookie, 0);
327  heap_free(str);
328  return FALSE;
329  }
330  str[size] = 0;
331  UnlockUrlCacheEntryStream(cookie, 0);
332 
334  for(pbeg=str; pbeg && *pbeg; name=data=NULL) {
335  pend = strchr(pbeg, '\n');
336  if(!pend)
337  break;
338  *pend = 0;
339  name = heap_strdupAtoW(pbeg);
340 
341  pbeg = pend+1;
342  pend = strchr(pbeg, '\n');
343  if(!pend)
344  break;
345  *pend = 0;
346  data = heap_strdupAtoW(pbeg);
347 
348  pbeg = strchr(pend+1, '\n');
349  if(!pbeg)
350  break;
351  sscanf(pbeg, "%u %u %u %u %u", &flags, &expiry.dwLowDateTime, &expiry.dwHighDateTime,
352  &create.dwLowDateTime, &create.dwHighDateTime);
353 
354  /* skip "*\n" */
355  pbeg = strchr(pbeg, '*');
356  if(pbeg) {
357  pbeg++;
358  if(*pbeg)
359  pbeg++;
360  }
361 
362  if(!name || !data)
363  break;
364 
365  if(CompareFileTime(&time, &expiry) <= 0) {
366  new_cookie = alloc_cookie(substr(NULL, 0), substr(NULL, 0), expiry, create, flags);
367  if(!new_cookie)
368  break;
369 
370  new_cookie->name = name;
371  new_cookie->data = data;
372 
373  replace_cookie(cookie_container, new_cookie);
374  }else {
375  heap_free(name);
376  heap_free(data);
377  }
378  }
379  heap_free(str);
380  heap_free(name);
381  heap_free(data);
382 
383  return TRUE;
384 }
385 
387 {
388  static const WCHAR txtW[] = {'t','x','t',0};
389 
390  WCHAR cookie_file[MAX_PATH];
391  HANDLE cookie_handle;
392  cookie_t *cookie_container = NULL, *cookie_iter;
393  BOOL do_save = FALSE;
394  char buf[64], *dyn_buf;
395  FILETIME time;
396  DWORD bytes_written;
397  size_t len;
398 
399  /* check if there's anything to save */
401  LIST_FOR_EACH_ENTRY_SAFE(cookie_container, cookie_iter, &container->cookie_list, cookie_t, entry)
402  {
403  if((cookie_container->expiry.dwLowDateTime || cookie_container->expiry.dwHighDateTime)
404  && CompareFileTime(&time, &cookie_container->expiry) > 0) {
405  delete_cookie(cookie_container);
406  continue;
407  }
408 
409  if(!(cookie_container->flags & INTERNET_COOKIE_IS_SESSION)) {
410  do_save = TRUE;
411  break;
412  }
413  }
414 
415  if(!do_save) {
416  DeleteUrlCacheEntryW(container->cookie_url);
417  return TRUE;
418  }
419 
420  if(!CreateUrlCacheEntryW(container->cookie_url, 0, txtW, cookie_file, 0))
421  return FALSE;
422 
423  cookie_handle = CreateFileW(cookie_file, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
424  if(cookie_handle == INVALID_HANDLE_VALUE) {
425  DeleteFileW(cookie_file);
426  return FALSE;
427  }
428 
429  LIST_FOR_EACH_ENTRY(cookie_container, &container->cookie_list, cookie_t, entry)
430  {
431  if(cookie_container->flags & INTERNET_COOKIE_IS_SESSION)
432  continue;
433 
434  dyn_buf = heap_strdupWtoA(cookie_container->name);
435  if(!dyn_buf || !WriteFile(cookie_handle, dyn_buf, strlen(dyn_buf), &bytes_written, NULL)) {
436  heap_free(dyn_buf);
437  do_save = FALSE;
438  break;
439  }
440  heap_free(dyn_buf);
441  if(!WriteFile(cookie_handle, "\n", 1, &bytes_written, NULL)) {
442  do_save = FALSE;
443  break;
444  }
445 
446  dyn_buf = heap_strdupWtoA(cookie_container->data);
447  if(!dyn_buf || !WriteFile(cookie_handle, dyn_buf, strlen(dyn_buf), &bytes_written, NULL)) {
448  heap_free(dyn_buf);
449  do_save = FALSE;
450  break;
451  }
452  heap_free(dyn_buf);
453  if(!WriteFile(cookie_handle, "\n", 1, &bytes_written, NULL)) {
454  do_save = FALSE;
455  break;
456  }
457 
458  dyn_buf = heap_strdupWtoA(container->domain->domain);
459  if(!dyn_buf || !WriteFile(cookie_handle, dyn_buf, strlen(dyn_buf), &bytes_written, NULL)) {
460  heap_free(dyn_buf);
461  do_save = FALSE;
462  break;
463  }
464  heap_free(dyn_buf);
465 
466  len = WideCharToMultiByte(CP_ACP, 0, container->path.str, container->path.len, NULL, 0, NULL, NULL);
467  dyn_buf = heap_alloc(len+1);
468  if(dyn_buf) {
469  WideCharToMultiByte(CP_ACP, 0, container->path.str, container->path.len, dyn_buf, len, NULL, NULL);
470  dyn_buf[len] = 0;
471  }
472  if(!dyn_buf || !WriteFile(cookie_handle, dyn_buf, strlen(dyn_buf), &bytes_written, NULL)) {
473  heap_free(dyn_buf);
474  do_save = FALSE;
475  break;
476  }
477  heap_free(dyn_buf);
478 
479  sprintf(buf, "\n%u\n%u\n%u\n%u\n%u\n*\n", cookie_container->flags,
480  cookie_container->expiry.dwLowDateTime, cookie_container->expiry.dwHighDateTime,
481  cookie_container->create.dwLowDateTime, cookie_container->create.dwHighDateTime);
482  if(!WriteFile(cookie_handle, buf, strlen(buf), &bytes_written, NULL)) {
483  do_save = FALSE;
484  break;
485  }
486  }
487 
488  CloseHandle(cookie_handle);
489  if(!do_save) {
490  ERR("error saving cookie file\n");
491  DeleteFileW(cookie_file);
492  return FALSE;
493  }
494 
495  memset(&time, 0, sizeof(time));
496  return CommitUrlCacheEntryW(container->cookie_url, cookie_file, time, time, 0, NULL, 0, txtW, 0);
497 }
498 
500 {
501  URL_COMPONENTSW comp = { sizeof(comp) };
502  static const WCHAR rootW[] = {'/',0};
503 
504  comp.dwHostNameLength = 1;
505  comp.dwUrlPathLength = 1;
506 
507  if(!InternetCrackUrlW(url, 0, 0, &comp) || !comp.dwHostNameLength)
508  return FALSE;
509 
510  /* discard the webpage off the end of the path */
511  while(comp.dwUrlPathLength && comp.lpszUrlPath[comp.dwUrlPathLength-1] != '/')
512  comp.dwUrlPathLength--;
513 
514  *host = substr(comp.lpszHostName, comp.dwHostNameLength);
515  *path = comp.dwUrlPathLength ? substr(comp.lpszUrlPath, comp.dwUrlPathLength) : substr(rootW, 1);
516  return TRUE;
517 }
518 
519 typedef struct {
521  unsigned cnt;
522  unsigned size;
523 
524  unsigned string_len;
525 } cookie_set_t;
526 
528 {
529  static const WCHAR empty_path[] = { '/',0 };
530 
531  const WCHAR *p;
532  cookie_domain_t *domain;
534  FILETIME tm;
535 
537 
538  p = host.str + host.len;
539  while(p > host.str && p[-1] != '.') p--;
540  while(p != host.str) {
541  p--;
542  while(p > host.str && p[-1] != '.') p--;
543  if(p == host.str) break;
544 
545  load_persistent_cookie(substr(p, host.str+host.len-p), substr(empty_path, 1));
546  }
547 
548  p = path.str + path.len;
549  do {
551 
552  p--;
553  while(p > path.str && p[-1] != '/') p--;
554  }while(p != path.str);
555 
556  domain = get_cookie_domain(host, FALSE);
557  if(!domain) {
558  TRACE("Unknown host %s\n", debugstr_wn(host.str, host.len));
559  return ERROR_NO_MORE_ITEMS;
560  }
561 
562  for(domain = get_cookie_domain(host, FALSE); domain; domain = domain->parent) {
564  struct list *cursor, *cursor2;
565 
567  continue;
568 
569  LIST_FOR_EACH_SAFE(cursor, cursor2, &container->cookie_list) {
570  cookie_t *cookie_iter = LIST_ENTRY(cursor, cookie_t, entry);
571 
572  /* check for expiry */
573  if((cookie_iter->expiry.dwLowDateTime != 0 || cookie_iter->expiry.dwHighDateTime != 0)
574  && CompareFileTime(&tm, &cookie_iter->expiry) > 0) {
575  TRACE("Found expired cookie. deleting\n");
576  delete_cookie(cookie_iter);
577  continue;
578  }
579 
580  if((cookie_iter->flags & INTERNET_COOKIE_HTTPONLY) && !(flags & INTERNET_COOKIE_HTTPONLY))
581  continue;
582 
583  if(!res->size) {
584  res->cookies = heap_alloc(4*sizeof(*res->cookies));
585  if(!res->cookies)
586  continue;
587  res->size = 4;
588  }else if(res->cnt == res->size) {
589  cookie_t **new_cookies = heap_realloc(res->cookies, res->size*2*sizeof(*res->cookies));
590  if(!new_cookies)
591  continue;
592  res->cookies = new_cookies;
593  res->size *= 2;
594  }
595 
596  TRACE("%s = %s domain %s path %s\n", debugstr_w(cookie_iter->name), debugstr_w(cookie_iter->data),
597  debugstr_w(domain->domain), debugstr_wn(container->path.str, container->path.len));
598 
599  if(res->cnt)
600  res->string_len += 2; /* '; ' */
601  res->cookies[res->cnt++] = cookie_iter;
602 
603  res->string_len += strlenW(cookie_iter->name);
604  if(*cookie_iter->data)
605  res->string_len += 1 /* = */ + strlenW(cookie_iter->data);
606  }
607  }
608  }
609 
610  return ERROR_SUCCESS;
611 }
612 
613 static void cookie_set_to_string(const cookie_set_t *cookie_set, WCHAR *str)
614 {
615  WCHAR *ptr = str;
616  unsigned i, len;
617 
618  for(i=0; i<cookie_set->cnt; i++) {
619  if(i) {
620  *ptr++ = ';';
621  *ptr++ = ' ';
622  }
623 
624  len = strlenW(cookie_set->cookies[i]->name);
625  memcpy(ptr, cookie_set->cookies[i]->name, len*sizeof(WCHAR));
626  ptr += len;
627 
628  if(*cookie_set->cookies[i]->data) {
629  *ptr++ = '=';
630  len = strlenW(cookie_set->cookies[i]->data);
631  memcpy(ptr, cookie_set->cookies[i]->data, len*sizeof(WCHAR));
632  ptr += len;
633  }
634  }
635 
636  assert(ptr-str == cookie_set->string_len);
637  TRACE("%s\n", debugstr_wn(str, ptr-str));
638 }
639 
641 {
642  cookie_set_t cookie_set = {0};
643  DWORD res;
644 
645  static const WCHAR cookieW[] = {'C','o','o','k','i','e',':',' '};
646 
648 
650  if(res != ERROR_SUCCESS) {
652  return res;
653  }
654 
655  if(cookie_set.cnt) {
656  WCHAR *header, *ptr;
657 
658  ptr = header = heap_alloc(sizeof(cookieW) + (cookie_set.string_len + 3 /* crlf0 */) * sizeof(WCHAR));
659  if(header) {
660  memcpy(ptr, cookieW, sizeof(cookieW));
661  ptr += sizeof(cookieW)/sizeof(*cookieW);
662 
663  cookie_set_to_string(&cookie_set, ptr);
664  heap_free(cookie_set.cookies);
665  ptr += cookie_set.string_len;
666 
667  *ptr++ = '\r';
668  *ptr++ = '\n';
669  *ptr++ = 0;
670 
671  *ret = header;
672  }else {
674  }
675  }else {
676  *ret = NULL;
677  }
678 
680  return res;
681 }
682 
683 static void free_cookie_domain_list(struct list *list)
684 {
686  cookie_domain_t *domain;
687 
688  while(!list_empty(list)) {
690 
692 
693  while(!list_empty(&domain->path_list)) {
695 
696  while(!list_empty(&container->cookie_list))
698 
699  heap_free(container->cookie_url);
702  }
703 
704  heap_free(domain->domain);
705  list_remove(&domain->entry);
706  heap_free(domain);
707  }
708 }
709 
710 /***********************************************************************
711  * InternetGetCookieExW (WININET.@)
712  *
713  * Retrieve cookie from the specified url
714  *
715  * It should be noted that on windows the lpszCookieName parameter is "not implemented".
716  * So it won't be implemented here.
717  *
718  * RETURNS
719  * TRUE on success
720  * FALSE on failure
721  *
722  */
724  LPWSTR lpCookieData, LPDWORD lpdwSize, DWORD flags, void *reserved)
725 {
726  cookie_set_t cookie_set = {0};
727  substr_t host, path;
728  DWORD res;
729  BOOL ret;
730 
731  TRACE("(%s, %s, %p, %p, %x, %p)\n", debugstr_w(lpszUrl),debugstr_w(lpszCookieName), lpCookieData, lpdwSize, flags, reserved);
732 
733  if (flags)
734  FIXME("flags 0x%08x not supported\n", flags);
735 
736  if (!lpszUrl)
737  {
739  return FALSE;
740  }
741 
742  ret = cookie_parse_url(lpszUrl, &host, &path);
743  if (!ret) {
745  return FALSE;
746  }
747 
749 
750  res = get_cookie(host, path, flags, &cookie_set);
751  if(res != ERROR_SUCCESS) {
753  SetLastError(res);
754  return FALSE;
755  }
756 
757  if(cookie_set.cnt) {
758  if(!lpCookieData || cookie_set.string_len+1 > *lpdwSize) {
759  *lpdwSize = (cookie_set.string_len + 1) * sizeof(WCHAR);
760  TRACE("returning %u\n", *lpdwSize);
761  if(lpCookieData) {
763  ret = FALSE;
764  }
765  }else {
766  *lpdwSize = cookie_set.string_len + 1;
767  cookie_set_to_string(&cookie_set, lpCookieData);
768  lpCookieData[cookie_set.string_len] = 0;
769  }
770  }else {
771  TRACE("no cookies found for %s\n", debugstr_wn(host.str, host.len));
773  ret = FALSE;
774  }
775 
776  heap_free(cookie_set.cookies);
778  return ret;
779 }
780 
781 /***********************************************************************
782  * InternetGetCookieW (WININET.@)
783  *
784  * Retrieve cookie for the specified URL.
785  */
787 {
788  TRACE("(%s, %s, %s, %p)\n", debugstr_w(url), debugstr_w(name), debugstr_w(data), size);
789 
790  return InternetGetCookieExW(url, name, data, size, 0, NULL);
791 }
792 
793 /***********************************************************************
794  * InternetGetCookieExA (WININET.@)
795  *
796  * Retrieve cookie from the specified url
797  *
798  * RETURNS
799  * TRUE on success
800  * FALSE on failure
801  *
802  */
803 BOOL WINAPI InternetGetCookieExA(LPCSTR lpszUrl, LPCSTR lpszCookieName,
804  LPSTR lpCookieData, LPDWORD lpdwSize, DWORD flags, void *reserved)
805 {
806  WCHAR *url, *name;
807  DWORD len, size = 0;
808  BOOL r;
809 
810  TRACE("(%s %s %p %p(%u) %x %p)\n", debugstr_a(lpszUrl), debugstr_a(lpszCookieName),
811  lpCookieData, lpdwSize, lpdwSize ? *lpdwSize : 0, flags, reserved);
812 
813  url = heap_strdupAtoW(lpszUrl);
814  name = heap_strdupAtoW(lpszCookieName);
815 
817  if( r )
818  {
819  WCHAR *szCookieData;
820 
821  szCookieData = heap_alloc(len * sizeof(WCHAR));
822  if( !szCookieData )
823  {
824  r = FALSE;
825  }
826  else
827  {
828  r = InternetGetCookieExW( url, name, szCookieData, &len, flags, reserved );
829 
830  if(r) {
831  size = WideCharToMultiByte( CP_ACP, 0, szCookieData, len, NULL, 0, NULL, NULL);
832  if(lpCookieData) {
833  if(*lpdwSize >= size) {
834  WideCharToMultiByte( CP_ACP, 0, szCookieData, len, lpCookieData, *lpdwSize, NULL, NULL);
835  }else {
837  r = FALSE;
838  }
839  }
840  }
841 
842  heap_free( szCookieData );
843  }
844  }
845  *lpdwSize = size;
846  heap_free( name );
847  heap_free( url );
848  return r;
849 }
850 
851 /***********************************************************************
852  * InternetGetCookieA (WININET.@)
853  *
854  * See InternetGetCookieW.
855  */
856 BOOL WINAPI InternetGetCookieA(const char *url, const char *name, char *data, DWORD *size)
857 {
858  TRACE("(%s, %s, %p, %p)\n", debugstr_a(url), debugstr_a(name), data, size);
859 
860  return InternetGetCookieExA(url, name, data, size, 0, NULL);
861 }
862 
864 {
865  const WCHAR *ptr;
866 
867  if(!domain.len || *domain.str == '.' || !full_domain.len || *full_domain.str == '.') {
869  return FALSE;
870  }
871 
872  if(domain.len > full_domain.len || !memchrW(domain.str, '.', domain.len) || !memchrW(full_domain.str, '.', full_domain.len))
873  return FALSE;
874 
875  ptr = full_domain.str + full_domain.len - domain.len;
876  if (strncmpiW(domain.str, ptr, domain.len) || (full_domain.len > domain.len && ptr[-1] != '.')) {
878  return FALSE;
879  }
880 
881  return TRUE;
882 }
883 
884 /***********************************************************************
885  * IsDomainLegalCookieDomainW (WININET.@)
886  */
887 BOOL WINAPI IsDomainLegalCookieDomainW(const WCHAR *domain, const WCHAR *full_domain)
888 {
889  FIXME("(%s, %s) semi-stub\n", debugstr_w(domain), debugstr_w(full_domain));
890 
891  if (!domain || !full_domain) {
893  return FALSE;
894  }
895 
896  return is_domain_legal_for_cookie(substrz(domain), substrz(full_domain));
897 }
898 
899 static void substr_skip(substr_t *str, size_t len)
900 {
901  assert(str->len >= len);
902  str->str += len;
903  str->len -= len;
904 }
905 
907 {
909  cookie_t *thisCookie;
910  substr_t value;
911  const WCHAR *end_ptr;
912  FILETIME expiry, create;
913  BOOL expired = FALSE, update_persistent = FALSE;
914  DWORD cookie_flags = 0, len;
915 
916  TRACE("%s %s %s=%s %x\n", debugstr_wn(domain.str, domain.len), debugstr_wn(path.str, path.len),
917  debugstr_wn(name.str, name.len), debugstr_wn(data.str, data.len), flags);
918 
919  memset(&expiry,0,sizeof(expiry));
921 
922  /* lots of information can be parsed out of the cookie value */
923 
924  if(!(end_ptr = memchrW(data.str, ';', data.len)))
925  end_ptr = data.str + data.len;
926  value = substr(data.str, end_ptr-data.str);
927  data.str += value.len;
928  data.len -= value.len;
929 
930  for(;;) {
931  static const WCHAR szDomain[] = {'d','o','m','a','i','n','='};
932  static const WCHAR szPath[] = {'p','a','t','h','='};
933  static const WCHAR szExpires[] = {'e','x','p','i','r','e','s','='};
934  static const WCHAR szSecure[] = {'s','e','c','u','r','e'};
935  static const WCHAR szHttpOnly[] = {'h','t','t','p','o','n','l','y'};
936  static const WCHAR szVersion[] = {'v','e','r','s','i','o','n','='};
937  static const WCHAR max_ageW[] = {'m','a','x','-','a','g','e','='};
938 
939  /* Skip ';' */
940  if(data.len)
941  substr_skip(&data, 1);
942 
943  while(data.len && *data.str == ' ')
944  substr_skip(&data, 1);
945 
946  if(!data.len)
947  break;
948 
949  if(!(end_ptr = memchrW(data.str, ';', data.len)))
950  end_ptr = data.str + data.len;
951 
952  if(data.len >= (len = sizeof(szDomain)/sizeof(WCHAR)) && !strncmpiW(data.str, szDomain, len)) {
953  substr_skip(&data, len);
954 
955  if(data.len && *data.str == '.')
956  substr_skip(&data, 1);
957 
958  if(!is_domain_legal_for_cookie(substr(data.str, end_ptr-data.str), domain))
959  return COOKIE_STATE_UNKNOWN;
960 
961  domain = substr(data.str, end_ptr-data.str);
962  TRACE("Parsing new domain %s\n", debugstr_wn(domain.str, domain.len));
963  }else if(data.len >= (len = sizeof(szPath)/sizeof(WCHAR)) && !strncmpiW(data.str, szPath, len)) {
964  substr_skip(&data, len);
965  path = substr(data.str, end_ptr - data.str);
966  TRACE("Parsing new path %s\n", debugstr_wn(path.str, path.len));
967  }else if(data.len >= (len = sizeof(szExpires)/sizeof(WCHAR)) && !strncmpiW(data.str, szExpires, len)) {
968  SYSTEMTIME st;
969  WCHAR buf[128];
970 
971  substr_skip(&data, len);
972 
973  if(end_ptr - data.str < sizeof(buf)/sizeof(WCHAR)-1) {
974  memcpy(buf, data.str, data.len*sizeof(WCHAR));
975  buf[data.len] = 0;
976 
977  if (InternetTimeToSystemTimeW(data.str, &st, 0)) {
978  SystemTimeToFileTime(&st, &expiry);
979 
980  if (CompareFileTime(&create,&expiry) > 0) {
981  TRACE("Cookie already expired.\n");
982  expired = TRUE;
983  }
984  }
985  }
986  }else if(data.len >= (len = sizeof(szSecure)/sizeof(WCHAR)) && !strncmpiW(data.str, szSecure, len)) {
987  substr_skip(&data, len);
988  FIXME("secure not handled\n");
989  }else if(data.len >= (len = sizeof(szHttpOnly)/sizeof(WCHAR)) && !strncmpiW(data.str, szHttpOnly, len)) {
990  substr_skip(&data, len);
991 
993  WARN("HTTP only cookie added without INTERNET_COOKIE_HTTPONLY flag\n");
995  return COOKIE_STATE_REJECT;
996  }
997 
998  cookie_flags |= INTERNET_COOKIE_HTTPONLY;
999  }else if(data.len >= (len = sizeof(szVersion)/sizeof(WCHAR)) && !strncmpiW(data.str, szVersion, len)) {
1000  substr_skip(&data, len);
1001 
1002  FIXME("version not handled (%s)\n",debugstr_wn(data.str, data.len));
1003  }else if(data.len >= (len = sizeof(max_ageW)/sizeof(WCHAR)) && !strncmpiW(data.str, max_ageW, len)) {
1004  /* Native doesn't support Max-Age attribute. */
1005  WARN("Max-Age ignored\n");
1006  }else if(data.len) {
1007  FIXME("Unknown additional option %s\n", debugstr_wn(data.str, data.len));
1008  }
1009 
1010  substr_skip(&data, end_ptr - data.str);
1011  }
1012 
1014 
1015  load_persistent_cookie(domain, path);
1016 
1017  container = get_cookie_container(domain, path, !expired);
1018  if(!container) {
1020  return COOKIE_STATE_ACCEPT;
1021  }
1022 
1023  if(!expiry.dwLowDateTime && !expiry.dwHighDateTime)
1024  cookie_flags |= INTERNET_COOKIE_IS_SESSION;
1025  else
1026  update_persistent = TRUE;
1027 
1028  if ((thisCookie = find_cookie(container, name))) {
1029  if ((thisCookie->flags & INTERNET_COOKIE_HTTPONLY) && !(flags & INTERNET_COOKIE_HTTPONLY)) {
1030  WARN("An attempt to override httponly cookie\n");
1033  return COOKIE_STATE_REJECT;
1034  }
1035 
1036  if (!(thisCookie->flags & INTERNET_COOKIE_IS_SESSION))
1037  update_persistent = TRUE;
1038  delete_cookie(thisCookie);
1039  }
1040 
1041  TRACE("setting cookie %s=%s for domain %s path %s\n", debugstr_wn(name.str, name.len),
1042  debugstr_wn(value.str, value.len), debugstr_w(container->domain->domain),
1043  debugstr_wn(container->path.str, container->path.len));
1044 
1045  if (!expired) {
1046  cookie_t *new_cookie;
1047 
1048  new_cookie = alloc_cookie(name, value, expiry, create, cookie_flags);
1049  if(!new_cookie) {
1051  return COOKIE_STATE_UNKNOWN;
1052  }
1053 
1054  add_cookie(container, new_cookie);
1055  }
1056 
1057  if (!update_persistent || save_persistent_cookie(container))
1058  {
1060  return COOKIE_STATE_ACCEPT;
1061  }
1063  return COOKIE_STATE_UNKNOWN;
1064 }
1065 
1066 /***********************************************************************
1067  * InternetSetCookieExW (WININET.@)
1068  *
1069  * Sets cookie for the specified url
1070  */
1072  LPCWSTR lpCookieData, DWORD flags, DWORD_PTR reserved)
1073 {
1074  substr_t host, path, name, data;
1075  BOOL ret;
1076 
1077  TRACE("(%s, %s, %s, %x, %lx)\n", debugstr_w(lpszUrl), debugstr_w(lpszCookieName),
1078  debugstr_w(lpCookieData), flags, reserved);
1079 
1081  FIXME("flags %x not supported\n", flags);
1082 
1083  if (!lpszUrl || !lpCookieData)
1084  {
1086  return COOKIE_STATE_UNKNOWN;
1087  }
1088 
1089  ret = cookie_parse_url(lpszUrl, &host, &path);
1090  if (!ret || !host.len) return COOKIE_STATE_UNKNOWN;
1091 
1092  if (!lpszCookieName) {
1093  const WCHAR *ptr;
1094 
1095  /* some apps (or is it us??) try to add a cookie with no cookie name, but
1096  * the cookie data in the form of name[=data].
1097  */
1098  if (!(ptr = strchrW(lpCookieData, '=')))
1099  ptr = lpCookieData + strlenW(lpCookieData);
1100 
1101  name = substr(lpCookieData, ptr - lpCookieData);
1102  data = substrz(*ptr == '=' ? ptr+1 : ptr);
1103  }else {
1104  name = substrz(lpszCookieName);
1105  data = substrz(lpCookieData);
1106  }
1107 
1108  return set_cookie(host, path, name, data, flags);
1109 }
1110 
1111 /***********************************************************************
1112  * InternetSetCookieW (WININET.@)
1113  *
1114  * Sets a cookie for the specified URL.
1115  */
1117 {
1118  TRACE("(%s, %s, %s)\n", debugstr_w(url), debugstr_w(name), debugstr_w(data));
1119 
1121 }
1122 
1123 /***********************************************************************
1124  * InternetSetCookieA (WININET.@)
1125  *
1126  * Sets cookie for the specified url
1127  *
1128  * RETURNS
1129  * TRUE on success
1130  * FALSE on failure
1131  *
1132  */
1133 BOOL WINAPI InternetSetCookieA(LPCSTR lpszUrl, LPCSTR lpszCookieName,
1134  LPCSTR lpCookieData)
1135 {
1136  LPWSTR data, url, name;
1137  BOOL r;
1138 
1139  TRACE("(%s,%s,%s)\n", debugstr_a(lpszUrl),
1140  debugstr_a(lpszCookieName), debugstr_a(lpCookieData));
1141 
1142  url = heap_strdupAtoW(lpszUrl);
1143  name = heap_strdupAtoW(lpszCookieName);
1144  data = heap_strdupAtoW(lpCookieData);
1145 
1146  r = InternetSetCookieW( url, name, data );
1147 
1148  heap_free( data );
1149  heap_free( name );
1150  heap_free( url );
1151  return r;
1152 }
1153 
1154 /***********************************************************************
1155  * InternetSetCookieExA (WININET.@)
1156  *
1157  * See InternetSetCookieExW.
1158  */
1159 DWORD WINAPI InternetSetCookieExA( LPCSTR lpszURL, LPCSTR lpszCookieName, LPCSTR lpszCookieData,
1161 {
1162  WCHAR *data, *url, *name;
1163  DWORD r;
1164 
1165  TRACE("(%s, %s, %s, %x, %lx)\n", debugstr_a(lpszURL), debugstr_a(lpszCookieName),
1166  debugstr_a(lpszCookieData), dwFlags, dwReserved);
1167 
1168  url = heap_strdupAtoW(lpszURL);
1169  name = heap_strdupAtoW(lpszCookieName);
1170  data = heap_strdupAtoW(lpszCookieData);
1171 
1173 
1174  heap_free( data );
1175  heap_free( name );
1176  heap_free( url );
1177  return r;
1178 }
1179 
1180 /***********************************************************************
1181  * InternetClearAllPerSiteCookieDecisions (WININET.@)
1182  *
1183  * Clears all per-site decisions about cookies.
1184  *
1185  * RETURNS
1186  * TRUE on success
1187  * FALSE on failure
1188  *
1189  */
1191 {
1192  FIXME("stub\n");
1193  return TRUE;
1194 }
1195 
1196 /***********************************************************************
1197  * InternetEnumPerSiteCookieDecisionA (WININET.@)
1198  *
1199  * See InternetEnumPerSiteCookieDecisionW.
1200  */
1202  ULONG *pdwDecision, ULONG dwIndex )
1203 {
1204  FIXME("(%s, %p, %p, 0x%08x) stub\n",
1205  debugstr_a(pszSiteName), pcSiteNameSize, pdwDecision, dwIndex);
1206  return FALSE;
1207 }
1208 
1209 /***********************************************************************
1210  * InternetEnumPerSiteCookieDecisionW (WININET.@)
1211  *
1212  * Enumerates all per-site decisions about cookies.
1213  *
1214  * RETURNS
1215  * TRUE on success
1216  * FALSE on failure
1217  *
1218  */
1220  ULONG *pdwDecision, ULONG dwIndex )
1221 {
1222  FIXME("(%s, %p, %p, 0x%08x) stub\n",
1223  debugstr_w(pszSiteName), pcSiteNameSize, pdwDecision, dwIndex);
1224  return FALSE;
1225 }
1226 
1227 /***********************************************************************
1228  * InternetGetPerSiteCookieDecisionA (WININET.@)
1229  */
1231 {
1232  FIXME("(%s, %p) stub\n", debugstr_a(pwchHostName), pResult);
1233  return FALSE;
1234 }
1235 
1236 /***********************************************************************
1237  * InternetGetPerSiteCookieDecisionW (WININET.@)
1238  */
1240 {
1241  FIXME("(%s, %p) stub\n", debugstr_w(pwchHostName), pResult);
1242  return FALSE;
1243 }
1244 
1245 /***********************************************************************
1246  * InternetSetPerSiteCookieDecisionA (WININET.@)
1247  */
1249 {
1250  FIXME("(%s, 0x%08x) stub\n", debugstr_a(pchHostName), dwDecision);
1251  return FALSE;
1252 }
1253 
1254 /***********************************************************************
1255  * InternetSetPerSiteCookieDecisionW (WININET.@)
1256  */
1258 {
1259  FIXME("(%s, 0x%08x) stub\n", debugstr_w(pchHostName), dwDecision);
1260  return FALSE;
1261 }
1262 
1263 void free_cookie(void)
1264 {
1266 
1268 
1270 }
BOOL WINAPI CreateUrlCacheEntryW(LPCWSTR lpszUrlName, DWORD dwExpectedFileSize, LPCWSTR lpszFileExtension, LPWSTR lpszFileName, DWORD dwReserved)
Definition: urlcache.c:2826
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
BOOL WINAPI InternetGetCookieW(const WCHAR *url, const WCHAR *name, WCHAR *data, DWORD *size)
Definition: cookie.c:786
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:398
BOOL WINAPI InternetGetCookieExW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName, LPWSTR lpCookieData, LPDWORD lpdwSize, DWORD flags, void *reserved)
Definition: cookie.c:723
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:803
#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:863
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
static void substr_skip(substr_t *str, size_t len)
Definition: cookie.c:899
#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:1190
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:683
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
#define assert(x)
Definition: debug.h:53
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
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:887
BOOL WINAPI InternetGetPerSiteCookieDecisionW(LPCWSTR pwchHostName, ULONG *pResult)
Definition: cookie.c:1239
__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:1071
struct _test_info info[]
Definition: SetCursorPos.c:19
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:527
__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:613
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:292
static void replace_cookie(cookie_container_t *container, cookie_t *new_cookie)
Definition: cookie.c:281
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED _In_opt_ LPTRANSMIT_FILE_BUFFERS _In_ DWORD dwReserved
Definition: mswsock.h:90
struct list entry
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:3144
#define FIXME(fmt,...)
Definition: debug.h:110
static PVOID ptr
Definition: dispmode.c:27
r reserved
Definition: btrfs.c:2893
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:1159
BOOL WINAPI InternetSetPerSiteCookieDecisionA(LPCSTR pchHostName, DWORD dwDecision)
Definition: cookie.c:1248
static BOOL save_persistent_cookie(cookie_container_t *container)
Definition: cookie.c:386
DWORD get_cookie_header(const WCHAR *host, const WCHAR *path, WCHAR **ret)
Definition: cookie.c:640
_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:426
static CRITICAL_SECTION cookie_cs
Definition: cookie.c:87
static cookie_t * find_cookie(cookie_container_t *container, substr_t name)
Definition: cookie.c:260
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:1219
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:3276
BOOL WINAPI CommitUrlCacheEntryW(LPCWSTR lpszUrlName, LPCWSTR lpszLocalFileName, FILETIME ExpireTime, FILETIME LastModifiedTime, DWORD CacheEntryType, LPWSTR lpHeaderInfo, DWORD dwHeaderSize, LPCWSTR lpszFileExtension, LPCWSTR lpszOriginalUrl)
Definition: urlcache.c:3096
#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:3222
#define debugstr_a
Definition: kernel32.h:31
BOOL WINAPI InternetSetCookieA(LPCSTR lpszUrl, LPCSTR lpszCookieName, LPCSTR lpCookieData)
Definition: cookie.c:1133
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:8
BOOL WINAPI InternetEnumPerSiteCookieDecisionA(LPSTR pszSiteName, ULONG *pcSiteNameSize, ULONG *pdwDecision, ULONG dwIndex)
Definition: cookie.c:1201
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:409
BOOL WINAPI InternetGetCookieA(const char *url, const char *name, char *data, DWORD *size)
Definition: cookie.c:856
BOOL WINAPI InternetSetCookieW(const WCHAR *url, const WCHAR *name, const WCHAR *data)
Definition: cookie.c:1116
cookie_t ** cookies
Definition: cookie.c:520
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:499
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:906
WCHAR * name
LIST_ENTRY ProcessLocksList
Definition: winbase.h:848
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:1263
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:272
__WINE_SERVER_LIST_INLINE int list_empty(const struct list *list)
Definition: list.h:143
static const WCHAR szExpires[]
Definition: http.c:103
BOOL WINAPI SystemTimeToFileTime(IN CONST SYSTEMTIME *lpSystemTime, OUT LPFILETIME lpFileTime)
Definition: time.c:148
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
LPCWSTR szPath
Definition: env.c:35
#define UNLEN
Definition: sspi.c:28
Definition: services.c:325
unsigned string_len
Definition: cookie.c:524
__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:400
static BOOL load_persistent_cookie(substr_t domain, substr_t path)
Definition: cookie.c:297
size_t len
Definition: internet.h:201
BOOL WINAPI InternetCrackUrlW(const WCHAR *lpszUrl, DWORD dwUrlLength, DWORD dwFlags, URL_COMPONENTSW *lpUC)
Definition: internet.c:1645
Definition: name.c:36
unsigned size
Definition: cookie.c:522
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:521
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:3259
#define LIST_ENTRY(type)
Definition: queue.h:175
BOOL WINAPI InternetGetPerSiteCookieDecisionA(LPCSTR pwchHostName, ULONG *pResult)
Definition: cookie.c:1230
#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:109
DWORD dwLowDateTime
Definition: mapidefs.h:65
BOOL WINAPI InternetSetPerSiteCookieDecisionW(LPCWSTR pchHostName, DWORD dwDecision)
Definition: cookie.c:1257
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
BOOL WINAPI DeleteUrlCacheEntryW(LPCWSTR lpszUrlName)
Definition: urlcache.c:3355
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
GLuint const GLchar * name
Definition: glext.h:6031
Definition: wininet.h:2126