xref: /reactos/dll/win32/wininet/internet.h (revision 84ccccab)
1 /*
2  * Wininet
3  *
4  * Copyright 1999 Corel Corporation
5  *
6  * Ulrich Czekalla
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 #ifndef _WINE_INTERNET_H_
24 #define _WINE_INTERNET_H_
25 
26 #include <wine/config.h>
27 
28 #include <assert.h>
29 #include <stdio.h>
30 
31 #define _INC_WINDOWS
32 #define COM_NO_WINDOWS_H
33 
34 #define NONAMELESSUNION
35 #define NONAMELESSSTRUCT
36 
37 #include <windef.h>
38 #include <winbase.h>
39 #include <winreg.h>
40 #include <winuser.h>
41 #include <wininet.h>
42 #define NO_SHLWAPI_STREAM
43 #define NO_SHLWAPI_REG
44 #define NO_SHLWAPI_GDI
45 #include <shlwapi.h>
46 
47 #include <wine/list.h>
48 #include <wine/debug.h>
49 #include <wine/unicode.h>
50 
51 #ifdef HAVE_ARPA_INET_H
52 # include <arpa/inet.h>
53 #endif
54 #ifdef HAVE_NETDB_H
55 # include <netdb.h>
56 #endif
57 #ifdef HAVE_NETINET_IN_H
58 # include <sys/types.h>
59 # include <netinet/in.h>
60 #endif
61 #ifdef HAVE_SYS_IOCTL_H
62 # include <sys/ioctl.h>
63 #endif
64 #ifdef HAVE_SYS_POLL_H
65 # include <sys/poll.h>
66 #endif
67 #ifdef HAVE_SYS_SOCKET_H
68 # include <sys/socket.h>
69 #endif
70 #ifdef HAVE_SYS_TIME_H
71 # include <sys/time.h>
72 #endif
73 #ifdef HAVE_UNISTD_H
74 # include <unistd.h>
75 #endif
76 
77 #if defined(__MINGW32__) || defined (_MSC_VER)
78 #include <ws2tcpip.h>
79 #else
80 #define closesocket close
81 #define ioctlsocket ioctl
82 #endif /* __MINGW32__ */
83 
84 #include <winineti.h>
85 
86 #include "resource.h"
87 
88 WINE_DEFAULT_DEBUG_CHANNEL(wininet);
89 
90 extern HMODULE WININET_hModule DECLSPEC_HIDDEN;
91 
92 typedef struct {
93     WCHAR *name;
94     INTERNET_PORT port;
95     BOOL is_https;
96     struct sockaddr_storage addr;
97     int addr_len;
98     char addr_str[INET6_ADDRSTRLEN];
99 
100     WCHAR *scheme_host_port;
101     const WCHAR *host_port;
102     const WCHAR *canon_host_port;
103 
104     LONG ref;
105 
106     DWORD security_flags;
107     const CERT_CHAIN_CONTEXT *cert_chain;
108 
109     struct list entry;
110     struct list conn_pool;
111 } server_t;
112 
113 void server_addref(server_t*) DECLSPEC_HIDDEN;
114 void server_release(server_t*) DECLSPEC_HIDDEN;
115 
116 typedef enum {
117     COLLECT_TIMEOUT,
118     COLLECT_CONNECTIONS,
119     COLLECT_CLEANUP
120 } collect_type_t;
121 BOOL collect_connections(collect_type_t) DECLSPEC_HIDDEN;
122 
123 /* used for netconnection.c stuff */
124 typedef struct
125 {
126     int socket;
127     BOOL secure;
128     BOOL is_blocking;
129     CtxtHandle ssl_ctx;
130     SecPkgContext_StreamSizes ssl_sizes;
131     server_t *server;
132     char *ssl_buf;
133     char *extra_buf;
134     size_t extra_len;
135     char *peek_msg;
136     char *peek_msg_mem;
137     size_t peek_len;
138     DWORD security_flags;
139     BOOL mask_errors;
140 
141     BOOL keep_alive;
142     DWORD64 keep_until;
143     struct list pool_entry;
144 } netconn_t;
145 
146 BOOL is_valid_netconn(netconn_t *) DECLSPEC_HIDDEN;
147 void close_netconn(netconn_t *) DECLSPEC_HIDDEN;
148 
149 static inline void * __WINE_ALLOC_SIZE(1) heap_alloc(size_t len)
150 {
151     return HeapAlloc(GetProcessHeap(), 0, len);
152 }
153 
154 static inline void * __WINE_ALLOC_SIZE(1) heap_alloc_zero(size_t len)
155 {
156     return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
157 }
158 
159 static inline void * __WINE_ALLOC_SIZE(2) heap_realloc(void *mem, size_t len)
160 {
161     return HeapReAlloc(GetProcessHeap(), 0, mem, len);
162 }
163 
164 static inline void * __WINE_ALLOC_SIZE(2) heap_realloc_zero(void *mem, size_t len)
165 {
166     return HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, mem, len);
167 }
168 
169 static inline BOOL heap_free(void *mem)
170 {
171     return HeapFree(GetProcessHeap(), 0, mem);
172 }
173 
174 static inline LPWSTR heap_strdupW(LPCWSTR str)
175 {
176     LPWSTR ret = NULL;
177 
178     if(str) {
179         DWORD size;
180 
181         size = (strlenW(str)+1)*sizeof(WCHAR);
182         ret = heap_alloc(size);
183         if(ret)
184             memcpy(ret, str, size);
185     }
186 
187     return ret;
188 }
189 
190 static inline char *heap_strdupA(const char *str)
191 {
192     char *ret = NULL;
193 
194     if(str) {
195         DWORD size = strlen(str)+1;
196 
197         ret = heap_alloc(size);
198         if(ret)
199             memcpy(ret, str, size);
200     }
201 
202     return ret;
203 }
204 
205 static inline LPWSTR heap_strndupW(LPCWSTR str, UINT max_len)
206 {
207     LPWSTR ret;
208     UINT len;
209 
210     if(!str)
211         return NULL;
212 
213     for(len=0; len<max_len; len++)
214         if(str[len] == '\0')
215             break;
216 
217     ret = heap_alloc(sizeof(WCHAR)*(len+1));
218     if(ret) {
219         memcpy(ret, str, sizeof(WCHAR)*len);
220         ret[len] = '\0';
221     }
222 
223     return ret;
224 }
225 
226 static inline WCHAR *heap_strndupAtoW(const char *str, int len_a, DWORD *len_w)
227 {
228     WCHAR *ret = NULL;
229 
230     if(str) {
231         size_t len;
232         if(len_a < 0) len_a = strlen(str);
233         len = MultiByteToWideChar(CP_ACP, 0, str, len_a, NULL, 0);
234         ret = heap_alloc((len+1)*sizeof(WCHAR));
235         if(ret) {
236             MultiByteToWideChar(CP_ACP, 0, str, len_a, ret, len);
237             ret[len] = 0;
238             *len_w = len;
239         }
240     }
241 
242     return ret;
243 }
244 
245 static inline WCHAR *heap_strdupAtoW(const char *str)
246 {
247     LPWSTR ret = NULL;
248 
249     if(str) {
250         DWORD len;
251 
252         len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
253         ret = heap_alloc(len*sizeof(WCHAR));
254         if(ret)
255             MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
256     }
257 
258     return ret;
259 }
260 
261 static inline char *heap_strdupWtoA(LPCWSTR str)
262 {
263     char *ret = NULL;
264 
265     if(str) {
266         DWORD size = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL);
267         ret = heap_alloc(size);
268         if(ret)
269             WideCharToMultiByte(CP_ACP, 0, str, -1, ret, size, NULL, NULL);
270     }
271 
272     return ret;
273 }
274 
275 typedef struct {
276     const WCHAR *str;
277     size_t len;
278 } substr_t;
279 
280 static inline substr_t substr(const WCHAR *str, size_t len)
281 {
282     substr_t r = {str, len};
283     return r;
284 }
285 
286 static inline substr_t substrz(const WCHAR *str)
287 {
288     return substr(str, strlenW(str));
289 }
290 
291 static inline void WININET_find_data_WtoA(LPWIN32_FIND_DATAW dataW, LPWIN32_FIND_DATAA dataA)
292 {
293     dataA->dwFileAttributes = dataW->dwFileAttributes;
294     dataA->ftCreationTime   = dataW->ftCreationTime;
295     dataA->ftLastAccessTime = dataW->ftLastAccessTime;
296     dataA->ftLastWriteTime  = dataW->ftLastWriteTime;
297     dataA->nFileSizeHigh    = dataW->nFileSizeHigh;
298     dataA->nFileSizeLow     = dataW->nFileSizeLow;
299     dataA->dwReserved0      = dataW->dwReserved0;
300     dataA->dwReserved1      = dataW->dwReserved1;
301     WideCharToMultiByte(CP_ACP, 0, dataW->cFileName, -1,
302         dataA->cFileName, sizeof(dataA->cFileName),
303         NULL, NULL);
304     WideCharToMultiByte(CP_ACP, 0, dataW->cAlternateFileName, -1,
305         dataA->cAlternateFileName, sizeof(dataA->cAlternateFileName),
306         NULL, NULL);
307 }
308 
309 typedef enum
310 {
311     WH_HINIT = INTERNET_HANDLE_TYPE_INTERNET,
312     WH_HFTPSESSION = INTERNET_HANDLE_TYPE_CONNECT_FTP,
313     WH_HGOPHERSESSION = INTERNET_HANDLE_TYPE_CONNECT_GOPHER,
314     WH_HHTTPSESSION = INTERNET_HANDLE_TYPE_CONNECT_HTTP,
315     WH_HFILE = INTERNET_HANDLE_TYPE_FTP_FILE,
316     WH_HFTPFINDNEXT = INTERNET_HANDLE_TYPE_FTP_FIND,
317     WH_HHTTPREQ = INTERNET_HANDLE_TYPE_HTTP_REQUEST,
318 } WH_TYPE;
319 
320 #define INET_OPENURL 0x0001
321 #define INET_CALLBACKW 0x0002
322 
323 typedef struct
324 {
325     LONG ref;
326     HANDLE file_handle;
327     WCHAR *file_name;
328     WCHAR *url;
329     BOOL is_committed;
330 } req_file_t;
331 
332 typedef struct _object_header_t object_header_t;
333 
334 typedef struct {
335     void (*Destroy)(object_header_t*);
336     void (*CloseConnection)(object_header_t*);
337     DWORD (*QueryOption)(object_header_t*,DWORD,void*,DWORD*,BOOL);
338     DWORD (*SetOption)(object_header_t*,DWORD,void*,DWORD);
339     DWORD (*ReadFile)(object_header_t*,void*,DWORD,DWORD*,DWORD,DWORD_PTR);
340     DWORD (*WriteFile)(object_header_t*,const void*,DWORD,DWORD*);
341     DWORD (*QueryDataAvailable)(object_header_t*,DWORD*,DWORD,DWORD_PTR);
342     DWORD (*FindNextFileW)(object_header_t*,void*);
343     DWORD (*LockRequestFile)(object_header_t*,req_file_t**);
344 } object_vtbl_t;
345 
346 #define INTERNET_HANDLE_IN_USE 1
347 
348 struct _object_header_t
349 {
350     WH_TYPE htype;
351     const object_vtbl_t *vtbl;
352     HINTERNET hInternet;
353     BOOL valid_handle;
354     DWORD  dwFlags;
355     DWORD_PTR dwContext;
356     DWORD  dwError;
357     ULONG  ErrorMask;
358     DWORD  dwInternalFlags;
359     LONG   refs;
360     BOOL   decoding;
361     INTERNET_STATUS_CALLBACK lpfnStatusCB;
362     struct list entry;
363     struct list children;
364 };
365 
366 typedef struct
367 {
368     object_header_t hdr;
369     LPWSTR  agent;
370     LPWSTR  proxy;
371     LPWSTR  proxyBypass;
372     LPWSTR  proxyUsername;
373     LPWSTR  proxyPassword;
374     DWORD   accessType;
375     DWORD   connect_timeout;
376 } appinfo_t;
377 
378 typedef struct
379 {
380     object_header_t hdr;
381     appinfo_t *appInfo;
382     LPWSTR  hostName; /* the final destination of the request */
383     LPWSTR  userName;
384     LPWSTR  password;
385     INTERNET_PORT hostPort; /* the final destination port of the request */
386     DWORD connect_timeout;
387     DWORD send_timeout;
388     DWORD receive_timeout;
389 } http_session_t;
390 
391 #define HDR_ISREQUEST		0x0001
392 #define HDR_COMMADELIMITED	0x0002
393 #define HDR_SEMIDELIMITED	0x0004
394 
395 typedef struct
396 {
397     LPWSTR lpszField;
398     LPWSTR lpszValue;
399     WORD wFlags;
400     WORD wCount;
401 } HTTPHEADERW, *LPHTTPHEADERW;
402 
403 
404 struct HttpAuthInfo;
405 
406 typedef struct data_stream_vtbl_t data_stream_vtbl_t;
407 
408 typedef struct {
409     const data_stream_vtbl_t *vtbl;
410 }  data_stream_t;
411 
412 typedef struct {
413     data_stream_t data_stream;
414     DWORD content_length;
415     DWORD content_read;
416 } netconn_stream_t;
417 
418 #define READ_BUFFER_SIZE 8192
419 
420 typedef struct
421 {
422     object_header_t hdr;
423     http_session_t *session;
424     server_t *server;
425     server_t *proxy;
426     LPWSTR path;
427     LPWSTR verb;
428     netconn_t *netconn;
429     DWORD security_flags;
430     DWORD connect_timeout;
431     DWORD send_timeout;
432     DWORD receive_timeout;
433     LPWSTR version;
434     DWORD status_code;
435     LPWSTR statusText;
436     DWORD bytesToWrite;
437     DWORD bytesWritten;
438 
439     CRITICAL_SECTION headers_section;  /* section to protect the headers array */
440     HTTPHEADERW *custHeaders;
441     DWORD nCustHeaders;
442 
443     FILETIME last_modified;
444     HANDLE hCacheFile;
445     req_file_t *req_file;
446     FILETIME expires;
447     struct HttpAuthInfo *authInfo;
448     struct HttpAuthInfo *proxyAuthInfo;
449 
450     CRITICAL_SECTION read_section;  /* section to protect the following fields */
451     DWORD contentLength;  /* total number of bytes to be read */
452     BOOL  read_gzip;      /* are we reading in gzip mode? */
453     DWORD read_pos;       /* current read position in read_buf */
454     DWORD read_size;      /* valid data size in read_buf */
455     BYTE  read_buf[READ_BUFFER_SIZE]; /* buffer for already read but not returned data */
456 
457     data_stream_t *data_stream;
458     netconn_stream_t netconn_stream;
459 } http_request_t;
460 
461 typedef struct task_header_t task_header_t;
462 typedef void (*async_task_proc_t)(task_header_t*);
463 
464 struct task_header_t
465 {
466     async_task_proc_t proc;
467     object_header_t *hdr;
468 };
469 
470 void *alloc_async_task(object_header_t*,async_task_proc_t,size_t) DECLSPEC_HIDDEN;
471 
472 void *alloc_object(object_header_t*,const object_vtbl_t*,size_t) DECLSPEC_HIDDEN;
473 object_header_t *get_handle_object( HINTERNET hinternet ) DECLSPEC_HIDDEN;
474 object_header_t *WININET_AddRef( object_header_t *info ) DECLSPEC_HIDDEN;
475 BOOL WININET_Release( object_header_t *info ) DECLSPEC_HIDDEN;
476 
477 DWORD INET_QueryOption(object_header_t*,DWORD,void*,DWORD*,BOOL) DECLSPEC_HIDDEN;
478 DWORD INET_SetOption(object_header_t*,DWORD,void*,DWORD) DECLSPEC_HIDDEN;
479 
480 time_t ConvertTimeString(LPCWSTR asctime) DECLSPEC_HIDDEN;
481 
482 HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName,
483 	INTERNET_PORT nServerPort, LPCWSTR lpszUserName,
484 	LPCWSTR lpszPassword, DWORD dwFlags, DWORD_PTR dwContext,
485 	DWORD dwInternalFlags) DECLSPEC_HIDDEN;
486 
487 DWORD HTTP_Connect(appinfo_t*,LPCWSTR,
488         INTERNET_PORT nServerPort, LPCWSTR lpszUserName,
489         LPCWSTR lpszPassword, DWORD dwFlags, DWORD_PTR dwContext,
490         DWORD dwInternalFlags, HINTERNET*) DECLSPEC_HIDDEN;
491 
492 BOOL GetAddress(const WCHAR*,INTERNET_PORT,SOCKADDR*,int*,char*) DECLSPEC_HIDDEN;
493 
494 DWORD get_cookie_header(const WCHAR*,const WCHAR*,WCHAR**) DECLSPEC_HIDDEN;
495 DWORD set_cookie(substr_t,substr_t,substr_t,substr_t,DWORD) DECLSPEC_HIDDEN;
496 
497 void INTERNET_SetLastError(DWORD dwError) DECLSPEC_HIDDEN;
498 DWORD INTERNET_GetLastError(void) DECLSPEC_HIDDEN;
499 DWORD INTERNET_AsyncCall(task_header_t*) DECLSPEC_HIDDEN;
500 LPSTR INTERNET_GetResponseBuffer(void) DECLSPEC_HIDDEN;
501 
502 VOID INTERNET_SendCallback(object_header_t *hdr, DWORD_PTR dwContext,
503                            DWORD dwInternetStatus, LPVOID lpvStatusInfo,
504                            DWORD dwStatusInfoLength) DECLSPEC_HIDDEN;
505 WCHAR *INTERNET_FindProxyForProtocol(LPCWSTR szProxy, LPCWSTR proto) DECLSPEC_HIDDEN;
506 
507 DWORD create_netconn(BOOL,server_t*,DWORD,BOOL,DWORD,netconn_t**) DECLSPEC_HIDDEN;
508 void free_netconn(netconn_t*) DECLSPEC_HIDDEN;
509 void NETCON_unload(void) DECLSPEC_HIDDEN;
510 DWORD NETCON_secure_connect(netconn_t*,server_t*) DECLSPEC_HIDDEN;
511 DWORD NETCON_send(netconn_t *connection, const void *msg, size_t len, int flags,
512 		int *sent /* out */) DECLSPEC_HIDDEN;
513 DWORD NETCON_recv(netconn_t*,void*,size_t,BOOL,int*) DECLSPEC_HIDDEN;
514 BOOL NETCON_is_alive(netconn_t*) DECLSPEC_HIDDEN;
515 LPCVOID NETCON_GetCert(netconn_t *connection) DECLSPEC_HIDDEN;
516 int NETCON_GetCipherStrength(netconn_t*) DECLSPEC_HIDDEN;
517 DWORD NETCON_set_timeout(netconn_t *connection, BOOL send, DWORD value) DECLSPEC_HIDDEN;
518 int sock_send(int fd, const void *msg, size_t len, int flags) DECLSPEC_HIDDEN;
519 int sock_recv(int fd, void *msg, size_t len, int flags) DECLSPEC_HIDDEN;
520 
521 server_t *get_server(substr_t,INTERNET_PORT,BOOL,BOOL) DECLSPEC_HIDDEN;
522 
523 DWORD create_req_file(const WCHAR*,req_file_t**) DECLSPEC_HIDDEN;
524 void req_file_release(req_file_t*) DECLSPEC_HIDDEN;
525 
526 static inline req_file_t *req_file_addref(req_file_t *req_file)
527 {
528     InterlockedIncrement(&req_file->ref);
529     return req_file;
530 }
531 
532 BOOL init_urlcache(void) DECLSPEC_HIDDEN;
533 void free_urlcache(void) DECLSPEC_HIDDEN;
534 void free_cookie(void) DECLSPEC_HIDDEN;
535 
536 void init_winsock(void) DECLSPEC_HIDDEN;
537 
538 #define MAX_REPLY_LEN	 	0x5B4
539 
540 /* Used for debugging - maybe need to be shared in the Wine debugging code ? */
541 typedef struct
542 {
543     DWORD val;
544     const char* name;
545 } wininet_flag_info;
546 
547 /* Undocumented security flags */
548 #define _SECURITY_FLAG_CERT_REV_FAILED    0x00800000
549 #define _SECURITY_FLAG_CERT_INVALID_CA    0x01000000
550 #define _SECURITY_FLAG_CERT_INVALID_CN    0x02000000
551 #define _SECURITY_FLAG_CERT_INVALID_DATE  0x04000000
552 
553 #define _SECURITY_ERROR_FLAGS_MASK              \
554     (_SECURITY_FLAG_CERT_REV_FAILED             \
555     |_SECURITY_FLAG_CERT_INVALID_CA             \
556     |_SECURITY_FLAG_CERT_INVALID_CN             \
557     |_SECURITY_FLAG_CERT_INVALID_DATE)
558 
559 #endif /* _WINE_INTERNET_H_ */
560