Reworking of http and asyncronous calls to get IE6 to install.
Added a version resource.
Added unit test for http.

diff --git a/configure b/configure
index 031f01d..1663aec 100755
--- a/configure
+++ b/configure
@@ -13079,6 +13079,8 @@
 
 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 @@
   "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/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 5a89e55..8f20a46 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1200,6 +1200,7 @@
 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 aaa584e..b45d952 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 bc41628..b73faed 100644
--- a/dlls/wininet/Makefile.in
+++ b/dlls/wininet/Makefile.in
@@ -17,6 +17,14 @@
 	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 aba3951..4ca1ed6 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 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 @@
         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 @@
 	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 @@
     LPWININETAPPINFOA hIC = NULL;
     LPWININETHTTPREQA lpwhr;
 
-    TRACE("\n");
+    TRACE("--> \n");
 
     if (NULL == lpwhs ||  lpwhs->hdr.htype != WH_HHTTPSESSION)
     {
@@ -238,10 +258,18 @@
 
     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 @@
         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 @@
                     strlen(lpwhr->StdHeaders[i].lpszValue) + delim + 2;
               }
            }
-
            size += delim;
 
            if (size + 1 > *lpdwBufferLength)
@@ -475,6 +518,7 @@
         }
 
         strncpy(lpBuffer, lphttpHdr->lpszValue, len);
+        ((char*)lpBuffer)[len]=0;
         *lpdwBufferLength = len;
         bSuccess = TRUE;
     }
@@ -544,14 +588,22 @@
     {
         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 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 @@
     /* Clear any error information */
     INTERNET_SetLastError(0);
 
+
     /* We must have a verb */
     if (NULL == lpwhr->lpszVerb)
     {
@@ -711,35 +765,50 @@
     /* 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 @@
     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 @@
 	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 @@
         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 @@
 	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 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 @@
 
     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 @@
        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 @@
     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 @@
 
 lend:
 
-    return bSuccess;
+    TRACE("<--\n");
+    if (bSuccess)
+        return rc;
+    else
+        return FALSE;
 }
 
 
@@ -1066,7 +1147,7 @@
         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 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 @@
     }
     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 @@
             }
         }
     }
-
+    TRACE("<--\n");
     return bSuccess;
 }
 
@@ -1241,11 +1322,27 @@
  */
 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_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_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 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 @@
  */
 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 5f8f1c8..06f22f8 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 rc = (HINTERNET) NULL;
 
-    TRACE("\n");
+    TRACE("ServerPort %i\n",nServerPort);
 
     /* Clear any error information */
     INTERNET_SetLastError(0);
@@ -387,15 +389,17 @@
 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 @@
  */
 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 retval = FALSE;
     LPWININETHANDLEHEADER lpwh = (LPWININETHANDLEHEADER) hInternet;
 
-    TRACE("\n");
+    TRACE("%p\n",hInternet);
     if (NULL == lpwh)
         return FALSE;
 
@@ -672,6 +682,8 @@
 
 	    if (lpszPort != lpszNetLoc)
                 lpUrlComponents->nPort = atoi(++lpszPort);
+            else
+                lpUrlComponents->nPort = 0;
             }
         }
 
@@ -851,11 +863,9 @@
 
     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 @@
     LPWININETHANDLEHEADER lpwh = (LPWININETHANDLEHEADER) hFile;
 
     TRACE("\n");
+
     if (NULL == lpwh)
         return FALSE;
 
@@ -899,13 +910,10 @@
 
     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 @@
 
     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 @@
  */
 INTERNET_SCHEME GetInternetScheme(LPCSTR lpszScheme, INT nMaxCmp)
 {
+    TRACE("\n");
     if(lpszScheme==NULL)
         return INTERNET_SCHEME_UNKNOWN;
 
@@ -1114,6 +1170,8 @@
   char host[1024];
   int status = -1;
 
+  FIXME("\n");
+
   /*
    * Crack or set the Address
    */
@@ -1243,43 +1301,6 @@
     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 @@
                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 @@
 LPSTR INTERNET_GetResponseBuffer()
 {
     LPWITHREADERROR lpwite = (LPWITHREADERROR)TlsGetValue(g_dwTlsErrIndex);
+    TRACE("\n");
     return lpwite->response;
 }
 
@@ -1662,3 +1690,70 @@
         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 6ecf1bd..02d23e5 100644
--- a/dlls/wininet/internet.h
+++ b/dlls/wininet/internet.h
@@ -154,6 +154,7 @@
     INTERNETFINDNEXTA,
     HTTPSENDREQUESTA,
     HTTPOPENREQUESTA,
+    SENDCALLBACK,
 } ASYNC_FUNC;
 
 typedef struct WORKREQ
@@ -220,8 +221,6 @@
 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 @@
 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 0000000..1beb01d
--- /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 0000000..9440817
--- /dev/null
+++ b/dlls/wininet/tests/http.c
@@ -0,0 +1,186 @@
+#include <stdio.h>
+#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 c7f5fce..e3717ef 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 @@
 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 1cff560..0f0d4ee 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 @@
 
     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 0000000..4e564cf
--- /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 6042b69..e1c839c 100644
--- a/dlls/wininet/wininet.spec
+++ b/dlls/wininet/wininet.spec
@@ -12,7 +12,7 @@
 @ 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 @@
 @ 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 @@
 @ 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 @@
 @ stub LoadUrlCacheContent
 @ stub ParseX509EncodedCertificateForListBoxEntry
 @ stub ReadUrlCacheEntryStream
-@ stub RetrieveUrlCacheEntryFileA
+@ stdcall RetrieveUrlCacheEntryFileA(str ptr ptr long) RetrieveUrlCacheEntryFileA
 @ stub RetrieveUrlCacheEntryFileW
 @ stub RetrieveUrlCacheEntryStreamA
 @ stub RetrieveUrlCacheEntryStreamW