source: trunk/src/wininet/internet.c@ 2624

Last change on this file since 2624 was 2624, checked in by sandervl, 26 years ago

Ported Corel wininet Wine version

File size: 14.3 KB
Line 
1/*
2 * Wininet
3 *
4 * Copyright 1999 Corel Corporation
5 *
6 * Ulrich Czekalla
7 *
8 */
9
10#include <windows.h>
11#include <wininet.h>
12#include <debugtools.h>
13#include <winerror.h>
14#include <tchar.h>
15#include <winsock.h>
16
17#ifdef __WIN32OS2__
18#include <stdlib.h>
19#include <string.h>
20#else
21#include <sys/types.h>
22#include <sys/socket.h>
23#include <stdlib.h>
24#endif
25
26#include "internet.h"
27
28INTERNET_SCHEME GetInternetScheme(LPSTR lpszScheme);
29
30DEFAULT_DEBUG_CHANNEL(wininet)
31
32/***********************************************************************
33 * WININET_LibMain [Internal] Initializes the internal 'WININET.DLL'.
34 *
35 * PARAMS
36 * hinstDLL [I] handle to the 'dlls' instance
37 * fdwReason [I]
38 * lpvReserved [I] reserverd, must be NULL
39 *
40 * RETURNS
41 * Success: TRUE
42 * Failure: FALSE
43 */
44
45BOOL WINAPI
46WININET_LibMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
47{
48 TRACE("%x,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);
49
50 switch (fdwReason) {
51 case DLL_PROCESS_ATTACH:
52 break;
53
54 case DLL_PROCESS_DETACH:
55 break;
56 }
57
58 return TRUE;
59}
60
61
62/***********************************************************************
63 * InternetOpenA (WININET.113)
64 *
65 * Per-application initialization of wininet
66 *
67 * RETURNS
68 * HINTERNET on success
69 * NULL on failure
70 *
71 */
72INTERNETAPI HINTERNET WINAPI InternetOpenA(LPCSTR lpszAgent,
73 DWORD dwAccessType, LPCSTR lpszProxy,
74 LPCSTR lpszProxyBypass, DWORD dwFlags)
75{
76 LPWININETAPPINFOA lpwai = NULL;
77
78 TRACE("\n");
79
80 if (dwFlags & INTERNET_FLAG_ASYNC)
81 {
82 FIXME("INTERNET_FLAG_ASYNC not supported\n");
83 }
84
85 lpwai = HeapAlloc(GetProcessHeap(), 0, sizeof(WININETAPPINFOA));
86 if (NULL == lpwai)
87 SetLastError(ERROR_OUTOFMEMORY);
88 else
89 {
90 memset(lpwai, 0, sizeof(WININETAPPINFOA));
91 lpwai->hdr.htype = WH_HINIT;
92 lpwai->hdr.lpwhparent = NULL;
93 lpwai->hdr.dwFlags = dwFlags;
94 if (NULL != lpszAgent)
95 lpwai->lpszAgent = strdup(lpszAgent);
96 if (NULL != lpszProxy)
97 lpwai->lpszProxy = strdup(lpszProxy);
98 if (NULL != lpszProxyBypass)
99 lpwai->lpszProxyBypass = strdup(lpszProxyBypass);
100 lpwai->dwAccessType = dwAccessType;
101 }
102
103 return (HINTERNET)lpwai;
104}
105
106
107/***********************************************************************
108 * InternetGetLastResponseInfoA (WININET.108)
109 *
110 * Return last wininet error description on the calling thread
111 *
112 * RETURNS
113 * TRUE on success of writting to buffer
114 * FALSE on failure
115 *
116 */
117BOOLAPI InternetGetLastResponseInfoA(LPDWORD lpdwError,
118 LPSTR lpszBuffer, LPDWORD lpdwBufferLength)
119{
120 FIXME("stub!\n");
121 return FALSE;
122}
123
124
125/***********************************************************************
126 * InternetConnectA (WININET.93)
127 *
128 * Open a ftp, gopher or http session
129 *
130 * RETURNS
131 * HINTERNET a session handle on success
132 * NULL on failure
133 *
134 */
135INTERNETAPI HINTERNET WINAPI InternetConnectA(HINTERNET hInternet,
136 LPCSTR lpszServerName, INTERNET_PORT nServerPort,
137 LPCSTR lpszUserName, LPCSTR lpszPassword,
138 DWORD dwService, DWORD dwFlags, DWORD dwContext)
139{
140 HINTERNET rc = (HINTERNET) NULL;
141
142 TRACE("\n");
143
144 /* Clear any error information */
145 SetLastError(0);
146
147 switch (dwService)
148 {
149 case INTERNET_SERVICE_FTP:
150 rc = FTP_Connect(hInternet, lpszServerName, nServerPort,
151 lpszUserName, lpszPassword, dwFlags, dwContext);
152 break;
153
154 case INTERNET_SERVICE_HTTP:
155 break;
156
157 case INTERNET_SERVICE_GOPHER:
158 default:
159 break;
160 }
161
162 return rc;
163}
164
165
166/***********************************************************************
167 * InternetFindNextFileA (WININET.102)
168 *
169 * Continues a file search from a previous call to FindFirstFile
170 *
171 * RETURNS
172 * TRUE on success
173 * FALSE on failure
174 *
175 */
176BOOLAPI InternetFindNextFileA(HINTERNET hFind, LPVOID lpvFindData)
177{
178 DWORD access;
179 LPWIN32_FIND_DATAA lpFindFileData;
180 LPWININETFINDNEXTA lpwh = (LPWININETFINDNEXTA) hFind;
181
182 TRACE("\n");
183 if (NULL == lpwh || lpwh->hdr.htype != WH_HFINDNEXT)
184 return FALSE;
185
186 if (lpwh->hdr.lpwhparent->htype != WH_HFTPSESSION)
187 {
188 FIXME("Only FTP find next supported\n");
189 return FALSE;
190 }
191
192 TRACE("index(%d) size(%d)\n", lpwh->index, lpwh->size);
193 if (lpwh->index >= lpwh->size)
194 {
195 SetLastError(ERROR_NO_MORE_FILES);
196 return FALSE;
197 }
198
199 lpFindFileData = (LPWIN32_FIND_DATAA) lpvFindData;
200 access = mktime(&lpwh->lpafp[lpwh->index].tmLastModified);
201
202 /* Not all fields are filled in */
203 lpFindFileData->ftLastAccessTime.dwHighDateTime = HIWORD(access);
204 lpFindFileData->ftLastAccessTime.dwLowDateTime = LOWORD(access);
205 lpFindFileData->nFileSizeHigh = HIWORD(lpwh->lpafp[lpwh->index].nSize);
206 lpFindFileData->nFileSizeLow = LOWORD(lpwh->lpafp[lpwh->index].nSize);
207 if (lpwh->lpafp[lpwh->index].lpszName)
208 strncpy(lpFindFileData->cFileName, lpwh->lpafp[lpwh->index].lpszName, MAX_PATH);
209 lpwh->index++;
210
211 return TRUE;
212}
213
214
215/***********************************************************************
216 * InternetCloseHandle (WININET.89)
217 *
218 * Continues a file search from a previous call to FindFirstFile
219 *
220 * RETURNS
221 * TRUE on success
222 * FALSE on failure
223 *
224 */
225BOOLAPI InternetCloseHandle(HINTERNET hInternet)
226{
227 BOOL retval = FALSE;
228 LPWININETHANDLEHEADER lpwh = (LPWININETHANDLEHEADER) hInternet;
229
230 TRACE("\n");
231 if (NULL == lpwh)
232 return FALSE;
233
234 switch (lpwh->htype)
235 {
236 case WH_HINIT:
237 case WH_HHTTPSESSION:
238 case WH_HHTTPREQ:
239 break;
240 case WH_HFTPSESSION:
241 retval = FTP_CloseSessionHandle((LPWININETFTPSESSIONA) lpwh);
242 break;
243
244 case WH_HFINDNEXT:
245 retval = FTP_CloseFindNextHandle((LPWININETFINDNEXTA) lpwh);
246 break;
247
248 default:
249 break;
250 }
251
252 return retval;
253}
254
255
256/***********************************************************************
257 * InternetCrackUrlA (WININET.95)
258 *
259 * Break up URL into its components
260 *
261 * RETURNS
262 * TRUE on success
263 * FALSE on failure
264 *
265 */
266BOOLAPI InternetCrackUrlA(LPCSTR lpszUrl, DWORD dwUrlLength, DWORD dwFlags,
267 LPURL_COMPONENTSA lpUrlComponents)
268{
269 /*
270 * RFC 1808
271 * <protocol>:[//<net_loc>][/path][;<params>][?<query>][#<fragment>]
272 *
273 */
274 char* szScheme = NULL;
275 char* szUser = NULL;
276 char* szPass = NULL;
277 char* szHost = NULL;
278 char* szUrlPath = NULL;
279 char* szParam = NULL;
280 char* szNetLoc = NULL;
281 int nPort = 80;
282 int nSchemeLen = 0;
283 int nUserLen = 0;
284 int nPassLen = 0;
285 int nHostLen = 0;
286 int nUrlLen = 0;
287
288 // Find out if the URI is absolute...
289 BOOL bIsAbsolute = FALSE;
290 char cAlphanum;
291 char* ap = (char*)lpszUrl;
292 char* cp = NULL;
293
294 TRACE("\n");
295 while( (cAlphanum = *ap) != '\0' )
296 {
297 if( ((cAlphanum >= 'a') && (cAlphanum <= 'z')) ||
298 ((cAlphanum >= 'A') && (cAlphanum <= 'Z')) ||
299 ((cAlphanum >= '0') && (cAlphanum <= '9')) )
300 {
301 ap++;
302 continue;
303 }
304 if( (cAlphanum == ':') && (ap - lpszUrl >= 2) )
305 {
306 bIsAbsolute = TRUE;
307 cp = ap;
308 break;
309 }
310 break;
311 }
312
313 // Absolute URI...
314 //FIXME!!!! This should work on relative urls too!
315 if( bIsAbsolute )
316 {
317 // Get scheme first...
318 nSchemeLen = cp - lpszUrl;
319 szScheme = strdup( lpszUrl );
320 szScheme[ nSchemeLen ] = '\0';
321
322 // Eat ':' in protocol...
323 cp++;
324
325 // Parse <params>...
326 szParam = strpbrk( lpszUrl, ";" );
327 if( szParam != NULL )
328 {
329 char* sParam;
330 // Eat ';' in Params...
331 szParam++;
332 sParam = strdup( szParam );
333 *szParam = '\0';
334 }
335
336 // Skip over slashes...
337 if( *cp == '/' )
338 {
339 cp++;
340 if( *cp == '/' )
341 {
342 cp++;
343 if( *cp == '/' )
344 cp++;
345 }
346 }
347
348 // Parse the <net-loc>...
349 if( GetInternetScheme( szScheme ) == INTERNET_SCHEME_FILE )
350 {
351 szUrlPath = strdup( cp );
352 nUrlLen = strlen( szUrlPath );
353 if( nUrlLen >= 2 && szUrlPath[ 1 ] == '|' )
354 szUrlPath[ 1 ] = ':';
355 }
356 else
357 {
358 size_t nNetLocLen;
359 szUrlPath = strpbrk(cp, "/");
360 if( szUrlPath != NULL )
361 nUrlLen = strlen( szUrlPath );
362
363 // Find the end of our net-loc...
364 nNetLocLen = strcspn( cp, "/" );
365 szNetLoc = strdup( cp );
366 szNetLoc[ nNetLocLen ] = '\0';
367
368 if( szNetLoc != NULL )
369 {
370 char* lpszPort;
371 int nPortLen;
372 // [<user>[<:password>]@]<host>[:<port>]
373 // First find the user and password if they exist...
374
375 szHost = strchr( szNetLoc, '@' );
376 if( szHost == NULL )
377 {
378 // username and password not specified...
379 szHost = szNetLoc;
380 nHostLen = nNetLocLen;
381 }
382 else
383 {
384 int nUserPassLen = nNetLocLen - nHostLen - 1;
385 char* szUserPass = strdup( szNetLoc );
386 // Get username and/or password...
387 // Eat '@' in domain...
388 ++szHost;
389 nHostLen = strlen( szHost );
390
391 szUserPass[ nUserPassLen ] = '\0';
392 if( szUserPass != NULL )
393 {
394 szPass = strpbrk( szUserPass, ":" );
395 if( szPass != NULL )
396 {
397 // Eat ':' in UserPass...
398 ++szPass;
399 nPassLen = strlen( szPass );
400 nUserLen = nUserPassLen - nPassLen - 1;
401 szUser = strdup( szUserPass );
402 szUser[ nUserLen ] = '\0';
403 }
404 else
405 {
406 // password not specified...
407 szUser = strdup( szUserPass );
408 nUserLen = strlen( szUser );
409 }
410 }
411 }
412
413 // <host><:port>...
414 // Then get the port if it exists...
415 lpszPort = strpbrk( szHost, ":" );
416 nPortLen = 0;
417 if( lpszPort != NULL )
418 {
419 char* szPort = lpszPort + 1;
420 if( szPort != NULL )
421 {
422 nPortLen = strlen( szPort );
423 nPort = atoi( szPort );
424 }
425 *lpszPort = '\0';
426 nHostLen = strlen(szHost);
427 }
428 }
429 }
430 }
431 // Relative URI...
432 else
433 return FALSE;
434
435 return TRUE;
436}
437
438
439/***********************************************************************
440 * InternetAttemptConnect (WININET.81)
441 *
442 * Attempt to make a connection to the internet
443 *
444 * RETURNS
445 * ERROR_SUCCESS on success
446 * Error value on failure
447 *
448 */
449INTERNETAPI DWORD WINAPI InternetAttemptConnect(DWORD dwReserved)
450{
451 FIXME("Stub\n");
452 return ERROR_SUCCESS;
453}
454
455
456/***********************************************************************
457 * InternetSetStatusCallback (WININET.133)
458 *
459 * Sets up a callback function which is called as progress is made
460 * during an operation.
461 *
462 * RETURNS
463 * Previous callback or NULL on success
464 * INTERNET_INVALID_STATUS_CALLBACK on failure
465 *
466 */
467INTERNETAPI INTERNET_STATUS_CALLBACK WINAPI InternetSetStatusCallback(
468 HINTERNET hInternet ,INTERNET_STATUS_CALLBACK lpfnIntCB)
469{
470 INTERNET_STATUS_CALLBACK retVal;
471 LPWININETAPPINFOA lpwai = (LPWININETAPPINFOA)hInternet;
472
473 TRACE("\n");
474 if (lpwai->hdr.htype != WH_HINIT)
475 return INTERNET_INVALID_STATUS_CALLBACK;
476
477 retVal = lpwai->lpfnStatusCB;
478 lpwai->lpfnStatusCB = lpfnIntCB;
479
480 return retVal;
481}
482
483
484/***********************************************************************
485 * InternetWriteFile (WININET.138)
486 *
487 * Write data to an open internet file
488 *
489 * RETURNS
490 * TRUE on success
491 * FALSE on failure
492 *
493 */
494BOOLAPI InternetWriteFile(HINTERNET hFile, LPCVOID lpBuffer ,
495 DWORD dwNumOfBytesToWrite, LPDWORD lpdwNumOfBytesWritten)
496{
497 BOOL retval = FALSE;
498 int nSocket = INVALID_SOCKET;
499 LPWININETHANDLEHEADER lpwh = (LPWININETHANDLEHEADER) hFile;
500
501 TRACE("\n");
502 if (NULL == lpwh)
503 return FALSE;
504
505 switch (lpwh->htype)
506 {
507 case WH_HHTTPREQ:
508 nSocket = ((LPWININETHTTPREQA)hFile)->nSocketFD;
509 break;
510
511 case WH_HFILE:
512 nSocket = ((LPWININETFILE)hFile)->nDataSocket;
513 break;
514
515 default:
516 break;
517 }
518
519 if (INVALID_SOCKET != nSocket)
520 {
521 *lpdwNumOfBytesWritten = WriteDataToStream(nSocket, lpBuffer, dwNumOfBytesToWrite);
522 if (*lpdwNumOfBytesWritten < 0)
523 *lpdwNumOfBytesWritten = 0;
524 else
525 retval = TRUE;
526 }
527
528 return retval;
529}
530
531
532/***********************************************************************
533 * InternetReadFile (WININET.121)
534 *
535 * Read data from an open internet file
536 *
537 * RETURNS
538 * TRUE on success
539 * FALSE on failure
540 *
541 */
542BOOLAPI InternetReadFile(HINTERNET hFile, LPVOID lpBuffer,
543 DWORD dwNumOfBytesToRead, LPDWORD dwNumOfBytesRead)
544{
545 BOOL retval = FALSE;
546 int nSocket = INVALID_SOCKET;
547 LPWININETHANDLEHEADER lpwh = (LPWININETHANDLEHEADER) hFile;
548
549 TRACE("\n");
550 if (NULL == lpwh)
551 return FALSE;
552
553 switch (lpwh->htype)
554 {
555 case WH_HHTTPREQ:
556 nSocket = ((LPWININETHTTPREQA)hFile)->nSocketFD;
557 break;
558
559 case WH_HFILE:
560 nSocket = ((LPWININETFILE)hFile)->nDataSocket;
561 break;
562
563 default:
564 break;
565 }
566
567 if (INVALID_SOCKET != nSocket)
568 {
569 *dwNumOfBytesRead = ReadDataFromStream(nSocket, lpBuffer, dwNumOfBytesToRead);
570 if (*dwNumOfBytesRead < 0)
571 *dwNumOfBytesRead = 0;
572 else
573 retval = TRUE;
574 }
575
576 return retval;
577}
578
579
580/***********************************************************************
581 * GetInternetScheme (internal)
582 *
583 * Get scheme of url
584 *
585 * RETURNS
586 * scheme on success
587 * INTERNET_SCHEME_UNKNOWN on failure
588 *
589 */
590INTERNET_SCHEME GetInternetScheme(LPSTR lpszScheme)
591{
592 if(lpszScheme==NULL)
593 return INTERNET_SCHEME_UNKNOWN;
594
595 if( (strcmp("ftp", lpszScheme) == 0) ||
596 (strcmp("FTP", lpszScheme) == 0) )
597 return INTERNET_SCHEME_FTP;
598
599 else if( (strcmp("gopher", lpszScheme) == 0) ||
600 (strcmp("GOPHER", lpszScheme) == 0) )
601 return INTERNET_SCHEME_GOPHER;
602
603 else if( (strcmp("http", lpszScheme) == 0) ||
604 (strcmp("HTTP", lpszScheme) == 0) )
605 return INTERNET_SCHEME_HTTP;
606
607 else if( (strcmp("https", lpszScheme) == 0) ||
608 (strcmp("HTTPS", lpszScheme) == 0) )
609 return INTERNET_SCHEME_HTTPS;
610
611 else if( (strcmp("file", lpszScheme) == 0) ||
612 (strcmp("FILE", lpszScheme) == 0) )
613 return INTERNET_SCHEME_FILE;
614
615 else if( (strcmp("news", lpszScheme) == 0) ||
616 (strcmp("NEWS", lpszScheme) == 0) )
617 return INTERNET_SCHEME_NEWS;
618
619 else if( (strcmp("mailto", lpszScheme) == 0) ||
620 (strcmp("MAILTO", lpszScheme) == 0) )
621 return INTERNET_SCHEME_MAILTO;
622
623 else
624 return INTERNET_SCHEME_UNKNOWN;
625}
626
627
628/***********************************************************************
629 * WriteDataToStream (internal)
630 *
631 * Send data to server
632 *
633 * RETURNS
634 *
635 * number of characters sent on success
636 * -1 on error
637 */
638int WriteDataToStream(int nDataSocket, LPCVOID Buffer, DWORD BytesToWrite)
639{
640 if (INVALID_SOCKET == nDataSocket)
641 return SOCKET_ERROR;
642
643 return send(nDataSocket, Buffer, BytesToWrite, 0);
644}
645
646
647/***********************************************************************
648 * ReadDataFromStream (internal)
649 *
650 * Read data from http server
651 *
652 * RETURNS
653 *
654 * number of characters sent on success
655 * -1 on error
656 */
657int ReadDataFromStream(int nDataSocket, LPVOID Buffer, DWORD BytesToRead)
658{
659 if (INVALID_SOCKET == nDataSocket)
660 return SOCKET_ERROR;
661
662 return recv(nDataSocket, Buffer, BytesToRead, 0);
663}
Note: See TracBrowser for help on using the repository browser.