From ff9b9d4ef8623e0f7fbf4b316cff62279c786a82 Mon Sep 17 00:00:00 2001 From: Aric Stewart Date: Fri, 21 Jun 2002 23:59:49 +0000 Subject: [PATCH] Reworking of http and asyncronous calls to get IE6 to install. Added a version resource. Added unit test for http. --- configure | 5 + configure.ac | 1 + dlls/wininet/.cvsignore | 1 + dlls/wininet/Makefile.in | 8 + dlls/wininet/http.c | 283 ++++++++++++++++++++++++---------- dlls/wininet/internet.c | 233 +++++++++++++++++++--------- dlls/wininet/internet.h | 11 +- dlls/wininet/tests/.cvsignore | 3 + dlls/wininet/tests/http.c | 186 ++++++++++++++++++++++ dlls/wininet/urlcache.c | 21 ++- dlls/wininet/utility.c | 51 ++++++ dlls/wininet/version.rc | 29 ++++ dlls/wininet/wininet.spec | 10 +- 13 files changed, 680 insertions(+), 162 deletions(-) create mode 100644 dlls/wininet/tests/.cvsignore create mode 100644 dlls/wininet/tests/http.c create mode 100644 dlls/wininet/version.rc diff --git a/configure b/configure index 031f01d3757..1663aec7751 100755 --- a/configure +++ b/configure @@ -13079,6 +13079,8 @@ ac_config_commands="$ac_config_commands dlls/user/tests" ac_config_commands="$ac_config_commands dlls/wineps/data" +ac_config_commands="$ac_config_commands dlls/wininet/tests" + ac_config_commands="$ac_config_commands dlls/winsock/tests" ac_config_commands="$ac_config_commands files" @@ -13760,6 +13762,7 @@ do "dlls/user/resources" ) CONFIG_COMMANDS="$CONFIG_COMMANDS dlls/user/resources" ;; "dlls/user/tests" ) CONFIG_COMMANDS="$CONFIG_COMMANDS dlls/user/tests" ;; "dlls/wineps/data" ) CONFIG_COMMANDS="$CONFIG_COMMANDS dlls/wineps/data" ;; + "dlls/wininet/tests" ) CONFIG_COMMANDS="$CONFIG_COMMANDS dlls/wininet/tests" ;; "dlls/winsock/tests" ) CONFIG_COMMANDS="$CONFIG_COMMANDS dlls/winsock/tests" ;; "files" ) CONFIG_COMMANDS="$CONFIG_COMMANDS files" ;; "graphics" ) CONFIG_COMMANDS="$CONFIG_COMMANDS graphics" ;; @@ -14458,6 +14461,8 @@ echo "$as_me: creating dlls/user/resources" >&6;} && mkdir "dlls/user/resources" echo "$as_me: creating dlls/user/tests" >&6;} && mkdir "dlls/user/tests") ;; dlls/wineps/data ) test -d "dlls/wineps/data" || ({ echo "$as_me:$LINENO: creating dlls/wineps/data" >&5 echo "$as_me: creating dlls/wineps/data" >&6;} && mkdir "dlls/wineps/data") ;; + dlls/wininet/tests ) test -d "dlls/wininet/tests" || ({ echo "$as_me:$LINENO: creating dlls/wininet/tests" >&5 +echo "$as_me: creating dlls/wininet/tests" >&6;} && mkdir "dlls/wininet/tests") ;; dlls/winsock/tests ) test -d "dlls/winsock/tests" || ({ echo "$as_me:$LINENO: creating dlls/winsock/tests" >&5 echo "$as_me: creating dlls/winsock/tests" >&6;} && mkdir "dlls/winsock/tests") ;; files ) test -d "files" || ({ echo "$as_me:$LINENO: creating files" >&5 diff --git a/configure.ac b/configure.ac index 5a89e5544c1..8f20a467e2d 100644 --- a/configure.ac +++ b/configure.ac @@ -1200,6 +1200,7 @@ WINE_CONFIG_EXTRA_DIR(dlls/user/dde) WINE_CONFIG_EXTRA_DIR(dlls/user/resources) WINE_CONFIG_EXTRA_DIR(dlls/user/tests) WINE_CONFIG_EXTRA_DIR(dlls/wineps/data) +WINE_CONFIG_EXTRA_DIR(dlls/wininet/tests) WINE_CONFIG_EXTRA_DIR(dlls/winsock/tests) WINE_CONFIG_EXTRA_DIR(files) WINE_CONFIG_EXTRA_DIR(graphics) diff --git a/dlls/wininet/.cvsignore b/dlls/wininet/.cvsignore index aaa584ef236..b45d952c187 100644 --- a/dlls/wininet/.cvsignore +++ b/dlls/wininet/.cvsignore @@ -1,3 +1,4 @@ Makefile +version.res wininet.dll.dbg.c wininet.spec.c diff --git a/dlls/wininet/Makefile.in b/dlls/wininet/Makefile.in index bc416281187..b73faedf398 100644 --- a/dlls/wininet/Makefile.in +++ b/dlls/wininet/Makefile.in @@ -17,6 +17,14 @@ C_SRCS = \ utility.c \ wininet_main.c +RC_SRCS= \ + version.rc + +CTESTS = \ + tests/http.c + +EXTRASUBDIRS = tests + @MAKE_DLL_RULES@ ### Dependencies: diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c index aba39515b97..4ca1ed6b3cf 100644 --- a/dlls/wininet/http.c +++ b/dlls/wininet/http.c @@ -2,8 +2,10 @@ * Wininet - Http Implementation * * Copyright 1999 Corel Corporation + * Copyright 2002 CodeWeavers Inc. * * Ulrich Czekalla + * Aric Stewart * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -105,6 +107,8 @@ BOOL WINAPI HttpAddRequestHeadersA(HINTERNET hHttpRequest, BOOL bSuccess = FALSE; LPWININETHTTPREQA lpwhr = (LPWININETHTTPREQA) hHttpRequest; + TRACE("\n"); + if (NULL == lpwhr || lpwhr->hdr.htype != WH_HHTTPREQ) { INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); @@ -167,10 +171,19 @@ HINTERNET WINAPI HttpOpenRequestA(HINTERNET hHttpSession, INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); return FALSE; } - hIC = (LPWININETAPPINFOA) lpwhs->hdr.lpwhparent; - if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC) + /* + * My tests seem to show that the windows version does not + * become asynchronous until after this point. And anyhow + * if this call was asynchronous then how would you get the + * necessary HINTERNET pointer returned by this function. + * + * I am leaving this here just in case I am wrong + * + * if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC) + */ + if (0) { WORKREQUEST workRequest; @@ -178,13 +191,20 @@ HINTERNET WINAPI HttpOpenRequestA(HINTERNET hHttpSession, workRequest.HFTPSESSION = (DWORD)hHttpSession; workRequest.LPSZVERB = (DWORD)HTTP_strdup(lpszVerb); workRequest.LPSZOBJECTNAME = (DWORD)HTTP_strdup(lpszObjectName); - workRequest.LPSZVERSION = (DWORD)HTTP_strdup(lpszVersion); - workRequest.LPSZREFERRER = (DWORD)HTTP_strdup(lpszReferrer); + if (lpszVersion) + workRequest.LPSZVERSION = (DWORD)HTTP_strdup(lpszVersion); + else + workRequest.LPSZVERSION = 0; + if (lpszReferrer) + workRequest.LPSZREFERRER = (DWORD)HTTP_strdup(lpszReferrer); + else + workRequest.LPSZREFERRER = 0; workRequest.LPSZACCEPTTYPES = (DWORD)lpszAcceptTypes; workRequest.DWFLAGS = dwFlags; workRequest.DWCONTEXT = dwContext; - return (HINTERNET)INTERNET_AsyncCall(&workRequest); + INTERNET_AsyncCall(&workRequest); + return NULL; } else { @@ -213,7 +233,7 @@ HINTERNET WINAPI HTTP_HttpOpenRequestA(HINTERNET hHttpSession, LPWININETAPPINFOA hIC = NULL; LPWININETHTTPREQA lpwhr; - TRACE("\n"); + TRACE("--> \n"); if (NULL == lpwhs || lpwhs->hdr.htype != WH_HHTTPSESSION) { @@ -238,10 +258,18 @@ HINTERNET WINAPI HTTP_HttpOpenRequestA(HINTERNET hHttpSession, if (NULL != lpszObjectName && strlen(lpszObjectName)) { DWORD needed = 0; - UrlEscapeA(lpszObjectName, NULL, &needed, URL_ESCAPE_SPACES_ONLY); + HRESULT rc; + rc = UrlEscapeA(lpszObjectName, NULL, &needed, URL_ESCAPE_SPACES_ONLY); + if (rc != E_POINTER) + needed = strlen(lpszObjectName)+1; lpwhr->lpszPath = HeapAlloc(GetProcessHeap(), 0, needed); - UrlEscapeA(lpszObjectName, lpwhr->lpszPath, &needed, + rc = UrlEscapeA(lpszObjectName, lpwhr->lpszPath, &needed, URL_ESCAPE_SPACES_ONLY); + if (rc) + { + ERR("Unable to escape string!(%s) (%ld)\n",lpszObjectName,rc); + strcpy(lpwhr->lpszPath,lpszObjectName); + } } if (NULL != lpszReferrer && strlen(lpszReferrer)) @@ -283,20 +311,36 @@ HINTERNET WINAPI HTTP_HttpOpenRequestA(HINTERNET hHttpSession, iar.dwResult = (DWORD)lpwhr; iar.dwError = ERROR_SUCCESS; - hIC->lpfnStatusCB(hHttpSession, dwContext, INTERNET_STATUS_HANDLE_CREATED, - &iar, sizeof(INTERNET_ASYNC_RESULT)); + SendAsyncCallback(hIC, hHttpSession, dwContext, + INTERNET_STATUS_HANDLE_CREATED, &iar, + sizeof(INTERNET_ASYNC_RESULT)); } - if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC && hIC->lpfnStatusCB) + /* + * A STATUS_REQUEST_COMPLETE is NOT sent here as per my tests on windows + */ + + /* + * According to my tests. The name is not resolved until a request is Opened + */ + SendAsyncCallback(hIC, hHttpSession, dwContext, + INTERNET_STATUS_RESOLVING_NAME, + lpwhs->lpszServerName, + strlen(lpwhs->lpszServerName)+1); + + if (!GetAddress(lpwhs->lpszServerName, lpwhs->nServerPort, + &lpwhs->phostent, &lpwhs->socketAddress)) { - INTERNET_ASYNC_RESULT iar; - - iar.dwResult = (DWORD)lpwhr; - iar.dwError = lpwhr ? ERROR_SUCCESS : INTERNET_GetLastError(); - hIC->lpfnStatusCB(hHttpSession, dwContext, INTERNET_STATUS_REQUEST_COMPLETE, - &iar, sizeof(INTERNET_ASYNC_RESULT)); + INTERNET_SetLastError(ERROR_INTERNET_NAME_NOT_RESOLVED); + return FALSE; } + SendAsyncCallback(hIC, hHttpSession, lpwhr->hdr.dwContext, + INTERNET_STATUS_NAME_RESOLVED, + &(lpwhs->socketAddress), + sizeof(struct sockaddr_in)); + + TRACE("<--\n"); return (HINTERNET) lpwhr; } @@ -367,7 +411,6 @@ BOOL WINAPI HttpQueryInfoA(HINTERNET hHttpRequest, DWORD dwInfoLevel, strlen(lpwhr->StdHeaders[i].lpszValue) + delim + 2; } } - size += delim; if (size + 1 > *lpdwBufferLength) @@ -475,6 +518,7 @@ BOOL WINAPI HttpQueryInfoA(HINTERNET hHttpRequest, DWORD dwInfoLevel, } strncpy(lpBuffer, lphttpHdr->lpszValue, len); + ((char*)lpBuffer)[len]=0; *lpdwBufferLength = len; bSuccess = TRUE; } @@ -544,14 +588,22 @@ BOOL WINAPI HttpSendRequestA(HINTERNET hHttpRequest, LPCSTR lpszHeaders, { WORKREQUEST workRequest; - workRequest.asyncall = HTTPSENDREQUESTA; - workRequest.HFTPSESSION = (DWORD)hHttpRequest; - workRequest.LPSZHEADER = (DWORD)HTTP_strdup(lpszHeaders); - workRequest.DWHEADERLENGTH = dwHeaderLength; - workRequest.LPOPTIONAL = (DWORD)lpOptional; - workRequest.DWOPTIONALLENGTH = dwOptionalLength; + workRequest.asyncall = HTTPSENDREQUESTA; + workRequest.HFTPSESSION = (DWORD)hHttpRequest; + if (lpszHeaders) + workRequest.LPSZHEADER = (DWORD)HTTP_strdup(lpszHeaders); + else + workRequest.LPSZHEADER = 0; + workRequest.DWHEADERLENGTH = dwHeaderLength; + workRequest.LPOPTIONAL = (DWORD)lpOptional; + workRequest.DWOPTIONALLENGTH = dwOptionalLength; - return INTERNET_AsyncCall(&workRequest); + INTERNET_AsyncCall(&workRequest); + /* + * This is from windows. I do not know what the name is + */ + SetLastError(0x3e5); + return 0; } else { @@ -579,12 +631,13 @@ BOOL WINAPI HTTP_HttpSendRequestA(HINTERNET hHttpRequest, LPCSTR lpszHeaders, BOOL bSuccess = FALSE; LPSTR requestString = NULL; INT requestStringLen; + INT responseLen; INT headerLength = 0; LPWININETHTTPREQA lpwhr = (LPWININETHTTPREQA) hHttpRequest; LPWININETHTTPSESSIONA lpwhs = NULL; LPWININETAPPINFOA hIC = NULL; - TRACE("0x%08lx\n", (ULONG)hHttpRequest); + TRACE("--> 0x%08lx\n", (ULONG)hHttpRequest); /* Verify our tree of internet handles */ if (NULL == lpwhr || lpwhr->hdr.htype != WH_HHTTPREQ) @@ -610,6 +663,7 @@ BOOL WINAPI HTTP_HttpSendRequestA(HINTERNET hHttpRequest, LPCSTR lpszHeaders, /* Clear any error information */ INTERNET_SetLastError(0); + /* We must have a verb */ if (NULL == lpwhr->lpszVerb) { @@ -711,35 +765,50 @@ BOOL WINAPI HTTP_HttpSendRequestA(HINTERNET hHttpRequest, LPCSTR lpszHeaders, /* Set termination string for request */ strcpy(requestString + cnt, "\r\n\r\n"); - if (hIC->lpfnStatusCB) - hIC->lpfnStatusCB(hHttpRequest, lpwhr->hdr.dwContext, INTERNET_STATUS_SENDING_REQUEST, NULL, 0); - TRACE("(%s) len(%d)\n", requestString, requestStringLen); /* Send the request and store the results */ if (!HTTP_OpenConnection(lpwhr)) goto lend; - cnt = INTERNET_WriteDataToStream(lpwhr->nSocketFD, requestString, requestStringLen); + SendAsyncCallback(hIC, hHttpRequest, lpwhr->hdr.dwContext, + INTERNET_STATUS_SENDING_REQUEST, NULL, 0); + + cnt = send(lpwhr->nSocketFD, requestString, requestStringLen, 0); + + SendAsyncCallback(hIC, hHttpRequest, lpwhr->hdr.dwContext, + INTERNET_STATUS_REQUEST_SENT, + &requestStringLen,sizeof(DWORD)); + + SendAsyncCallback(hIC, hHttpRequest, lpwhr->hdr.dwContext, + INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0); if (cnt < 0) goto lend; - if (HTTP_GetResponseHeaders(lpwhr)) + responseLen = HTTP_GetResponseHeaders(lpwhr); + if (responseLen) bSuccess = TRUE; + SendAsyncCallback(hIC, hHttpRequest, lpwhr->hdr.dwContext, + INTERNET_STATUS_RESPONSE_RECEIVED, &responseLen, + sizeof(DWORD)); + lend: if (requestString) HeapFree(GetProcessHeap(), 0, requestString); - if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC && hIC->lpfnStatusCB) + + if (hIC->lpfnStatusCB) { INTERNET_ASYNC_RESULT iar; iar.dwResult = (DWORD)bSuccess; iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError(); - hIC->lpfnStatusCB(hHttpRequest, lpwhr->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE, - &iar, sizeof(INTERNET_ASYNC_RESULT)); + + SendAsyncCallback(hIC, hHttpRequest, lpwhr->hdr.dwContext, + INTERNET_STATUS_REQUEST_COMPLETE, &iar, + sizeof(INTERNET_ASYNC_RESULT)); } TRACE("<--\n"); @@ -765,12 +834,13 @@ HINTERNET HTTP_Connect(HINTERNET hInternet, LPCSTR lpszServerName, LPWININETAPPINFOA hIC = NULL; LPWININETHTTPSESSIONA lpwhs = NULL; - TRACE("\n"); + TRACE("-->\n"); if (((LPWININETHANDLEHEADER)hInternet)->htype != WH_HINIT) goto lerror; hIC = (LPWININETAPPINFOA) hInternet; + hIC->hdr.dwContext = dwContext; lpwhs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WININETHTTPSESSIONA)); if (NULL == lpwhs) @@ -779,23 +849,13 @@ HINTERNET HTTP_Connect(HINTERNET hInternet, LPCSTR lpszServerName, goto lerror; } - if (hIC->lpfnStatusCB) - hIC->lpfnStatusCB(hInternet, dwContext, INTERNET_STATUS_RESOLVING_NAME, - (LPVOID)lpszServerName, strlen(lpszServerName)); + /* + * According to my tests. The name is not resolved until a request is sent + */ if (nServerPort == INTERNET_INVALID_PORT_NUMBER) nServerPort = INTERNET_DEFAULT_HTTP_PORT; - if (!GetAddress(lpszServerName, nServerPort, &lpwhs->phostent, &lpwhs->socketAddress)) - { - INTERNET_SetLastError(ERROR_INTERNET_NAME_NOT_RESOLVED); - goto lerror; - } - - if (hIC->lpfnStatusCB) - hIC->lpfnStatusCB(hInternet, dwContext, INTERNET_STATUS_NAME_RESOLVED, - (LPVOID)lpszServerName, strlen(lpszServerName)); - lpwhs->hdr.htype = WH_HHTTPSESSION; lpwhs->hdr.lpwhparent = (LPWININETHANDLEHEADER)hInternet; lpwhs->hdr.dwFlags = dwFlags; @@ -813,8 +873,9 @@ HINTERNET HTTP_Connect(HINTERNET hInternet, LPCSTR lpszServerName, iar.dwResult = (DWORD)lpwhs; iar.dwError = ERROR_SUCCESS; - hIC->lpfnStatusCB(hInternet, dwContext, INTERNET_STATUS_HANDLE_CREATED, - &iar, sizeof(INTERNET_ASYNC_RESULT)); + SendAsyncCallback(hIC, hInternet, dwContext, + INTERNET_STATUS_HANDLE_CREATED, &iar, + sizeof(INTERNET_ASYNC_RESULT)); } bSuccess = TRUE; @@ -826,15 +887,11 @@ lerror: lpwhs = NULL; } - if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC && hIC->lpfnStatusCB) - { - INTERNET_ASYNC_RESULT iar; +/* + * a INTERNET_STATUS_REQUEST_COMPLETE is NOT sent here as per my tests on + * windows + */ - iar.dwResult = (DWORD)lpwhs; - iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError(); - hIC->lpfnStatusCB(hInternet, dwContext, INTERNET_STATUS_REQUEST_COMPLETE, - &iar, sizeof(INTERNET_ASYNC_RESULT)); - } TRACE("<--\n"); return (HINTERNET)lpwhs; } @@ -855,8 +912,10 @@ BOOL HTTP_OpenConnection(LPWININETHTTPREQA lpwhr) BOOL bSuccess = FALSE; INT result; LPWININETHTTPSESSIONA lpwhs; + LPWININETAPPINFOA hIC = NULL; + + TRACE("-->\n"); - TRACE("\n"); if (NULL == lpwhr || lpwhr->hdr.htype != WH_HHTTPREQ) { @@ -866,6 +925,12 @@ BOOL HTTP_OpenConnection(LPWININETHTTPREQA lpwhr) lpwhs = (LPWININETHTTPSESSIONA)lpwhr->hdr.lpwhparent; + hIC = (LPWININETAPPINFOA) lpwhs->hdr.lpwhparent; + SendAsyncCallback(hIC, lpwhr, lpwhr->hdr.dwContext, + INTERNET_STATUS_CONNECTING_TO_SERVER, + &(lpwhs->socketAddress), + sizeof(struct sockaddr_in)); + lpwhr->nSocketFD = socket(lpwhs->phostent->h_addrtype,SOCK_STREAM,0); if (lpwhr->nSocketFD == -1) { @@ -882,10 +947,15 @@ BOOL HTTP_OpenConnection(LPWININETHTTPREQA lpwhr) goto lend; } + SendAsyncCallback(hIC, lpwhr, lpwhr->hdr.dwContext, + INTERNET_STATUS_CONNECTED_TO_SERVER, + &(lpwhs->socketAddress), + sizeof(struct sockaddr_in)); + bSuccess = TRUE; lend: - TRACE(": %d\n", bSuccess); + TRACE("%d <--\n", bSuccess); return bSuccess; } @@ -906,16 +976,23 @@ BOOL HTTP_GetResponseHeaders(LPWININETHTTPREQA lpwhr) CHAR buffer[MAX_REPLY_LEN]; DWORD buflen = MAX_REPLY_LEN; BOOL bSuccess = FALSE; + INT rc = 0; CHAR value[MAX_FIELD_VALUE_LEN], field[MAX_FIELD_LEN]; - TRACE("\n"); + TRACE("-->\n"); if (lpwhr->nSocketFD == -1) goto lend; + /* + * HACK peek at the buffer + */ + rc = recv(lpwhr->nSocketFD,buffer,buflen,MSG_PEEK); + /* * We should first receive 'HTTP/1.x nnn' where nnn is the status code. */ + buflen = MAX_REPLY_LEN; if (!INTERNET_GetNextLine(lpwhr->nSocketFD, buffer, &buflen)) goto lend; @@ -948,7 +1025,11 @@ BOOL HTTP_GetResponseHeaders(LPWININETHTTPREQA lpwhr) lend: - return bSuccess; + TRACE("<--\n"); + if (bSuccess) + return rc; + else + return FALSE; } @@ -1066,7 +1147,7 @@ INT HTTP_GetStdHeaderIndex(LPCSTR lpszField) index = HTTP_QUERY_USER_AGENT; else { - FIXME("Couldn't find %s in standard header table\n", lpszField); + TRACE("Couldn't find %s in standard header table\n", lpszField); } return index; @@ -1088,7 +1169,7 @@ BOOL HTTP_ProcessHeader(LPWININETHTTPREQA lpwhr, LPCSTR field, LPCSTR value, DWO BOOL bSuccess = FALSE; INT index; - TRACE("%s:%s - 0x%08x\n", field, value, (unsigned int)dwModifier); + TRACE("--> %s:%s - 0x%08x\n", field, value, (unsigned int)dwModifier); /* Adjust modifier flags */ if (dwModifier & COALESCEFLASG) @@ -1102,29 +1183,29 @@ BOOL HTTP_ProcessHeader(LPWININETHTTPREQA lpwhr, LPCSTR field, LPCSTR value, DWO } else /* Find or create new custom header */ { - index = HTTP_GetCustomHeaderIndex(lpwhr, field); - if (index >= 0) - { - if (dwModifier & HTTP_ADDHDR_FLAG_ADD_IF_NEW) - { - return FALSE; - } - lphttpHdr = &lpwhr->pCustHeaders[index]; - } - else - { - HTTPHEADERA hdr; + index = HTTP_GetCustomHeaderIndex(lpwhr, field); + if (index >= 0) + { + if (dwModifier & HTTP_ADDHDR_FLAG_ADD_IF_NEW) + { + return FALSE; + } + lphttpHdr = &lpwhr->pCustHeaders[index]; + } + else + { + HTTPHEADERA hdr; - hdr.lpszField = (LPSTR)field; - hdr.lpszValue = (LPSTR)value; - hdr.wFlags = hdr.wCount = 0; + hdr.lpszField = (LPSTR)field; + hdr.lpszValue = (LPSTR)value; + hdr.wFlags = hdr.wCount = 0; if (dwModifier & HTTP_ADDHDR_FLAG_REQ) hdr.wFlags |= HDR_ISREQUEST; - index = HTTP_InsertCustomHeader(lpwhr, &hdr); - return index >= 0; - } + index = HTTP_InsertCustomHeader(lpwhr, &hdr); + return index >= 0; + } } if (dwModifier & HTTP_ADDHDR_FLAG_REQ) @@ -1228,7 +1309,7 @@ BOOL HTTP_ProcessHeader(LPWININETHTTPREQA lpwhr, LPCSTR field, LPCSTR value, DWO } } } - + TRACE("<--\n"); return bSuccess; } @@ -1241,11 +1322,27 @@ BOOL HTTP_ProcessHeader(LPWININETHTTPREQA lpwhr, LPCSTR field, LPCSTR value, DWO */ VOID HTTP_CloseConnection(LPWININETHTTPREQA lpwhr) { + + + LPWININETHTTPSESSIONA lpwhs = NULL; + LPWININETAPPINFOA hIC = NULL; + + TRACE("%p\n",lpwhr); + + lpwhs = (LPWININETHTTPSESSIONA) lpwhr->hdr.lpwhparent; + hIC = (LPWININETAPPINFOA) lpwhs->hdr.lpwhparent; + + SendAsyncCallback(hIC, lpwhr, lpwhr->hdr.dwContext, + INTERNET_STATUS_CLOSING_CONNECTION, 0, 0); + if (lpwhr->nSocketFD != -1) { close(lpwhr->nSocketFD); lpwhr->nSocketFD = -1; } + + SendAsyncCallback(hIC, lpwhr, lpwhr->hdr.dwContext, + INTERNET_STATUS_CONNECTION_CLOSED, 0, 0); } @@ -1258,12 +1355,21 @@ VOID HTTP_CloseConnection(LPWININETHTTPREQA lpwhr) void HTTP_CloseHTTPRequestHandle(LPWININETHTTPREQA lpwhr) { int i; + LPWININETHTTPSESSIONA lpwhs = NULL; + LPWININETAPPINFOA hIC = NULL; TRACE("\n"); if (lpwhr->nSocketFD != -1) HTTP_CloseConnection(lpwhr); + lpwhs = (LPWININETHTTPSESSIONA) lpwhr->hdr.lpwhparent; + hIC = (LPWININETAPPINFOA) lpwhs->hdr.lpwhparent; + + SendAsyncCallback(hIC, lpwhr, lpwhr->hdr.dwContext, + INTERNET_STATUS_HANDLE_CLOSING, lpwhr, + sizeof(HINTERNET)); + if (lpwhr->lpszPath) HeapFree(GetProcessHeap(), 0, lpwhr->lpszPath); if (lpwhr->lpszVerb) @@ -1300,8 +1406,15 @@ void HTTP_CloseHTTPRequestHandle(LPWININETHTTPREQA lpwhr) */ void HTTP_CloseHTTPSessionHandle(LPWININETHTTPSESSIONA lpwhs) { + LPWININETAPPINFOA hIC = NULL; TRACE("\n"); + hIC = (LPWININETAPPINFOA) lpwhs->hdr.lpwhparent; + + SendAsyncCallback(hIC, lpwhs, lpwhs->hdr.dwContext, + INTERNET_STATUS_HANDLE_CLOSING, lpwhs, + sizeof(HINTERNET)); + if (lpwhs->lpszServerName) HeapFree(GetProcessHeap(), 0, lpwhs->lpszServerName); if (lpwhs->lpszUserName) @@ -1348,7 +1461,7 @@ INT HTTP_InsertCustomHeader(LPWININETHTTPREQA lpwhr, LPHTTPHEADERA lpHdr) INT count; LPHTTPHEADERA lph = NULL; - TRACE("%s: %s\n", lpHdr->lpszField, lpHdr->lpszValue); + TRACE("--> %s: %s\n", lpHdr->lpszField, lpHdr->lpszValue); count = lpwhr->nCustHeaders + 1; if (count > 1) lph = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, lpwhr->pCustHeaders, sizeof(HTTPHEADERA) * count); @@ -1383,6 +1496,6 @@ INT HTTP_InsertCustomHeader(LPWININETHTTPREQA lpwhr, LPHTTPHEADERA lpHdr) */ BOOL HTTP_DeleteCustomHeader(INT index) { - TRACE("\n"); + FIXME("STUB\n"); return FALSE; } diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c index 5f8f1c89214..06f22f84788 100644 --- a/dlls/wininet/internet.c +++ b/dlls/wininet/internet.c @@ -2,8 +2,10 @@ * Wininet * * Copyright 1999 Corel Corporation + * Copyright 2002 CodeWeavers Inc. * * Ulrich Czekalla + * Aric Stewart * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -267,7 +269,7 @@ HINTERNET WINAPI InternetConnectA(HINTERNET hInternet, { HINTERNET rc = (HINTERNET) NULL; - TRACE("\n"); + TRACE("ServerPort %i\n",nServerPort); /* Clear any error information */ INTERNET_SetLastError(0); @@ -387,15 +389,17 @@ BOOL WINAPI INTERNET_FindNextFileA(HINTERNET hFind, LPVOID lpvFindData) lend: hIC = GET_HWININET_FROM_LPWININETFINDNEXT(lpwh); - if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC && hIC->lpfnStatusCB) + if (hIC->lpfnStatusCB) { INTERNET_ASYNC_RESULT iar; iar.dwResult = (DWORD)bSuccess; - iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError(); + iar.dwError = iar.dwError = bSuccess ? ERROR_SUCCESS : + INTERNET_GetLastError(); - hIC->lpfnStatusCB(hFind, lpwh->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE, - &iar, sizeof(INTERNET_ASYNC_RESULT)); + SendAsyncCallback(hIC, hFind, lpwh->hdr.dwContext, + INTERNET_STATUS_REQUEST_COMPLETE, &iar, + sizeof(INTERNET_ASYNC_RESULT)); } return bSuccess; @@ -413,6 +417,12 @@ lend: */ VOID INTERNET_CloseHandle(LPWININETAPPINFOA lpwai) { + TRACE("%p\n",lpwai); + + SendAsyncCallback(lpwai, lpwai, lpwai->hdr.dwContext, + INTERNET_STATUS_HANDLE_CLOSING, lpwai, + sizeof(HINTERNET)); + if (lpwai->lpszAgent) HeapFree(GetProcessHeap(), 0, lpwai->lpszAgent); @@ -441,7 +451,7 @@ BOOL WINAPI InternetCloseHandle(HINTERNET hInternet) BOOL retval = FALSE; LPWININETHANDLEHEADER lpwh = (LPWININETHANDLEHEADER) hInternet; - TRACE("\n"); + TRACE("%p\n",hInternet); if (NULL == lpwh) return FALSE; @@ -672,6 +682,8 @@ BOOL WINAPI InternetCrackUrlA(LPCSTR lpszUrl, DWORD dwUrlLength, DWORD dwFlags, if (lpszPort != lpszNetLoc) lpUrlComponents->nPort = atoi(++lpszPort); + else + lpUrlComponents->nPort = 0; } } @@ -851,11 +863,9 @@ BOOL WINAPI InternetWriteFile(HINTERNET hFile, LPCVOID lpBuffer , if (nSocket != -1) { - *lpdwNumOfBytesWritten = INTERNET_WriteDataToStream(nSocket, lpBuffer, dwNumOfBytesToWrite); - if (*lpdwNumOfBytesWritten < 0) - *lpdwNumOfBytesWritten = 0; - else - retval = TRUE; + int res = send(nSocket, lpBuffer, dwNumOfBytesToWrite, 0); + retval = (res >= 0); + *lpdwNumOfBytesWritten = retval ? res : 0; } return retval; @@ -880,6 +890,7 @@ BOOL WINAPI InternetReadFile(HINTERNET hFile, LPVOID lpBuffer, LPWININETHANDLEHEADER lpwh = (LPWININETHANDLEHEADER) hFile; TRACE("\n"); + if (NULL == lpwh) return FALSE; @@ -899,13 +910,10 @@ BOOL WINAPI InternetReadFile(HINTERNET hFile, LPVOID lpBuffer, if (nSocket != -1) { - *dwNumOfBytesRead = INTERNET_ReadDataFromStream(nSocket, lpBuffer, dwNumOfBytesToRead); - if (*dwNumOfBytesRead < 0) - *dwNumOfBytesRead = 0; - else - retval = TRUE; + int res = recv(nSocket, lpBuffer, dwNumOfBytesToRead, 0); + retval = (res >= 0); + *dwNumOfBytesRead = retval ? res : 0; } - return retval; } @@ -938,25 +946,72 @@ BOOL WINAPI InternetQueryOptionA(HINTERNET hInternet, DWORD dwOption, switch (dwOption) { - case INTERNET_OPTION_HANDLE_TYPE: + case INTERNET_OPTION_HANDLE_TYPE: + { + ULONG type = lpwhh->htype; + TRACE("INTERNET_OPTION_HANDLE_TYPE: %ld\n", type); + + if (*lpdwBufferLength < sizeof(ULONG)) + INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER); + else + { + memcpy(lpBuffer, &type, sizeof(ULONG)); + *lpdwBufferLength = sizeof(ULONG); + bSuccess = TRUE; + } + break; + } + + case INTERNET_OPTION_REQUEST_FLAGS: + { + ULONG flags = 4; + TRACE("INTERNET_OPTION_REQUEST_FLAGS: %ld\n", flags); + if (*lpdwBufferLength < sizeof(ULONG)) + INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER); + else + { + memcpy(lpBuffer, &flags, sizeof(ULONG)); + *lpdwBufferLength = sizeof(ULONG); + bSuccess = TRUE; + } + break; + } + + case INTERNET_OPTION_URL: + case INTERNET_OPTION_DATAFILE_NAME: + { + ULONG type = lpwhh->htype; + if (type == WH_HHTTPREQ) + { + LPWININETHTTPREQA lpreq = hInternet; + char url[1023]; + + sprintf(url,"http://%s%s",lpreq->lpszHostName,lpreq->lpszPath); + TRACE("INTERNET_OPTION_URL: %s\n",url); + if (*lpdwBufferLength < strlen(url)+1) + INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER); + else + { + memcpy(lpBuffer, url, strlen(url)+1); + *lpdwBufferLength = strlen(url)+1; + bSuccess = TRUE; + } + } + break; + } + case INTERNET_OPTION_HTTP_VERSION: { - ULONG type = lpwhh->htype; - TRACE("INTERNET_OPTION_HANDLE_TYPE: %ld\n", type); - - if (*lpdwBufferLength < sizeof(ULONG)) - INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER); - else - { - memcpy(lpBuffer, &type, sizeof(ULONG)); - *lpdwBufferLength = sizeof(ULONG); - bSuccess = TRUE; - } - - break; + /* + * Presently hardcoded to 1.1 + */ + ((HTTP_VERSION_INFO*)lpBuffer)->dwMajorVersion = 1; + ((HTTP_VERSION_INFO*)lpBuffer)->dwMinorVersion = 1; + bSuccess = TRUE; + break; } default: - FIXME("Stub!\n"); + FIXME("Stub! %ld \n",dwOption); break; } @@ -1069,6 +1124,7 @@ BOOL WINAPI InternetSetCookieA( */ INTERNET_SCHEME GetInternetScheme(LPCSTR lpszScheme, INT nMaxCmp) { + TRACE("\n"); if(lpszScheme==NULL) return INTERNET_SCHEME_UNKNOWN; @@ -1114,6 +1170,8 @@ BOOL WINAPI InternetCheckConnectionA( LPCSTR lpszUrl, DWORD dwFlags, DWORD dwRes char host[1024]; int status = -1; + FIXME("\n"); + /* * Crack or set the Address */ @@ -1243,43 +1301,6 @@ HINTERNET WINAPI InternetOpenUrlA(HINTERNET hInternet, LPCSTR lpszUrl, LPCSTR lp InternetCloseHandle(client); } -/*********************************************************************** - * INTERNET_WriteDataToStream (internal) - * - * Send data to server - * - * RETURNS - * - * number of characters sent on success - * -1 on error - */ -int INTERNET_WriteDataToStream(int nDataSocket, LPCVOID Buffer, DWORD BytesToWrite) -{ - if (nDataSocket == -1) - return -1; - - return send(nDataSocket, Buffer, BytesToWrite, 0); -} - - -/*********************************************************************** - * INTERNET_ReadDataFromStream (internal) - * - * Read data from http server - * - * RETURNS - * - * number of characters sent on success - * -1 on error - */ -int INTERNET_ReadDataFromStream(int nDataSocket, LPVOID Buffer, DWORD BytesToRead) -{ - if (nDataSocket == -1) - return -1; - - return recv(nDataSocket, Buffer, BytesToRead, 0); -} - /*********************************************************************** * INTERNET_SetLastError (internal) @@ -1581,6 +1602,12 @@ VOID INTERNET_ExecuteWork() HeapFree(GetProcessHeap(), 0, (LPVOID)workRequest.LPSZREFERRER); break; + case SENDCALLBACK: + SendAsyncCallbackInt((LPWININETAPPINFOA)workRequest.param1, + (HINTERNET)workRequest.param2, workRequest.param3, + workRequest.param4, (LPVOID)workRequest.param5, + workRequest.param6); + break; } } } @@ -1595,6 +1622,7 @@ VOID INTERNET_ExecuteWork() LPSTR INTERNET_GetResponseBuffer() { LPWITHREADERROR lpwite = (LPWITHREADERROR)TlsGetValue(g_dwTlsErrIndex); + TRACE("\n"); return lpwite->response; } @@ -1662,3 +1690,70 @@ lend: return NULL; } } + +/*********************************************************************** + * + */ +BOOL WINAPI InternetQueryDataAvailable( HINTERNET hFile, + LPDWORD lpdwNumberOfBytesAvailble, + DWORD dwFlags, DWORD dwConext) +{ + LPWININETHTTPREQA lpwhr = (LPWININETHTTPREQA) hFile; + INT retval = -1; + int nSocket = -1; + + + if (NULL == lpwhr) + { + SetLastError(ERROR_NO_MORE_FILES); + return FALSE; + } + + TRACE("--> %p %i %i\n",lpwhr,lpwhr->hdr.htype,lpwhr->nSocketFD); + + switch (lpwhr->hdr.htype) + { + case WH_HHTTPREQ: + nSocket = lpwhr->nSocketFD; + break; + + default: + break; + } + + if (nSocket != -1) + { + char buffer[4048]; + + retval = recv(nSocket,buffer,4048,MSG_PEEK); + } + else + { + SetLastError(ERROR_NO_MORE_FILES); + } + + if (lpdwNumberOfBytesAvailble) + { + (*lpdwNumberOfBytesAvailble) = retval; + } + + TRACE("<-- %i\n",retval); + return (retval+1); +} + + +/*********************************************************************** + * + */ +BOOL WINAPI InternetLockRequestFile( HINTERNET hInternet, HANDLE +*lphLockReqHandle) +{ + FIXME("STUB\n"); + return FALSE; +} + +BOOL WINAPI InternetUnlockRequestFile( HANDLE hLockHandle) +{ + FIXME("STUB\n"); + return FALSE; +} diff --git a/dlls/wininet/internet.h b/dlls/wininet/internet.h index 6ecf1bd8474..02d23e55793 100644 --- a/dlls/wininet/internet.h +++ b/dlls/wininet/internet.h @@ -154,6 +154,7 @@ typedef enum INTERNETFINDNEXTA, HTTPSENDREQUESTA, HTTPOPENREQUESTA, + SENDCALLBACK, } ASYNC_FUNC; typedef struct WORKREQ @@ -220,8 +221,6 @@ HINTERNET HTTP_Connect(HINTERNET hInterent, LPCSTR lpszServerName, BOOL GetAddress(LPCSTR lpszServerName, INTERNET_PORT nServerPort, struct hostent **phe, struct sockaddr_in *psa); -int INTERNET_WriteDataToStream(int nDataSocket, LPCVOID Buffer, DWORD BytesToWrite); -int INTERNET_ReadDataFromStream(int nDataSocket, LPVOID Buffer, DWORD BytesToRead); void INTERNET_SetLastError(DWORD dwError); DWORD INTERNET_GetLastError(); BOOL INTERNET_AsyncCall(LPWORKREQUEST lpWorkRequest); @@ -257,6 +256,14 @@ INTERNETAPI HINTERNET WINAPI HTTP_HttpOpenRequestA(HINTERNET hHttpSession, void HTTP_CloseHTTPSessionHandle(LPWININETHTTPSESSIONA lpwhs); void HTTP_CloseHTTPRequestHandle(LPWININETHTTPREQA lpwhr); +VOID SendAsyncCallback(LPWININETAPPINFOA hIC, HINTERNET hHttpSession, + DWORD dwContext, DWORD dwInternetStatus, LPVOID + lpvStatusInfo , DWORD dwStatusInfoLength); + +VOID SendAsyncCallbackInt(LPWININETAPPINFOA hIC, HINTERNET hHttpSession, + DWORD dwContext, DWORD dwInternetStatus, LPVOID + lpvStatusInfo , DWORD dwStatusInfoLength); + #define MAX_REPLY_LEN 0x5B4 diff --git a/dlls/wininet/tests/.cvsignore b/dlls/wininet/tests/.cvsignore new file mode 100644 index 00000000000..1beb01d6632 --- /dev/null +++ b/dlls/wininet/tests/.cvsignore @@ -0,0 +1,3 @@ +http.ok +testlist.c +wininet_test.exe.spec.c diff --git a/dlls/wininet/tests/http.c b/dlls/wininet/tests/http.c new file mode 100644 index 00000000000..94408177d84 --- /dev/null +++ b/dlls/wininet/tests/http.c @@ -0,0 +1,186 @@ +#include +#include "winbase.h" +#include "wininet.h" +#include "wine/test.h" + +int goon = 0; + +VOID WINAPI callback( + HINTERNET hInternet, + DWORD dwContext, + DWORD dwInternetStatus, + LPVOID lpvStatusInformation, + DWORD dwStatusInformationLength +) +{ + char name[124]; + + switch (dwInternetStatus) + { + case INTERNET_STATUS_RESOLVING_NAME: + strcpy(name,"INTERNET_STATUS_RESOLVING_NAME"); + break; + case INTERNET_STATUS_NAME_RESOLVED: + strcpy(name,"INTERNET_STATUS_NAME_RESOLVED"); + break; + case INTERNET_STATUS_CONNECTING_TO_SERVER: + strcpy(name,"INTERNET_STATUS_CONNECTING_TO_SERVER"); + break; + case INTERNET_STATUS_CONNECTED_TO_SERVER: + strcpy(name,"INTERNET_STATUS_CONNECTED_TO_SERVER"); + break; + case INTERNET_STATUS_SENDING_REQUEST: + strcpy(name,"INTERNET_STATUS_SENDING_REQUEST"); + break; + case INTERNET_STATUS_REQUEST_SENT: + strcpy(name,"INTERNET_STATUS_REQUEST_SENT"); + break; + case INTERNET_STATUS_RECEIVING_RESPONSE: + strcpy(name,"INTERNET_STATUS_RECEIVING_RESPONSE"); + break; + case INTERNET_STATUS_RESPONSE_RECEIVED: + strcpy(name,"INTERNET_STATUS_RESPONSE_RECEIVED"); + break; + case INTERNET_STATUS_CTL_RESPONSE_RECEIVED: + strcpy(name,"INTERNET_STATUS_CTL_RESPONSE_RECEIVED"); + break; + case INTERNET_STATUS_PREFETCH: + strcpy(name,"INTERNET_STATUS_PREFETCH"); + break; + case INTERNET_STATUS_CLOSING_CONNECTION: + strcpy(name,"INTERNET_STATUS_CLOSING_CONNECTION"); + break; + case INTERNET_STATUS_CONNECTION_CLOSED: + strcpy(name,"INTERNET_STATUS_CONNECTION_CLOSED"); + break; + case INTERNET_STATUS_HANDLE_CREATED: + strcpy(name,"INTERNET_STATUS_HANDLE_CREATED"); + break; + case INTERNET_STATUS_HANDLE_CLOSING: + strcpy(name,"INTERNET_STATUS_HANDLE_CLOSING"); + break; + case INTERNET_STATUS_REQUEST_COMPLETE: + strcpy(name,"INTERNET_STATUS_REQUEST_COMPLETE"); + goon = 1; + break; + case INTERNET_STATUS_REDIRECT: + strcpy(name,"INTERNET_STATUS_REDIRECT"); + break; + case INTERNET_STATUS_INTERMEDIATE_RESPONSE: + strcpy(name,"INTERNET_STATUS_INTERMEDIATE_RESPONSE"); + break; + } + + trace("Callback %p 0x%lx %s(%li) %p %ld\n",hInternet,dwContext,name,dwInternetStatus,lpvStatusInformation,dwStatusInformationLength); +} + +void winapi_test(int flags) +{ + DWORD rc; + CHAR buffer[4000]; + DWORD length; + DWORD out; + char *types; + HINTERNET hi,hic,hor; + + trace("Starting with flags 0x%x\n",flags); + + trace("InternetOpenA <--\n"); + hi = InternetOpenA("",0x0,0x0,0x0,flags); + ok((hi != 0x0),"InternetOpen Failed"); + trace("InternetOpenA -->\n"); + + InternetSetStatusCallback(hi,&callback); + + trace("InternetConnectA <--\n"); + hic=InternetConnectA(hi,"www.winehq.com",0x0,0x0,0x0,0x3,0x0,0xdeadbeef); + ok((hic != 0x0),"InternetConnect Failed"); + trace("InternetConnectA -->\n"); + + types = (char*)malloc(100); + strcpy(types,"*"); + + trace("HttpOpenRequestA <--\n"); + hor = HttpOpenRequestA(hic, "GET", + "/about/", + 0x0,0x0,(const char**)&types,0x00400800,0xdeadbead); + + ok((hor != 0x0),"HttpOpenRequest Failed"); + trace("HttpOpenRequestA -->\n"); + + trace("HttpSendRequestA -->\n"); + rc = HttpSendRequestA(hor, "", 0xffffffff,0x0,0x0); + if (flags) + ok(((rc == 0)&&(GetLastError()==997)), + "Asyncronous HttpSendRequest NOT returning 0 with error 997"); + else + ok((rc != 0), "Syncronous HttpSendRequest returning 0"); + trace("HttpSendRequestA <--\n"); + + while ((flags)&&(!goon)) + Sleep(100); + + length = 4; + rc = InternetQueryOptionA(hor,0x17,&out,&length); + trace("Option 0x17 -> %li %li\n",rc,out); + + length = 100; + rc = InternetQueryOptionA(hor,0x22,buffer,&length); + trace("Option 0x22 -> %li %s\n",rc,buffer); + + length = 4000; + rc = HttpQueryInfoA(hor,0x16,buffer,&length,0x0); + buffer[length]=0; + trace("Option 0x16 -> %li %s\n",rc,buffer); + + length = 4000; + rc = InternetQueryOptionA(hor,0x22,buffer,&length); + buffer[length]=0; + trace("Option 0x22 -> %li %s\n",rc,buffer); + + length = 16; + rc = HttpQueryInfoA(hor,0x5,&buffer,&length,0x0); + trace("Option 0x5 -> %li %s (%li)\n",rc,buffer,GetLastError()); + + length = 100; + rc = HttpQueryInfoA(hor,0x1,buffer,&length,0x0); + buffer[length]=0; + trace("Option 0x1 -> %li %s\n",rc,buffer); + + length = 100; + trace("Entery Query loop\n"); + + while (length) + { + + rc = InternetQueryDataAvailable(hor,&length,0x0,0x0); + ok((rc != 0),"InternetQueryDataAvailable failed"); + + if (length) + { + char *buffer; + buffer = (char*)HeapAlloc(GetProcessHeap(),0,length+1); + + rc = InternetReadFile(hor,buffer,length,&length); + + buffer[length]=0; + + trace("ReadFile -> %li %li\n",rc,length); + + HeapFree(GetProcessHeap(),0,buffer); + } + } + rc = InternetCloseHandle(hi); + ok ((rc != 0), "InternetCloseHandle failed"); + rc = InternetCloseHandle(hor); + ok ((rc != 0), "InternetCloseHandle failed"); + if (flags) + Sleep(100); +} + + +START_TEST(http) +{ + winapi_test(0x10000000); + winapi_test(0x00000000); +} diff --git a/dlls/wininet/urlcache.c b/dlls/wininet/urlcache.c index c7f5fce56cd..e3717efcd85 100644 --- a/dlls/wininet/urlcache.c +++ b/dlls/wininet/urlcache.c @@ -1,9 +1,10 @@ /* * Wininet - Url Cache functions * - * Copyright 2001 CodeWeavers + * Copyright 2001,2002 CodeWeavers * * Eric Kohl + * Aric Stewart * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -39,11 +40,29 @@ WINE_DEFAULT_DEBUG_CHANNEL(wininet); INTERNETAPI HANDLE WINAPI FindFirstUrlCacheEntryA(LPCSTR lpszUrlSearchPattern, LPINTERNET_CACHE_ENTRY_INFOA lpFirstCacheEntryInfo, LPDWORD lpdwFirstCacheEntryInfoBufferSize) { + FIXME("STUB\n"); return 0; } INTERNETAPI HANDLE WINAPI FindFirstUrlCacheEntryW(LPCWSTR lpszUrlSearchPattern, LPINTERNET_CACHE_ENTRY_INFOW lpFirstCacheEntryInfo, LPDWORD lpdwFirstCacheEntryInfoBufferSize) { + FIXME("STUB\n"); return 0; } + +BOOL WINAPI RetrieveUrlCacheEntryFileA (LPCSTR lpszUrlName, + LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntryInfo, LPDWORD + lpdwCacheEntryInfoBufferSize, DWORD dwReserved) +{ + FIXME("STUB\n"); + SetLastError(ERROR_FILE_NOT_FOUND); + return FALSE; +} + +BOOL WINAPI DeleteUrlCacheEntry(LPCSTR lpszUrlName) +{ + FIXME("STUB (%s)\n",lpszUrlName); + SetLastError(ERROR_FILE_NOT_FOUND); + return FALSE; +} diff --git a/dlls/wininet/utility.c b/dlls/wininet/utility.c index 1cff5606df9..0f0d4ee3053 100644 --- a/dlls/wininet/utility.c +++ b/dlls/wininet/utility.c @@ -2,8 +2,10 @@ * Wininet - Utility functions * * Copyright 1999 Corel Corporation + * Copyright 2002 CodeWeavers Inc. * * Ulrich Czekalla + * Aric Stewart * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -161,3 +163,52 @@ BOOL GetAddress(LPCSTR lpszServerName, INTERNET_PORT nServerPort, return TRUE; } + +/* + * Helper function for sending async Callbacks + */ + +VOID SendAsyncCallbackInt(LPWININETAPPINFOA hIC, HINTERNET hHttpSession, + DWORD dwContext, DWORD dwInternetStatus, LPVOID + lpvStatusInfo, DWORD dwStatusInfoLength) +{ + if (! (hIC->lpfnStatusCB)) + return; + + TRACE("--> Callback %ld\n",dwInternetStatus); + + hIC->lpfnStatusCB(hHttpSession, dwContext, dwInternetStatus, + lpvStatusInfo, dwStatusInfoLength); + + TRACE("<-- Callback %ld\n",dwInternetStatus); +} + + + +VOID SendAsyncCallback(LPWININETAPPINFOA hIC, HINTERNET hHttpSession, + DWORD dwContext, DWORD dwInternetStatus, LPVOID + lpvStatusInfo, DWORD dwStatusInfoLength) +{ + TRACE("Send Callback %ld\n",dwInternetStatus); + + if (! (hIC->lpfnStatusCB)) + return; + if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC) + { + WORKREQUEST workRequest; + + workRequest.asyncall = SENDCALLBACK; + + workRequest.param1 = (DWORD)hIC; + workRequest.param2 = (DWORD)hHttpSession; + workRequest.param3 = dwContext; + workRequest.param4 = dwInternetStatus; + workRequest.param5 = (DWORD)lpvStatusInfo; + workRequest.param6 = dwStatusInfoLength; + + INTERNET_AsyncCall(&workRequest); + } + else + SendAsyncCallbackInt(hIC, hHttpSession, dwContext, dwInternetStatus, + lpvStatusInfo, dwStatusInfoLength); +} diff --git a/dlls/wininet/version.rc b/dlls/wininet/version.rc new file mode 100644 index 00000000000..4e564cf4e4e --- /dev/null +++ b/dlls/wininet/version.rc @@ -0,0 +1,29 @@ +/* + * Copyright 2002 CodeWeavers + * + * Aric Stewart + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define WINE_FILEDESCRIPTION_STR "Wine WinInet" +#define WINE_FILENAME_STR "wininet.dll" +#define WINE_FILEVERSION 5,0,0,0 +#define WINE_FILEVERSION_STR "5.0.0.0" +#define WINE_PRODUCTVERSION 5,0,0,0 +#define WINE_PRODUCTVERSION_STR "5.0" +#define WINE_PRODUCTNAME_STR "wininet" + +#include "wine/wine_common_ver.rc" diff --git a/dlls/wininet/wininet.spec b/dlls/wininet/wininet.spec index 6042b693b6b..e1c839c3bb1 100644 --- a/dlls/wininet/wininet.spec +++ b/dlls/wininet/wininet.spec @@ -12,7 +12,7 @@ init WININET_LibMain @ stub DeleteIE3Cache @ stub DeleteUrlCacheContainerA @ stub DeleteUrlCacheContainerW -@ stub DeleteUrlCacheEntry +@ stdcall DeleteUrlCacheEntry(str) DeleteUrlCacheEntry @ stub DeleteUrlCacheGroup @ stdcall DllInstall(long ptr) WININET_DllInstall @ stub FindCloseUrlCache @@ -111,13 +111,13 @@ init WININET_LibMain @ stub InternetGetLastResponseInfoW @ stub InternetGoOnline @ stub InternetHangUp -@ stub InternetLockRequestFile +@ stdcall InternetLockRequestFile(ptr ptr) InternetLockRequestFile @ stdcall InternetOpenA(str long str str long) InternetOpenA @ stub InternetOpenServerPushParse @ stdcall InternetOpenUrlA(ptr str str long long long) InternetOpenUrlA @ stub InternetOpenUrlW @ stub InternetOpenW -@ stub InternetQueryDataAvailable +@ stdcall InternetQueryDataAvailable(ptr ptr long long) InternetQueryDataAvailable @ stdcall InternetQueryOptionA(ptr long ptr ptr) InternetQueryOptionA @ stub InternetQueryOptionW @ stdcall InternetReadFile(ptr ptr long ptr) InternetReadFile @@ -136,7 +136,7 @@ init WININET_LibMain @ stub InternetShowSecurityInfoByURL @ stub InternetTimeFromSystemTime @ stub InternetTimeToSystemTime -@ stub InternetUnlockRequestFile +@ stdcall InternetUnlockRequestFile(ptr) InternetUnlockRequestFile @ stdcall InternetWriteFile(ptr ptr long ptr) InternetWriteFile @ stub InternetWriteFileExA @ stub InternetWriteFileExW @@ -144,7 +144,7 @@ init WININET_LibMain @ stub LoadUrlCacheContent @ stub ParseX509EncodedCertificateForListBoxEntry @ stub ReadUrlCacheEntryStream -@ stub RetrieveUrlCacheEntryFileA +@ stdcall RetrieveUrlCacheEntryFileA(str ptr ptr long) RetrieveUrlCacheEntryFileA @ stub RetrieveUrlCacheEntryFileW @ stub RetrieveUrlCacheEntryStreamA @ stub RetrieveUrlCacheEntryStreamW