[WINHTTP] Properly initialize winsock. Based on wine tests CORE-12104
[reactos.git] / reactos / dll / win32 / winhttp / session.c
index ff49e21..960619a 100644 (file)
@@ -42,9 +42,12 @@ DWORD get_last_error( void )
 
 void send_callback( object_header_t *hdr, DWORD status, LPVOID info, DWORD buflen )
 {
-    TRACE("%p, 0x%08x, %p, %u\n", hdr, status, info, buflen);
-
-    if (hdr->callback && (hdr->notify_mask & status)) hdr->callback( hdr->handle, hdr->context, status, info, buflen );
+    if (hdr->callback && (hdr->notify_mask & status))
+    {
+        TRACE("%p, 0x%08x, %p, %u\n", hdr, status, info, buflen);
+        hdr->callback( hdr->handle, hdr->context, status, info, buflen );
+        TRACE("returning from 0x%08x callback\n", status);
+    }
 }
 
 /***********************************************************************
@@ -67,6 +70,8 @@ static void session_destroy( object_header_t *hdr )
 
     TRACE("%p\n", session);
 
+    if (session->unload_event) SetEvent( session->unload_event );
+
     LIST_FOR_EACH_SAFE( item, next, &session->cookie_cache )
     {
         domain = LIST_ENTRY( item, domain_t, entry );
@@ -78,9 +83,6 @@ static void session_destroy( object_header_t *hdr )
     heap_free( session->proxy_username );
     heap_free( session->proxy_password );
     heap_free( session );
-#ifdef __REACTOS__
-    WSACleanup();
-#endif
 }
 
 static BOOL session_query_option( object_header_t *hdr, DWORD option, LPVOID buffer, LPDWORD buflen )
@@ -171,6 +173,10 @@ static BOOL session_set_option( object_header_t *hdr, DWORD option, LPVOID buffe
     case WINHTTP_OPTION_CONFIGURE_PASSPORT_AUTH:
         FIXME("WINHTTP_OPTION_CONFIGURE_PASSPORT_AUTH: 0x%x\n", *(DWORD *)buffer);
         return TRUE;
+    case WINHTTP_OPTION_UNLOAD_NOTIFY_EVENT:
+        TRACE("WINHTTP_OPTION_UNLOAD_NOTIFY_EVENT: %p\n", *(HANDLE *)buffer);
+        session->unload_event = *(HANDLE *)buffer;
+        return TRUE;
     default:
         FIXME("unimplemented option %u\n", option);
         set_last_error( ERROR_INVALID_PARAMETER );
@@ -185,6 +191,9 @@ static const object_vtbl_t session_vtbl =
     session_set_option
 };
 
+#ifdef __REACTOS__
+BOOL netconn_init_winsock();
+#endif /* __REACTOS__ */
 /***********************************************************************
  *          WinHttpOpen (winhttp.@)
  */
@@ -193,9 +202,7 @@ HINTERNET WINAPI WinHttpOpen( LPCWSTR agent, DWORD access, LPCWSTR proxy, LPCWST
     session_t *session;
     HINTERNET handle = NULL;
 #ifdef __REACTOS__
-    WSADATA wsaData;
-    int error = WSAStartup(MAKEWORD(2, 2), &wsaData);
-    if (error) ERR("WSAStartup failed: %d\n", error);
+    if (!netconn_init_winsock()) return NULL;
 #endif
 
     TRACE("%s, %u, %s, %s, 0x%08x\n", debugstr_w(agent), access, debugstr_w(proxy), debugstr_w(bypass), flags);
@@ -247,6 +254,7 @@ HINTERNET WINAPI WinHttpOpen( LPCWSTR agent, DWORD access, LPCWSTR proxy, LPCWST
 end:
     release_object( &session->hdr );
     TRACE("returning %p\n", handle);
+    if (handle) set_last_error( ERROR_SUCCESS );
     return handle;
 }
 
@@ -523,6 +531,7 @@ end:
     release_object( &connect->hdr );
     release_object( &session->hdr );
     TRACE("returning %p\n", hconnect);
+    if (hconnect) set_last_error( ERROR_SUCCESS );
     return hconnect;
 }
 
@@ -532,10 +541,20 @@ end:
 static void request_destroy( object_header_t *hdr )
 {
     request_t *request = (request_t *)hdr;
-    unsigned int i;
+    unsigned int i, j;
 
     TRACE("%p\n", request);
 
+    if (request->task_thread)
+    {
+        /* Signal to the task proc to quit.  It will call
+           this again when it does. */
+        HANDLE thread = request->task_thread;
+        request->task_thread = 0;
+        SetEvent( request->task_cancel );
+        CloseHandle( thread );
+        return;
+    }
     release_object( &request->connect->hdr );
 
     destroy_authinfo( request->authinfo );
@@ -554,6 +573,14 @@ static void request_destroy( object_header_t *hdr )
     heap_free( request->headers );
     for (i = 0; i < request->num_accept_types; i++) heap_free( request->accept_types[i] );
     heap_free( request->accept_types );
+    for (i = 0; i < TARGET_MAX; i++)
+    {
+        for (j = 0; j < SCHEME_MAX; j++)
+        {
+            heap_free( request->creds[i][j].username );
+            heap_free( request->creds[i][j].password );
+        }
+    }
     heap_free( request );
 }
 
@@ -1037,6 +1064,7 @@ HINTERNET WINAPI WinHttpOpenRequest( HINTERNET hconnect, LPCWSTR verb, LPCWSTR o
     request->hdr.context = connect->hdr.context;
     request->hdr.redirect_policy = connect->hdr.redirect_policy;
     list_init( &request->hdr.children );
+    list_init( &request->task_queue );
 
     addref_object( &connect->hdr );
     request->connect = connect;
@@ -1079,6 +1107,7 @@ end:
     release_object( &request->hdr );
     release_object( &connect->hdr );
     TRACE("returning %p\n", hrequest);
+    if (hrequest) set_last_error( ERROR_SUCCESS );
     return hrequest;
 }
 
@@ -1098,6 +1127,7 @@ BOOL WINAPI WinHttpCloseHandle( HINTERNET handle )
     }
     release_object( hdr );
     free_handle( handle );
+    set_last_error( ERROR_SUCCESS );
     return TRUE;
 }
 
@@ -1158,6 +1188,7 @@ BOOL WINAPI WinHttpQueryOption( HINTERNET handle, DWORD option, LPVOID buffer, L
     ret = query_option( hdr, option, buffer, buflen );
 
     release_object( hdr );
+    if (ret) set_last_error( ERROR_SUCCESS );
     return ret;
 }
 
@@ -1216,6 +1247,7 @@ BOOL WINAPI WinHttpSetOption( HINTERNET handle, DWORD option, LPVOID buffer, DWO
     ret = set_option( hdr, option, buffer, buflen );
 
     release_object( hdr );
+    if (ret) set_last_error( ERROR_SUCCESS );
     return ret;
 }
 
@@ -1297,7 +1329,8 @@ static BOOL get_system_proxy_autoconfig_url( char *buf, DWORD buflen )
     CFRelease( settings );
     return ret;
 #else
-    FIXME( "no support on this platform\n" );
+    static int once;
+    if (!once++) FIXME( "no support on this platform\n" );
     return FALSE;
 #endif
 }
@@ -1325,6 +1358,7 @@ BOOL WINAPI WinHttpDetectAutoProxyConfigUrl( DWORD flags, LPWSTR *url )
 
         if (!(urlW = strdupAW( system_url ))) return FALSE;
         *url = urlW;
+        set_last_error( ERROR_SUCCESS );
         return TRUE;
     }
     if (flags & WINHTTP_AUTO_DETECT_TYPE_DHCP)
@@ -1385,6 +1419,7 @@ BOOL WINAPI WinHttpDetectAutoProxyConfigUrl( DWORD flags, LPWSTR *url )
         set_last_error( ERROR_WINHTTP_AUTODETECTION_FAILED );
         *url = NULL;
     }
+    else set_last_error( ERROR_SUCCESS );
     return ret;
 }
 
@@ -1552,6 +1587,7 @@ BOOL WINAPI WinHttpGetDefaultProxyConfiguration( WINHTTP_PROXY_INFO *info )
         info->lpszProxy       = NULL;
         info->lpszProxyBypass = NULL;
     }
+    set_last_error( ERROR_SUCCESS );
     return TRUE;
 }
 
@@ -1634,6 +1670,7 @@ done:
         GlobalFree( config->lpszProxyBypass );
         config->lpszProxyBypass = NULL;
     }
+    else set_last_error( ERROR_SUCCESS );
     return ret;
 }
 
@@ -1818,6 +1855,7 @@ BOOL WINAPI WinHttpGetProxyForUrl( HINTERNET hsession, LPCWSTR url, WINHTTP_AUTO
 done:
     GlobalFree( detected_pac_url );
     release_object( &session->hdr );
+    if (ret) set_last_error( ERROR_SUCCESS );
     return ret;
 }
 
@@ -1925,6 +1963,7 @@ BOOL WINAPI WinHttpSetDefaultProxyConfiguration( WINHTTP_PROXY_INFO *info )
         }
         RegCloseKey( key );
     }
+    if (ret) set_last_error( ERROR_SUCCESS );
     return ret;
 }
 
@@ -1949,6 +1988,7 @@ WINHTTP_STATUS_CALLBACK WINAPI WinHttpSetStatusCallback( HINTERNET handle, WINHT
     hdr->notify_mask = flags;
 
     release_object( hdr );
+    set_last_error( ERROR_SUCCESS );
     return ret;
 }
 
@@ -1996,8 +2036,6 @@ BOOL WINAPI WinHttpSetTimeouts( HINTERNET handle, int resolve, int connect, int
                 if (netconn_set_timeout( &request->netconn, TRUE, send )) ret = FALSE;
                 if (netconn_set_timeout( &request->netconn, FALSE, receive )) ret = FALSE;
             }
-
-            release_object( &request->hdr );
             break;
 
         case WINHTTP_HANDLE_TYPE_SESSION:
@@ -2015,10 +2053,11 @@ BOOL WINAPI WinHttpSetTimeouts( HINTERNET handle, int resolve, int connect, int
             break;
 
         default:
-            release_object( hdr );
             set_last_error( ERROR_WINHTTP_INCORRECT_HANDLE_TYPE );
-            return FALSE;
+            ret = FALSE;
     }
+    release_object( hdr );
+    if (ret) set_last_error( ERROR_SUCCESS );
     return ret;
 }
 
@@ -2041,7 +2080,11 @@ BOOL WINAPI WinHttpTimeFromSystemTime( const SYSTEMTIME *time, LPWSTR string )
 
     TRACE("%p, %p\n", time, string);
 
-    if (!time || !string) return FALSE;
+    if (!time || !string)
+    {
+        set_last_error( ERROR_INVALID_PARAMETER );
+        return FALSE;
+    }
 
     sprintfW( string, format,
               wkday[time->wDayOfWeek],
@@ -2052,6 +2095,7 @@ BOOL WINAPI WinHttpTimeFromSystemTime( const SYSTEMTIME *time, LPWSTR string )
               time->wMinute,
               time->wSecond );
 
+    set_last_error( ERROR_SUCCESS );
     return TRUE;
 }
 
@@ -2066,7 +2110,11 @@ BOOL WINAPI WinHttpTimeToSystemTime( LPCWSTR string, SYSTEMTIME *time )
 
     TRACE("%s, %p\n", debugstr_w(string), time);
 
-    if (!string || !time) return FALSE;
+    if (!string || !time)
+    {
+        set_last_error( ERROR_INVALID_PARAMETER );
+        return FALSE;
+    }
 
     /* Windows does this too */
     GetSystemTime( time );
@@ -2075,6 +2123,8 @@ BOOL WINAPI WinHttpTimeToSystemTime( LPCWSTR string, SYSTEMTIME *time )
      *  a SYSTEMTIME structure.
      */
 
+    set_last_error( ERROR_SUCCESS );
+
     while (*s && !isalphaW( *s )) s++;
     if (s[0] == '\0' || s[1] == '\0' || s[2] == '\0') return TRUE;
     time->wDayOfWeek = 7;