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

Last change on this file since 3898 was 3898, checked in by bird, 25 years ago

Added the CVS Id keyword to the header.

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