As we implement some more functions in the network stack now, I could remove some hacks from the "wininet_ros.diff" file.
Anyways, the following things still needed to be changed:
- Pass a variable to WriteFile for receiving the number of bytes written. This parameter is not checked for NULL in ReactOS and Windows, when lpOverlapped is also NULL.
I'll submit a patch about this to Wine as well.
- Replace Unix poll() calls by equivalent select() calls
- Bypass sock_get_error(), directly call WSAGetLastError() as we don't have to translate Unix socket errors.
See issue #3197 for more details.
svn path=/trunk/; revision=33788
DWORD WINAPI InternetSetCookieExA( LPCSTR lpszURL, LPCSTR lpszCookieName, LPCSTR lpszCookieData,
DWORD dwFlags, DWORD_PTR dwReserved)
{
- FIXME("(%s, %s, %s, 0x%08x, 0x%08lx) stub\n",
+ TRACE("(%s, %s, %s, 0x%08x, 0x%08lx)\n",
debugstr_a(lpszURL), debugstr_a(lpszCookieName), debugstr_a(lpszCookieData),
dwFlags, dwReserved);
- return TRUE;
+
+ if (dwFlags) FIXME("flags 0x%08x not supported\n", dwFlags);
+ return InternetSetCookieA(lpszURL, lpszCookieName, lpszCookieData);
}
/***********************************************************************
DWORD WINAPI InternetSetCookieExW( LPCWSTR lpszURL, LPCWSTR lpszCookieName, LPCWSTR lpszCookieData,
DWORD dwFlags, DWORD_PTR dwReserved)
{
- FIXME("(%s, %s, %s, 0x%08x, 0x%08lx) stub\n",
+ TRACE("(%s, %s, %s, 0x%08x, 0x%08lx)\n",
debugstr_w(lpszURL), debugstr_w(lpszCookieName), debugstr_w(lpszCookieData),
dwFlags, dwReserved);
- return TRUE;
+
+ if (dwFlags) FIXME("flags 0x%08x not supported\n", dwFlags);
+ return InternetSetCookieW(lpszURL, lpszCookieName, lpszCookieData);
}
/***********************************************************************
BOOL WINAPI InternetGetCookieExA( LPCSTR pchURL, LPCSTR pchCookieName, LPSTR pchCookieData,
LPDWORD pcchCookieData, DWORD dwFlags, LPVOID lpReserved)
{
- FIXME("(%s, %s, %s, %p, 0x%08x, %p) stub\n",
+ TRACE("(%s, %s, %s, %p, 0x%08x, %p)\n",
debugstr_a(pchURL), debugstr_a(pchCookieName), debugstr_a(pchCookieData),
pcchCookieData, dwFlags, lpReserved);
- return FALSE;
+
+ if (dwFlags) FIXME("flags 0x%08x not supported\n", dwFlags);
+ return InternetGetCookieA(pchURL, pchCookieName, pchCookieData, pcchCookieData);
}
/***********************************************************************
BOOL WINAPI InternetGetCookieExW( LPCWSTR pchURL, LPCWSTR pchCookieName, LPWSTR pchCookieData,
LPDWORD pcchCookieData, DWORD dwFlags, LPVOID lpReserved)
{
- FIXME("(%s, %s, %s, %p, 0x%08x, %p) stub\n",
+ TRACE("(%s, %s, %s, %p, 0x%08x, %p)\n",
debugstr_w(pchURL), debugstr_w(pchCookieName), debugstr_w(pchCookieData),
pcchCookieData, dwFlags, lpReserved);
- return FALSE;
+
+ if (dwFlags) FIXME("flags 0x%08x not supported\n", dwFlags);
+ return InternetGetCookieW(pchURL, pchCookieName, pchCookieData, pcchCookieData);
}
/***********************************************************************
#include "wine/debug.h"
#include "internet.h"
-typedef size_t socklen_t;
WINE_DEFAULT_DEBUG_CHANNEL(wininet);
+typedef struct _WININETFTPSESSIONW WININETFTPSESSIONW;
+
+typedef struct
+{
+ WININETHANDLEHEADER hdr;
+ WININETFTPSESSIONW *lpFtpSession;
+ BOOL session_deleted;
+ int nDataSocket;
+} WININETFTPFILE, *LPWININETFTPFILE;
+
+typedef struct _WININETFTPSESSIONW
+{
+ WININETHANDLEHEADER hdr;
+ WININETAPPINFOW *lpAppInfo;
+ int sndSocket;
+ int lstnSocket;
+ int pasvSocket; /* data socket connected by us in case of passive FTP */
+ LPWININETFTPFILE download_in_progress;
+ struct sockaddr_in socketAddress;
+ struct sockaddr_in lstnSocketAddress;
+ LPWSTR lpszPassword;
+ LPWSTR lpszUserName;
+} *LPWININETFTPSESSIONW;
+
+typedef struct
+{
+ BOOL bIsDirectory;
+ LPWSTR lpszName;
+ DWORD nSize;
+ struct tm tmLastModified;
+ unsigned short permissions;
+} FILEPROPERTIESW, *LPFILEPROPERTIESW;
+
+typedef struct
+{
+ WININETHANDLEHEADER hdr;
+ WININETFTPSESSIONW *lpFtpSession;
+ DWORD index;
+ DWORD size;
+ LPFILEPROPERTIESW lpafp;
+} WININETFTPFINDNEXTW, *LPWININETFTPFINDNEXTW;
+
#define DATA_PACKET_SIZE 0x2000
#define szCRLF "\r\n"
#define MAX_BACKLOG 5
static const CHAR szMonths[] = "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";
static const WCHAR szNoAccount[] = {'n','o','a','c','c','o','u','n','t','\0'};
-static void FTP_CloseFileTransferHandle(LPWININETHANDLEHEADER hdr);
-static void FTP_CloseSessionHandle(LPWININETHANDLEHEADER hdr);
-static void FTP_CloseConnection(LPWININETHANDLEHEADER hdr);
-static void FTP_CloseFindNextHandle(LPWININETHANDLEHEADER hdr);
static BOOL FTP_SendCommand(INT nSocket, FTP_COMMAND ftpCmd, LPCWSTR lpszParam,
INTERNET_STATUS_CALLBACK lpfnStatusCB, LPWININETHANDLEHEADER hdr, DWORD_PTR dwContext);
static BOOL FTP_SendStore(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszRemoteFile, DWORD dwType);
static BOOL FTP_ParsePermission(LPCSTR lpszPermission, LPFILEPROPERTIESW lpfp);
static BOOL FTP_ParseNextFile(INT nSocket, LPCWSTR lpszSearchFile, LPFILEPROPERTIESW fileprop);
static BOOL FTP_ParseDirectory(LPWININETFTPSESSIONW lpwfs, INT nSocket, LPCWSTR lpszSearchFile,
- LPFILEPROPERTIESW *lpafp, LPDWORD dwfp);
+ LPFILEPROPERTIESW *lpafp, LPDWORD dwfp);
static HINTERNET FTP_ReceiveFileList(LPWININETFTPSESSIONW lpwfs, INT nSocket, LPCWSTR lpszSearchFile,
- LPWIN32_FIND_DATAW lpFindFileData, DWORD_PTR dwContext);
+ LPWIN32_FIND_DATAW lpFindFileData, DWORD_PTR dwContext);
static DWORD FTP_SetResponseError(DWORD dwResponse);
+static BOOL FTP_ConvertFileProp(LPFILEPROPERTIESW lpafp, LPWIN32_FIND_DATAW lpFindFileData);
+static BOOL FTP_FtpPutFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszLocalFile,
+ LPCWSTR lpszNewRemoteFile, DWORD dwFlags, DWORD_PTR dwContext);
+static BOOL FTP_FtpSetCurrentDirectoryW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszDirectory);
+static BOOL FTP_FtpCreateDirectoryW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszDirectory);
+static HINTERNET FTP_FtpFindFirstFileW(LPWININETFTPSESSIONW lpwfs,
+ LPCWSTR lpszSearchFile, LPWIN32_FIND_DATAW lpFindFileData, DWORD dwFlags, DWORD_PTR dwContext);
+static BOOL FTP_FtpGetCurrentDirectoryW(LPWININETFTPSESSIONW lpwfs, LPWSTR lpszCurrentDirectory,
+ LPDWORD lpdwCurrentDirectory);
+static BOOL FTP_FtpRenameFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszSrc, LPCWSTR lpszDest);
+static BOOL FTP_FtpRemoveDirectoryW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszDirectory);
+static BOOL FTP_FtpDeleteFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszFileName);
+static HINTERNET FTP_FtpOpenFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszFileName,
+ DWORD fdwAccess, DWORD dwFlags, DWORD_PTR dwContext);
+static BOOL FTP_FtpGetFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszRemoteFile, LPCWSTR lpszNewFile,
+ BOOL fFailIfExists, DWORD dwLocalFlagsAttribute, DWORD dwInternetFlags,
+ DWORD_PTR dwContext);
+
/***********************************************************************
* FtpPutFileA (WININET.@)
* FALSE on failure
*
*/
-BOOL WINAPI FTP_FtpPutFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszLocalFile,
+static BOOL FTP_FtpPutFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszLocalFile,
LPCWSTR lpszNewRemoteFile, DWORD dwFlags, DWORD_PTR dwContext)
{
HANDLE hFile;
* FALSE on failure
*
*/
-BOOL WINAPI FTP_FtpSetCurrentDirectoryW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszDirectory)
+static BOOL FTP_FtpSetCurrentDirectoryW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszDirectory)
{
INT nResCode;
LPWININETAPPINFOW hIC = NULL;
{
INTERNET_ASYNC_RESULT iar;
- iar.dwResult = (DWORD)bSuccess;
+ iar.dwResult = bSuccess;
iar.dwError = bSuccess ? ERROR_SUCCESS : ERROR_INTERNET_EXTENDED_ERROR;
SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
&iar, sizeof(INTERNET_ASYNC_RESULT));
* FALSE on failure
*
*/
-BOOL WINAPI FTP_FtpCreateDirectoryW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszDirectory)
+static BOOL FTP_FtpCreateDirectoryW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszDirectory)
{
INT nResCode;
BOOL bSuccess = FALSE;
* NULL on failure
*
*/
-HINTERNET WINAPI FTP_FtpFindFirstFileW(LPWININETFTPSESSIONW lpwfs,
+static HINTERNET FTP_FtpFindFirstFileW(LPWININETFTPSESSIONW lpwfs,
LPCWSTR lpszSearchFile, LPWIN32_FIND_DATAW lpFindFileData, DWORD dwFlags, DWORD_PTR dwContext)
{
INT nResCode;
LPWININETAPPINFOW hIC = NULL;
BOOL r = FALSE;
- TRACE("len(%d)\n", *lpdwCurrentDirectory);
+ TRACE("%p %p %p\n", hFtpSession, lpszCurrentDirectory, lpdwCurrentDirectory);
lpwfs = (LPWININETFTPSESSIONW) WININET_GetObject( hFtpSession );
if (NULL == lpwfs)
* FALSE on failure
*
*/
-BOOL WINAPI FTP_FtpGetCurrentDirectoryW(LPWININETFTPSESSIONW lpwfs, LPWSTR lpszCurrentDirectory,
+static BOOL FTP_FtpGetCurrentDirectoryW(LPWININETFTPSESSIONW lpwfs, LPWSTR lpszCurrentDirectory,
LPDWORD lpdwCurrentDirectory)
{
INT nResCode;
LPWININETAPPINFOW hIC = NULL;
DWORD bSuccess = FALSE;
- TRACE("len(%d)\n", *lpdwCurrentDirectory);
-
/* Clear any error information */
INTERNET_SetLastError(0);
{
INTERNET_ASYNC_RESULT iar;
- iar.dwResult = (DWORD)bSuccess;
+ iar.dwResult = bSuccess;
iar.dwError = bSuccess ? ERROR_SUCCESS : ERROR_INTERNET_EXTENDED_ERROR;
SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
&iar, sizeof(INTERNET_ASYNC_RESULT));
}
- return (DWORD) bSuccess;
+ return bSuccess;
}
/***********************************************************************
}
+/***********************************************************************
+ * FTPFILE_Destroy(internal)
+ *
+ * Closes the file transfer handle. This also 'cleans' the data queue of
+ * the 'transfer complete' message (this is a bit of a hack though :-/ )
+ *
+ */
+static void FTPFILE_Destroy(WININETHANDLEHEADER *hdr)
+{
+ LPWININETFTPFILE lpwh = (LPWININETFTPFILE) hdr;
+ LPWININETFTPSESSIONW lpwfs = lpwh->lpFtpSession;
+ INT nResCode;
+
+ TRACE("\n");
+
+ WININET_Release(&lpwh->lpFtpSession->hdr);
+
+ if (!lpwh->session_deleted)
+ lpwfs->download_in_progress = NULL;
+
+ if (lpwh->nDataSocket != -1)
+ closesocket(lpwh->nDataSocket);
+
+ nResCode = FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext);
+ if (nResCode > 0 && nResCode != 226) WARN("server reports failed transfer\n");
+
+ HeapFree(GetProcessHeap(), 0, lpwh);
+}
+
+static DWORD FTPFILE_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode)
+{
+ switch(option) {
+ case INTERNET_OPTION_HANDLE_TYPE:
+ TRACE("INTERNET_OPTION_HANDLE_TYPE\n");
+
+ if (*size < sizeof(ULONG))
+ return ERROR_INSUFFICIENT_BUFFER;
+
+ *size = sizeof(DWORD);
+ *(DWORD*)buffer = INTERNET_HANDLE_TYPE_FTP_FILE;
+ return ERROR_SUCCESS;
+ }
+
+ FIXME("Not implemented option %d\n", option);
+ return ERROR_INTERNET_INVALID_OPTION;
+}
+
+static DWORD FTPFILE_ReadFile(WININETHANDLEHEADER *hdr, void *buffer, DWORD size, DWORD *read)
+{
+ WININETFTPFILE *file = (WININETFTPFILE*)hdr;
+ int res;
+
+ if (file->nDataSocket == -1)
+ return ERROR_INTERNET_DISCONNECTED;
+
+ /* FIXME: FTP should use NETCON_ stuff */
+ res = recv(file->nDataSocket, buffer, size, MSG_WAITALL);
+ *read = res>0 ? res : 0;
+
+ return res>=0 ? ERROR_SUCCESS : INTERNET_ERROR_BASE; /* FIXME*/
+}
+
+static BOOL FTPFILE_WriteFile(WININETHANDLEHEADER *hdr, const void *buffer, DWORD size, DWORD *written)
+{
+ LPWININETFTPFILE lpwh = (LPWININETFTPFILE) hdr;
+ int res;
+
+ res = send(lpwh->nDataSocket, buffer, size, 0);
+
+ *written = res>0 ? res : 0;
+ return res >= 0;
+}
+
+static const HANDLEHEADERVtbl FTPFILEVtbl = {
+ FTPFILE_Destroy,
+ NULL,
+ FTPFILE_QueryOption,
+ NULL,
+ FTPFILE_ReadFile,
+ NULL,
+ FTPFILE_WriteFile,
+ NULL,
+ NULL
+};
+
/***********************************************************************
* FTP_FtpOpenFileW (Internal)
*
{
lpwh = HeapAlloc(GetProcessHeap(), 0, sizeof(WININETFTPFILE));
lpwh->hdr.htype = WH_HFILE;
+ lpwh->hdr.vtbl = &FTPFILEVtbl;
lpwh->hdr.dwFlags = dwFlags;
lpwh->hdr.dwContext = dwContext;
- lpwh->hdr.dwRefCount = 1;
- lpwh->hdr.close_connection = NULL;
- lpwh->hdr.destroy = FTP_CloseFileTransferHandle;
+ lpwh->hdr.refs = 1;
lpwh->hdr.lpfnStatusCB = lpwfs->hdr.lpfnStatusCB;
lpwh->nDataSocket = nDataSocket;
lpwh->session_deleted = FALSE;
* FALSE on failure
*
*/
-BOOL WINAPI FTP_FtpGetFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszRemoteFile, LPCWSTR lpszNewFile,
+static BOOL FTP_FtpGetFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszRemoteFile, LPCWSTR lpszNewFile,
BOOL fFailIfExists, DWORD dwLocalFlagsAttribute, DWORD dwInternetFlags,
DWORD_PTR dwContext)
{
return r;
}
+
+/***********************************************************************
+ * FTPSESSION_Destroy (internal)
+ *
+ * Deallocate session handle
+ */
+static void FTPSESSION_Destroy(WININETHANDLEHEADER *hdr)
+{
+ LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) hdr;
+
+ TRACE("\n");
+
+ WININET_Release(&lpwfs->lpAppInfo->hdr);
+
+ HeapFree(GetProcessHeap(), 0, lpwfs->lpszPassword);
+ HeapFree(GetProcessHeap(), 0, lpwfs->lpszUserName);
+ HeapFree(GetProcessHeap(), 0, lpwfs);
+}
+
+static void FTPSESSION_CloseConnection(WININETHANDLEHEADER *hdr)
+{
+ LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) hdr;
+
+ TRACE("\n");
+
+ SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext,
+ INTERNET_STATUS_CLOSING_CONNECTION, 0, 0);
+
+ if (lpwfs->download_in_progress != NULL)
+ lpwfs->download_in_progress->session_deleted = TRUE;
+
+ if (lpwfs->sndSocket != -1)
+ closesocket(lpwfs->sndSocket);
+
+ if (lpwfs->lstnSocket != -1)
+ closesocket(lpwfs->lstnSocket);
+
+ if (lpwfs->pasvSocket != -1)
+ closesocket(lpwfs->pasvSocket);
+
+ SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext,
+ INTERNET_STATUS_CONNECTION_CLOSED, 0, 0);
+}
+
+static DWORD FTPSESSION_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode)
+{
+ switch(option) {
+ case INTERNET_OPTION_HANDLE_TYPE:
+ TRACE("INTERNET_OPTION_HANDLE_TYPE\n");
+
+ if (*size < sizeof(ULONG))
+ return ERROR_INSUFFICIENT_BUFFER;
+
+ *size = sizeof(DWORD);
+ *(DWORD*)buffer = INTERNET_HANDLE_TYPE_CONNECT_FTP;
+ return ERROR_SUCCESS;
+ }
+
+ FIXME("Not implemented option %d\n", option);
+ return ERROR_INTERNET_INVALID_OPTION;
+}
+
+static const HANDLEHEADERVtbl FTPSESSIONVtbl = {
+ FTPSESSION_Destroy,
+ FTPSESSION_CloseConnection,
+ FTPSESSION_QueryOption,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+
/***********************************************************************
* FTP_Connect (internal)
*
nServerPort = INTERNET_DEFAULT_FTP_PORT;
lpwfs->hdr.htype = WH_HFTPSESSION;
+ lpwfs->hdr.vtbl = &FTPSESSIONVtbl;
lpwfs->hdr.dwFlags = dwFlags;
lpwfs->hdr.dwContext = dwContext;
lpwfs->hdr.dwInternalFlags = dwInternalFlags;
- lpwfs->hdr.dwRefCount = 1;
- lpwfs->hdr.close_connection = FTP_CloseConnection;
- lpwfs->hdr.destroy = FTP_CloseSessionHandle;
+ lpwfs->hdr.refs = 1;
lpwfs->hdr.lpfnStatusCB = hIC->hdr.lpfnStatusCB;
lpwfs->download_in_progress = NULL;
lpwfs->sndSocket = -1;
INT rc = 0;
char firstprefix[5];
BOOL multiline = FALSE;
- LPWININETAPPINFOW hIC = NULL;
TRACE("socket(%d)\n", lpwfs->sndSocket);
- hIC = lpwfs->lpAppInfo;
SendAsyncCallback(&lpwfs->hdr, dwContext, INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0);
while(1)
static BOOL FTP_RetrieveFileData(LPWININETFTPSESSIONW lpwfs, INT nDataSocket, HANDLE hFile)
{
DWORD nBytesWritten;
- DWORD nBytesReceived = 0;
INT nRC = 0;
CHAR *lpszBuffer;
if (nRC == 0)
goto recv_end;
WriteFile(hFile, lpszBuffer, nRC, &nBytesWritten, NULL);
- nBytesReceived += nRC;
}
}
}
/***********************************************************************
- * FTP_CloseConnection (internal)
- *
- * Close connections
- */
-static void FTP_CloseConnection(LPWININETHANDLEHEADER hdr)
-{
- LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) hdr;
-
- TRACE("\n");
-
- SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext,
- INTERNET_STATUS_CLOSING_CONNECTION, 0, 0);
-
- if (lpwfs->download_in_progress != NULL)
- lpwfs->download_in_progress->session_deleted = TRUE;
-
- if (lpwfs->sndSocket != -1)
- closesocket(lpwfs->sndSocket);
-
- if (lpwfs->lstnSocket != -1)
- closesocket(lpwfs->lstnSocket);
-
- if (lpwfs->pasvSocket != -1)
- closesocket(lpwfs->pasvSocket);
-
- SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext,
- INTERNET_STATUS_CONNECTION_CLOSED, 0, 0);
-}
-
-
-/***********************************************************************
- * FTP_CloseSessionHandle (internal)
+ * FTPFINDNEXT_Destroy (internal)
*
* Deallocate session handle
*/
-static void FTP_CloseSessionHandle(LPWININETHANDLEHEADER hdr)
+static void FTPFINDNEXT_Destroy(WININETHANDLEHEADER *hdr)
{
- LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) hdr;
+ LPWININETFTPFINDNEXTW lpwfn = (LPWININETFTPFINDNEXTW) hdr;
+ DWORD i;
TRACE("\n");
- WININET_Release(&lpwfs->lpAppInfo->hdr);
+ WININET_Release(&lpwfn->lpFtpSession->hdr);
- HeapFree(GetProcessHeap(), 0, lpwfs->lpszPassword);
- HeapFree(GetProcessHeap(), 0, lpwfs->lpszUserName);
- HeapFree(GetProcessHeap(), 0, lpwfs);
-}
+ for (i = 0; i < lpwfn->size; i++)
+ {
+ HeapFree(GetProcessHeap(), 0, lpwfn->lpafp[i].lpszName);
+ }
+ HeapFree(GetProcessHeap(), 0, lpwfn->lpafp);
+ HeapFree(GetProcessHeap(), 0, lpwfn);
+}
-/***********************************************************************
- * FTP_FindNextFileW (Internal)
- *
- * Continues a file search from a previous call to FindFirstFile
- *
- * RETURNS
- * TRUE on success
- * FALSE on failure
- *
- */
-BOOL WINAPI FTP_FindNextFileW(LPWININETFTPFINDNEXTW lpwh, LPVOID lpvFindData)
+static DWORD WINAPI FTPFINDNEXT_FindNextFileProc(WININETFTPFINDNEXTW *find, LPVOID data)
{
- BOOL bSuccess = TRUE;
- LPWIN32_FIND_DATAW lpFindFileData;
+ WIN32_FIND_DATAW *find_data = data;
+ DWORD res = ERROR_SUCCESS;
- TRACE("index(%d) size(%d)\n", lpwh->index, lpwh->size);
+ TRACE("index(%d) size(%d)\n", find->index, find->size);
- assert (lpwh->hdr.htype == WH_HFTPFINDNEXT);
-
- /* Clear any error information */
- INTERNET_SetLastError(0);
+ ZeroMemory(find_data, sizeof(WIN32_FIND_DATAW));
- lpFindFileData = (LPWIN32_FIND_DATAW) lpvFindData;
- ZeroMemory(lpFindFileData, sizeof(WIN32_FIND_DATAA));
+ if (find->index < find->size) {
+ FTP_ConvertFileProp(&find->lpafp[find->index], find_data);
+ find->index++;
- if (lpwh->index >= lpwh->size)
- {
- INTERNET_SetLastError(ERROR_NO_MORE_FILES);
- bSuccess = FALSE;
- goto lend;
+ TRACE("Name: %s\nSize: %d\n", debugstr_w(find_data->cFileName), find_data->nFileSizeLow);
+ }else {
+ res = ERROR_NO_MORE_FILES;
}
- FTP_ConvertFileProp(&lpwh->lpafp[lpwh->index], lpFindFileData);
- lpwh->index++;
-
- TRACE("\nName: %s\nSize: %d\n", debugstr_w(lpFindFileData->cFileName), lpFindFileData->nFileSizeLow);
-
-lend:
-
- if (lpwh->hdr.dwFlags & INTERNET_FLAG_ASYNC)
+ if (find->hdr.dwFlags & INTERNET_FLAG_ASYNC)
{
INTERNET_ASYNC_RESULT iar;
- iar.dwResult = (DWORD)bSuccess;
- iar.dwError = iar.dwError = bSuccess ? ERROR_SUCCESS :
- INTERNET_GetLastError();
+ iar.dwResult = (res == ERROR_SUCCESS);
+ iar.dwError = res;
- INTERNET_SendCallback(&lpwh->hdr, lpwh->hdr.dwContext,
+ INTERNET_SendCallback(&find->hdr, find->hdr.dwContext,
INTERNET_STATUS_REQUEST_COMPLETE, &iar,
sizeof(INTERNET_ASYNC_RESULT));
}
- return bSuccess;
+ return res;
}
-
-/***********************************************************************
- * FTP_CloseFindNextHandle (internal)
- *
- * Deallocate session handle
- *
- * RETURNS
- * TRUE on success
- * FALSE on failure
- *
- */
-static void FTP_CloseFindNextHandle(LPWININETHANDLEHEADER hdr)
+static void FTPFINDNEXT_AsyncFindNextFileProc(WORKREQUEST *workRequest)
{
- LPWININETFTPFINDNEXTW lpwfn = (LPWININETFTPFINDNEXTW) hdr;
- DWORD i;
+ struct WORKREQ_FTPFINDNEXTW *req = &workRequest->u.FtpFindNextW;
- TRACE("\n");
+ FTPFINDNEXT_FindNextFileProc((WININETFTPFINDNEXTW*)workRequest->hdr, req->lpFindFileData);
+}
- WININET_Release(&lpwfn->lpFtpSession->hdr);
+static DWORD FTPFINDNEXT_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode)
+{
+ switch(option) {
+ case INTERNET_OPTION_HANDLE_TYPE:
+ TRACE("INTERNET_OPTION_HANDLE_TYPE\n");
- for (i = 0; i < lpwfn->size; i++)
- {
- HeapFree(GetProcessHeap(), 0, lpwfn->lpafp[i].lpszName);
+ if (*size < sizeof(ULONG))
+ return ERROR_INSUFFICIENT_BUFFER;
+
+ *size = sizeof(DWORD);
+ *(DWORD*)buffer = INTERNET_HANDLE_TYPE_FTP_FIND;
+ return ERROR_SUCCESS;
}
- HeapFree(GetProcessHeap(), 0, lpwfn->lpafp);
- HeapFree(GetProcessHeap(), 0, lpwfn);
+ FIXME("Not implemented option %d\n", option);
+ return ERROR_INTERNET_INVALID_OPTION;
}
-/***********************************************************************
- * FTP_CloseFileTransferHandle (internal)
- *
- * Closes the file transfer handle. This also 'cleans' the data queue of
- * the 'transfer complete' message (this is a bit of a hack though :-/ )
- *
- */
-static void FTP_CloseFileTransferHandle(LPWININETHANDLEHEADER hdr)
+static DWORD FTPFINDNEXT_FindNextFileW(WININETHANDLEHEADER *hdr, void *data)
{
- LPWININETFTPFILE lpwh = (LPWININETFTPFILE) hdr;
- LPWININETFTPSESSIONW lpwfs = lpwh->lpFtpSession;
- INT nResCode;
-
- TRACE("\n");
+ WININETFTPFINDNEXTW *find = (WININETFTPFINDNEXTW*)hdr;
- WININET_Release(&lpwh->lpFtpSession->hdr);
+ if (find->lpFtpSession->lpAppInfo->hdr.dwFlags & INTERNET_FLAG_ASYNC)
+ {
+ WORKREQUEST workRequest;
+ struct WORKREQ_FTPFINDNEXTW *req;
- if (!lpwh->session_deleted)
- lpwfs->download_in_progress = NULL;
+ workRequest.asyncproc = FTPFINDNEXT_AsyncFindNextFileProc;
+ workRequest.hdr = WININET_AddRef( &find->hdr );
+ req = &workRequest.u.FtpFindNextW;
+ req->lpFindFileData = data;
- if (lpwh->nDataSocket != -1)
- closesocket(lpwh->nDataSocket);
+ INTERNET_AsyncCall(&workRequest);
- nResCode = FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext);
- if (nResCode > 0 && nResCode != 226) WARN("server reports failed transfer\n");
+ return ERROR_SUCCESS;
+ }
- HeapFree(GetProcessHeap(), 0, lpwh);
+ return FTPFINDNEXT_FindNextFileProc(find, data);
}
+static const HANDLEHEADERVtbl FTPFINDNEXTVtbl = {
+ FTPFINDNEXT_Destroy,
+ NULL,
+ FTPFINDNEXT_QueryOption,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ FTPFINDNEXT_FindNextFileW
+};
+
/***********************************************************************
* FTP_ReceiveFileList (internal)
*
if (lpwfn)
{
lpwfn->hdr.htype = WH_HFTPFINDNEXT;
+ lpwfn->hdr.vtbl = &FTPFINDNEXTVtbl;
lpwfn->hdr.dwContext = dwContext;
- lpwfn->hdr.dwRefCount = 1;
- lpwfn->hdr.close_connection = NULL;
- lpwfn->hdr.destroy = FTP_CloseFindNextHandle;
+ lpwfn->hdr.refs = 1;
lpwfn->hdr.lpfnStatusCB = lpwfs->hdr.lpfnStatusCB;
lpwfn->index = 1; /* Next index is 1 since we return index 0 */
lpwfn->size = dwSize;
* FALSE on failure
*
*/
-BOOL FTP_ConvertFileProp(LPFILEPROPERTIESW lpafp, LPWIN32_FIND_DATAW lpFindFileData)
+static BOOL FTP_ConvertFileProp(LPFILEPROPERTIESW lpafp, LPWIN32_FIND_DATAW lpFindFileData)
{
BOOL bSuccess = FALSE;
#define NO_SHLWAPI_GDI
#include "shlwapi.h"
#include "sspi.h"
+#include "wincrypt.h"
#include "internet.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(wininet);
-static const WCHAR g_szHttp1_0[] = {' ','H','T','T','P','/','1','.','0',0 };
-static const WCHAR g_szHttp1_1[] = {' ','H','T','T','P','/','1','.','1',0 };
+static const WCHAR g_szHttp1_0[] = {'H','T','T','P','/','1','.','0',0};
+static const WCHAR g_szHttp1_1[] = {'H','T','T','P','/','1','.','1',0};
static const WCHAR g_szReferer[] = {'R','e','f','e','r','e','r',0};
static const WCHAR g_szAccept[] = {'A','c','c','e','p','t',0};
static const WCHAR g_szUserAgent[] = {'U','s','e','r','-','A','g','e','n','t',0};
static const WCHAR szProxy_Authorization[] = { 'P','r','o','x','y','-','A','u','t','h','o','r','i','z','a','t','i','o','n',0 };
static const WCHAR szStatus[] = { 'S','t','a','t','u','s',0 };
static const WCHAR szKeepAlive[] = {'K','e','e','p','-','A','l','i','v','e',0};
+static const WCHAR szGET[] = { 'G','E','T', 0 };
#define MAXHOSTNAME 100
#define MAX_FIELD_VALUE_LEN 256
CtxtHandle ctx;
TimeStamp exp;
ULONG attr;
+ ULONG max_token;
void *auth_data;
unsigned int auth_data_len;
BOOL finished; /* finished authenticating */
};
-static void HTTP_CloseConnection(LPWININETHANDLEHEADER hdr);
-static void HTTP_CloseHTTPRequestHandle(LPWININETHANDLEHEADER hdr);
-static void HTTP_CloseHTTPSessionHandle(LPWININETHANDLEHEADER hdr);
static BOOL HTTP_OpenConnection(LPWININETHTTPREQW lpwhr);
-static BOOL HTTP_GetResponseHeaders(LPWININETHTTPREQW lpwhr);
+static BOOL HTTP_GetResponseHeaders(LPWININETHTTPREQW lpwhr, BOOL clear);
static BOOL HTTP_ProcessHeader(LPWININETHTTPREQW lpwhr, LPCWSTR field, LPCWSTR value, DWORD dwModifier);
static LPWSTR * HTTP_InterpretHttpHeader(LPCWSTR buffer);
static BOOL HTTP_InsertCustomHeader(LPWININETHTTPREQW lpwhr, LPHTTPHEADERW lpHdr);
static BOOL HTTP_HandleRedirect(LPWININETHTTPREQW lpwhr, LPCWSTR lpszUrl);
static UINT HTTP_DecodeBase64(LPCWSTR base64, LPSTR bin);
static BOOL HTTP_VerifyValidHeader(LPWININETHTTPREQW lpwhr, LPCWSTR field);
-
+static void HTTP_DrainContent(WININETHTTPREQW *req);
LPHTTPHEADERW HTTP_GetHeader(LPWININETHTTPREQW req, LPCWSTR head)
{
HeapFree(GetProcessHeap(), 0, req->lpszHeader);
}
-static void HTTP_FixVerb( LPWININETHTTPREQW lpwhr )
-{
- /* if the verb is NULL default to GET */
- if (NULL == lpwhr->lpszVerb)
- {
- static const WCHAR szGET[] = { 'G','E','T', 0 };
- lpwhr->lpszVerb = WININET_strdupW(szGET);
- }
-}
-
static void HTTP_FixURL( LPWININETHTTPREQW lpwhr)
{
static const WCHAR szSlash[] = { '/',0 };
}
}
-static LPWSTR HTTP_BuildHeaderRequestString( LPWININETHTTPREQW lpwhr, LPCWSTR verb, LPCWSTR path, BOOL http1_1 )
+static LPWSTR HTTP_BuildHeaderRequestString( LPWININETHTTPREQW lpwhr, LPCWSTR verb, LPCWSTR path, LPCWSTR version )
{
LPWSTR requestString;
DWORD len, n;
static const WCHAR sztwocrlf[] = {'\r','\n','\r','\n', 0};
/* allocate space for an array of all the string pointers to be added */
- len = (lpwhr->nCustHeaders)*4 + 9;
+ len = (lpwhr->nCustHeaders)*4 + 10;
req = HeapAlloc( GetProcessHeap(), 0, len*sizeof(LPCWSTR) );
/* add the verb, path and HTTP version string */
req[n++] = verb;
req[n++] = szSpace;
req[n++] = path;
- req[n++] = http1_1 ? g_szHttp1_1 : g_szHttp1_0;
+ req[n++] = szSpace;
+ req[n++] = version;
/* Append custom request headers */
for (i = 0; i < lpwhr->nCustHeaders; i++)
return requestString;
}
-static void HTTP_ProcessHeaders( LPWININETHTTPREQW lpwhr )
+static void HTTP_ProcessCookies( LPWININETHTTPREQW lpwhr )
{
static const WCHAR szSet_Cookie[] = { 'S','e','t','-','C','o','o','k','i','e',0 };
int HeaderIndex;
{
static const WCHAR szBasic[] = {'B','a','s','i','c'}; /* Note: not nul-terminated */
return !strncmpiW(pszAuthValue, szBasic, ARRAYSIZE(szBasic)) &&
- ((pszAuthValue[ARRAYSIZE(szBasic)] != ' ') || !pszAuthValue[ARRAYSIZE(szBasic)]);
+ ((pszAuthValue[ARRAYSIZE(szBasic)] == ' ') || !pszAuthValue[ARRAYSIZE(szBasic)]);
}
static BOOL HTTP_DoAuthorization( LPWININETHTTPREQW lpwhr, LPCWSTR pszAuthValue,
TRACE("%s\n", debugstr_w(pszAuthValue));
- if (!domain_and_username) return FALSE;
-
if (!pAuthInfo)
{
TimeStamp exp;
}
else
{
+ PVOID pAuthData;
SEC_WINNT_AUTH_IDENTITY_W nt_auth_identity;
- WCHAR *user = strchrW(domain_and_username, '\\');
- WCHAR *domain = domain_and_username;
pAuthInfo->scheme = WININET_strdupW(pszAuthValue);
if (!pAuthInfo->scheme)
return FALSE;
}
- if (user) user++;
- else
+ if (domain_and_username)
{
- user = domain_and_username;
- domain = NULL;
- }
- nt_auth_identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
- nt_auth_identity.User = user;
- nt_auth_identity.UserLength = strlenW(nt_auth_identity.User);
- nt_auth_identity.Domain = domain;
- nt_auth_identity.DomainLength = domain ? user - domain - 1 : 0;
- nt_auth_identity.Password = password;
- nt_auth_identity.PasswordLength = strlenW(nt_auth_identity.Password);
+ WCHAR *user = strchrW(domain_and_username, '\\');
+ WCHAR *domain = domain_and_username;
- /* FIXME: make sure scheme accepts SEC_WINNT_AUTH_IDENTITY before calling AcquireCredentialsHandle */
+ /* FIXME: make sure scheme accepts SEC_WINNT_AUTH_IDENTITY before calling AcquireCredentialsHandle */
+
+ pAuthData = &nt_auth_identity;
+
+ if (user) user++;
+ else
+ {
+ user = domain_and_username;
+ domain = NULL;
+ }
+
+ nt_auth_identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
+ nt_auth_identity.User = user;
+ nt_auth_identity.UserLength = strlenW(nt_auth_identity.User);
+ nt_auth_identity.Domain = domain;
+ nt_auth_identity.DomainLength = domain ? user - domain - 1 : 0;
+ nt_auth_identity.Password = password;
+ nt_auth_identity.PasswordLength = strlenW(nt_auth_identity.Password);
+ }
+ else
+ /* use default credentials */
+ pAuthData = NULL;
sec_status = AcquireCredentialsHandleW(NULL, pAuthInfo->scheme,
SECPKG_CRED_OUTBOUND, NULL,
- &nt_auth_identity, NULL,
+ pAuthData, NULL,
NULL, &pAuthInfo->cred,
&exp);
+ if (sec_status == SEC_E_OK)
+ {
+ PSecPkgInfoW sec_pkg_info;
+ sec_status = QuerySecurityPackageInfoW(pAuthInfo->scheme, &sec_pkg_info);
+ if (sec_status == SEC_E_OK)
+ {
+ pAuthInfo->max_token = sec_pkg_info->cbMaxToken;
+ FreeContextBuffer(sec_pkg_info);
+ }
+ }
if (sec_status != SEC_E_OK)
{
WARN("AcquireCredentialsHandleW for scheme %s failed with error 0x%08x\n",
if (is_basic_auth_value(pszAuthValue))
{
- int userlen = WideCharToMultiByte(CP_UTF8, 0, domain_and_username, lstrlenW(domain_and_username), NULL, 0, NULL, NULL);
- int passlen = WideCharToMultiByte(CP_UTF8, 0, password, lstrlenW(password), NULL, 0, NULL, NULL);
+ int userlen;
+ int passlen;
char *auth_data;
TRACE("basic authentication\n");
+ /* we don't cache credentials for basic authentication, so we can't
+ * retrieve them if the application didn't pass us any credentials */
+ if (!domain_and_username) return FALSE;
+
+ userlen = WideCharToMultiByte(CP_UTF8, 0, domain_and_username, lstrlenW(domain_and_username), NULL, 0, NULL, NULL);
+ passlen = WideCharToMultiByte(CP_UTF8, 0, password, lstrlenW(password), NULL, 0, NULL, NULL);
+
/* length includes a nul terminator, which will be re-used for the ':' */
auth_data = HeapAlloc(GetProcessHeap(), 0, userlen + 1 + passlen);
if (!auth_data)
HTTP_DecodeBase64(pszAuthData, in.pvBuffer);
}
- buffer = HeapAlloc(GetProcessHeap(), 0, 0x100);
+ buffer = HeapAlloc(GetProcessHeap(), 0, pAuthInfo->max_token);
out.BufferType = SECBUFFER_TOKEN;
- out.cbBuffer = 0x100;
+ out.cbBuffer = pAuthInfo->max_token;
out.pvBuffer = buffer;
out_desc.ulVersion = 0;
out_desc.pBuffers = &out;
sec_status = InitializeSecurityContextW(first ? &pAuthInfo->cred : NULL,
- first ? NULL : &pAuthInfo->ctx, NULL,
+ first ? NULL : &pAuthInfo->ctx,
+ first ? lpwhr->lpHttpSession->lpszServerName : NULL,
context_req, 0, SECURITY_NETWORK_DREP,
in.pvBuffer ? &in_desc : NULL,
0, &pAuthInfo->ctx, &out_desc,
else
{
ERR("InitializeSecurityContextW returned error 0x%08x\n", sec_status);
+ pAuthInfo->finished = TRUE;
HeapFree(GetProcessHeap(), 0, out.pvBuffer);
return FALSE;
}
BOOL bSuccess = FALSE;
DWORD len;
- TRACE("copying header: %s\n", debugstr_w(lpszHeader));
+ TRACE("copying header: %s\n", debugstr_wn(lpszHeader, dwHeaderLength));
if( dwHeaderLength == ~0U )
len = strlenW(lpszHeader);
*
* Adds one or more HTTP header to the request handler
*
+ * NOTE
+ * On Windows if dwHeaderLength includes the trailing '\0', then
+ * HttpAddRequestHeadersW() adds it too. However this results in an
+ * invalid Http header which is rejected by some servers so we probably
+ * don't need to match Windows on that point.
+ *
* RETURNS
* TRUE on success
* FALSE on failure
BOOL bSuccess = FALSE;
LPWININETHTTPREQW lpwhr;
- TRACE("%p, %s, %i, %i\n", hHttpRequest, debugstr_w(lpszHeader), dwHeaderLength,
- dwModifier);
+ TRACE("%p, %s, %i, %i\n", hHttpRequest, debugstr_wn(lpszHeader, dwHeaderLength), dwHeaderLength, dwModifier);
if (!lpszHeader)
return TRUE;
LPWSTR hdr;
BOOL r;
- TRACE("%p, %s, %i, %i\n", hHttpRequest, debugstr_a(lpszHeader), dwHeaderLength,
- dwModifier);
+ TRACE("%p, %s, %i, %i\n", hHttpRequest, debugstr_an(lpszHeader, dwHeaderLength), dwHeaderLength, dwModifier);
len = MultiByteToWideChar( CP_ACP, 0, lpszHeader, dwHeaderLength, NULL, 0 );
hdr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
return r;
}
-/* read any content returned by the server so that the connection can be
- * reused */
-static void HTTP_DrainContent(LPWININETHTTPREQW lpwhr)
-{
- DWORD bytes_read;
-
- if (!NETCON_connected(&lpwhr->netConnection)) return;
-
- if (lpwhr->dwContentLength == -1)
- NETCON_close(&lpwhr->netConnection);
-
- do
- {
- char buffer[2048];
- if (!INTERNET_ReadFile(&lpwhr->hdr, buffer, sizeof(buffer), &bytes_read,
- TRUE, FALSE))
- return;
- } while (bytes_read);
-}
-
/***********************************************************************
* HttpEndRequestA (WININET.@)
*
FIXME("Do we need to translate info out of these buffer?\n");
- HeapFree(GetProcessHeap(),0,(LPVOID)ptrW->lpvBuffer);
+ HeapFree(GetProcessHeap(),0,ptrW->lpvBuffer);
ptrW2 = ptrW->Next;
HeapFree(GetProcessHeap(),0,ptrW);
ptrW = ptrW2;
SendAsyncCallback(&lpwhr->hdr, lpwhr->hdr.dwContext,
INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0);
- responseLen = HTTP_GetResponseHeaders(lpwhr);
+ responseLen = HTTP_GetResponseHeaders(lpwhr, TRUE);
if (responseLen)
rc = TRUE;
SendAsyncCallback(&lpwhr->hdr, lpwhr->hdr.dwContext,
INTERNET_STATUS_RESPONSE_RECEIVED, &responseLen, sizeof(DWORD));
- /* process headers here. Is this right? */
- HTTP_ProcessHeaders(lpwhr);
+ /* process cookies here. Is this right? */
+ HTTP_ProcessCookies(lpwhr);
dwBufferSize = sizeof(lpwhr->dwContentLength);
if (!HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_CONTENT_LENGTH,
if(HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_STATUS_CODE,&dwCode,&dwCodeLength,NULL) &&
(dwCode==302 || dwCode==301))
{
- WCHAR szNewLocation[2048];
+ WCHAR szNewLocation[INTERNET_MAX_URL_LENGTH];
dwBufferSize=sizeof(szNewLocation);
if(HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_LOCATION,szNewLocation,&dwBufferSize,NULL))
{
- static const WCHAR szGET[] = { 'G','E','T', 0 };
/* redirects are always GETs */
HeapFree(GetProcessHeap(),0,lpwhr->lpszVerb);
- lpwhr->lpszVerb = WININET_strdupW(szGET);
+ lpwhr->lpszVerb = WININET_strdupW(szGET);
HTTP_DrainContent(lpwhr);
+ INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext,
+ INTERNET_STATUS_REDIRECT, szNewLocation,
+ dwBufferSize);
rc = HTTP_HandleRedirect(lpwhr, szNewLocation);
if (rc)
rc = HTTP_HttpSendRequestW(lpwhr, NULL, 0, NULL, 0, 0, TRUE);
{
LPWSTR szVerb = NULL, szObjectName = NULL;
LPWSTR szVersion = NULL, szReferrer = NULL, *szAcceptTypes = NULL;
- INT len;
- INT acceptTypesCount;
+ INT len, acceptTypesCount;
HINTERNET rc = FALSE;
+ LPCSTR *types;
+
TRACE("(%p, %s, %s, %s, %s, %p, %08x, %08lx)\n", hHttpSession,
debugstr_a(lpszVerb), debugstr_a(lpszObjectName),
debugstr_a(lpszVersion), debugstr_a(lpszReferrer), lpszAcceptTypes,
MultiByteToWideChar(CP_ACP, 0, lpszReferrer, -1, szReferrer, len );
}
- acceptTypesCount = 0;
if (lpszAcceptTypes)
{
- /* find out how many there are */
- while (lpszAcceptTypes[acceptTypesCount] && *lpszAcceptTypes[acceptTypesCount])
- acceptTypesCount++;
+ acceptTypesCount = 0;
+ types = lpszAcceptTypes;
+ while (*types)
+ {
+ /* find out how many there are */
+ if (((ULONG_PTR)*types >> 16) && **types)
+ {
+ TRACE("accept type: %s\n", debugstr_a(*types));
+ acceptTypesCount++;
+ }
+ types++;
+ }
szAcceptTypes = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR *) * (acceptTypesCount+1));
+ if (!szAcceptTypes) goto end;
+
acceptTypesCount = 0;
- while (lpszAcceptTypes[acceptTypesCount] && *lpszAcceptTypes[acceptTypesCount])
- {
- len = MultiByteToWideChar(CP_ACP, 0, lpszAcceptTypes[acceptTypesCount],
- -1, NULL, 0 );
- szAcceptTypes[acceptTypesCount] = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
- if (!szAcceptTypes[acceptTypesCount] )
- goto end;
- MultiByteToWideChar(CP_ACP, 0, lpszAcceptTypes[acceptTypesCount],
- -1, szAcceptTypes[acceptTypesCount], len );
- acceptTypesCount++;
+ types = lpszAcceptTypes;
+ while (*types)
+ {
+ if (((ULONG_PTR)*types >> 16) && **types)
+ {
+ len = MultiByteToWideChar(CP_ACP, 0, *types, -1, NULL, 0 );
+ szAcceptTypes[acceptTypesCount] = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (!szAcceptTypes[acceptTypesCount]) goto end;
+
+ MultiByteToWideChar(CP_ACP, 0, *types, -1, szAcceptTypes[acceptTypesCount], len);
+ acceptTypesCount++;
+ }
+ types++;
}
szAcceptTypes[acceptTypesCount] = NULL;
}
{
signed char in[4];
- if (base64[0] > ARRAYSIZE(HTTP_Base64Dec) ||
+ if (base64[0] >= ARRAYSIZE(HTTP_Base64Dec) ||
((in[0] = HTTP_Base64Dec[base64[0]]) == -1) ||
- base64[1] > ARRAYSIZE(HTTP_Base64Dec) ||
+ base64[1] >= ARRAYSIZE(HTTP_Base64Dec) ||
((in[1] = HTTP_Base64Dec[base64[1]]) == -1))
{
WARN("invalid base64: %s\n", debugstr_w(base64));
}
/***********************************************************************
- * HTTP_InsertAuthorizationForHeader
+ * HTTP_InsertAuthorization
*
* Insert or delete the authorization field in the request header.
*/
-static BOOL HTTP_InsertAuthorizationForHeader( LPWININETHTTPREQW lpwhr, struct HttpAuthInfo *pAuthInfo, LPCWSTR header )
+static BOOL HTTP_InsertAuthorization( LPWININETHTTPREQW lpwhr, struct HttpAuthInfo *pAuthInfo, LPCWSTR header )
{
- WCHAR *authorization = NULL;
-
- if (pAuthInfo && pAuthInfo->auth_data_len)
+ if (pAuthInfo)
{
static const WCHAR wszSpace[] = {' ',0};
static const WCHAR wszBasic[] = {'B','a','s','i','c',0};
unsigned int len;
+ WCHAR *authorization = NULL;
- /* scheme + space + base64 encoded data (3/2/1 bytes data -> 4 bytes of characters) */
- len = strlenW(pAuthInfo->scheme)+1+((pAuthInfo->auth_data_len+2)*4)/3;
- authorization = HeapAlloc(GetProcessHeap(), 0, (len+1)*sizeof(WCHAR));
- if (!authorization)
- return FALSE;
+ if (pAuthInfo->auth_data_len)
+ {
+ /* scheme + space + base64 encoded data (3/2/1 bytes data -> 4 bytes of characters) */
+ len = strlenW(pAuthInfo->scheme)+1+((pAuthInfo->auth_data_len+2)*4)/3;
+ authorization = HeapAlloc(GetProcessHeap(), 0, (len+1)*sizeof(WCHAR));
+ if (!authorization)
+ return FALSE;
- strcpyW(authorization, pAuthInfo->scheme);
- strcatW(authorization, wszSpace);
- HTTP_EncodeBase64(pAuthInfo->auth_data,
- pAuthInfo->auth_data_len,
- authorization+strlenW(authorization));
+ strcpyW(authorization, pAuthInfo->scheme);
+ strcatW(authorization, wszSpace);
+ HTTP_EncodeBase64(pAuthInfo->auth_data,
+ pAuthInfo->auth_data_len,
+ authorization+strlenW(authorization));
- /* clear the data as it isn't valid now that it has been sent to the
- * server, unless it's Basic authentication which doesn't do
- * connection tracking */
- if (strcmpiW(pAuthInfo->scheme, wszBasic))
- {
- HeapFree(GetProcessHeap(), 0, pAuthInfo->auth_data);
- pAuthInfo->auth_data = NULL;
- pAuthInfo->auth_data_len = 0;
+ /* clear the data as it isn't valid now that it has been sent to the
+ * server, unless it's Basic authentication which doesn't do
+ * connection tracking */
+ if (strcmpiW(pAuthInfo->scheme, wszBasic))
+ {
+ HeapFree(GetProcessHeap(), 0, pAuthInfo->auth_data);
+ pAuthInfo->auth_data = NULL;
+ pAuthInfo->auth_data_len = 0;
+ }
}
- }
-
- TRACE("Inserting authorization: %s\n", debugstr_w(authorization));
- HTTP_ProcessHeader(lpwhr, header, authorization,
- HTTP_ADDHDR_FLAG_REPLACE | HTTP_ADDHDR_FLAG_REQ);
+ TRACE("Inserting authorization: %s\n", debugstr_w(authorization));
- HeapFree(GetProcessHeap(), 0, authorization);
+ HTTP_ProcessHeader(lpwhr, header, authorization, HTTP_ADDHDR_FLAG_REQ | HTTP_ADDHDR_FLAG_REPLACE);
+ HeapFree(GetProcessHeap(), 0, authorization);
+ }
return TRUE;
}
-/***********************************************************************
- * HTTP_InsertAuthorization
- *
- * Insert the authorization field in the request header
- */
-static BOOL HTTP_InsertAuthorization( LPWININETHTTPREQW lpwhr )
+static WCHAR *HTTP_BuildProxyRequestUrl(WININETHTTPREQW *req)
{
- return HTTP_InsertAuthorizationForHeader(lpwhr, lpwhr->pAuthInfo, szAuthorization);
-}
+ WCHAR new_location[INTERNET_MAX_URL_LENGTH], *url;
+ DWORD size;
-/***********************************************************************
- * HTTP_InsertProxyAuthorization
- *
- * Insert the proxy authorization field in the request header
- */
-static BOOL HTTP_InsertProxyAuthorization( LPWININETHTTPREQW lpwhr )
-{
- return HTTP_InsertAuthorizationForHeader(lpwhr, lpwhr->pProxyAuthInfo, szProxy_Authorization);
+ size = sizeof(new_location);
+ if (HTTP_HttpQueryInfoW(req, HTTP_QUERY_LOCATION, new_location, &size, NULL))
+ {
+ if (!(url = HeapAlloc( GetProcessHeap(), 0, size + sizeof(WCHAR) ))) return NULL;
+ strcpyW( url, new_location );
+ }
+ else
+ {
+ static const WCHAR slash[] = { '/',0 };
+ static const WCHAR format[] = { 'h','t','t','p',':','/','/','%','s',':','%','d',0 };
+ static const WCHAR formatSSL[] = { 'h','t','t','p','s',':','/','/','%','s',':','%','d',0 };
+ WININETHTTPSESSIONW *session = req->lpHttpSession;
+
+ size = 16; /* "https://" + sizeof(port#) + ":/\0" */
+ size += strlenW( session->lpszHostName ) + strlenW( req->lpszPath );
+
+ if (!(url = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) ))) return NULL;
+
+ if (req->hdr.dwFlags & INTERNET_FLAG_SECURE)
+ sprintfW( url, formatSSL, session->lpszHostName, session->nHostPort );
+ else
+ sprintfW( url, format, session->lpszHostName, session->nHostPort );
+ if (req->lpszPath[0] != '/') strcatW( url, slash );
+ strcatW( url, req->lpszPath );
+ }
+ TRACE("url=%s\n", debugstr_w(url));
+ return url;
}
/***********************************************************************
{
WCHAR buf[MAXHOSTNAME];
WCHAR proxy[MAXHOSTNAME + 15]; /* 15 == "http://" + sizeof(port#) + ":/\0" */
- WCHAR* url;
static WCHAR szNul[] = { 0 };
URL_COMPONENTSW UrlComponents;
- static const WCHAR szHttp[] = { 'h','t','t','p',':','/','/',0 }, szSlash[] = { '/',0 } ;
- static const WCHAR szFormat1[] = { 'h','t','t','p',':','/','/','%','s',0 };
- static const WCHAR szFormat2[] = { 'h','t','t','p',':','/','/','%','s',':','%','d',0 };
- int len;
+ static const WCHAR szHttp[] = { 'h','t','t','p',':','/','/',0 };
+ static const WCHAR szFormat[] = { 'h','t','t','p',':','/','/','%','s',0 };
memset( &UrlComponents, 0, sizeof UrlComponents );
UrlComponents.dwStructSize = sizeof UrlComponents;
if( CSTR_EQUAL != CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE,
hIC->lpszProxy,strlenW(szHttp),szHttp,strlenW(szHttp)) )
- sprintfW(proxy, szFormat1, hIC->lpszProxy);
+ sprintfW(proxy, szFormat, hIC->lpszProxy);
else
strcpyW(proxy, hIC->lpszProxy);
if( !InternetCrackUrlW(proxy, 0, 0, &UrlComponents) )
if( !lpwhr->lpszPath )
lpwhr->lpszPath = szNul;
- TRACE("server=%s path=%s\n",
- debugstr_w(lpwhs->lpszHostName), debugstr_w(lpwhr->lpszPath));
- /* for constant 15 see above */
- len = strlenW(lpwhs->lpszHostName) + strlenW(lpwhr->lpszPath) + 15;
- url = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
if(UrlComponents.nPort == INTERNET_INVALID_PORT_NUMBER)
UrlComponents.nPort = INTERNET_DEFAULT_HTTP_PORT;
- sprintfW(url, szFormat2, lpwhs->lpszHostName, lpwhs->nHostPort);
-
- if( lpwhr->lpszPath[0] != '/' )
- strcatW( url, szSlash );
- strcatW(url, lpwhr->lpszPath);
- if(lpwhr->lpszPath != szNul)
- HeapFree(GetProcessHeap(), 0, lpwhr->lpszPath);
- lpwhr->lpszPath = url;
-
HeapFree(GetProcessHeap(), 0, lpwhs->lpszServerName);
lpwhs->lpszServerName = WININET_strdupW(UrlComponents.lpszHostName);
lpwhs->nServerPort = UrlComponents.nPort;
+ TRACE("proxy server=%s port=%d\n", debugstr_w(lpwhs->lpszServerName), lpwhs->nServerPort);
return TRUE;
}
return TRUE;
}
+
+/***********************************************************************
+ * HTTPREQ_Destroy (internal)
+ *
+ * Deallocate request handle
+ *
+ */
+static void HTTPREQ_Destroy(WININETHANDLEHEADER *hdr)
+{
+ LPWININETHTTPREQW lpwhr = (LPWININETHTTPREQW) hdr;
+ DWORD i;
+
+ TRACE("\n");
+
+ if(lpwhr->hCacheFile)
+ CloseHandle(lpwhr->hCacheFile);
+
+ if(lpwhr->lpszCacheFile) {
+ DeleteFileW(lpwhr->lpszCacheFile); /* FIXME */
+ HeapFree(GetProcessHeap(), 0, lpwhr->lpszCacheFile);
+ }
+
+ WININET_Release(&lpwhr->lpHttpSession->hdr);
+
+ HeapFree(GetProcessHeap(), 0, lpwhr->lpszPath);
+ HeapFree(GetProcessHeap(), 0, lpwhr->lpszVerb);
+ HeapFree(GetProcessHeap(), 0, lpwhr->lpszRawHeaders);
+ HeapFree(GetProcessHeap(), 0, lpwhr->lpszVersion);
+ HeapFree(GetProcessHeap(), 0, lpwhr->lpszStatusText);
+
+ for (i = 0; i < lpwhr->nCustHeaders; i++)
+ {
+ HeapFree(GetProcessHeap(), 0, lpwhr->pCustHeaders[i].lpszField);
+ HeapFree(GetProcessHeap(), 0, lpwhr->pCustHeaders[i].lpszValue);
+ }
+
+ HeapFree(GetProcessHeap(), 0, lpwhr->pCustHeaders);
+ HeapFree(GetProcessHeap(), 0, lpwhr);
+}
+
+static void HTTPREQ_CloseConnection(WININETHANDLEHEADER *hdr)
+{
+ LPWININETHTTPREQW lpwhr = (LPWININETHTTPREQW) hdr;
+ LPWININETHTTPSESSIONW lpwhs = NULL;
+
+ TRACE("%p\n",lpwhr);
+
+ if (!NETCON_connected(&lpwhr->netConnection))
+ return;
+
+ if (lpwhr->pAuthInfo)
+ {
+ if (SecIsValidHandle(&lpwhr->pAuthInfo->ctx))
+ DeleteSecurityContext(&lpwhr->pAuthInfo->ctx);
+ if (SecIsValidHandle(&lpwhr->pAuthInfo->cred))
+ FreeCredentialsHandle(&lpwhr->pAuthInfo->cred);
+
+ HeapFree(GetProcessHeap(), 0, lpwhr->pAuthInfo->auth_data);
+ HeapFree(GetProcessHeap(), 0, lpwhr->pAuthInfo->scheme);
+ HeapFree(GetProcessHeap(), 0, lpwhr->pAuthInfo);
+ lpwhr->pAuthInfo = NULL;
+ }
+ if (lpwhr->pProxyAuthInfo)
+ {
+ if (SecIsValidHandle(&lpwhr->pProxyAuthInfo->ctx))
+ DeleteSecurityContext(&lpwhr->pProxyAuthInfo->ctx);
+ if (SecIsValidHandle(&lpwhr->pProxyAuthInfo->cred))
+ FreeCredentialsHandle(&lpwhr->pProxyAuthInfo->cred);
+
+ HeapFree(GetProcessHeap(), 0, lpwhr->pProxyAuthInfo->auth_data);
+ HeapFree(GetProcessHeap(), 0, lpwhr->pProxyAuthInfo->scheme);
+ HeapFree(GetProcessHeap(), 0, lpwhr->pProxyAuthInfo);
+ lpwhr->pProxyAuthInfo = NULL;
+ }
+
+ lpwhs = lpwhr->lpHttpSession;
+
+ INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext,
+ INTERNET_STATUS_CLOSING_CONNECTION, 0, 0);
+
+ NETCON_close(&lpwhr->netConnection);
+
+ INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext,
+ INTERNET_STATUS_CONNECTION_CLOSED, 0, 0);
+}
+
+static DWORD HTTPREQ_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode)
+{
+ WININETHTTPREQW *req = (WININETHTTPREQW*)hdr;
+
+ switch(option) {
+ case INTERNET_OPTION_HANDLE_TYPE:
+ TRACE("INTERNET_OPTION_HANDLE_TYPE\n");
+
+ if (*size < sizeof(ULONG))
+ return ERROR_INSUFFICIENT_BUFFER;
+
+ *size = sizeof(DWORD);
+ *(DWORD*)buffer = INTERNET_HANDLE_TYPE_HTTP_REQUEST;
+ return ERROR_SUCCESS;
+
+ case INTERNET_OPTION_URL: {
+ WCHAR url[INTERNET_MAX_URL_LENGTH];
+ HTTPHEADERW *host;
+ DWORD len;
+
+ static const WCHAR formatW[] = {'h','t','t','p',':','/','/','%','s','%','s',0};
+ static const WCHAR hostW[] = {'H','o','s','t',0};
+
+ TRACE("INTERNET_OPTION_URL\n");
+
+ host = HTTP_GetHeader(req, hostW);
+ sprintfW(url, formatW, host->lpszValue, req->lpszPath);
+ TRACE("INTERNET_OPTION_URL: %s\n",debugstr_w(url));
+
+ if(unicode) {
+ len = (strlenW(url)+1) * sizeof(WCHAR);
+ if(*size < len)
+ return ERROR_INSUFFICIENT_BUFFER;
+
+ *size = len;
+ strcpyW(buffer, url);
+ return ERROR_SUCCESS;
+ }else {
+ len = WideCharToMultiByte(CP_ACP, 0, url, -1, buffer, *size, NULL, NULL);
+ if(len > *size)
+ return ERROR_INSUFFICIENT_BUFFER;
+
+ *size = len;
+ return ERROR_SUCCESS;
+ }
+ }
+
+ case INTERNET_OPTION_DATAFILE_NAME: {
+ DWORD req_size;
+
+ TRACE("INTERNET_OPTION_DATAFILE_NAME\n");
+
+ if(!req->lpszCacheFile) {
+ *size = 0;
+ return ERROR_INTERNET_ITEM_NOT_FOUND;
+ }
+
+ if(unicode) {
+ req_size = (lstrlenW(req->lpszCacheFile)+1) * sizeof(WCHAR);
+ if(*size < req_size)
+ return ERROR_INSUFFICIENT_BUFFER;
+
+ *size = req_size;
+ memcpy(buffer, req->lpszCacheFile, *size);
+ return ERROR_SUCCESS;
+ }else {
+ req_size = WideCharToMultiByte(CP_ACP, 0, req->lpszCacheFile, -1, NULL, 0, NULL, NULL);
+ if (req_size > *size)
+ return ERROR_INSUFFICIENT_BUFFER;
+
+ *size = WideCharToMultiByte(CP_ACP, 0, req->lpszCacheFile,
+ -1, buffer, *size, NULL, NULL);
+ return ERROR_SUCCESS;
+ }
+ }
+
+ case INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT: {
+ PCCERT_CONTEXT context;
+
+ if(*size < sizeof(INTERNET_CERTIFICATE_INFOW)) {
+ *size = sizeof(INTERNET_CERTIFICATE_INFOW);
+ return ERROR_INSUFFICIENT_BUFFER;
+ }
+
+ context = (PCCERT_CONTEXT)NETCON_GetCert(&(req->netConnection));
+ if(context) {
+ INTERNET_CERTIFICATE_INFOW *info = (INTERNET_CERTIFICATE_INFOW*)buffer;
+ DWORD len;
+
+ memset(info, 0, sizeof(INTERNET_CERTIFICATE_INFOW));
+ info->ftExpiry = context->pCertInfo->NotAfter;
+ info->ftStart = context->pCertInfo->NotBefore;
+ if(unicode) {
+ len = CertNameToStrW(context->dwCertEncodingType,
+ &context->pCertInfo->Subject, CERT_SIMPLE_NAME_STR, NULL, 0);
+ info->lpszSubjectInfo = LocalAlloc(0, len*sizeof(WCHAR));
+ if(info->lpszSubjectInfo)
+ CertNameToStrW(context->dwCertEncodingType,
+ &context->pCertInfo->Subject, CERT_SIMPLE_NAME_STR,
+ info->lpszSubjectInfo, len);
+ len = CertNameToStrW(context->dwCertEncodingType,
+ &context->pCertInfo->Issuer, CERT_SIMPLE_NAME_STR, NULL, 0);
+ info->lpszIssuerInfo = LocalAlloc(0, len*sizeof(WCHAR));
+ if (info->lpszIssuerInfo)
+ CertNameToStrW(context->dwCertEncodingType,
+ &context->pCertInfo->Issuer, CERT_SIMPLE_NAME_STR,
+ info->lpszIssuerInfo, len);
+ }else {
+ INTERNET_CERTIFICATE_INFOA *infoA = (INTERNET_CERTIFICATE_INFOA*)info;
+
+ len = CertNameToStrA(context->dwCertEncodingType,
+ &context->pCertInfo->Subject, CERT_SIMPLE_NAME_STR, NULL, 0);
+ infoA->lpszSubjectInfo = LocalAlloc(0, len);
+ if(infoA->lpszSubjectInfo)
+ CertNameToStrA(context->dwCertEncodingType,
+ &context->pCertInfo->Subject, CERT_SIMPLE_NAME_STR,
+ infoA->lpszSubjectInfo, len);
+ len = CertNameToStrA(context->dwCertEncodingType,
+ &context->pCertInfo->Issuer, CERT_SIMPLE_NAME_STR, NULL, 0);
+ infoA->lpszIssuerInfo = LocalAlloc(0, len);
+ if(infoA->lpszIssuerInfo)
+ CertNameToStrA(context->dwCertEncodingType,
+ &context->pCertInfo->Issuer, CERT_SIMPLE_NAME_STR,
+ infoA->lpszIssuerInfo, len);
+ }
+
+ /*
+ * Contrary to MSDN, these do not appear to be set.
+ * lpszProtocolName
+ * lpszSignatureAlgName
+ * lpszEncryptionAlgName
+ * dwKeySize
+ */
+ CertFreeCertificateContext(context);
+ return ERROR_SUCCESS;
+ }
+ }
+ }
+
+ FIXME("Not implemented option %d\n", option);
+ return ERROR_INTERNET_INVALID_OPTION;
+}
+
+static DWORD HTTPREQ_SetOption(WININETHANDLEHEADER *hdr, DWORD option, void *buffer, DWORD size)
+{
+ WININETHTTPREQW *req = (WININETHTTPREQW*)hdr;
+
+ switch(option) {
+ case INTERNET_OPTION_SEND_TIMEOUT:
+ case INTERNET_OPTION_RECEIVE_TIMEOUT:
+ TRACE("INTERNET_OPTION_SEND/RECEIVE_TIMEOUT\n");
+
+ if (size != sizeof(DWORD))
+ return ERROR_INVALID_PARAMETER;
+
+ return NETCON_set_timeout(&req->netConnection, option == INTERNET_OPTION_SEND_TIMEOUT,
+ *(DWORD*)buffer);
+ }
+
+ return ERROR_INTERNET_INVALID_OPTION;
+}
+
+static DWORD HTTP_Read(WININETHTTPREQW *req, void *buffer, DWORD size, DWORD *read, BOOL sync)
+{
+ int bytes_read;
+
+ if(!NETCON_recv(&req->netConnection, buffer, min(size, req->dwContentLength - req->dwContentRead),
+ sync ? MSG_WAITALL : 0, &bytes_read)) {
+ if(req->dwContentLength != -1 && req->dwContentRead != req->dwContentLength)
+ ERR("not all data received %d/%d\n", req->dwContentRead, req->dwContentLength);
+
+ /* always return success, even if the network layer returns an error */
+ *read = 0;
+ HTTP_FinishedReading(req);
+ return ERROR_SUCCESS;
+ }
+
+ req->dwContentRead += bytes_read;
+ *read = bytes_read;
+
+ if(req->lpszCacheFile) {
+ BOOL res;
+ DWORD dwBytesWritten;
+
+ res = WriteFile(req->hCacheFile, buffer, bytes_read, &dwBytesWritten, NULL);
+ if(!res)
+ WARN("WriteFile failed: %u\n", GetLastError());
+ }
+
+ if(!bytes_read && (req->dwContentRead == req->dwContentLength))
+ HTTP_FinishedReading(req);
+
+ return ERROR_SUCCESS;
+}
+
+static DWORD get_chunk_size(const char *buffer)
+{
+ const char *p;
+ DWORD size = 0;
+
+ for (p = buffer; *p; p++)
+ {
+ if (*p >= '0' && *p <= '9') size = size * 16 + *p - '0';
+ else if (*p >= 'a' && *p <= 'f') size = size * 16 + *p - 'a' + 10;
+ else if (*p >= 'A' && *p <= 'F') size = size * 16 + *p - 'A' + 10;
+ else if (*p == ';') break;
+ }
+ return size;
+}
+
+static DWORD HTTP_ReadChunked(WININETHTTPREQW *req, void *buffer, DWORD size, DWORD *read, BOOL sync)
+{
+ char reply[MAX_REPLY_LEN], *p = buffer;
+ DWORD buflen, to_read, to_write = size;
+ int bytes_read;
+
+ *read = 0;
+ for (;;)
+ {
+ if (*read == size) break;
+
+ if (req->dwContentLength == ~0UL) /* new chunk */
+ {
+ buflen = sizeof(reply);
+ if (!NETCON_getNextLine(&req->netConnection, reply, &buflen)) break;
+
+ if (!(req->dwContentLength = get_chunk_size(reply)))
+ {
+ /* zero sized chunk marks end of transfer; read any trailing headers and return */
+ HTTP_GetResponseHeaders(req, FALSE);
+ break;
+ }
+ }
+ to_read = min(to_write, req->dwContentLength - req->dwContentRead);
+
+ if (!NETCON_recv(&req->netConnection, p, to_read, sync ? MSG_WAITALL : 0, &bytes_read))
+ {
+ if (bytes_read != to_read)
+ ERR("Not all data received %d/%d\n", bytes_read, to_read);
+
+ /* always return success, even if the network layer returns an error */
+ *read = 0;
+ break;
+ }
+ if (!bytes_read) break;
+
+ req->dwContentRead += bytes_read;
+ to_write -= bytes_read;
+ *read += bytes_read;
+
+ if (req->lpszCacheFile)
+ {
+ if (!WriteFile(req->hCacheFile, p, bytes_read, NULL, NULL))
+ WARN("WriteFile failed: %u\n", GetLastError());
+ }
+ p += bytes_read;
+
+ if (req->dwContentRead == req->dwContentLength) /* chunk complete */
+ {
+ req->dwContentRead = 0;
+ req->dwContentLength = ~0UL;
+
+ buflen = sizeof(reply);
+ if (!NETCON_getNextLine(&req->netConnection, reply, &buflen))
+ {
+ ERR("Malformed chunk\n");
+ *read = 0;
+ break;
+ }
+ }
+ }
+ if (!*read) HTTP_FinishedReading(req);
+ return ERROR_SUCCESS;
+}
+
+static DWORD HTTPREQ_Read(WININETHTTPREQW *req, void *buffer, DWORD size, DWORD *read, BOOL sync)
+{
+ WCHAR encoding[20];
+ DWORD buflen = sizeof(encoding);
+ static const WCHAR szChunked[] = {'c','h','u','n','k','e','d',0};
+
+ if (HTTP_HttpQueryInfoW(req, HTTP_QUERY_TRANSFER_ENCODING, encoding, &buflen, NULL) &&
+ !strcmpiW(encoding, szChunked))
+ {
+ return HTTP_ReadChunked(req, buffer, size, read, sync);
+ }
+ else
+ return HTTP_Read(req, buffer, size, read, sync);
+}
+
+static DWORD HTTPREQ_ReadFile(WININETHANDLEHEADER *hdr, void *buffer, DWORD size, DWORD *read)
+{
+ WININETHTTPREQW *req = (WININETHTTPREQW*)hdr;
+ return HTTPREQ_Read(req, buffer, size, read, TRUE);
+}
+
+static void HTTPREQ_AsyncReadFileExProc(WORKREQUEST *workRequest)
+{
+ struct WORKREQ_INTERNETREADFILEEXA const *data = &workRequest->u.InternetReadFileExA;
+ WININETHTTPREQW *req = (WININETHTTPREQW*)workRequest->hdr;
+ INTERNET_ASYNC_RESULT iar;
+ DWORD res;
+
+ TRACE("INTERNETREADFILEEXA %p\n", workRequest->hdr);
+
+ res = HTTPREQ_Read(req, data->lpBuffersOut->lpvBuffer,
+ data->lpBuffersOut->dwBufferLength, &data->lpBuffersOut->dwBufferLength, TRUE);
+
+ iar.dwResult = res == ERROR_SUCCESS;
+ iar.dwError = res;
+
+ INTERNET_SendCallback(&req->hdr, req->hdr.dwContext,
+ INTERNET_STATUS_REQUEST_COMPLETE, &iar,
+ sizeof(INTERNET_ASYNC_RESULT));
+}
+
+static DWORD HTTPREQ_ReadFileExA(WININETHANDLEHEADER *hdr, INTERNET_BUFFERSA *buffers,
+ DWORD flags, DWORD_PTR context)
+{
+
+ WININETHTTPREQW *req = (WININETHTTPREQW*)hdr;
+ DWORD res;
+
+ if (flags & ~(IRF_ASYNC|IRF_NO_WAIT))
+ FIXME("these dwFlags aren't implemented: 0x%x\n", flags & ~(IRF_ASYNC|IRF_NO_WAIT));
+
+ if (buffers->dwStructSize != sizeof(*buffers))
+ return ERROR_INVALID_PARAMETER;
+
+ INTERNET_SendCallback(&req->hdr, req->hdr.dwContext, INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0);
+
+ if (hdr->dwFlags & INTERNET_FLAG_ASYNC) {
+ DWORD available = 0;
+
+ NETCON_query_data_available(&req->netConnection, &available);
+ if (!available)
+ {
+ WORKREQUEST workRequest;
+
+ workRequest.asyncproc = HTTPREQ_AsyncReadFileExProc;
+ workRequest.hdr = WININET_AddRef(&req->hdr);
+ workRequest.u.InternetReadFileExA.lpBuffersOut = buffers;
+
+ INTERNET_AsyncCall(&workRequest);
+
+ return ERROR_IO_PENDING;
+ }
+ }
+
+ res = HTTPREQ_Read(req, buffers->lpvBuffer, buffers->dwBufferLength, &buffers->dwBufferLength,
+ !(flags & IRF_NO_WAIT));
+
+ if (res == ERROR_SUCCESS) {
+ DWORD size = buffers->dwBufferLength;
+ INTERNET_SendCallback(&req->hdr, req->hdr.dwContext, INTERNET_STATUS_RESPONSE_RECEIVED,
+ &size, sizeof(size));
+ }
+
+ return res;
+}
+
+static BOOL HTTPREQ_WriteFile(WININETHANDLEHEADER *hdr, const void *buffer, DWORD size, DWORD *written)
+{
+ LPWININETHTTPREQW lpwhr = (LPWININETHTTPREQW)hdr;
+
+ return NETCON_send(&lpwhr->netConnection, buffer, size, 0, (LPINT)written);
+}
+
+static void HTTPREQ_AsyncQueryDataAvailableProc(WORKREQUEST *workRequest)
+{
+ WININETHTTPREQW *req = (WININETHTTPREQW*)workRequest->hdr;
+ INTERNET_ASYNC_RESULT iar;
+ char buffer[4048];
+
+ TRACE("%p\n", workRequest->hdr);
+
+ iar.dwResult = NETCON_recv(&req->netConnection, buffer,
+ min(sizeof(buffer), req->dwContentLength - req->dwContentRead),
+ MSG_PEEK, (int *)&iar.dwError);
+
+ INTERNET_SendCallback(&req->hdr, req->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE, &iar,
+ sizeof(INTERNET_ASYNC_RESULT));
+}
+
+static DWORD HTTPREQ_QueryDataAvailable(WININETHANDLEHEADER *hdr, DWORD *available, DWORD flags, DWORD_PTR ctx)
+{
+ WININETHTTPREQW *req = (WININETHTTPREQW*)hdr;
+ BYTE buffer[4048];
+ BOOL async;
+
+ TRACE("(%p %p %x %lx)\n", req, available, flags, ctx);
+
+ if(!NETCON_query_data_available(&req->netConnection, available) || *available)
+ return ERROR_SUCCESS;
+
+ /* Even if we are in async mode, we need to determine whether
+ * there is actually more data available. We do this by trying
+ * to peek only a single byte in async mode. */
+ async = (req->lpHttpSession->lpAppInfo->hdr.dwFlags & INTERNET_FLAG_ASYNC) != 0;
+
+ if (NETCON_recv(&req->netConnection, buffer,
+ min(async ? 1 : sizeof(buffer), req->dwContentLength - req->dwContentRead),
+ MSG_PEEK, (int *)available) && async && *available)
+ {
+ WORKREQUEST workRequest;
+
+ *available = 0;
+ workRequest.asyncproc = HTTPREQ_AsyncQueryDataAvailableProc;
+ workRequest.hdr = WININET_AddRef( &req->hdr );
+
+ INTERNET_AsyncCall(&workRequest);
+
+ return ERROR_IO_PENDING;
+ }
+
+ return ERROR_SUCCESS;
+}
+
+static const HANDLEHEADERVtbl HTTPREQVtbl = {
+ HTTPREQ_Destroy,
+ HTTPREQ_CloseConnection,
+ HTTPREQ_QueryOption,
+ HTTPREQ_SetOption,
+ HTTPREQ_ReadFile,
+ HTTPREQ_ReadFileExA,
+ HTTPREQ_WriteFile,
+ HTTPREQ_QueryDataAvailable,
+ NULL
+};
+
/***********************************************************************
* HTTP_HttpOpenRequestW (internal)
*
goto lend;
}
lpwhr->hdr.htype = WH_HHTTPREQ;
+ lpwhr->hdr.vtbl = &HTTPREQVtbl;
lpwhr->hdr.dwFlags = dwFlags;
lpwhr->hdr.dwContext = dwContext;
- lpwhr->hdr.dwRefCount = 1;
- lpwhr->hdr.close_connection = HTTP_CloseConnection;
- lpwhr->hdr.destroy = HTTP_CloseHTTPRequestHandle;
+ lpwhr->hdr.refs = 1;
lpwhr->hdr.lpfnStatusCB = lpwhs->hdr.lpfnStatusCB;
lpwhr->hdr.dwInternalFlags = lpwhs->hdr.dwInternalFlags & INET_CALLBACKW;
goto lend;
}
- if (NULL != lpszObjectName && strlenW(lpszObjectName)) {
+ if (lpszObjectName && *lpszObjectName) {
HRESULT rc;
len = 0;
}
}
- if (NULL != lpszReferrer && strlenW(lpszReferrer))
+ if (lpszReferrer && *lpszReferrer)
HTTP_ProcessHeader(lpwhr, HTTP_REFERER, lpszReferrer, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDHDR_FLAG_REQ);
if (lpszAcceptTypes)
}
}
- if (NULL == lpszVerb)
- {
- static const WCHAR szGet[] = {'G','E','T',0};
- lpwhr->lpszVerb = WININET_strdupW(szGet);
- }
- else if (strlenW(lpszVerb))
- lpwhr->lpszVerb = WININET_strdupW(lpszVerb);
+ lpwhr->lpszVerb = WININET_strdupW(lpszVerb && *lpszVerb ? lpszVerb : szGET);
+
+ if (lpszVersion)
+ lpwhr->lpszVersion = WININET_strdupW(lpszVersion);
+ else
+ lpwhr->lpszVersion = WININET_strdupW(g_szHttp1_1);
HTTP_ProcessHeader(lpwhr, szHost, lpwhs->lpszHostName, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDHDR_FLAG_REQ);
lpwhs->nServerPort = (dwFlags & INTERNET_FLAG_SECURE ?
INTERNET_DEFAULT_HTTPS_PORT :
INTERNET_DEFAULT_HTTP_PORT);
- lpwhs->nHostPort = lpwhs->nServerPort;
-
- if (NULL != hIC->lpszProxy && hIC->lpszProxy[0] != 0)
- HTTP_DealWithProxy( hIC, lpwhs, lpwhr );
-
- if (hIC->lpszAgent)
- {
- WCHAR *agent_header;
- static const WCHAR user_agent[] = {'U','s','e','r','-','A','g','e','n','t',':',' ','%','s','\r','\n',0 };
- len = strlenW(hIC->lpszAgent) + strlenW(user_agent);
- agent_header = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
- sprintfW(agent_header, user_agent, hIC->lpszAgent );
+ if (lpwhs->nHostPort == INTERNET_INVALID_PORT_NUMBER)
+ lpwhs->nHostPort = (dwFlags & INTERNET_FLAG_SECURE ?
+ INTERNET_DEFAULT_HTTPS_PORT :
+ INTERNET_DEFAULT_HTTP_PORT);
- HTTP_HttpAddRequestHeadersW(lpwhr, agent_header, strlenW(agent_header),
- HTTP_ADDREQ_FLAG_ADD);
- HeapFree(GetProcessHeap(), 0, agent_header);
- }
+ if (NULL != hIC->lpszProxy && hIC->lpszProxy[0] != 0)
+ HTTP_DealWithProxy( hIC, lpwhs, lpwhr );
Host = HTTP_GetHeader(lpwhr,szHost);
return handle;
}
+/* read any content returned by the server so that the connection can be
+ * reused */
+static void HTTP_DrainContent(WININETHTTPREQW *req)
+{
+ DWORD bytes_read;
+
+ if (!NETCON_connected(&req->netConnection)) return;
+
+ if (req->dwContentLength == -1)
+ NETCON_close(&req->netConnection);
+
+ do
+ {
+ char buffer[2048];
+ if (HTTP_Read(req, buffer, sizeof(buffer), &bytes_read, TRUE) != ERROR_SUCCESS)
+ return;
+ } while (bytes_read);
+}
+
static const WCHAR szAccept[] = { 'A','c','c','e','p','t',0 };
static const WCHAR szAccept_Charset[] = { 'A','c','c','e','p','t','-','C','h','a','r','s','e','t', 0 };
static const WCHAR szAccept_Encoding[] = { 'A','c','c','e','p','t','-','E','n','c','o','d','i','n','g',0 };
{
LPWSTR headers;
DWORD len;
- BOOL ret;
+ BOOL ret = FALSE;
if (request_only)
- headers = HTTP_BuildHeaderRequestString(lpwhr, lpwhr->lpszVerb, lpwhr->lpszPath, FALSE);
+ headers = HTTP_BuildHeaderRequestString(lpwhr, lpwhr->lpszVerb, lpwhr->lpszPath, lpwhr->lpszVersion);
else
headers = lpwhr->lpszRawHeaders;
- len = strlenW(headers);
- if (len + 1 > *lpdwBufferLength/sizeof(WCHAR))
+ len = (strlenW(headers) + 1) * sizeof(WCHAR);
+ if (len > *lpdwBufferLength)
{
- *lpdwBufferLength = (len + 1) * sizeof(WCHAR);
INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER);
ret = FALSE;
- } else
+ }
+ else if (lpBuffer)
{
- memcpy(lpBuffer, headers, (len+1)*sizeof(WCHAR));
- *lpdwBufferLength = len * sizeof(WCHAR);
-
- TRACE("returning data: %s\n", debugstr_wn((WCHAR*)lpBuffer, len));
+ memcpy(lpBuffer, headers, len);
+ TRACE("returning data: %s\n", debugstr_wn(lpBuffer, len / sizeof(WCHAR)));
ret = TRUE;
}
+ *lpdwBufferLength = len;
if (request_only)
HeapFree(GetProcessHeap(), 0, headers);
if (lpBuffer)
{
+ DWORD alloclen;
len = (*lpdwBufferLength)*sizeof(WCHAR);
- bufferW = HeapAlloc( GetProcessHeap(), 0, len );
+ if ((dwInfoLevel & HTTP_QUERY_HEADER_MASK) == HTTP_QUERY_CUSTOM)
+ {
+ alloclen = MultiByteToWideChar( CP_ACP, 0, lpBuffer, -1, NULL, 0 ) * sizeof(WCHAR);
+ if (alloclen < len)
+ alloclen = len;
+ }
+ else
+ alloclen = len;
+ bufferW = HeapAlloc( GetProcessHeap(), 0, alloclen );
/* buffer is in/out because of HTTP_QUERY_CUSTOM */
if ((dwInfoLevel & HTTP_QUERY_HEADER_MASK) == HTTP_QUERY_CUSTOM)
- MultiByteToWideChar(CP_ACP,0,lpBuffer,-1,bufferW,len);
+ MultiByteToWideChar( CP_ACP, 0, lpBuffer, -1, bufferW, alloclen / sizeof(WCHAR) );
} else
{
bufferW = NULL;
DWORD headerlen;
LPWSTR header = NULL;
- TRACE("(%p, %p, %p, %08x, %08lx): stub\n", hRequest, lpBuffersIn,
+ TRACE("(%p, %p, %p, %08x, %08lx)\n", hRequest, lpBuffersIn,
lpBuffersOut, dwFlags, dwContext);
if (lpBuffersIn)
return result;
}
+static BOOL HTTP_GetRequestURL(WININETHTTPREQW *req, LPWSTR buf)
+{
+ LPHTTPHEADERW host_header;
+
+ static const WCHAR formatW[] = {'h','t','t','p',':','/','/','%','s','%','s',0};
+
+ host_header = HTTP_GetHeader(req, szHost);
+ if(!host_header)
+ return FALSE;
+
+ sprintfW(buf, formatW, host_header->lpszValue, req->lpszPath); /* FIXME */
+ return TRUE;
+}
+
/***********************************************************************
* HTTP_HandleRedirect (internal)
*/
static BOOL HTTP_HandleRedirect(LPWININETHTTPREQW lpwhr, LPCWSTR lpszUrl)
{
+ static const WCHAR szContentType[] = {'C','o','n','t','e','n','t','-','T','y','p','e',0};
+ static const WCHAR szContentLength[] = {'C','o','n','t','e','n','t','-','L','e','n','g','t','h',0};
LPWININETHTTPSESSIONW lpwhs = lpwhr->lpHttpSession;
LPWININETAPPINFOW hIC = lpwhs->lpAppInfo;
- WCHAR path[2048];
+ BOOL using_proxy = hIC->lpszProxy && hIC->lpszProxy[0];
+ WCHAR path[INTERNET_MAX_URL_LENGTH];
+ int index;
if(lpszUrl[0]=='/')
{
/* if it's an absolute path, keep the same session info */
- lstrcpynW(path, lpszUrl, 2048);
- }
- else if (NULL != hIC->lpszProxy && hIC->lpszProxy[0] != 0)
- {
- TRACE("Redirect through proxy\n");
- lstrcpynW(path, lpszUrl, 2048);
+ lstrcpynW(path, lpszUrl, INTERNET_MAX_URL_LENGTH);
}
else
{
HeapFree(GetProcessHeap(), 0, combined_url);
return FALSE;
}
+
HeapFree(GetProcessHeap(), 0, combined_url);
if (!strncmpW(szHttp, urlComponents.lpszScheme, strlenW(szHttp)) &&
*/
/* consider the current host as the referrer */
- if (NULL != lpwhs->lpszServerName && strlenW(lpwhs->lpszServerName))
+ if (lpwhs->lpszServerName && *lpwhs->lpszServerName)
HTTP_ProcessHeader(lpwhr, HTTP_REFERER, lpwhs->lpszServerName,
HTTP_ADDHDR_FLAG_REQ|HTTP_ADDREQ_FLAG_REPLACE|
HTTP_ADDHDR_FLAG_ADD_IF_NEW);
#endif
- HeapFree(GetProcessHeap(), 0, lpwhs->lpszServerName);
- lpwhs->lpszServerName = WININET_strdupW(hostName);
HeapFree(GetProcessHeap(), 0, lpwhs->lpszHostName);
if (urlComponents.nPort != INTERNET_DEFAULT_HTTP_PORT &&
- urlComponents.nPort != INTERNET_DEFAULT_HTTPS_PORT)
+ urlComponents.nPort != INTERNET_DEFAULT_HTTPS_PORT)
{
int len;
static const WCHAR fmt[] = {'%','s',':','%','i',0};
HTTP_ProcessHeader(lpwhr, szHost, lpwhs->lpszHostName, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDHDR_FLAG_REQ);
-
HeapFree(GetProcessHeap(), 0, lpwhs->lpszUserName);
lpwhs->lpszUserName = NULL;
if (userName[0])
lpwhs->lpszUserName = WININET_strdupW(userName);
- lpwhs->nServerPort = urlComponents.nPort;
- if (!HTTP_ResolveName(lpwhr))
- return FALSE;
+ if (!using_proxy)
+ {
+ HeapFree(GetProcessHeap(), 0, lpwhs->lpszServerName);
+ lpwhs->lpszServerName = WININET_strdupW(hostName);
+ lpwhs->nServerPort = urlComponents.nPort;
+
+ if (!HTTP_ResolveName(lpwhr))
+ return FALSE;
- NETCON_close(&lpwhr->netConnection);
+ NETCON_close(&lpwhr->netConnection);
- if (!NETCON_init(&lpwhr->netConnection,lpwhr->hdr.dwFlags & INTERNET_FLAG_SECURE))
- return FALSE;
+ if (!NETCON_init(&lpwhr->netConnection,lpwhr->hdr.dwFlags & INTERNET_FLAG_SECURE))
+ return FALSE;
+ }
+ else
+ TRACE("Redirect through proxy\n");
}
HeapFree(GetProcessHeap(), 0, lpwhr->lpszPath);
lpwhr->lpszPath=NULL;
- if (strlenW(path))
+ if (*path)
{
DWORD needed = 0;
HRESULT rc;
}
}
+ /* Remove custom content-type/length headers on redirects. */
+ index = HTTP_GetCustomHeaderIndex(lpwhr, szContentType, 0, TRUE);
+ if (0 <= index)
+ HTTP_DeleteCustomHeader(lpwhr, index);
+ index = HTTP_GetCustomHeaderIndex(lpwhr, szContentLength, 0, TRUE);
+ if (0 <= index)
+ HTTP_DeleteCustomHeader(lpwhr, index);
+
return TRUE;
}
lpszPath = HeapAlloc( GetProcessHeap(), 0, (lstrlenW( lpwhs->lpszHostName ) + 13)*sizeof(WCHAR) );
sprintfW( lpszPath, szFormat, lpwhs->lpszHostName, lpwhs->nHostPort );
- requestString = HTTP_BuildHeaderRequestString( lpwhr, szConnect, lpszPath, FALSE );
+ requestString = HTTP_BuildHeaderRequestString( lpwhr, szConnect, lpszPath, g_szHttp1_1 );
HeapFree( GetProcessHeap(), 0, lpszPath );
len = WideCharToMultiByte( CP_ACP, 0, requestString, -1,
if (!ret || cnt < 0)
return FALSE;
- responseLen = HTTP_GetResponseHeaders( lpwhr );
+ responseLen = HTTP_GetResponseHeaders( lpwhr, TRUE );
if (!responseLen)
return FALSE;
BOOL loop_next;
INTERNET_ASYNC_RESULT iar;
static const WCHAR szClose[] = { 'C','l','o','s','e',0 };
+ static const WCHAR szPost[] = { 'P','O','S','T',0 };
static const WCHAR szContentLength[] =
{ 'C','o','n','t','e','n','t','-','L','e','n','g','t','h',':',' ','%','l','i','\r','\n',0 };
WCHAR contentLengthStr[sizeof szContentLength/2 /* includes \r\n */ + 20 /* int */ ];
/* Clear any error information */
INTERNET_SetLastError(0);
- HTTP_FixVerb(lpwhr);
-
- sprintfW(contentLengthStr, szContentLength, dwContentLength);
- HTTP_HttpAddRequestHeadersW(lpwhr, contentLengthStr, -1L, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDHDR_FLAG_REPLACE);
+ /* if the verb is NULL default to GET */
+ if (!lpwhr->lpszVerb)
+ lpwhr->lpszVerb = WININET_strdupW(szGET);
+
+ if (dwContentLength || !strcmpW(lpwhr->lpszVerb, szPost))
+ {
+ sprintfW(contentLengthStr, szContentLength, dwContentLength);
+ HTTP_HttpAddRequestHeadersW(lpwhr, contentLengthStr, -1L, HTTP_ADDREQ_FLAG_ADD_IF_NEW);
+ }
+ if (lpwhr->lpHttpSession->lpAppInfo->lpszAgent)
+ {
+ WCHAR *agent_header;
+ static const WCHAR user_agent[] = {'U','s','e','r','-','A','g','e','n','t',':',' ','%','s','\r','\n',0};
+ int len;
+
+ len = strlenW(lpwhr->lpHttpSession->lpAppInfo->lpszAgent) + strlenW(user_agent);
+ agent_header = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ sprintfW(agent_header, user_agent, lpwhr->lpHttpSession->lpAppInfo->lpszAgent);
+
+ HTTP_HttpAddRequestHeadersW(lpwhr, agent_header, strlenW(agent_header), HTTP_ADDREQ_FLAG_ADD_IF_NEW);
+ HeapFree(GetProcessHeap(), 0, agent_header);
+ }
do
{
lpwhr->hdr.dwFlags & INTERNET_FLAG_KEEP_CONNECTION ? szKeepAlive : szClose,
HTTP_ADDHDR_FLAG_REQ | HTTP_ADDHDR_FLAG_REPLACE);
- HTTP_InsertAuthorization(lpwhr);
- HTTP_InsertProxyAuthorization(lpwhr);
+ HTTP_InsertAuthorization(lpwhr, lpwhr->pAuthInfo, szAuthorization);
+ HTTP_InsertAuthorization(lpwhr, lpwhr->pProxyAuthInfo, szProxy_Authorization);
/* add the headers the caller supplied */
if( lpszHeaders && dwHeaderLength )
HTTP_ADDREQ_FLAG_ADD | HTTP_ADDHDR_FLAG_REPLACE);
}
- requestString = HTTP_BuildHeaderRequestString(lpwhr, lpwhr->lpszVerb, lpwhr->lpszPath, FALSE);
+ if (lpwhr->lpHttpSession->lpAppInfo->lpszProxy && lpwhr->lpHttpSession->lpAppInfo->lpszProxy[0])
+ {
+ WCHAR *url = HTTP_BuildProxyRequestUrl(lpwhr);
+ requestString = HTTP_BuildHeaderRequestString(lpwhr, lpwhr->lpszVerb, url, lpwhr->lpszVersion);
+ HeapFree(GetProcessHeap(), 0, url);
+ }
+ else
+ requestString = HTTP_BuildHeaderRequestString(lpwhr, lpwhr->lpszVerb, lpwhr->lpszPath, lpwhr->lpszVersion);
+
TRACE("Request header -> %s\n", debugstr_w(requestString) );
{
DWORD dwBufferSize;
DWORD dwStatusCode;
+ WCHAR encoding[20];
+ static const WCHAR szChunked[] = {'c','h','u','n','k','e','d',0};
INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext,
INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0);
if (cnt < 0)
goto lend;
- responseLen = HTTP_GetResponseHeaders(lpwhr);
+ responseLen = HTTP_GetResponseHeaders(lpwhr, TRUE);
if (responseLen)
bSuccess = TRUE;
INTERNET_STATUS_RESPONSE_RECEIVED, &responseLen,
sizeof(DWORD));
- HTTP_ProcessHeaders(lpwhr);
+ HTTP_ProcessCookies(lpwhr);
dwBufferSize = sizeof(lpwhr->dwContentLength);
if (!HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_CONTENT_LENGTH,
if (lpwhr->dwContentLength == 0)
HTTP_FinishedReading(lpwhr);
+ /* Correct the case where both a Content-Length and Transfer-encoding = chunked are set */
+
+ dwBufferSize = sizeof(encoding);
+ if (HTTP_HttpQueryInfoW(lpwhr, HTTP_QUERY_TRANSFER_ENCODING, encoding, &dwBufferSize, NULL) &&
+ !strcmpiW(encoding, szChunked))
+ {
+ lpwhr->dwContentLength = -1;
+ }
+
dwBufferSize = sizeof(dwStatusCode);
if (!HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_STATUS_CODE,
&dwStatusCode,&dwBufferSize,NULL))
if (!(lpwhr->hdr.dwFlags & INTERNET_FLAG_NO_AUTO_REDIRECT) && bSuccess)
{
- WCHAR szNewLocation[2048];
+ WCHAR szNewLocation[INTERNET_MAX_URL_LENGTH];
dwBufferSize=sizeof(szNewLocation);
if ((dwStatusCode==HTTP_STATUS_REDIRECT || dwStatusCode==HTTP_STATUS_MOVED) &&
HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_LOCATION,szNewLocation,&dwBufferSize,NULL))
}
while (loop_next);
+ /* FIXME: Better check, when we have to create the cache file */
+ if(bSuccess && (lpwhr->hdr.dwFlags & INTERNET_FLAG_NEED_FILE)) {
+ WCHAR url[INTERNET_MAX_URL_LENGTH];
+ WCHAR cacheFileName[MAX_PATH+1];
+ BOOL b;
+
+ b = HTTP_GetRequestURL(lpwhr, url);
+ if(!b) {
+ WARN("Could not get URL\n");
+ goto lend;
+ }
+
+ b = CreateUrlCacheEntryW(url, lpwhr->dwContentLength > 0 ? lpwhr->dwContentLength : 0, NULL, cacheFileName, 0);
+ if(b) {
+ lpwhr->lpszCacheFile = WININET_strdupW(cacheFileName);
+ lpwhr->hCacheFile = CreateFileW(lpwhr->lpszCacheFile, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
+ NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ if(lpwhr->hCacheFile == INVALID_HANDLE_VALUE) {
+ WARN("Could not create file: %u\n", GetLastError());
+ lpwhr->hCacheFile = NULL;
+ }
+ }else {
+ WARN("Could not create cache entry: %08x\n", GetLastError());
+ }
+ }
+
lend:
HeapFree(GetProcessHeap(), 0, requestString);
/* TODO: send notification for P3P header */
- iar.dwResult = (DWORD)bSuccess;
+ iar.dwResult = (DWORD_PTR)lpwhr->hdr.hInternet;
iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError();
INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext,
return bSuccess;
}
+/***********************************************************************
+ * HTTPSESSION_Destroy (internal)
+ *
+ * Deallocate session handle
+ *
+ */
+static void HTTPSESSION_Destroy(WININETHANDLEHEADER *hdr)
+{
+ LPWININETHTTPSESSIONW lpwhs = (LPWININETHTTPSESSIONW) hdr;
+
+ TRACE("%p\n", lpwhs);
+
+ WININET_Release(&lpwhs->lpAppInfo->hdr);
+
+ HeapFree(GetProcessHeap(), 0, lpwhs->lpszHostName);
+ HeapFree(GetProcessHeap(), 0, lpwhs->lpszServerName);
+ HeapFree(GetProcessHeap(), 0, lpwhs->lpszPassword);
+ HeapFree(GetProcessHeap(), 0, lpwhs->lpszUserName);
+ HeapFree(GetProcessHeap(), 0, lpwhs);
+}
+
+static DWORD HTTPSESSION_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode)
+{
+ switch(option) {
+ case INTERNET_OPTION_HANDLE_TYPE:
+ TRACE("INTERNET_OPTION_HANDLE_TYPE\n");
+
+ if (*size < sizeof(ULONG))
+ return ERROR_INSUFFICIENT_BUFFER;
+
+ *size = sizeof(DWORD);
+ *(DWORD*)buffer = INTERNET_HANDLE_TYPE_CONNECT_HTTP;
+ return ERROR_SUCCESS;
+ }
+
+ FIXME("Not implemented option %d\n", option);
+ return ERROR_INTERNET_INVALID_OPTION;
+}
+
+static const HANDLEHEADERVtbl HTTPSESSIONVtbl = {
+ HTTPSESSION_Destroy,
+ NULL,
+ HTTPSESSION_QueryOption,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+
/***********************************************************************
* HTTP_Connect (internal)
*
LPCWSTR lpszPassword, DWORD dwFlags, DWORD_PTR dwContext,
DWORD dwInternalFlags)
{
- BOOL bSuccess = FALSE;
LPWININETHTTPSESSIONW lpwhs = NULL;
HINTERNET handle = NULL;
TRACE("-->\n");
+ if (!lpszServerName || !lpszServerName[0])
+ {
+ INTERNET_SetLastError(ERROR_INVALID_PARAMETER);
+ goto lerror;
+ }
+
assert( hIC->hdr.htype == WH_HINIT );
lpwhs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WININETHTTPSESSIONW));
*/
lpwhs->hdr.htype = WH_HHTTPSESSION;
+ lpwhs->hdr.vtbl = &HTTPSESSIONVtbl;
lpwhs->hdr.dwFlags = dwFlags;
lpwhs->hdr.dwContext = dwContext;
lpwhs->hdr.dwInternalFlags = dwInternalFlags | (hIC->hdr.dwInternalFlags & INET_CALLBACKW);
- lpwhs->hdr.dwRefCount = 1;
- lpwhs->hdr.close_connection = NULL;
- lpwhs->hdr.destroy = HTTP_CloseHTTPSessionHandle;
+ lpwhs->hdr.refs = 1;
lpwhs->hdr.lpfnStatusCB = hIC->hdr.lpfnStatusCB;
WININET_AddRef( &hIC->hdr );
sizeof(handle));
}
- bSuccess = TRUE;
-
lerror:
if( lpwhs )
WININET_Release( &lpwhs->hdr );
* TRUE on success
* FALSE on error
*/
-static INT HTTP_GetResponseHeaders(LPWININETHTTPREQW lpwhr)
+static INT HTTP_GetResponseHeaders(LPWININETHTTPREQW lpwhr, BOOL clear)
{
INT cbreaks = 0;
WCHAR buffer[MAX_REPLY_LEN];
BOOL bSuccess = FALSE;
INT rc = 0;
static const WCHAR szCrLf[] = {'\r','\n',0};
+ static const WCHAR szHundred[] = {'1','0','0',0};
char bufferA[MAX_REPLY_LEN];
LPWSTR status_code, status_text;
DWORD cchMaxRawHeaders = 1024;
TRACE("-->\n");
/* clear old response headers (eg. from a redirect response) */
- HTTP_clear_response_headers( lpwhr );
+ if (clear) HTTP_clear_response_headers( lpwhr );
if (!NETCON_connected(&lpwhr->netConnection))
goto lend;
- /*
- * HACK peek at the buffer
- */
-#if 0
- /* This is Wine code, we don't support MSG_PEEK yet so we have to do it
- a bit different */
- NETCON_recv(&lpwhr->netConnection, buffer, buflen, MSG_PEEK, &rc);
-#endif
+ do {
+ /*
+ * HACK peek at the buffer
+ */
+ buflen = MAX_REPLY_LEN;
+ NETCON_recv(&lpwhr->netConnection, buffer, buflen, MSG_PEEK, &rc);
- /*
- * We should first receive 'HTTP/1.x nnn OK' where nnn is the status code.
- */
- buflen = MAX_REPLY_LEN;
- memset(buffer, 0, MAX_REPLY_LEN);
- if (!NETCON_getNextLine(&lpwhr->netConnection, bufferA, &buflen))
- goto lend;
-#if 1
- rc = buflen;
-#endif
- MultiByteToWideChar( CP_ACP, 0, bufferA, buflen, buffer, MAX_REPLY_LEN );
+ /*
+ * We should first receive 'HTTP/1.x nnn OK' where nnn is the status code.
+ */
+ memset(buffer, 0, MAX_REPLY_LEN);
+ if (!NETCON_getNextLine(&lpwhr->netConnection, bufferA, &buflen))
+ goto lend;
+ MultiByteToWideChar( CP_ACP, 0, bufferA, buflen, buffer, MAX_REPLY_LEN );
- /* regenerate raw headers */
- while (cchRawHeaders + buflen + strlenW(szCrLf) > cchMaxRawHeaders)
- {
- cchMaxRawHeaders *= 2;
- lpszRawHeaders = HeapReAlloc(GetProcessHeap(), 0, lpszRawHeaders, (cchMaxRawHeaders+1)*sizeof(WCHAR));
- }
- memcpy(lpszRawHeaders+cchRawHeaders, buffer, (buflen-1)*sizeof(WCHAR));
- cchRawHeaders += (buflen-1);
- memcpy(lpszRawHeaders+cchRawHeaders, szCrLf, sizeof(szCrLf));
- cchRawHeaders += sizeof(szCrLf)/sizeof(szCrLf[0])-1;
- lpszRawHeaders[cchRawHeaders] = '\0';
+ /* split the version from the status code */
+ status_code = strchrW( buffer, ' ' );
+ if( !status_code )
+ goto lend;
+ *status_code++=0;
- /* split the version from the status code */
- status_code = strchrW( buffer, ' ' );
- if( !status_code )
- goto lend;
- *status_code++=0;
+ /* split the status code from the status text */
+ status_text = strchrW( status_code, ' ' );
+ if( !status_text )
+ goto lend;
+ *status_text++=0;
- /* split the status code from the status text */
- status_text = strchrW( status_code, ' ' );
- if( !status_text )
- goto lend;
- *status_text++=0;
+ TRACE("version [%s] status code [%s] status text [%s]\n",
+ debugstr_w(buffer), debugstr_w(status_code), debugstr_w(status_text) );
- TRACE("version [%s] status code [%s] status text [%s]\n",
- debugstr_w(buffer), debugstr_w(status_code), debugstr_w(status_text) );
+ } while (!strcmpW(status_code, szHundred)); /* ignore "100 Continue" responses */
+ /* Add status code */
HTTP_ProcessHeader(lpwhr, szStatus, status_code,
HTTP_ADDHDR_FLAG_REPLACE);
lpwhr->lpszVersion= WININET_strdupW(buffer);
lpwhr->lpszStatusText = WININET_strdupW(status_text);
+ /* Restore the spaces */
+ *(status_code-1) = ' ';
+ *(status_text-1) = ' ';
+
+ /* regenerate raw headers */
+ while (cchRawHeaders + buflen + strlenW(szCrLf) > cchMaxRawHeaders)
+ {
+ cchMaxRawHeaders *= 2;
+ lpszRawHeaders = HeapReAlloc(GetProcessHeap(), 0, lpszRawHeaders, (cchMaxRawHeaders+1)*sizeof(WCHAR));
+ }
+ memcpy(lpszRawHeaders+cchRawHeaders, buffer, (buflen-1)*sizeof(WCHAR));
+ cchRawHeaders += (buflen-1);
+ memcpy(lpszRawHeaders+cchRawHeaders, szCrLf, sizeof(szCrLf));
+ cchRawHeaders += sizeof(szCrLf)/sizeof(szCrLf[0])-1;
+ lpszRawHeaders[cchRawHeaders] = '\0';
+
/* Parse each response line */
do
{
}
-/***********************************************************************
- * HTTP_CloseConnection (internal)
- *
- * Close socket connection
- *
- */
-static void HTTP_CloseConnection(LPWININETHANDLEHEADER hdr)
-{
- LPWININETHTTPREQW lpwhr = (LPWININETHTTPREQW) hdr;
- LPWININETHTTPSESSIONW lpwhs = NULL;
- LPWININETAPPINFOW hIC = NULL;
-
- TRACE("%p\n",lpwhr);
-
- if (!NETCON_connected(&lpwhr->netConnection))
- return;
-
- if (lpwhr->pAuthInfo)
- {
- DeleteSecurityContext(&lpwhr->pAuthInfo->ctx);
- FreeCredentialsHandle(&lpwhr->pAuthInfo->cred);
-
- HeapFree(GetProcessHeap(), 0, lpwhr->pAuthInfo->auth_data);
- HeapFree(GetProcessHeap(), 0, lpwhr->pAuthInfo->scheme);
- HeapFree(GetProcessHeap(), 0, lpwhr->pAuthInfo);
- lpwhr->pAuthInfo = NULL;
- }
- if (lpwhr->pProxyAuthInfo)
- {
- DeleteSecurityContext(&lpwhr->pProxyAuthInfo->ctx);
- FreeCredentialsHandle(&lpwhr->pProxyAuthInfo->cred);
-
- HeapFree(GetProcessHeap(), 0, lpwhr->pProxyAuthInfo->auth_data);
- HeapFree(GetProcessHeap(), 0, lpwhr->pProxyAuthInfo->scheme);
- HeapFree(GetProcessHeap(), 0, lpwhr->pProxyAuthInfo);
- lpwhr->pProxyAuthInfo = NULL;
- }
-
- lpwhs = lpwhr->lpHttpSession;
- hIC = lpwhs->lpAppInfo;
-
- INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext,
- INTERNET_STATUS_CLOSING_CONNECTION, 0, 0);
-
- NETCON_close(&lpwhr->netConnection);
-
- INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext,
- INTERNET_STATUS_CONNECTION_CLOSED, 0, 0);
-}
-
-
/***********************************************************************
* HTTP_FinishedReading (internal)
*
*/
BOOL HTTP_FinishedReading(LPWININETHTTPREQW lpwhr)
{
- WCHAR szConnectionResponse[20];
- DWORD dwBufferSize = sizeof(szConnectionResponse);
+ WCHAR szVersion[10];
+ DWORD dwBufferSize = sizeof(szVersion);
TRACE("\n");
- if (!HTTP_HttpQueryInfoW(lpwhr, HTTP_QUERY_CONNECTION, szConnectionResponse,
+ /* as per RFC 2068, S8.1.2.1, if the client is HTTP/1.1 then assume that
+ * the connection is keep-alive by default */
+ if (!HTTP_HttpQueryInfoW(lpwhr, HTTP_QUERY_VERSION, szVersion,
&dwBufferSize, NULL) ||
- strcmpiW(szConnectionResponse, szKeepAlive))
+ strcmpiW(szVersion, g_szHttp1_1))
{
- HTTP_CloseConnection(&lpwhr->hdr);
+ WCHAR szConnectionResponse[20];
+ dwBufferSize = sizeof(szConnectionResponse);
+ if ((!HTTP_HttpQueryInfoW(lpwhr, HTTP_QUERY_CONNECTION, szConnectionResponse, &dwBufferSize, NULL) ||
+ strcmpiW(szConnectionResponse, szKeepAlive)) &&
+ (!HTTP_HttpQueryInfoW(lpwhr, HTTP_QUERY_PROXY_CONNECTION, szConnectionResponse, &dwBufferSize, NULL) ||
+ strcmpiW(szConnectionResponse, szKeepAlive)))
+ {
+ HTTPREQ_CloseConnection(&lpwhr->hdr);
+ }
}
/* FIXME: store data in the URL cache here */
return TRUE;
}
-/***********************************************************************
- * HTTP_CloseHTTPRequestHandle (internal)
- *
- * Deallocate request handle
- *
- */
-static void HTTP_CloseHTTPRequestHandle(LPWININETHANDLEHEADER hdr)
-{
- DWORD i;
- LPWININETHTTPREQW lpwhr = (LPWININETHTTPREQW) hdr;
-
- TRACE("\n");
-
- WININET_Release(&lpwhr->lpHttpSession->hdr);
-
- HeapFree(GetProcessHeap(), 0, lpwhr->lpszPath);
- HeapFree(GetProcessHeap(), 0, lpwhr->lpszVerb);
- HeapFree(GetProcessHeap(), 0, lpwhr->lpszRawHeaders);
- HeapFree(GetProcessHeap(), 0, lpwhr->lpszVersion);
- HeapFree(GetProcessHeap(), 0, lpwhr->lpszStatusText);
-
- for (i = 0; i < lpwhr->nCustHeaders; i++)
- {
- HeapFree(GetProcessHeap(), 0, lpwhr->pCustHeaders[i].lpszField);
- HeapFree(GetProcessHeap(), 0, lpwhr->pCustHeaders[i].lpszValue);
- }
-
- HeapFree(GetProcessHeap(), 0, lpwhr->pCustHeaders);
- HeapFree(GetProcessHeap(), 0, lpwhr);
-}
-
-
-/***********************************************************************
- * HTTP_CloseHTTPSessionHandle (internal)
- *
- * Deallocate session handle
- *
- */
-static void HTTP_CloseHTTPSessionHandle(LPWININETHANDLEHEADER hdr)
-{
- LPWININETHTTPSESSIONW lpwhs = (LPWININETHTTPSESSIONW) hdr;
-
- TRACE("%p\n", lpwhs);
-
- WININET_Release(&lpwhs->lpAppInfo->hdr);
-
- HeapFree(GetProcessHeap(), 0, lpwhs->lpszHostName);
- HeapFree(GetProcessHeap(), 0, lpwhs->lpszServerName);
- HeapFree(GetProcessHeap(), 0, lpwhs->lpszPassword);
- HeapFree(GetProcessHeap(), 0, lpwhs->lpszUserName);
- HeapFree(GetProcessHeap(), 0, lpwhs);
-}
-
/***********************************************************************
* HTTP_GetCustomHeaderIndex (internal)
*/
static BOOL HTTP_VerifyValidHeader(LPWININETHTTPREQW lpwhr, LPCWSTR field)
{
- BOOL rc = TRUE;
-
/* Accept-Encoding is stripped from HTTP/1.0 requests. It is invalid */
- if (strcmpiW(field,szAccept_Encoding)==0)
+ if (!strcmpW(lpwhr->lpszVersion, g_szHttp1_0) && !strcmpiW(field, szAccept_Encoding))
return FALSE;
- return rc;
+ return TRUE;
}
/***********************************************************************
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#endif
+#ifdef HAVE_SYS_POLL_H
+# include <sys/poll.h>
+#endif
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include "winerror.h"
#define NO_SHLWAPI_STREAM
#include "shlwapi.h"
-#include "wincrypt.h"
#include "wine/exception.h"
#include "resource.h"
#include "wine/unicode.h"
-#define CP_UNIXCP CP_THREAD_ACP
WINE_DEFAULT_DEBUG_CHANNEL(wininet);
CHAR response[MAX_REPLY_LEN];
} WITHREADERROR, *LPWITHREADERROR;
-static VOID INTERNET_CloseHandle(LPWININETHANDLEHEADER hdr);
-HINTERNET WINAPI INTERNET_InternetOpenUrlW(LPWININETAPPINFOW hIC, LPCWSTR lpszUrl,
- LPCWSTR lpszHeaders, DWORD dwHeadersLength, DWORD dwFlags, DWORD_PTR dwContext);
-
static DWORD g_dwTlsErrIndex = TLS_OUT_OF_INDEXES;
static HMODULE WININET_hModule;
LPWININETHANDLEHEADER WININET_AddRef( LPWININETHANDLEHEADER info )
{
- info->dwRefCount++;
- TRACE("%p -> refcount = %d\n", info, info->dwRefCount );
+ ULONG refs = InterlockedIncrement(&info->refs);
+ TRACE("%p -> refcount = %d\n", info, refs );
return info;
}
BOOL WININET_Release( LPWININETHANDLEHEADER info )
{
- info->dwRefCount--;
- TRACE( "object %p refcount = %d\n", info, info->dwRefCount );
- if( !info->dwRefCount )
+ ULONG refs = InterlockedDecrement(&info->refs);
+ TRACE( "object %p refcount = %d\n", info, refs );
+ if( !refs )
{
- if ( info->close_connection )
+ if ( info->vtbl->CloseConnection )
{
TRACE( "closing connection %p\n", info);
- info->close_connection( info );
+ info->vtbl->CloseConnection( info );
}
INTERNET_SendCallback(info, info->dwContext,
INTERNET_STATUS_HANDLE_CLOSING, &info->hInternet,
TRACE( "destroying object %p\n", info);
if ( info->htype != WH_HINIT )
list_remove( &info->entry );
- info->destroy( info );
+ info->vtbl->Destroy( info );
}
return TRUE;
}
URLCacheContainers_CreateDefaults();
- WININET_hModule = (HMODULE)hinstDLL;
+ WININET_hModule = hinstDLL;
case DLL_THREAD_ATTACH:
break;
/***********************************************************************
- * INTERNET_ConfigureProxyFromReg
+ * INTERNET_ConfigureProxy
*
* FIXME:
* The proxy may be specified in the form 'http=proxy.my.org'
* Presumably that means there can be ftp=ftpproxy.my.org too.
*/
-static BOOL INTERNET_ConfigureProxyFromReg( LPWININETAPPINFOW lpwai )
+static BOOL INTERNET_ConfigureProxy( LPWININETAPPINFOW lpwai )
{
HKEY key;
- DWORD r, keytype, len, enabled;
- LPCSTR lpszInternetSettings =
- "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings";
+ DWORD type, len, enabled = 0;
+ LPCSTR envproxy;
+ static const WCHAR szInternetSettings[] =
+ { 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
+ 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+ 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s',0 };
static const WCHAR szProxyServer[] = { 'P','r','o','x','y','S','e','r','v','e','r', 0 };
+ static const WCHAR szProxyEnable[] = { 'P','r','o','x','y','E','n','a','b','l','e', 0 };
- r = RegOpenKeyA(HKEY_CURRENT_USER, lpszInternetSettings, &key);
- if ( r != ERROR_SUCCESS )
- return FALSE;
+ if (RegOpenKeyW( HKEY_CURRENT_USER, szInternetSettings, &key )) return FALSE;
len = sizeof enabled;
- r = RegQueryValueExA( key, "ProxyEnable", NULL, &keytype,
- (BYTE*)&enabled, &len);
- if( (r == ERROR_SUCCESS) && enabled )
+ if (RegQueryValueExW( key, szProxyEnable, NULL, &type, (BYTE *)&enabled, &len ) || type != REG_DWORD)
+ RegSetValueExW( key, szProxyEnable, 0, REG_DWORD, (BYTE *)&enabled, sizeof(REG_DWORD) );
+
+ if (enabled)
{
TRACE("Proxy is enabled.\n");
/* figure out how much memory the proxy setting takes */
- r = RegQueryValueExW( key, szProxyServer, NULL, &keytype,
- NULL, &len);
- if( (r == ERROR_SUCCESS) && len && (keytype == REG_SZ) )
+ if (!RegQueryValueExW( key, szProxyServer, NULL, &type, NULL, &len ) && len && (type == REG_SZ))
{
LPWSTR szProxy, p;
static const WCHAR szHttp[] = {'h','t','t','p','=',0};
- szProxy=HeapAlloc( GetProcessHeap(), 0, len );
- RegQueryValueExW( key, szProxyServer, NULL, &keytype,
- (BYTE*)szProxy, &len);
+ if (!(szProxy = HeapAlloc( GetProcessHeap(), 0, len )))
+ {
+ RegCloseKey( key );
+ return FALSE;
+ }
+ RegQueryValueExW( key, szProxyServer, NULL, &type, (BYTE*)szProxy, &len );
/* find the http proxy, and strip away everything else */
p = strstrW( szProxy, szHttp );
- if( p )
+ if (p)
{
- p += lstrlenW(szHttp);
- lstrcpyW( szProxy, p );
+ p += lstrlenW( szHttp );
+ lstrcpyW( szProxy, p );
}
p = strchrW( szProxy, ' ' );
- if( p )
- *p = 0;
+ if (p) *p = 0;
lpwai->dwAccessType = INTERNET_OPEN_TYPE_PROXY;
lpwai->lpszProxy = szProxy;
TRACE("http proxy = %s\n", debugstr_w(lpwai->lpszProxy));
}
else
- ERR("Couldn't read proxy server settings.\n");
+ ERR("Couldn't read proxy server settings from registry.\n");
}
- else
- TRACE("Proxy is not enabled.\n");
- RegCloseKey(key);
+ else if ((envproxy = getenv( "http_proxy" )))
+ {
+ WCHAR *envproxyW;
- return enabled;
+ len = MultiByteToWideChar( CP_UNIXCP, 0, envproxy, -1, NULL, 0 );
+ if (!(envproxyW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR)))) return FALSE;
+ MultiByteToWideChar( CP_UNIXCP, 0, envproxy, -1, envproxyW, len );
+
+ lpwai->dwAccessType = INTERNET_OPEN_TYPE_PROXY;
+ lpwai->lpszProxy = envproxyW;
+
+ TRACE("http proxy (from environment) = %s\n", debugstr_w(lpwai->lpszProxy));
+ enabled = 1;
+ }
+ if (!enabled) TRACE("Proxy is not enabled.\n");
+
+ RegCloseKey( key );
+ return (enabled > 0);
}
/***********************************************************************
TRACE("\n");
}
+/***********************************************************************
+ * INTERNET_CloseHandle (internal)
+ *
+ * Close internet handle
+ *
+ */
+static VOID APPINFO_Destroy(WININETHANDLEHEADER *hdr)
+{
+ LPWININETAPPINFOW lpwai = (LPWININETAPPINFOW) hdr;
+
+ TRACE("%p\n",lpwai);
+
+ HeapFree(GetProcessHeap(), 0, lpwai->lpszAgent);
+ HeapFree(GetProcessHeap(), 0, lpwai->lpszProxy);
+ HeapFree(GetProcessHeap(), 0, lpwai->lpszProxyBypass);
+ HeapFree(GetProcessHeap(), 0, lpwai->lpszProxyUsername);
+ HeapFree(GetProcessHeap(), 0, lpwai->lpszProxyPassword);
+ HeapFree(GetProcessHeap(), 0, lpwai);
+}
+
+static DWORD APPINFO_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode)
+{
+ switch(option) {
+ case INTERNET_OPTION_HANDLE_TYPE:
+ TRACE("INTERNET_OPTION_HANDLE_TYPE\n");
+
+ if (*size < sizeof(ULONG))
+ return ERROR_INSUFFICIENT_BUFFER;
+
+ *size = sizeof(DWORD);
+ *(DWORD*)buffer = INTERNET_HANDLE_TYPE_INTERNET;
+ return ERROR_SUCCESS;
+ }
+
+ FIXME("Not implemented option %d\n", option);
+ return ERROR_INTERNET_INVALID_OPTION;
+}
+
+static const HANDLEHEADERVtbl APPINFOVtbl = {
+ APPINFO_Destroy,
+ NULL,
+ APPINFO_QueryOption,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+
/***********************************************************************
* InternetOpenW (WININET.@)
*
}
lpwai->hdr.htype = WH_HINIT;
+ lpwai->hdr.vtbl = &APPINFOVtbl;
lpwai->hdr.dwFlags = dwFlags;
- lpwai->hdr.dwRefCount = 1;
- lpwai->hdr.close_connection = NULL;
- lpwai->hdr.destroy = INTERNET_CloseHandle;
+ lpwai->hdr.refs = 1;
lpwai->dwAccessType = dwAccessType;
lpwai->lpszProxyUsername = NULL;
lpwai->lpszProxyPassword = NULL;
lstrcpyW( lpwai->lpszAgent, lpszAgent );
}
if(dwAccessType == INTERNET_OPEN_TYPE_PRECONFIG)
- INTERNET_ConfigureProxyFromReg( lpwai );
+ INTERNET_ConfigureProxy( lpwai );
else if (NULL != lpszProxy)
{
lpwai->lpszProxy = HeapAlloc( GetProcessHeap(), 0,
HINTERNET WINAPI InternetOpenA(LPCSTR lpszAgent, DWORD dwAccessType,
LPCSTR lpszProxy, LPCSTR lpszProxyBypass, DWORD dwFlags)
{
- HINTERNET rc = (HINTERNET)NULL;
+ HINTERNET rc = NULL;
INT len;
WCHAR *szAgent = NULL, *szProxy = NULL, *szBypass = NULL;
LPCSTR lpszUserName, LPCSTR lpszPassword,
DWORD dwService, DWORD dwFlags, DWORD_PTR dwContext)
{
- HINTERNET rc = (HINTERNET)NULL;
+ HINTERNET rc = NULL;
INT len = 0;
LPWSTR szServerName = NULL;
LPWSTR szUserName = NULL;
* FALSE on failure
*
*/
-static void AsyncFtpFindNextFileProc(WORKREQUEST *workRequest)
-{
- struct WORKREQ_FTPFINDNEXTW *req = &workRequest->u.FtpFindNextW;
- LPWININETFTPFINDNEXTW lpwh = (LPWININETFTPFINDNEXTW) workRequest->hdr;
-
- TRACE("%p\n", lpwh);
-
- FTP_FindNextFileW(lpwh, req->lpFindFileData);
-}
-
BOOL WINAPI InternetFindNextFileW(HINTERNET hFind, LPVOID lpvFindData)
{
- LPWININETAPPINFOW hIC = NULL;
- LPWININETFTPFINDNEXTW lpwh;
- BOOL bSuccess = FALSE;
+ WININETHANDLEHEADER *hdr;
+ DWORD res;
TRACE("\n");
- lpwh = (LPWININETFTPFINDNEXTW) WININET_GetObject( hFind );
- if (NULL == lpwh || lpwh->hdr.htype != WH_HFTPFINDNEXT)
- {
- FIXME("Only FTP supported\n");
- INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
- goto lend;
+ hdr = WININET_GetObject(hFind);
+ if(!hdr) {
+ WARN("Invalid handle\n");
+ SetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
}
- hIC = lpwh->lpFtpSession->lpAppInfo;
- if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
- {
- WORKREQUEST workRequest;
- struct WORKREQ_FTPFINDNEXTW *req;
-
- workRequest.asyncproc = AsyncFtpFindNextFileProc;
- workRequest.hdr = WININET_AddRef( &lpwh->hdr );
- req = &workRequest.u.FtpFindNextW;
- req->lpFindFileData = lpvFindData;
-
- bSuccess = INTERNET_AsyncCall(&workRequest);
+ if(hdr->vtbl->FindNextFileW) {
+ res = hdr->vtbl->FindNextFileW(hdr, lpvFindData);
+ }else {
+ WARN("Handle doesn't support NextFile\n");
+ res = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
}
- else
- {
- bSuccess = FTP_FindNextFileW(lpwh, lpvFindData);
- }
-lend:
- if( lpwh )
- WININET_Release( &lpwh->hdr );
- return bSuccess;
-}
-/***********************************************************************
- * INTERNET_CloseHandle (internal)
- *
- * Close internet handle
- *
- * RETURNS
- * Void
- *
- */
-static VOID INTERNET_CloseHandle(LPWININETHANDLEHEADER hdr)
-{
- LPWININETAPPINFOW lpwai = (LPWININETAPPINFOW) hdr;
+ WININET_Release(hdr);
- TRACE("%p\n",lpwai);
-
- HeapFree(GetProcessHeap(), 0, lpwai->lpszAgent);
- HeapFree(GetProcessHeap(), 0, lpwai->lpszProxy);
- HeapFree(GetProcessHeap(), 0, lpwai->lpszProxyBypass);
- HeapFree(GetProcessHeap(), 0, lpwai->lpszProxyUsername);
- HeapFree(GetProcessHeap(), 0, lpwai->lpszProxyPassword);
- HeapFree(GetProcessHeap(), 0, lpwai);
+ if(res != ERROR_SUCCESS)
+ SetLastError(res);
+ return res == ERROR_SUCCESS;
}
-
/***********************************************************************
* InternetCloseHandle (WININET.@)
*
* FALSE on failure
*
*/
-BOOL WINAPI InternetWriteFile(HINTERNET hFile, LPCVOID lpBuffer ,
+BOOL WINAPI InternetWriteFile(HINTERNET hFile, LPCVOID lpBuffer,
DWORD dwNumOfBytesToWrite, LPDWORD lpdwNumOfBytesWritten)
{
- BOOL retval = FALSE;
- int nSocket = -1;
LPWININETHANDLEHEADER lpwh;
+ BOOL retval = FALSE;
- TRACE("\n");
- lpwh = (LPWININETHANDLEHEADER) WININET_GetObject( hFile );
- if (NULL == lpwh)
- return FALSE;
-
- switch (lpwh->htype)
- {
- case WH_HHTTPREQ:
- {
- LPWININETHTTPREQW lpwhr;
- lpwhr = (LPWININETHTTPREQW)lpwh;
-
- TRACE("HTTPREQ %i\n",dwNumOfBytesToWrite);
- retval = NETCON_send(&lpwhr->netConnection, lpBuffer,
- dwNumOfBytesToWrite, 0, (LPINT)lpdwNumOfBytesWritten);
-
- WININET_Release( lpwh );
- return retval;
- }
- break;
-
- case WH_HFILE:
- nSocket = ((LPWININETFTPFILE)lpwh)->nDataSocket;
- break;
+ TRACE("(%p %p %d %p)\n", hFile, lpBuffer, dwNumOfBytesToWrite, lpdwNumOfBytesWritten);
- default:
- break;
+ lpwh = WININET_GetObject( hFile );
+ if (!lpwh) {
+ WARN("Invalid handle\n");
+ SetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
}
- if (nSocket != -1)
- {
- int res = send(nSocket, lpBuffer, dwNumOfBytesToWrite, 0);
- retval = (res >= 0);
- *lpdwNumOfBytesWritten = retval ? res : 0;
+ if(lpwh->vtbl->WriteFile) {
+ retval = lpwh->vtbl->WriteFile(lpwh, lpBuffer, dwNumOfBytesToWrite, lpdwNumOfBytesWritten);
+ }else {
+ WARN("No Writefile method.\n");
+ SetLastError(ERROR_INVALID_HANDLE);
+ retval = FALSE;
}
+
WININET_Release( lpwh );
return retval;
}
-BOOL INTERNET_ReadFile(LPWININETHANDLEHEADER lpwh, LPVOID lpBuffer,
- DWORD dwNumOfBytesToRead, LPDWORD pdwNumOfBytesRead,
- BOOL bWait, BOOL bSendCompletionStatus)
-{
- BOOL retval = FALSE;
- int nSocket = -1;
- int bytes_read;
- LPWININETHTTPREQW lpwhr;
-
- /* FIXME: this should use NETCON functions! */
- switch (lpwh->htype)
- {
- case WH_HHTTPREQ:
- lpwhr = (LPWININETHTTPREQW)lpwh;
-
- if (!NETCON_recv(&lpwhr->netConnection, lpBuffer,
- min(dwNumOfBytesToRead, lpwhr->dwContentLength - lpwhr->dwContentRead),
- bWait ? MSG_WAITALL : 0, &bytes_read))
- {
-
- if (((lpwhr->dwContentLength != -1) &&
- (lpwhr->dwContentRead != lpwhr->dwContentLength)))
- ERR("not all data received %d/%d\n", lpwhr->dwContentRead,
- lpwhr->dwContentLength);
-
- /* always returns TRUE, even if the network layer returns an
- * error */
- *pdwNumOfBytesRead = 0;
- HTTP_FinishedReading(lpwhr);
- retval = TRUE;
- }
- else
- {
- lpwhr->dwContentRead += bytes_read;
- *pdwNumOfBytesRead = bytes_read;
- if (!bytes_read && (lpwhr->dwContentRead == lpwhr->dwContentLength))
- retval = HTTP_FinishedReading(lpwhr);
- else
- retval = TRUE;
- }
- break;
-
- case WH_HFILE:
- /* FIXME: FTP should use NETCON_ stuff */
- nSocket = ((LPWININETFTPFILE)lpwh)->nDataSocket;
- if (nSocket != -1)
- {
- int res = recv(nSocket, lpBuffer, dwNumOfBytesToRead, bWait ? MSG_WAITALL : 0);
- retval = (res >= 0);
- *pdwNumOfBytesRead = retval ? res : 0;
- }
- break;
-
- default:
- break;
- }
-
- if (bSendCompletionStatus)
- {
- INTERNET_ASYNC_RESULT iar;
-
- iar.dwResult = retval;
- iar.dwError = iar.dwError = retval ? ERROR_SUCCESS :
- INTERNET_GetLastError();
-
- INTERNET_SendCallback(lpwh, lpwh->dwContext,
- INTERNET_STATUS_REQUEST_COMPLETE, &iar,
- sizeof(INTERNET_ASYNC_RESULT));
- }
- return retval;
-}
-
/***********************************************************************
* InternetReadFile (WININET.@)
*
*
*/
BOOL WINAPI InternetReadFile(HINTERNET hFile, LPVOID lpBuffer,
- DWORD dwNumOfBytesToRead, LPDWORD pdwNumOfBytesRead)
+ DWORD dwNumOfBytesToRead, LPDWORD pdwNumOfBytesRead)
{
- LPWININETHANDLEHEADER lpwh;
- BOOL retval;
+ LPWININETHANDLEHEADER hdr;
+ DWORD res = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
TRACE("%p %p %d %p\n", hFile, lpBuffer, dwNumOfBytesToRead, pdwNumOfBytesRead);
- lpwh = WININET_GetObject( hFile );
- if (!lpwh)
- {
+ hdr = WININET_GetObject(hFile);
+ if (!hdr) {
INTERNET_SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
- retval = INTERNET_ReadFile(lpwh, lpBuffer, dwNumOfBytesToRead, pdwNumOfBytesRead, TRUE, FALSE);
- WININET_Release( lpwh );
+ if(hdr->vtbl->ReadFile)
+ res = hdr->vtbl->ReadFile(hdr, lpBuffer, dwNumOfBytesToRead, pdwNumOfBytesRead);
- TRACE("-- %s (bytes read: %d)\n", retval ? "TRUE": "FALSE", pdwNumOfBytesRead ? *pdwNumOfBytesRead : -1);
- return retval;
+ WININET_Release(hdr);
+
+ TRACE("-- %s (%u) (bytes read: %d)\n", res == ERROR_SUCCESS ? "TRUE": "FALSE", res,
+ pdwNumOfBytesRead ? *pdwNumOfBytesRead : -1);
+
+ if(res != ERROR_SUCCESS)
+ SetLastError(res);
+ return res == ERROR_SUCCESS;
}
/***********************************************************************
* SEE
* InternetOpenUrlA(), HttpOpenRequestA()
*/
-void AsyncInternetReadFileExProc(WORKREQUEST *workRequest)
-{
- struct WORKREQ_INTERNETREADFILEEXA const *req = &workRequest->u.InternetReadFileExA;
-
- TRACE("INTERNETREADFILEEXA %p\n", workRequest->hdr);
-
- INTERNET_ReadFile(workRequest->hdr, req->lpBuffersOut->lpvBuffer,
- req->lpBuffersOut->dwBufferLength,
- &req->lpBuffersOut->dwBufferLength, TRUE, TRUE);
-}
-
BOOL WINAPI InternetReadFileExA(HINTERNET hFile, LPINTERNET_BUFFERSA lpBuffersOut,
DWORD dwFlags, DWORD_PTR dwContext)
{
- BOOL retval = FALSE;
- LPWININETHANDLEHEADER lpwh;
+ LPWININETHANDLEHEADER hdr;
+ DWORD res = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
TRACE("(%p %p 0x%x 0x%lx)\n", hFile, lpBuffersOut, dwFlags, dwContext);
- if (dwFlags & ~(IRF_ASYNC|IRF_NO_WAIT))
- FIXME("these dwFlags aren't implemented: 0x%x\n", dwFlags & ~(IRF_ASYNC|IRF_NO_WAIT));
-
- if (lpBuffersOut->dwStructSize != sizeof(*lpBuffersOut))
- {
- INTERNET_SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- lpwh = (LPWININETHANDLEHEADER) WININET_GetObject( hFile );
- if (!lpwh)
- {
+ hdr = WININET_GetObject(hFile);
+ if (!hdr) {
INTERNET_SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
- INTERNET_SendCallback(lpwh, lpwh->dwContext,
- INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0);
+ if(hdr->vtbl->ReadFileExA)
+ res = hdr->vtbl->ReadFileExA(hdr, lpBuffersOut, dwFlags, dwContext);
- /* FIXME: IRF_ASYNC may not be the right thing to test here;
- * hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC is probably better */
- if (dwFlags & IRF_ASYNC)
- {
- DWORD dwDataAvailable = 0;
-
- if (lpwh->htype == WH_HHTTPREQ)
- NETCON_query_data_available(&((LPWININETHTTPREQW)lpwh)->netConnection,
- &dwDataAvailable);
+ WININET_Release(hdr);
- if (!dwDataAvailable)
- {
- WORKREQUEST workRequest;
- struct WORKREQ_INTERNETREADFILEEXA *req;
+ TRACE("-- %s (%u, bytes read: %d)\n", res == ERROR_SUCCESS ? "TRUE": "FALSE",
+ res, lpBuffersOut->dwBufferLength);
- workRequest.asyncproc = AsyncInternetReadFileExProc;
- workRequest.hdr = WININET_AddRef( lpwh );
- req = &workRequest.u.InternetReadFileExA;
- req->lpBuffersOut = lpBuffersOut;
-
- if (!INTERNET_AsyncCall(&workRequest))
- WININET_Release( lpwh );
- else
- INTERNET_SetLastError(ERROR_IO_PENDING);
- goto end;
- }
- }
-
- retval = INTERNET_ReadFile(lpwh, lpBuffersOut->lpvBuffer,
- lpBuffersOut->dwBufferLength, &lpBuffersOut->dwBufferLength,
- !(dwFlags & IRF_NO_WAIT), FALSE);
-
- if (retval)
- {
- DWORD dwBytesReceived = lpBuffersOut->dwBufferLength;
- INTERNET_SendCallback(lpwh, lpwh->dwContext,
- INTERNET_STATUS_RESPONSE_RECEIVED, &dwBytesReceived,
- sizeof(dwBytesReceived));
- }
-
-end:
- WININET_Release( lpwh );
-
- TRACE("-- %s (bytes read: %d)\n", retval ? "TRUE": "FALSE", lpBuffersOut->dwBufferLength);
- return retval;
+ if(res != ERROR_SUCCESS)
+ SetLastError(res);
+ return res == ERROR_SUCCESS;
}
/***********************************************************************
TRACE("(%p, 0x%08x, %p, %p)\n", hInternet, dwOption, lpBuffer, lpdwBufferLength);
- lpwhh = (LPWININETHANDLEHEADER) WININET_GetObject( hInternet );
+ lpwhh = WININET_GetObject( hInternet );
switch (dwOption)
{
- case INTERNET_OPTION_HANDLE_TYPE:
- {
- ULONG type;
-
- if (!lpwhh)
- {
- WARN("Invalid hInternet handle\n");
- INTERNET_SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
-
- type = lpwhh->htype;
-
- TRACE("INTERNET_OPTION_HANDLE_TYPE: %d\n", type);
-
- if (*lpdwBufferLength < sizeof(ULONG))
- INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER);
- else
- {
- memcpy(lpBuffer, &type, sizeof(ULONG));
- bSuccess = TRUE;
- }
- *lpdwBufferLength = sizeof(ULONG);
- break;
- }
-
case INTERNET_OPTION_REQUEST_FLAGS:
{
ULONG flags = 4;
break;
}
- case INTERNET_OPTION_URL:
- case INTERNET_OPTION_DATAFILE_NAME:
+ case INTERNET_OPTION_USER_AGENT:
{
- if (!lpwhh)
+ DWORD required;
+ LPWININETAPPINFOW ai = (LPWININETAPPINFOW)lpwhh;
+
+ TRACE("INTERNET_OPTION_USER_AGENT\n");
+
+ if (lpwhh->htype != INTERNET_HANDLE_TYPE_INTERNET)
{
- WARN("Invalid hInternet handle\n");
- INTERNET_SetLastError(ERROR_INVALID_HANDLE);
+ INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
return FALSE;
}
- if (lpwhh->htype == WH_HHTTPREQ)
+ if (bIsUnicode)
{
- LPWININETHTTPREQW lpreq = (LPWININETHTTPREQW) lpwhh;
- WCHAR url[1023];
- static const WCHAR szFmt[] = {'h','t','t','p',':','/','/','%','s','%','s',0};
- static const WCHAR szHost[] = {'H','o','s','t',0};
- DWORD sizeRequired;
- LPHTTPHEADERW Host;
-
- Host = HTTP_GetHeader(lpreq,szHost);
- sprintfW(url,szFmt,Host->lpszValue,lpreq->lpszPath);
- TRACE("INTERNET_OPTION_URL: %s\n",debugstr_w(url));
- if(!bIsUnicode)
+ required = (strlenW(ai->lpszAgent) + 1) * sizeof(WCHAR);
+ if (*lpdwBufferLength < required)
+ INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ else if (lpBuffer)
{
- sizeRequired = WideCharToMultiByte(CP_ACP,0,url,-1,
- lpBuffer,*lpdwBufferLength,NULL,NULL);
- if (sizeRequired > *lpdwBufferLength)
- INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER);
- else
- bSuccess = TRUE;
- *lpdwBufferLength = sizeRequired;
+ strcpyW(lpBuffer, ai->lpszAgent);
+ bSuccess = TRUE;
}
- else
+ }
+ else
+ {
+ required = WideCharToMultiByte(CP_ACP, 0, ai->lpszAgent, -1, NULL, 0, NULL, NULL);
+ if (*lpdwBufferLength < required)
+ INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ else if (lpBuffer)
{
- sizeRequired = (lstrlenW(url)+1) * sizeof(WCHAR);
- if (*lpdwBufferLength < sizeRequired)
- INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER);
- else
- {
- strcpyW(lpBuffer, url);
- bSuccess = TRUE;
- }
- *lpdwBufferLength = sizeRequired;
+ WideCharToMultiByte(CP_ACP, 0, ai->lpszAgent, -1, lpBuffer, required, NULL, NULL);
+ bSuccess = TRUE;
}
}
+ *lpdwBufferLength = required;
break;
}
case INTERNET_OPTION_HTTP_VERSION:
{
TRACE("Getting global proxy info\n");
memset(&wai, 0, sizeof(WININETAPPINFOW));
- INTERNET_ConfigureProxyFromReg( &wai );
+ INTERNET_ConfigureProxy( &wai );
lpwai = &wai;
}
bSuccess = TRUE;
break;
- case INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT:
- if (!lpwhh)
- {
- INTERNET_SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
- if (*lpdwBufferLength < sizeof(INTERNET_CERTIFICATE_INFOW))
- {
- *lpdwBufferLength = sizeof(INTERNET_CERTIFICATE_INFOW);
- INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER);
- }
- else if (lpwhh->htype == WH_HHTTPREQ)
- {
- LPWININETHTTPREQW lpwhr;
- PCCERT_CONTEXT context;
-
- lpwhr = (LPWININETHTTPREQW)lpwhh;
- context = (PCCERT_CONTEXT)NETCON_GetCert(&(lpwhr->netConnection));
- if (context)
- {
- LPINTERNET_CERTIFICATE_INFOW info = (LPINTERNET_CERTIFICATE_INFOW)lpBuffer;
- DWORD strLen;
-
- memset(info,0,sizeof(INTERNET_CERTIFICATE_INFOW));
- info->ftExpiry = context->pCertInfo->NotAfter;
- info->ftStart = context->pCertInfo->NotBefore;
- if (bIsUnicode)
- {
- strLen = CertNameToStrW(context->dwCertEncodingType,
- &context->pCertInfo->Subject, CERT_SIMPLE_NAME_STR,
- NULL, 0);
- info->lpszSubjectInfo = LocalAlloc(0,
- strLen * sizeof(WCHAR));
- if (info->lpszSubjectInfo)
- CertNameToStrW(context->dwCertEncodingType,
- &context->pCertInfo->Subject, CERT_SIMPLE_NAME_STR,
- info->lpszSubjectInfo, strLen);
- strLen = CertNameToStrW(context->dwCertEncodingType,
- &context->pCertInfo->Issuer, CERT_SIMPLE_NAME_STR,
- NULL, 0);
- info->lpszIssuerInfo = LocalAlloc(0,
- strLen * sizeof(WCHAR));
- if (info->lpszIssuerInfo)
- CertNameToStrW(context->dwCertEncodingType,
- &context->pCertInfo->Issuer, CERT_SIMPLE_NAME_STR,
- info->lpszIssuerInfo, strLen);
- }
- else
- {
- LPINTERNET_CERTIFICATE_INFOA infoA =
- (LPINTERNET_CERTIFICATE_INFOA)info;
-
- strLen = CertNameToStrA(context->dwCertEncodingType,
- &context->pCertInfo->Subject, CERT_SIMPLE_NAME_STR,
- NULL, 0);
- infoA->lpszSubjectInfo = LocalAlloc(0, strLen);
- if (infoA->lpszSubjectInfo)
- CertNameToStrA(context->dwCertEncodingType,
- &context->pCertInfo->Subject, CERT_SIMPLE_NAME_STR,
- infoA->lpszSubjectInfo, strLen);
- strLen = CertNameToStrA(context->dwCertEncodingType,
- &context->pCertInfo->Issuer, CERT_SIMPLE_NAME_STR,
- NULL, 0);
- infoA->lpszIssuerInfo = LocalAlloc(0, strLen);
- if (infoA->lpszIssuerInfo)
- CertNameToStrA(context->dwCertEncodingType,
- &context->pCertInfo->Issuer, CERT_SIMPLE_NAME_STR,
- infoA->lpszIssuerInfo, strLen);
- }
- /*
- * Contrary to MSDN, these do not appear to be set.
- * lpszProtocolName
- * lpszSignatureAlgName
- * lpszEncryptionAlgName
- * dwKeySize
- */
- CertFreeCertificateContext(context);
- bSuccess = TRUE;
- }
- }
- break;
case INTERNET_OPTION_VERSION:
{
TRACE("INTERNET_OPTION_VERSION\n");
INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER);
else
{
- static const INTERNET_VERSION_INFO info = { 6, 0 };
+ static const INTERNET_VERSION_INFO info = { 1, 2 };
memcpy(lpBuffer, &info, sizeof(info));
*lpdwBufferLength = sizeof(info);
bSuccess = TRUE;
}
break;
}
- default:
- FIXME("Stub! %d\n", dwOption);
+ case INTERNET_OPTION_PER_CONNECTION_OPTION:
+ FIXME("INTERNET_OPTION_PER_CONNECTION_OPTION stub\n");
+ if (*lpdwBufferLength < sizeof(INTERNET_PER_CONN_OPTION_LISTW))
+ INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ else
+ {
+ INTERNET_PER_CONN_OPTION_LISTW *con = lpBuffer;
+ int x;
+ bSuccess = TRUE;
+ for (x = 0; x < con->dwOptionCount; ++x)
+ {
+ INTERNET_PER_CONN_OPTIONW *option = con->pOptions + x;
+ switch (option->dwOption)
+ {
+ case INTERNET_PER_CONN_FLAGS:
+ option->Value.dwValue = PROXY_TYPE_DIRECT;
+ break;
+
+ case INTERNET_PER_CONN_PROXY_SERVER:
+ case INTERNET_PER_CONN_PROXY_BYPASS:
+ case INTERNET_PER_CONN_AUTOCONFIG_URL:
+ case INTERNET_PER_CONN_AUTODISCOVERY_FLAGS:
+ case INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL:
+ case INTERNET_PER_CONN_AUTOCONFIG_RELOAD_DELAY_MINS:
+ case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_TIME:
+ case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_URL:
+ FIXME("Unhandled dwOption %d\n", option->dwOption);
+ option->Value.dwValue = 0;
+ bSuccess = FALSE;
+ break;
+
+ default:
+ FIXME("Unknown dwOption %d\n", option->dwOption);
+ bSuccess = FALSE;
+ break;
+ }
+ }
+ if (!bSuccess)
+ INTERNET_SetLastError(ERROR_INVALID_PARAMETER);
+ }
break;
+ case 66:
+ FIXME("66\n");
+ bSuccess = TRUE;
+ break;
+ default: {
+ if(lpwhh) {
+ DWORD res;
+
+ res = lpwhh->vtbl->QueryOption(lpwhh, dwOption, lpBuffer, lpdwBufferLength, bIsUnicode);
+ if(res == ERROR_SUCCESS)
+ bSuccess = TRUE;
+ else
+ SetLastError(res);
+ }else {
+ FIXME("Stub! %d\n", dwOption);
+ break;
+ }
+ }
}
if (lpwhh)
WININET_Release( lpwhh );
LPWININETHANDLEHEADER lpwhh;
BOOL ret = TRUE;
- TRACE("0x%08x\n", dwOption);
+ TRACE("(%p %d %p %d)\n", hInternet, dwOption, lpBuffer, dwBufferLength);
lpwhh = (LPWININETHANDLEHEADER) WININET_GetObject( hInternet );
- if( !lpwhh )
- return FALSE;
+ if(lpwhh && lpwhh->vtbl->SetOption) {
+ DWORD res;
+
+ res = lpwhh->vtbl->SetOption(lpwhh, dwOption, lpBuffer, dwBufferLength);
+ if(res != ERROR_INTERNET_INVALID_OPTION) {
+ WININET_Release( lpwhh );
+
+ if(res != ERROR_SUCCESS)
+ SetLastError(res);
+
+ return res == ERROR_SUCCESS;
+ }
+ }
switch (dwOption)
{
break;
case INTERNET_OPTION_SEND_TIMEOUT:
case INTERNET_OPTION_RECEIVE_TIMEOUT:
- TRACE("INTERNET_OPTION_SEND/RECEIVE_TIMEOUT\n");
- if (dwBufferLength == sizeof(DWORD))
- {
- if (lpwhh->htype == WH_HHTTPREQ)
- ret = NETCON_set_timeout(
- &((LPWININETHTTPREQW)lpwhh)->netConnection,
- dwOption == INTERNET_OPTION_SEND_TIMEOUT,
- *(DWORD *)lpBuffer);
- else
- {
- FIXME("INTERNET_OPTION_SEND/RECEIVE_TIMEOUT not supported on protocol %d\n",
- lpwhh->htype);
- }
- }
- else
- {
- INTERNET_SetLastError(ERROR_INVALID_PARAMETER);
- ret = FALSE;
- }
+ FIXME("INTERNET_OPTION_SEND/RECEIVE_TIMEOUT\n");
break;
case INTERNET_OPTION_CONNECT_RETRIES:
FIXME("Option INTERNET_OPTION_CONNECT_RETRIES: STUB\n");
case INTERNET_OPTION_SECURITY_FLAGS:
FIXME("Option INTERNET_OPTION_SECURITY_FLAGS; STUB\n");
break;
+ case 86:
+ FIXME("86\n");
+ break;
default:
FIXME("Option %d STUB\n",dwOption);
- INTERNET_SetLastError(ERROR_INVALID_PARAMETER);
+ INTERNET_SetLastError(ERROR_INTERNET_INVALID_OPTION);
ret = FALSE;
break;
}
- WININET_Release( lpwhh );
+
+ if(lpwhh)
+ WININET_Release( lpwhh );
return ret;
}
LPWININETHANDLEHEADER lpwh;
INTERNET_STATUS_CALLBACK callback = *(INTERNET_STATUS_CALLBACK *)lpBuffer;
- if (!(lpwh = (LPWININETHANDLEHEADER)WININET_GetObject(hInternet))) return FALSE;
+ if (!(lpwh = WININET_GetObject(hInternet))) return FALSE;
r = (set_status_callback(lpwh, callback, FALSE) != INTERNET_INVALID_STATUS_CALLBACK);
WININET_Release(lpwh);
return r;
* RETURNS
* handle of connection or NULL on failure
*/
-HINTERNET WINAPI INTERNET_InternetOpenUrlW(LPWININETAPPINFOW hIC, LPCWSTR lpszUrl,
+static HINTERNET INTERNET_InternetOpenUrlW(LPWININETAPPINFOW hIC, LPCWSTR lpszUrl,
LPCWSTR lpszHeaders, DWORD dwHeadersLength, DWORD dwFlags, DWORD_PTR dwContext)
{
URL_COMPONENTSW urlComponents;
HINTERNET WINAPI InternetOpenUrlA(HINTERNET hInternet, LPCSTR lpszUrl,
LPCSTR lpszHeaders, DWORD dwHeadersLength, DWORD dwFlags, DWORD_PTR dwContext)
{
- HINTERNET rc = (HINTERNET)NULL;
+ HINTERNET rc = NULL;
INT lenUrl;
INT lenHeaders = 0;
lenUrl = MultiByteToWideChar(CP_ACP, 0, lpszUrl, -1, NULL, 0 );
szUrl = HeapAlloc(GetProcessHeap(), 0, lenUrl*sizeof(WCHAR));
if(!szUrl)
- return (HINTERNET)NULL;
+ return NULL;
MultiByteToWideChar(CP_ACP, 0, lpszUrl, -1, szUrl, lenUrl);
}
-
+
if(lpszHeaders) {
lenHeaders = MultiByteToWideChar(CP_ACP, 0, lpszHeaders, dwHeadersLength, NULL, 0 );
szHeaders = HeapAlloc(GetProcessHeap(), 0, lenHeaders*sizeof(WCHAR));
if(!szHeaders) {
HeapFree(GetProcessHeap(), 0, szUrl);
- return (HINTERNET)NULL;
+ return NULL;
}
MultiByteToWideChar(CP_ACP, 0, lpszHeaders, dwHeadersLength, szHeaders, lenHeaders);
}
TRACE("\n");
- memcpy(&workRequest, lpRequest, sizeof(WORKREQUEST));
+ workRequest = *lpRequest;
HeapFree(GetProcessHeap(), 0, lpRequest);
workRequest.asyncproc(&workRequest);
if (!lpNewRequest)
return FALSE;
- memcpy(lpNewRequest, lpWorkRequest, sizeof(WORKREQUEST));
+ *lpNewRequest = *lpWorkRequest;
bSuccess = QueueUserWorkItem(INTERNET_WorkerThreadFunc, lpNewRequest, WT_EXECUTELONGFUNCTION);
if (!bSuccess)
* INTERNET_STATUS_REQUEST_COMPLETE will be sent when more
* data is available.
*/
-void AsyncInternetQueryDataAvailableProc(WORKREQUEST *workRequest)
-{
- LPWININETHTTPREQW lpwhr;
- INTERNET_ASYNC_RESULT iar;
- char buffer[4048];
-
- TRACE("INTERNETQUERYDATAAVAILABLE %p\n", workRequest->hdr);
-
- switch (workRequest->hdr->htype)
- {
- case WH_HHTTPREQ:
- lpwhr = (LPWININETHTTPREQW)workRequest->hdr;
- iar.dwResult = NETCON_recv(&lpwhr->netConnection, buffer,
- min(sizeof(buffer),
- lpwhr->dwContentLength - lpwhr->dwContentRead),
- MSG_PEEK, (int *)&iar.dwError);
- INTERNET_SendCallback(workRequest->hdr, workRequest->hdr->dwContext,
- INTERNET_STATUS_REQUEST_COMPLETE, &iar,
- sizeof(INTERNET_ASYNC_RESULT));
- break;
-
- default:
- FIXME("unsupported file type\n");
- break;
- }
-}
-
BOOL WINAPI InternetQueryDataAvailable( HINTERNET hFile,
LPDWORD lpdwNumberOfBytesAvailble,
DWORD dwFlags, DWORD_PTR dwContext)
{
- LPWININETHTTPREQW lpwhr;
- BOOL retval = FALSE;
- char buffer[4048];
+ WININETHANDLEHEADER *hdr;
+ DWORD res;
- lpwhr = (LPWININETHTTPREQW) WININET_GetObject( hFile );
- if (NULL == lpwhr)
- {
- INTERNET_SetLastError(ERROR_NO_MORE_FILES);
+ TRACE("(%p %p %x %lx)\n", hFile, lpdwNumberOfBytesAvailble, dwFlags, dwContext);
+
+ hdr = WININET_GetObject( hFile );
+ if (!hdr) {
+ INTERNET_SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
- TRACE("--> %p %i\n",lpwhr,lpwhr->hdr.htype);
-
- switch (lpwhr->hdr.htype)
- {
- case WH_HHTTPREQ:
- retval = TRUE;
- if (NETCON_query_data_available(&lpwhr->netConnection,
- lpdwNumberOfBytesAvailble) &&
- !*lpdwNumberOfBytesAvailble)
- {
- /* Even if we are in async mode, we need to determine whether
- * there is actually more data available. We do this by trying
- * to peek only a single byte in async mode. */
- BOOL async = (lpwhr->lpHttpSession->lpAppInfo->hdr.dwFlags & INTERNET_FLAG_ASYNC);
- if (NETCON_recv(&lpwhr->netConnection, buffer,
- min(async ? 1 : sizeof(buffer),
- lpwhr->dwContentLength - lpwhr->dwContentRead),
- MSG_PEEK, (int *)lpdwNumberOfBytesAvailble) &&
- async && *lpdwNumberOfBytesAvailble)
- {
- WORKREQUEST workRequest;
-
- *lpdwNumberOfBytesAvailble = 0;
- workRequest.asyncproc = AsyncInternetQueryDataAvailableProc;
- workRequest.hdr = WININET_AddRef( &lpwhr->hdr );
-
- retval = INTERNET_AsyncCall(&workRequest);
- if (!retval)
- {
- WININET_Release( &lpwhr->hdr );
- }
- else
- {
- INTERNET_SetLastError(ERROR_IO_PENDING);
- retval = FALSE;
- }
- }
- }
- break;
-
- default:
- FIXME("unsupported file type\n");
- break;
+ if(hdr->vtbl->QueryDataAvailable) {
+ res = hdr->vtbl->QueryDataAvailable(hdr, lpdwNumberOfBytesAvailble, dwFlags, dwContext);
+ }else {
+ WARN("wrong handle\n");
+ res = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
}
- WININET_Release( &lpwhr->hdr );
- TRACE("<-- %i\n",retval);
- return retval;
+ WININET_Release(hdr);
+
+ if(res != ERROR_SUCCESS)
+ SetLastError(res);
+ return res == ERROR_SUCCESS;
}
#ifndef _WINE_INTERNET_H_
#define _WINE_INTERNET_H_
+/* ReactOS-specific definitions */
+#define CP_UNIXCP CP_THREAD_ACP
+
#ifndef __WINE_CONFIG_H
# error You must include config.h to use this header
#endif
#endif
#if defined(__MINGW32__) || defined (_MSC_VER)
-#include "winsock2.h"
+#include "ws2tcpip.h"
#ifndef MSG_WAITALL
#define MSG_WAITALL 0
#endif
#else
#define closesocket close
+#define ioctlsocket ioctl
#endif /* __MINGW32__ */
/* used for netconnection.c stuff */
#define INET_OPENURL 0x0001
#define INET_CALLBACKW 0x0002
-struct _WININETHANDLEHEADER;
typedef struct _WININETHANDLEHEADER WININETHANDLEHEADER, *LPWININETHANDLEHEADER;
-typedef void (*WININET_object_function)( LPWININETHANDLEHEADER );
+typedef struct {
+ void (*Destroy)(WININETHANDLEHEADER*);
+ void (*CloseConnection)(WININETHANDLEHEADER*);
+ DWORD (*QueryOption)(WININETHANDLEHEADER*,DWORD,void*,DWORD*,BOOL);
+ DWORD (*SetOption)(WININETHANDLEHEADER*,DWORD,void*,DWORD);
+ DWORD (*ReadFile)(WININETHANDLEHEADER*,void*,DWORD,DWORD*);
+ DWORD (*ReadFileExA)(WININETHANDLEHEADER*,INTERNET_BUFFERSA*,DWORD,DWORD_PTR);
+ BOOL (*WriteFile)(WININETHANDLEHEADER*,const void*,DWORD,DWORD*);
+ DWORD (*QueryDataAvailable)(WININETHANDLEHEADER*,DWORD*,DWORD,DWORD_PTR);
+ DWORD (*FindNextFileW)(WININETHANDLEHEADER*,void*);
+} HANDLEHEADERVtbl;
struct _WININETHANDLEHEADER
{
WH_TYPE htype;
+ const HANDLEHEADERVtbl *vtbl;
HINTERNET hInternet;
DWORD dwFlags;
DWORD_PTR dwContext;
DWORD dwError;
DWORD dwInternalFlags;
- DWORD dwRefCount;
- WININET_object_function close_connection;
- WININET_object_function destroy;
+ LONG refs;
INTERNET_STATUS_CALLBACK lpfnStatusCB;
struct list entry;
struct list children;
DWORD dwContentRead; /* bytes of the content read so far */
HTTPHEADERW *pCustHeaders;
DWORD nCustHeaders;
+ HANDLE hCacheFile;
+ LPWSTR lpszCacheFile;
struct HttpAuthInfo *pAuthInfo;
struct HttpAuthInfo *pProxyAuthInfo;
} WININETHTTPREQW, *LPWININETHTTPREQW;
-struct _WININETFTPSESSIONW;
-
-typedef struct
-{
- WININETHANDLEHEADER hdr;
- struct _WININETFTPSESSIONW *lpFtpSession;
- BOOL session_deleted;
- int nDataSocket;
-} WININETFTPFILE, *LPWININETFTPFILE;
-
-
-typedef struct _WININETFTPSESSIONW
-{
- WININETHANDLEHEADER hdr;
- WININETAPPINFOW *lpAppInfo;
- int sndSocket;
- int lstnSocket;
- int pasvSocket; /* data socket connected by us in case of passive FTP */
- LPWININETFTPFILE download_in_progress;
- struct sockaddr_in socketAddress;
- struct sockaddr_in lstnSocketAddress;
- LPWSTR lpszPassword;
- LPWSTR lpszUserName;
-} WININETFTPSESSIONW, *LPWININETFTPSESSIONW;
-
-
-typedef struct
-{
- BOOL bIsDirectory;
- LPWSTR lpszName;
- DWORD nSize;
- struct tm tmLastModified;
- unsigned short permissions;
-} FILEPROPERTIESW, *LPFILEPROPERTIESW;
-
-
-typedef struct
-{
- WININETHANDLEHEADER hdr;
- WININETFTPSESSIONW *lpFtpSession;
- DWORD index;
- DWORD size;
- LPFILEPROPERTIESW lpafp;
-} WININETFTPFINDNEXTW, *LPWININETFTPFINDNEXTW;
struct WORKREQ_FTPPUTFILEW
{
BOOL INTERNET_AsyncCall(LPWORKREQUEST lpWorkRequest);
LPSTR INTERNET_GetResponseBuffer(void);
LPSTR INTERNET_GetNextLine(INT nSocket, LPDWORD dwLen);
-BOOL INTERNET_ReadFile(LPWININETHANDLEHEADER lpwh, LPVOID lpBuffer,
- DWORD dwNumOfBytesToRead, LPDWORD pdwNumOfBytesRead,
- BOOL bWait, BOOL bSendCompletionStatus);
-
-BOOLAPI FTP_FtpPutFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszLocalFile,
- LPCWSTR lpszNewRemoteFile, DWORD dwFlags, DWORD_PTR dwContext);
-BOOLAPI FTP_FtpSetCurrentDirectoryW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszDirectory);
-BOOLAPI FTP_FtpCreateDirectoryW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszDirectory);
-INTERNETAPI HINTERNET WINAPI FTP_FtpFindFirstFileW(LPWININETFTPSESSIONW lpwfs,
- LPCWSTR lpszSearchFile, LPWIN32_FIND_DATAW lpFindFileData, DWORD dwFlags, DWORD_PTR dwContext);
-BOOL WINAPI FTP_FindNextFileW(LPWININETFTPFINDNEXTW lpwh, LPVOID lpvFindData);
-BOOLAPI FTP_FtpGetCurrentDirectoryW(LPWININETFTPSESSIONW lpwfs, LPWSTR lpszCurrentDirectory,
- LPDWORD lpdwCurrentDirectory);
-BOOL FTP_ConvertFileProp(LPFILEPROPERTIESW lpafp, LPWIN32_FIND_DATAW lpFindFileData);
-BOOL FTP_FtpRenameFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszSrc, LPCWSTR lpszDest);
-BOOL FTP_FtpRemoveDirectoryW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszDirectory);
-BOOL FTP_FtpDeleteFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszFileName);
-HINTERNET FTP_FtpOpenFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszFileName,
- DWORD fdwAccess, DWORD dwFlags, DWORD_PTR dwContext);
-BOOLAPI FTP_FtpGetFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszRemoteFile, LPCWSTR lpszNewFile,
- BOOL fFailIfExists, DWORD dwLocalFlagsAttribute, DWORD dwInternetFlags,
- DWORD_PTR dwContext);
BOOLAPI HTTP_HttpSendRequestW(LPWININETHTTPREQW lpwhr, LPCWSTR lpszHeaders,
DWORD dwHeaderLength, LPVOID lpOptional, DWORD dwOptionalLength,
BOOL NETCON_query_data_available(WININET_NETCONNECTION *connection, DWORD *available);
BOOL NETCON_getNextLine(WININET_NETCONNECTION *connection, LPSTR lpszBuffer, LPDWORD dwBuffer);
LPCVOID NETCON_GetCert(WININET_NETCONNECTION *connection);
-BOOL NETCON_set_timeout(WININET_NETCONNECTION *connection, BOOL send, int value);
+DWORD NETCON_set_timeout(WININET_NETCONNECTION *connection, BOOL send, int value);
extern void URLCacheContainers_CreateDefaults(void);
extern void URLCacheContainers_DeleteAll(void);
#include "config.h"
#include "wine/port.h"
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#endif
+#ifdef HAVE_SYS_POLL_H
+# include <sys/poll.h>
+#endif
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include "winerror.h"
#include "wincrypt.h"
+#include "wine/debug.h"
+#include "internet.h"
+
/* To avoid conflicts with the Unix socket headers. we only need it for
* the error codes anyway. */
#define USE_WS_PREFIX
#include "winsock2.h"
-#include "wine/debug.h"
-#include "internet.h"
-
#define RESPONSE_TIMEOUT 30 /* FROM internet.c */
#define sock_get_error(x) WSAGetLastError()
-#undef FIONREAD
-
WINE_DEFAULT_DEBUG_CHANNEL(wininet);
connection->socketFD = -1;
if (useSSL)
{
-#ifdef SONAME_LIBSSL
+#if defined(SONAME_LIBSSL) && defined(SONAME_LIBCRYPTO)
TRACE("using SSL connection\n");
if (OpenSSL_ssl_handle) /* already initialized everything */
return TRUE;
return TRUE;
}
-#ifndef __REACTOS__
+#if 0
/* translate a unix error code into a winsock one */
static int sock_get_error( int err )
{
+#if !defined(__MINGW32__) && !defined (_MSC_VER)
switch (err)
{
case EINTR: return WSAEINTR;
#endif
default: errno=err; perror("sock_set_error"); return WSAEFAULT;
}
+#endif
+ return err;
}
#endif
if (!connection->useSSL)
{
int unread;
- int retval = ioctl(connection->socketFD, FIONREAD, &unread);
+ int retval = ioctlsocket(connection->socketFD, FIONREAD, &unread);
if (!retval)
{
TRACE("%d bytes of queued, but unread data\n", unread);
#endif
}
-BOOL NETCON_set_timeout(WININET_NETCONNECTION *connection, BOOL send, int value)
+DWORD NETCON_set_timeout(WININET_NETCONNECTION *connection, BOOL send, int value)
{
int result;
struct timeval tv;
/* FIXME: we should probably store the timeout in the connection to set
* when we do connect */
if (!NETCON_connected(connection))
- return TRUE;
+ return ERROR_SUCCESS;
/* value is in milliseconds, convert to struct timeval */
tv.tv_sec = value / 1000;
if (result == -1)
{
WARN("setsockopt failed (%s)\n", strerror(errno));
- INTERNET_SetLastError(sock_get_error(errno));
- return FALSE;
+ return sock_get_error(errno);
}
- return TRUE;
+ return ERROR_SUCCESS;
}
*/
#include "wininet_Bg.rc"
#include "wininet_Cs.rc"
+#include "wininet_Da.rc"
#include "wininet_De.rc"
#include "wininet_En.rc"
#include "wininet_Eo.rc"
#include "wininet_Ru.rc"
#include "wininet_Si.rc"
#include "wininet_Sv.rc"
-#include "wininet_Tr.rc"
#include "wininet_Uk.rc"
+#include "wininet_Tr.rc"
DWORD CacheEntryType; /* see INTERNET_CACHE_ENTRY_INFO::CacheEntryType */
DWORD dwOffsetHeaderInfo; /* offset of start of header info from start of entry */
DWORD dwHeaderInfoSize;
- DWORD dwUnknown6; /* usually zero */
+ DWORD dwOffsetFileExtension; /* offset of start of file extension from start of entry */
WORD wLastSyncDate; /* last sync date in dos format */
WORD wLastSyncTime; /* last sync time in dos format */
DWORD dwHitRate; /* see INTERNET_CACHE_ENTRY_INFO::dwHitRate */
if (CreateDirectoryW(wszDirPath, 0))
{
- int k;
-
/* The following is OK because we generated an
* 8 character directory name made from characters
* [A-Z0-9], which are equivalent for all code
WCHAR wszMutexName[MAX_PATH];
int path_len, suffix_len;
- if (FAILED(SHGetSpecialFolderPathW(NULL, wszCachePath, DefaultContainerData[i].nFolder, TRUE)))
+ if (!SHGetSpecialFolderPathW(NULL, wszCachePath, DefaultContainerData[i].nFolder, TRUE))
{
ERR("Couldn't get path for default container %u\n", i);
continue;
static BOOL URLCacheContainers_FindContainerW(LPCWSTR lpwszUrl, URLCACHECONTAINER ** ppContainer)
{
- struct list * cursor;
+ URLCACHECONTAINER * pContainer;
TRACE("searching for prefix for URL: %s\n", debugstr_w(lpwszUrl));
- LIST_FOR_EACH(cursor, &UrlContainers)
+ LIST_FOR_EACH_ENTRY(pContainer, &UrlContainers, URLCACHECONTAINER, entry)
{
- URLCACHECONTAINER * pContainer = LIST_ENTRY(cursor, URLCACHECONTAINER, entry);
int prefix_len = strlenW(pContainer->cache_prefix);
if (!strncmpW(pContainer->cache_prefix, lpwszUrl, prefix_len))
{
return FALSE;
}
+static BOOL URLCacheContainers_Enum(LPCWSTR lpwszSearchPattern, DWORD dwIndex, URLCACHECONTAINER ** ppContainer)
+{
+ DWORD i = 0;
+ URLCACHECONTAINER * pContainer;
+
+ TRACE("searching for prefix: %s\n", debugstr_w(lpwszSearchPattern));
+
+ /* non-NULL search pattern only returns one container ever */
+ if (lpwszSearchPattern && dwIndex > 0)
+ return FALSE;
+
+ LIST_FOR_EACH_ENTRY(pContainer, &UrlContainers, URLCACHECONTAINER, entry)
+ {
+ if (lpwszSearchPattern)
+ {
+ if (!strcmpW(pContainer->cache_prefix, lpwszSearchPattern))
+ {
+ TRACE("found container with prefix %s\n", debugstr_w(pContainer->cache_prefix));
+ *ppContainer = pContainer;
+ return TRUE;
+ }
+ }
+ else
+ {
+ if (i == dwIndex)
+ {
+ TRACE("found container with prefix %s\n", debugstr_w(pContainer->cache_prefix));
+ *ppContainer = pContainer;
+ return TRUE;
+ }
+ }
+ i++;
+ }
+ return FALSE;
+}
+
/***********************************************************************
* URLCacheContainer_LockIndex (Internal)
*
return FALSE;
}
- path_len = WideCharToMultiByte(CP_ACP, 0, pContainer->path, -1, NULL, 0, NULL, NULL);
- file_name_len = strlen(szLocalFileName);
+ path_len = WideCharToMultiByte(CP_ACP, 0, pContainer->path, -1, NULL, 0, NULL, NULL) - 1;
+ file_name_len = strlen(szLocalFileName) + 1 /* for nul-terminator */;
dir_len = DIR_LENGTH;
- nRequired = (path_len + dir_len + 1 + file_name_len) * sizeof(WCHAR);
+ nRequired = (path_len + dir_len + 1 + file_name_len) * sizeof(char);
if (nRequired < *lpBufferSize)
{
- WideCharToMultiByte(CP_ACP, 0, pContainer->path, -1, szPath, -1, NULL, NULL);
+ WideCharToMultiByte(CP_ACP, 0, pContainer->path, -1, szPath, path_len, NULL, NULL);
memcpy(szPath+path_len, pHeader->directory_data[Directory].filename, dir_len);
szPath[path_len + dir_len] = '\\';
memcpy(szPath + path_len + dir_len + 1, szLocalFileName, file_name_len);
LPCURLCACHE_HEADER pHeader,
LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntryInfo,
LPDWORD lpdwBufferSize,
- URL_CACHEFILE_ENTRY * pUrlEntry,
+ const URL_CACHEFILE_ENTRY * pUrlEntry,
BOOL bUnicode)
{
int lenUrl;
ZeroMemory((LPBYTE)lpCacheEntryInfo + dwRequiredSize, 4 - (dwRequiredSize % 4));
dwRequiredSize = DWORD_ALIGN(dwRequiredSize);
+ if (pUrlEntry->dwOffsetFileExtension)
+ {
+ int lenExtension;
+
+ if (bUnicode)
+ lenExtension = MultiByteToWideChar(CP_ACP, 0, (LPSTR)pUrlEntry + pUrlEntry->dwOffsetFileExtension, -1, NULL, 0);
+ else
+ lenExtension = strlen((LPSTR)pUrlEntry + pUrlEntry->dwOffsetFileExtension) + 1;
+ dwRequiredSize += lenExtension * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
+
+ if (*lpdwBufferSize >= dwRequiredSize)
+ {
+ lpCacheEntryInfo->lpszFileExtension = (LPSTR)lpCacheEntryInfo + dwRequiredSize - lenExtension;
+ if (bUnicode)
+ MultiByteToWideChar(CP_ACP, 0, (LPSTR)pUrlEntry + pUrlEntry->dwOffsetFileExtension, -1, (LPWSTR)lpCacheEntryInfo->lpszSourceUrlName, lenExtension);
+ else
+ memcpy(lpCacheEntryInfo->lpszFileExtension, (LPSTR)pUrlEntry + pUrlEntry->dwOffsetFileExtension, lenExtension * sizeof(CHAR));
+ }
+
+ if ((dwRequiredSize % 4) && (dwRequiredSize < *lpdwBufferSize))
+ ZeroMemory((LPBYTE)lpCacheEntryInfo + dwRequiredSize, 4 - (dwRequiredSize % 4));
+ dwRequiredSize = DWORD_ALIGN(dwRequiredSize);
+ }
+
if (dwRequiredSize > *lpdwBufferSize)
{
*lpdwBufferSize = dwRequiredSize;
};
BYTE key[4];
DWORD i;
- int subscript[sizeof(key) / sizeof(key[0])];
-
- subscript[0] = *lpszKey;
- subscript[1] = (char)(*lpszKey + 1);
- subscript[2] = (char)(*lpszKey + 2);
- subscript[3] = (char)(*lpszKey + 3);
for (i = 0; i < sizeof(key) / sizeof(key[0]); i++)
key[i] = lookupTable[i];
return (HASH_CACHEFILE_ENTRY *)((LPBYTE)pHeader + dwOffset);
}
+static inline BOOL URLCache_IsHashEntryValid(LPCURLCACHE_HEADER pHeader, const HASH_CACHEFILE_ENTRY *pHashEntry)
+{
+ /* check pHashEntry located within acceptable bounds in the URL cache mapping */
+ return ((DWORD)((LPBYTE)pHashEntry - (LPBYTE)pHeader) >= ENTRY_START_OFFSET) &&
+ ((DWORD)((LPBYTE)pHashEntry - (LPBYTE)pHeader) < pHeader->dwFileSize);
+}
+
static BOOL URLCache_FindHash(LPCURLCACHE_HEADER pHeader, LPCSTR lpszUrl, struct _HASH_ENTRY ** ppHashEntry)
{
/* structure of hash table:
HASH_CACHEFILE_ENTRY * pHashEntry;
DWORD dwHashTableNumber = 0;
- key = (DWORD)(key / HASHTABLE_NUM_ENTRIES) * HASHTABLE_NUM_ENTRIES;
+ key = (key / HASHTABLE_NUM_ENTRIES) * HASHTABLE_NUM_ENTRIES;
for (pHashEntry = URLCache_HashEntryFromOffset(pHeader, pHeader->dwOffsetFirstHashTable);
- ((DWORD)((LPBYTE)pHashEntry - (LPBYTE)pHeader) >= ENTRY_START_OFFSET) && ((DWORD)((LPBYTE)pHashEntry - (LPBYTE)pHeader) < pHeader->dwFileSize);
+ URLCache_IsHashEntryValid(pHeader, pHashEntry);
pHashEntry = URLCache_HashEntryFromOffset(pHeader, pHashEntry->dwAddressNext))
{
int i;
for (i = 0; i < HASHTABLE_BLOCKSIZE; i++)
{
struct _HASH_ENTRY * pHashElement = &pHashEntry->HashTable[offset + i];
- if (key == (DWORD)(pHashElement->dwHashKey / HASHTABLE_NUM_ENTRIES) * HASHTABLE_NUM_ENTRIES)
+ if (key == (pHashElement->dwHashKey / HASHTABLE_NUM_ENTRIES) * HASHTABLE_NUM_ENTRIES)
{
/* FIXME: we should make sure that this is the right element
* before returning and claiming that it is. We can do this
*/
static BOOL URLCache_HashEntrySetUse(struct _HASH_ENTRY * pHashEntry, DWORD dwUseCount)
{
- pHashEntry->dwHashKey = dwUseCount | (DWORD)(pHashEntry->dwHashKey / HASHTABLE_NUM_ENTRIES) * HASHTABLE_NUM_ENTRIES;
+ pHashEntry->dwHashKey = dwUseCount | (pHashEntry->dwHashKey / HASHTABLE_NUM_ENTRIES) * HASHTABLE_NUM_ENTRIES;
return TRUE;
}
HASH_CACHEFILE_ENTRY * pHashEntry;
DWORD dwHashTableNumber = 0;
- key = (DWORD)(key / HASHTABLE_NUM_ENTRIES) * HASHTABLE_NUM_ENTRIES;
+ key = (key / HASHTABLE_NUM_ENTRIES) * HASHTABLE_NUM_ENTRIES;
for (pHashEntry = URLCache_HashEntryFromOffset(pHeader, pHeader->dwOffsetFirstHashTable);
- ((DWORD)((LPBYTE)pHashEntry - (LPBYTE)pHeader) >= ENTRY_START_OFFSET) && ((DWORD)((LPBYTE)pHashEntry - (LPBYTE)pHeader) < pHeader->dwFileSize);
+ URLCache_IsHashEntryValid(pHeader, pHashEntry);
pHashEntry = URLCache_HashEntryFromOffset(pHeader, pHashEntry->dwAddressNext))
{
int i;
return TRUE;
}
+/***********************************************************************
+ * URLCache_CreateHashTable (Internal)
+ *
+ * Creates a new hash table in free space and adds it to the chain of existing
+ * hash tables.
+ *
+ * RETURNS
+ * TRUE if the hash table was created
+ * FALSE if the hash table could not be created
+ *
+ */
static HASH_CACHEFILE_ENTRY *URLCache_CreateHashTable(LPURLCACHE_HEADER pHeader, HASH_CACHEFILE_ENTRY *pPrevHash)
{
HASH_CACHEFILE_ENTRY *pHash;
return pHash;
}
+/***********************************************************************
+ * URLCache_EnumHashTables (Internal)
+ *
+ * Enumerates the hash tables in a container.
+ *
+ * RETURNS
+ * TRUE if an entry was found
+ * FALSE if there are no more tables to enumerate.
+ *
+ */
+static BOOL URLCache_EnumHashTables(LPCURLCACHE_HEADER pHeader, DWORD *pdwHashTableNumber, HASH_CACHEFILE_ENTRY ** ppHashEntry)
+{
+ for (*ppHashEntry = URLCache_HashEntryFromOffset(pHeader, pHeader->dwOffsetFirstHashTable);
+ URLCache_IsHashEntryValid(pHeader, *ppHashEntry);
+ *ppHashEntry = URLCache_HashEntryFromOffset(pHeader, (*ppHashEntry)->dwAddressNext))
+ {
+ TRACE("looking at hash table number %d\n", (*ppHashEntry)->dwHashTableNumber);
+ if ((*ppHashEntry)->dwHashTableNumber != *pdwHashTableNumber)
+ continue;
+ /* make sure that it is in fact a hash entry */
+ if ((*ppHashEntry)->CacheFileEntry.dwSignature != HASH_SIGNATURE)
+ {
+ ERR("Error: not right signature (\"%.4s\") - expected \"HASH\"\n", (LPCSTR)&(*ppHashEntry)->CacheFileEntry.dwSignature);
+ (*pdwHashTableNumber)++;
+ continue;
+ }
+
+ TRACE("hash table number %d found\n", *pdwHashTableNumber);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/***********************************************************************
+ * URLCache_EnumHashTableEntries (Internal)
+ *
+ * Enumerates entries in a hash table and returns the next non-free entry.
+ *
+ * RETURNS
+ * TRUE if an entry was found
+ * FALSE if the hash table is empty or there are no more entries to
+ * enumerate.
+ *
+ */
+static BOOL URLCache_EnumHashTableEntries(LPCURLCACHE_HEADER pHeader, const HASH_CACHEFILE_ENTRY * pHashEntry,
+ DWORD * index, const struct _HASH_ENTRY ** ppHashEntry)
+{
+ for (; *index < HASHTABLE_SIZE ; (*index)++)
+ {
+ if (pHashEntry->HashTable[*index].dwHashKey == HASHTABLE_FREE)
+ continue;
+
+ *ppHashEntry = &pHashEntry->HashTable[*index];
+ TRACE("entry found %d\n", *index);
+ return TRUE;
+ }
+ TRACE("no more entries (%d)\n", *index);
+ return FALSE;
+}
+
/***********************************************************************
* GetUrlCacheEntryInfoExA (WININET.@)
*
{
LPURLCACHE_HEADER pHeader;
struct _HASH_ENTRY * pHashEntry;
- CACHEFILE_ENTRY * pEntry;
- URL_CACHEFILE_ENTRY * pUrlEntry;
+ const CACHEFILE_ENTRY * pEntry;
+ const URL_CACHEFILE_ENTRY * pUrlEntry;
URLCACHECONTAINER * pContainer;
TRACE("(%s, %p, %p)\n", debugstr_a(lpszUrlName), lpCacheEntryInfo, lpdwCacheEntryInfoBufferSize);
return FALSE;
}
- pEntry = (CACHEFILE_ENTRY *)((LPBYTE)pHeader + pHashEntry->dwOffsetEntry);
+ pEntry = (const CACHEFILE_ENTRY *)((LPBYTE)pHeader + pHashEntry->dwOffsetEntry);
if (pEntry->dwSignature != URL_SIGNATURE)
{
URLCacheContainer_UnlockIndex(pContainer, pHeader);
return FALSE;
}
- pUrlEntry = (URL_CACHEFILE_ENTRY *)pEntry;
+ pUrlEntry = (const URL_CACHEFILE_ENTRY *)pEntry;
TRACE("Found URL: %s\n", debugstr_a((LPSTR)pUrlEntry + pUrlEntry->dwOffsetUrl));
if (pUrlEntry->dwOffsetHeaderInfo)
TRACE("Header info: %s\n", debugstr_a((LPSTR)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo));
- if (!URLCache_CopyEntry(
- pContainer,
- pHeader,
- lpCacheEntryInfo,
- lpdwCacheEntryInfoBufferSize,
- pUrlEntry,
- FALSE /* ANSI */))
+ if (lpdwCacheEntryInfoBufferSize)
{
- URLCacheContainer_UnlockIndex(pContainer, pHeader);
- return FALSE;
+ if (!URLCache_CopyEntry(
+ pContainer,
+ pHeader,
+ lpCacheEntryInfo,
+ lpdwCacheEntryInfoBufferSize,
+ pUrlEntry,
+ FALSE /* ANSI */))
+ {
+ URLCacheContainer_UnlockIndex(pContainer, pHeader);
+ return FALSE;
+ }
+ TRACE("Local File Name: %s\n", debugstr_a(lpCacheEntryInfo->lpszLocalFileName));
}
- TRACE("Local File Name: %s\n", debugstr_a(lpCacheEntryInfo->lpszLocalFileName));
URLCacheContainer_UnlockIndex(pContainer, pHeader);
{
LPURLCACHE_HEADER pHeader;
struct _HASH_ENTRY * pHashEntry;
- CACHEFILE_ENTRY * pEntry;
- URL_CACHEFILE_ENTRY * pUrlEntry;
+ const CACHEFILE_ENTRY * pEntry;
+ const URL_CACHEFILE_ENTRY * pUrlEntry;
URLCACHECONTAINER * pContainer;
TRACE("(%s, %p, %p)\n", debugstr_w(lpszUrl), lpCacheEntryInfo, lpdwCacheEntryInfoBufferSize);
return FALSE;
}
- pEntry = (CACHEFILE_ENTRY *)((LPBYTE)pHeader + pHashEntry->dwOffsetEntry);
+ pEntry = (const CACHEFILE_ENTRY *)((LPBYTE)pHeader + pHashEntry->dwOffsetEntry);
if (pEntry->dwSignature != URL_SIGNATURE)
{
URLCacheContainer_UnlockIndex(pContainer, pHeader);
return FALSE;
}
- pUrlEntry = (URL_CACHEFILE_ENTRY *)pEntry;
+ pUrlEntry = (const URL_CACHEFILE_ENTRY *)pEntry;
TRACE("Found URL: %s\n", debugstr_a((LPSTR)pUrlEntry + pUrlEntry->dwOffsetUrl));
TRACE("Header info: %s\n", debugstr_a((LPSTR)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo));
- if (!URLCache_CopyEntry(
- pContainer,
- pHeader,
- (LPINTERNET_CACHE_ENTRY_INFOA)lpCacheEntryInfo,
- lpdwCacheEntryInfoBufferSize,
- pUrlEntry,
- TRUE /* UNICODE */))
+ if (lpdwCacheEntryInfoBufferSize)
{
- URLCacheContainer_UnlockIndex(pContainer, pHeader);
- return FALSE;
+ if (!URLCache_CopyEntry(
+ pContainer,
+ pHeader,
+ (LPINTERNET_CACHE_ENTRY_INFOA)lpCacheEntryInfo,
+ lpdwCacheEntryInfoBufferSize,
+ pUrlEntry,
+ TRUE /* UNICODE */))
+ {
+ URLCacheContainer_UnlockIndex(pContainer, pHeader);
+ return FALSE;
+ }
+ TRACE("Local File Name: %s\n", debugstr_w(lpCacheEntryInfo->lpszLocalFileName));
}
- TRACE("Local File Name: %s\n", debugstr_w(lpCacheEntryInfo->lpszLocalFileName));
URLCacheContainer_UnlockIndex(pContainer, pHeader);
return FALSE;
}
- for (lpszUrlEnd = lpszUrlName; *lpszUrlEnd; lpszUrlEnd++)
- ;
+ lpszUrlEnd = lpszUrlName + strlenW(lpszUrlName);
if (((lpszUrlEnd - lpszUrlName) > 1) && (*(lpszUrlEnd - 1) == '/' || *(lpszUrlEnd - 1) == '\\'))
lpszUrlEnd--;
lpszUrlPart++;
break;
}
+ else if(*lpszUrlPart == '?' || *lpszUrlPart == '#')
+ {
+ lpszUrlEnd = lpszUrlPart;
+ }
}
if (!lstrcmpW(lpszUrlPart, szWWW))
{
DWORD dwBytesNeeded = DWORD_ALIGN(sizeof(*pUrlEntry));
DWORD dwOffsetLocalFileName = 0;
DWORD dwOffsetHeader = 0;
+ DWORD dwOffsetFileExtension = 0;
DWORD dwFileSizeLow = 0;
DWORD dwFileSizeHigh = 0;
BYTE cDirectory = 0;
+ int len;
char achFile[MAX_PATH];
- char achUrl[MAX_PATH];
+ LPSTR lpszUrlNameA = NULL;
+ LPSTR lpszFileExtensionA = NULL;
char *pchLocalFileName = 0;
+ DWORD error = ERROR_SUCCESS;
TRACE("(%s, %s, ..., ..., %x, %p, %d, %s, %s)\n",
debugstr_w(lpszUrlName),
if (!(pHeader = URLCacheContainer_LockIndex(pContainer)))
return FALSE;
- WideCharToMultiByte(CP_ACP, 0, lpszUrlName, -1, achUrl, -1, NULL, NULL);
+ len = WideCharToMultiByte(CP_ACP, 0, lpszUrlName, -1, NULL, 0, NULL, NULL);
+ lpszUrlNameA = HeapAlloc(GetProcessHeap(), 0, len * sizeof(char));
+ if (!lpszUrlNameA)
+ {
+ error = GetLastError();
+ goto cleanup;
+ }
+ WideCharToMultiByte(CP_ACP, 0, lpszUrlName, -1, lpszUrlNameA, len, NULL, NULL);
- if (URLCache_FindHash(pHeader, achUrl, &pHashEntry))
+ if (lpszFileExtension)
+ {
+ len = WideCharToMultiByte(CP_ACP, 0, lpszFileExtension, -1, NULL, 0, NULL, NULL);
+ lpszFileExtensionA = HeapAlloc(GetProcessHeap(), 0, len * sizeof(char));
+ if (!lpszFileExtensionA)
+ {
+ error = GetLastError();
+ goto cleanup;
+ }
+ WideCharToMultiByte(CP_ACP, 0, lpszFileExtension, -1, lpszFileExtensionA, len, NULL, NULL);
+ }
+
+ if (URLCache_FindHash(pHeader, lpszUrlNameA, &pHashEntry))
{
- URLCacheContainer_UnlockIndex(pContainer, pHeader);
FIXME("entry already in cache - don't know what to do!\n");
/*
* SetLastError(ERROR_FILE_NOT_FOUND);
* return FALSE;
*/
- return TRUE;
+ goto cleanup;
}
if (lpszLocalFileName)
if (strncmpW(lpszLocalFileName, pContainer->path, lstrlenW(pContainer->path)))
{
- URLCacheContainer_UnlockIndex(pContainer, pHeader);
ERR("path %s must begin with cache content path %s\n", debugstr_w(lpszLocalFileName), debugstr_w(pContainer->path));
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
+ error = ERROR_INVALID_PARAMETER;
+ goto cleanup;
}
/* skip container path prefix */
if (!bFound)
{
- URLCacheContainer_UnlockIndex(pContainer, pHeader);
ERR("cache directory not found in path %s\n", debugstr_w(lpszLocalFileName));
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
+ error = ERROR_INVALID_PARAMETER;
+ goto cleanup;
}
lpszLocalFileName += (DIR_LENGTH + 1); /* "1234WXYZ\" */
}
- dwBytesNeeded = DWORD_ALIGN(dwBytesNeeded + strlen(achUrl) + 1);
+ dwBytesNeeded = DWORD_ALIGN(dwBytesNeeded + strlen(lpszUrlNameA) + 1);
if (lpszLocalFileName)
{
+ len = WideCharToMultiByte(CP_ACP, 0, lpszUrlName, -1, NULL, 0, NULL, NULL);
dwOffsetLocalFileName = dwBytesNeeded;
dwBytesNeeded = DWORD_ALIGN(dwBytesNeeded + strlen(pchLocalFileName) + 1);
}
dwOffsetHeader = dwBytesNeeded;
dwBytesNeeded = DWORD_ALIGN(dwBytesNeeded + dwHeaderSize);
}
+ if (lpszFileExtensionA)
+ {
+ dwOffsetFileExtension = dwBytesNeeded;
+ dwBytesNeeded = DWORD_ALIGN(dwBytesNeeded + strlen(lpszFileExtensionA) + 1);
+ }
/* round up to next block */
if (dwBytesNeeded % BLOCKSIZE)
if (!URLCache_FindFirstFreeEntry(pHeader, dwBytesNeeded / BLOCKSIZE, &pEntry))
{
- URLCacheContainer_UnlockIndex(pContainer, pHeader);
ERR("no free entries\n");
- SetLastError(ERROR_DISK_FULL);
- return FALSE;
+ error = ERROR_DISK_FULL;
+ goto cleanup;
}
/* FindFirstFreeEntry fills in blocks used */
pUrlEntry->dwHeaderInfoSize = dwHeaderSize;
pUrlEntry->dwExemptDelta = 0;
pUrlEntry->dwHitRate = 0;
+ pUrlEntry->dwOffsetFileExtension = dwOffsetFileExtension;
pUrlEntry->dwOffsetHeaderInfo = dwOffsetHeader;
pUrlEntry->dwOffsetLocalName = dwOffsetLocalFileName;
pUrlEntry->dwOffsetUrl = DWORD_ALIGN(sizeof(*pUrlEntry));
pUrlEntry->dwUnknown3 = 0x60;
pUrlEntry->Unknown4 = 0;
pUrlEntry->wUnknown5 = 0x1010;
- pUrlEntry->dwUnknown6 = 0;
pUrlEntry->dwUnknown7 = 0;
pUrlEntry->dwUnknown8 = 0;
- strcpy((LPSTR)pUrlEntry + pUrlEntry->dwOffsetUrl, achUrl);
+ strcpy((LPSTR)pUrlEntry + pUrlEntry->dwOffsetUrl, lpszUrlNameA);
if (dwOffsetLocalFileName)
strcpy((LPSTR)((LPBYTE)pUrlEntry + dwOffsetLocalFileName), pchLocalFileName + DIR_LENGTH + 1);
if (dwOffsetHeader)
- memcpy((LPBYTE)pUrlEntry + dwOffsetHeader, lpHeaderInfo, dwHeaderSize);
+ memcpy((LPBYTE)pUrlEntry + dwOffsetHeader, lpHeaderInfo, dwHeaderSize);
+ if (dwOffsetFileExtension)
+ strcpy((LPSTR)((LPBYTE)pUrlEntry + dwOffsetFileExtension), lpszFileExtensionA);
- if (!URLCache_AddEntryToHash(pHeader, achUrl, (DWORD)((LPBYTE)pUrlEntry - (LPBYTE)pHeader)))
+ if (!URLCache_AddEntryToHash(pHeader, lpszUrlNameA, (DWORD)((LPBYTE)pUrlEntry - (LPBYTE)pHeader)))
{
URLCache_DeleteEntry(pHeader, &pUrlEntry->CacheFileEntry);
URLCacheContainer_UnlockIndex(pContainer, pHeader);
+ HeapFree(GetProcessHeap(), 0, lpszUrlNameA);
return FALSE;
}
+cleanup:
URLCacheContainer_UnlockIndex(pContainer, pHeader);
+ HeapFree(GetProcessHeap(), 0, lpszUrlNameA);
+ HeapFree(GetProcessHeap(), 0, lpszFileExtensionA);
- return TRUE;
+ if (error == ERROR_SUCCESS)
+ return TRUE;
+ else
+ {
+ SetLastError(error);
+ return FALSE;
+ }
}
/***********************************************************************
)
{
DWORD len;
- WCHAR *url_name;
- WCHAR *local_file_name;
+ WCHAR *url_name = NULL;
+ WCHAR *local_file_name = NULL;
WCHAR *original_url = NULL;
+ WCHAR *file_extension = NULL;
BOOL bSuccess = FALSE;
- DWORD dwError = 0;
TRACE("(%s, %s, ..., ..., %x, %p, %d, %s, %s)\n",
debugstr_a(lpszUrlName),
debugstr_a(lpszFileExtension),
debugstr_a(lpszOriginalUrl));
- if (lpszFileExtension != 0)
+ len = MultiByteToWideChar(CP_ACP, 0, lpszUrlName, -1, NULL, 0);
+ url_name = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (!url_name)
+ goto cleanup;
+ MultiByteToWideChar(CP_ACP, 0, lpszUrlName, -1, url_name, len);
+
+ if (lpszLocalFileName)
{
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
+ len = MultiByteToWideChar(CP_ACP, 0, lpszLocalFileName, -1, NULL, 0);
+ local_file_name = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (!local_file_name)
+ goto cleanup;
+ MultiByteToWideChar(CP_ACP, 0, lpszLocalFileName, -1, local_file_name, len);
}
- if ((len = MultiByteToWideChar(CP_ACP, 0, lpszUrlName, -1, NULL, 0)) != 0 &&
- (url_name = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR))) != 0)
+ if (lpszFileExtension)
{
- MultiByteToWideChar(CP_ACP, 0, lpszUrlName, -1, url_name, len);
- if ((len = MultiByteToWideChar(CP_ACP, 0, lpszLocalFileName, -1, NULL, 0)) != 0 &&
- (local_file_name = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR))) != 0)
- {
- MultiByteToWideChar(CP_ACP, 0, lpszLocalFileName, -1, local_file_name, len);
- if (!lpszOriginalUrl ||
- ((len = MultiByteToWideChar(CP_ACP, 0, lpszOriginalUrl, -1, NULL, 0)) != 0 &&
- (original_url = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR))) != 0))
- {
- if (original_url)
- MultiByteToWideChar(CP_ACP, 0, lpszOriginalUrl, -1, original_url, len);
- if (CommitUrlCacheEntryInternal(url_name, local_file_name, ExpireTime, LastModifiedTime,
- CacheEntryType, lpHeaderInfo, dwHeaderSize,
- NULL, original_url))
- {
- bSuccess = TRUE;
- }
- else
- {
- dwError = GetLastError();
- }
- HeapFree(GetProcessHeap(), 0, original_url);
- }
- else
- {
- dwError = GetLastError();
- }
- HeapFree(GetProcessHeap(), 0, local_file_name);
- }
- else
- {
- dwError = GetLastError();
- }
- HeapFree(GetProcessHeap(), 0, url_name);
- if (!bSuccess)
- SetLastError(dwError);
+ len = MultiByteToWideChar(CP_ACP, 0, lpszFileExtension, -1, NULL, 0);
+ file_extension = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (!file_extension)
+ goto cleanup;
+ MultiByteToWideChar(CP_ACP, 0, lpszFileExtension, -1, file_extension, len);
}
+ if (lpszOriginalUrl)
+ {
+ len = MultiByteToWideChar(CP_ACP, 0, lpszOriginalUrl, -1, NULL, 0);
+ original_url = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (!original_url)
+ goto cleanup;
+ MultiByteToWideChar(CP_ACP, 0, lpszOriginalUrl, -1, original_url, len);
+ }
+
+ bSuccess = CommitUrlCacheEntryInternal(url_name, local_file_name, ExpireTime, LastModifiedTime,
+ CacheEntryType, lpHeaderInfo, dwHeaderSize,
+ file_extension, original_url);
+
+cleanup:
+ HeapFree(GetProcessHeap(), 0, original_url);
+ HeapFree(GetProcessHeap(), 0, file_extension);
+ HeapFree(GetProcessHeap(), 0, local_file_name);
+ HeapFree(GetProcessHeap(), 0, url_name);
+
return bSuccess;
}
return TRUE;
}
-/***********************************************************************
- * FindCloseUrlCache (WININET.@)
- */
-BOOL WINAPI FindCloseUrlCache(HANDLE hEnumHandle)
-{
- FIXME("(%p) stub\n", hEnumHandle);
- return TRUE;
-}
-
/***********************************************************************
* FindFirstUrlCacheContainerA (WININET.@)
*/
return NULL;
}
+#define URLCACHE_FIND_ENTRY_HANDLE_MAGIC 0xF389ABCD
+
+typedef struct URLCacheFindEntryHandle
+{
+ DWORD dwMagic;
+ LPWSTR lpszUrlSearchPattern;
+ DWORD dwContainerIndex;
+ DWORD dwHashTableIndex;
+ DWORD dwHashEntryIndex;
+} URLCacheFindEntryHandle;
+
/***********************************************************************
* FindFirstUrlCacheEntryA (WININET.@)
*
INTERNETAPI HANDLE WINAPI FindFirstUrlCacheEntryA(LPCSTR lpszUrlSearchPattern,
LPINTERNET_CACHE_ENTRY_INFOA lpFirstCacheEntryInfo, LPDWORD lpdwFirstCacheEntryInfoBufferSize)
{
- FIXME("(%s, %p, %p): stub\n", debugstr_a(lpszUrlSearchPattern), lpFirstCacheEntryInfo, lpdwFirstCacheEntryInfoBufferSize);
- SetLastError(ERROR_FILE_NOT_FOUND);
- return 0;
+ URLCacheFindEntryHandle *pEntryHandle;
+
+ TRACE("(%s, %p, %p)\n", debugstr_a(lpszUrlSearchPattern), lpFirstCacheEntryInfo, lpdwFirstCacheEntryInfoBufferSize);
+
+ pEntryHandle = HeapAlloc(GetProcessHeap(), 0, sizeof(*pEntryHandle));
+ if (!pEntryHandle)
+ return NULL;
+
+ pEntryHandle->dwMagic = URLCACHE_FIND_ENTRY_HANDLE_MAGIC;
+ if (lpszUrlSearchPattern)
+ {
+ int len = MultiByteToWideChar(CP_ACP, 0, lpszUrlSearchPattern, -1, NULL, 0);
+ pEntryHandle->lpszUrlSearchPattern = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (!pEntryHandle->lpszUrlSearchPattern)
+ {
+ HeapFree(GetProcessHeap(), 0, pEntryHandle);
+ return NULL;
+ }
+ MultiByteToWideChar(CP_ACP, 0, lpszUrlSearchPattern, -1, pEntryHandle->lpszUrlSearchPattern, len);
+ }
+ else
+ pEntryHandle->lpszUrlSearchPattern = NULL;
+ pEntryHandle->dwContainerIndex = 0;
+ pEntryHandle->dwHashTableIndex = 0;
+ pEntryHandle->dwHashEntryIndex = 0;
+
+ if (!FindNextUrlCacheEntryA(pEntryHandle, lpFirstCacheEntryInfo, lpdwFirstCacheEntryInfoBufferSize))
+ {
+ HeapFree(GetProcessHeap(), 0, pEntryHandle);
+ return NULL;
+ }
+ return pEntryHandle;
}
/***********************************************************************
INTERNETAPI HANDLE WINAPI FindFirstUrlCacheEntryW(LPCWSTR lpszUrlSearchPattern,
LPINTERNET_CACHE_ENTRY_INFOW lpFirstCacheEntryInfo, LPDWORD lpdwFirstCacheEntryInfoBufferSize)
{
- FIXME("(%s, %p, %p): stub\n", debugstr_w(lpszUrlSearchPattern), lpFirstCacheEntryInfo, lpdwFirstCacheEntryInfoBufferSize);
- SetLastError(ERROR_FILE_NOT_FOUND);
- return 0;
-}
+ URLCacheFindEntryHandle *pEntryHandle;
-HANDLE WINAPI FindFirstUrlCacheGroup( DWORD dwFlags, DWORD dwFilter, LPVOID lpSearchCondition,
- DWORD dwSearchCondition, GROUPID* lpGroupId, LPVOID lpReserved )
-{
- FIXME("(0x%08x, 0x%08x, %p, 0x%08x, %p, %p) stub\n", dwFlags, dwFilter, lpSearchCondition,
- dwSearchCondition, lpGroupId, lpReserved);
- return NULL;
+ TRACE("(%s, %p, %p)\n", debugstr_w(lpszUrlSearchPattern), lpFirstCacheEntryInfo, lpdwFirstCacheEntryInfoBufferSize);
+
+ pEntryHandle = HeapAlloc(GetProcessHeap(), 0, sizeof(*pEntryHandle));
+ if (!pEntryHandle)
+ return NULL;
+
+ pEntryHandle->dwMagic = URLCACHE_FIND_ENTRY_HANDLE_MAGIC;
+ if (lpszUrlSearchPattern)
+ {
+ int len = strlenW(lpszUrlSearchPattern);
+ pEntryHandle->lpszUrlSearchPattern = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
+ if (!pEntryHandle->lpszUrlSearchPattern)
+ {
+ HeapFree(GetProcessHeap(), 0, pEntryHandle);
+ return NULL;
+ }
+ memcpy(pEntryHandle->lpszUrlSearchPattern, lpszUrlSearchPattern, (len + 1) * sizeof(WCHAR));
+ }
+ else
+ pEntryHandle->lpszUrlSearchPattern = NULL;
+ pEntryHandle->dwContainerIndex = 0;
+ pEntryHandle->dwHashTableIndex = 0;
+ pEntryHandle->dwHashEntryIndex = 0;
+
+ if (!FindNextUrlCacheEntryW(pEntryHandle, lpFirstCacheEntryInfo, lpdwFirstCacheEntryInfoBufferSize))
+ {
+ HeapFree(GetProcessHeap(), 0, pEntryHandle);
+ return NULL;
+ }
+ return pEntryHandle;
}
+/***********************************************************************
+ * FindNextUrlCacheEntryA (WININET.@)
+ */
BOOL WINAPI FindNextUrlCacheEntryA(
HANDLE hEnumHandle,
LPINTERNET_CACHE_ENTRY_INFOA lpNextCacheEntryInfo,
- LPDWORD lpdwNextCacheEntryInfoBufferSize
-)
+ LPDWORD lpdwNextCacheEntryInfoBufferSize)
{
- FIXME("(%p, %p, %p) stub\n", hEnumHandle, lpNextCacheEntryInfo, lpdwNextCacheEntryInfoBufferSize);
+ URLCacheFindEntryHandle *pEntryHandle = (URLCacheFindEntryHandle *)hEnumHandle;
+ URLCACHECONTAINER * pContainer;
+
+ TRACE("(%p, %p, %p)\n", hEnumHandle, lpNextCacheEntryInfo, lpdwNextCacheEntryInfoBufferSize);
+
+ if (pEntryHandle->dwMagic != URLCACHE_FIND_ENTRY_HANDLE_MAGIC)
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ for (; URLCacheContainers_Enum(pEntryHandle->lpszUrlSearchPattern, pEntryHandle->dwContainerIndex, &pContainer);
+ pEntryHandle->dwContainerIndex++, pEntryHandle->dwHashTableIndex = 0)
+ {
+ LPURLCACHE_HEADER pHeader;
+ HASH_CACHEFILE_ENTRY *pHashTableEntry;
+
+ if (!URLCacheContainer_OpenIndex(pContainer))
+ return FALSE;
+
+ if (!(pHeader = URLCacheContainer_LockIndex(pContainer)))
+ return FALSE;
+
+ for (; URLCache_EnumHashTables(pHeader, &pEntryHandle->dwHashTableIndex, &pHashTableEntry);
+ pEntryHandle->dwHashTableIndex++, pEntryHandle->dwHashEntryIndex = 0)
+ {
+ const struct _HASH_ENTRY *pHashEntry = NULL;
+ for (; URLCache_EnumHashTableEntries(pHeader, pHashTableEntry, &pEntryHandle->dwHashEntryIndex, &pHashEntry);
+ pEntryHandle->dwHashEntryIndex++)
+ {
+ const URL_CACHEFILE_ENTRY *pUrlEntry;
+ const CACHEFILE_ENTRY *pEntry = (const CACHEFILE_ENTRY *)((LPBYTE)pHeader + pHashEntry->dwOffsetEntry);
+
+ if (pEntry->dwSignature != URL_SIGNATURE)
+ continue;
+
+ pUrlEntry = (URL_CACHEFILE_ENTRY *)pEntry;
+ TRACE("Found URL: %s\n", (LPSTR)pUrlEntry + pUrlEntry->dwOffsetUrl);
+ TRACE("Header info: %s\n", (LPBYTE)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo);
+
+ if (!URLCache_CopyEntry(
+ pContainer,
+ pHeader,
+ lpNextCacheEntryInfo,
+ lpdwNextCacheEntryInfoBufferSize,
+ pUrlEntry,
+ FALSE /* not UNICODE */))
+ {
+ URLCacheContainer_UnlockIndex(pContainer, pHeader);
+ return FALSE;
+ }
+ TRACE("Local File Name: %s\n", debugstr_a(lpNextCacheEntryInfo->lpszLocalFileName));
+
+ /* increment the current index so that next time the function
+ * is called the next entry is returned */
+ pEntryHandle->dwHashEntryIndex++;
+ URLCacheContainer_UnlockIndex(pContainer, pHeader);
+ return TRUE;
+ }
+ }
+
+ URLCacheContainer_UnlockIndex(pContainer, pHeader);
+ }
+
+ SetLastError(ERROR_NO_MORE_ITEMS);
return FALSE;
}
)
{
FIXME("(%p, %p, %p) stub\n", hEnumHandle, lpNextCacheEntryInfo, lpdwNextCacheEntryInfoBufferSize);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
+/***********************************************************************
+ * FindCloseUrlCache (WININET.@)
+ */
+BOOL WINAPI FindCloseUrlCache(HANDLE hEnumHandle)
+{
+ URLCacheFindEntryHandle *pEntryHandle = (URLCacheFindEntryHandle *)hEnumHandle;
+
+ TRACE("(%p)\n", hEnumHandle);
+
+ if (!pEntryHandle || pEntryHandle->dwMagic != URLCACHE_FIND_ENTRY_HANDLE_MAGIC)
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ pEntryHandle->dwMagic = 0;
+ HeapFree(GetProcessHeap(), 0, pEntryHandle->lpszUrlSearchPattern);
+ HeapFree(GetProcessHeap(), 0, pEntryHandle);
+
+ return TRUE;
+}
+
+HANDLE WINAPI FindFirstUrlCacheGroup( DWORD dwFlags, DWORD dwFilter, LPVOID lpSearchCondition,
+ DWORD dwSearchCondition, GROUPID* lpGroupId, LPVOID lpReserved )
+{
+ FIXME("(0x%08x, 0x%08x, %p, 0x%08x, %p, %p) stub\n", dwFlags, dwFilter, lpSearchCondition,
+ dwSearchCondition, lpGroupId, lpReserved);
+ return NULL;
+}
+
BOOL WINAPI FindNextUrlCacheEntryExA(
HANDLE hEnumHandle,
LPINTERNET_CACHE_ENTRY_INFOA lpFirstCacheEntryInfo,
{
LPURLCACHE_HEADER pHeader;
struct _HASH_ENTRY * pHashEntry;
- CACHEFILE_ENTRY * pEntry;
- URL_CACHEFILE_ENTRY * pUrlEntry;
+ const CACHEFILE_ENTRY * pEntry;
+ const URL_CACHEFILE_ENTRY * pUrlEntry;
URLCACHECONTAINER * pContainer;
TRACE("(%s, %08x, %p)\n", debugstr_a(url), dwFlags, pftLastModified);
return FALSE;
}
- pEntry = (CACHEFILE_ENTRY *)((LPBYTE)pHeader + pHashEntry->dwOffsetEntry);
+ pEntry = (const CACHEFILE_ENTRY *)((LPBYTE)pHeader + pHashEntry->dwOffsetEntry);
if (pEntry->dwSignature != URL_SIGNATURE)
{
URLCacheContainer_UnlockIndex(pContainer, pHeader);
return FALSE;
}
- pUrlEntry = (URL_CACHEFILE_ENTRY *)pEntry;
+ pUrlEntry = (const URL_CACHEFILE_ENTRY *)pEntry;
DosDateTimeToFileTime(pUrlEntry->wExpiredDate, pUrlEntry->wExpiredTime, pftLastModified);
{
LPURLCACHE_HEADER pHeader;
struct _HASH_ENTRY * pHashEntry;
- CACHEFILE_ENTRY * pEntry;
- URL_CACHEFILE_ENTRY * pUrlEntry;
+ const CACHEFILE_ENTRY * pEntry;
+ const URL_CACHEFILE_ENTRY * pUrlEntry;
URLCACHECONTAINER * pContainer;
TRACE("(%s, %08x, %p)\n", debugstr_w(url), dwFlags, pftLastModified);
return FALSE;
}
- pEntry = (CACHEFILE_ENTRY *)((LPBYTE)pHeader + pHashEntry->dwOffsetEntry);
+ pEntry = (const CACHEFILE_ENTRY *)((LPBYTE)pHeader + pHashEntry->dwOffsetEntry);
if (pEntry->dwSignature != URL_SIGNATURE)
{
URLCacheContainer_UnlockIndex(pContainer, pHeader);
return FALSE;
}
- pUrlEntry = (URL_CACHEFILE_ENTRY *)pEntry;
+ pUrlEntry = (const URL_CACHEFILE_ENTRY *)pEntry;
DosDateTimeToFileTime(pUrlEntry->wExpiredDate, pUrlEntry->wExpiredTime, pftLastModified);
#include "wine/debug.h"
#include "internet.h"
-#define CP_UNIXCP CP_THREAD_ACP
WINE_DEFAULT_DEBUG_CHANNEL(wininet);
tmpChar[22]='\0';
tmpChar[25]='\0';
+ memset( &t, 0, sizeof(t) );
t.tm_year = atoiW(tmpChar+12) - 1900;
t.tm_mday = atoiW(tmpChar+5);
t.tm_hour = atoiW(tmpChar+17);
memset(psa,0,sizeof(struct sockaddr_in));
memcpy((char *)&psa->sin_addr, phe->h_addr, phe->h_length);
psa->sin_family = phe->h_addrtype;
- psa->sin_port = htons((u_short)nServerPort);
+ psa->sin_port = htons(nServerPort);
return TRUE;
}
@ stdcall InternetAutodial(long ptr)
@ stub InternetAutodialCallback
@ stdcall InternetAutodialHangup(long)
-@ stdcall InternetCanonicalizeUrlA(str str ptr long)
-@ stdcall InternetCanonicalizeUrlW(wstr wstr ptr long)
+@ stdcall InternetCanonicalizeUrlA(str ptr ptr long)
+@ stdcall InternetCanonicalizeUrlW(wstr ptr ptr long)
@ stdcall InternetCheckConnectionA(ptr long long)
@ stdcall InternetCheckConnectionW(ptr long long)
@ stdcall InternetClearAllPerSiteCookieDecisions()
--- /dev/null
+/*
+ * Copyright 2008 Jens Albretsen
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+LANGUAGE LANG_DANISH, SUBLANG_DEFAULT
+
+IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Skriv netværkskodeord"
+FONT 8, "MS Shell Dlg"
+{
+ LTEXT "Skriv dit brugernavn og kodeord:", -1, 40, 6, 150, 15
+ LTEXT "Proxy", -1, 40, 26, 50, 10
+ LTEXT "Realm", -1, 40, 46, 50, 10
+ LTEXT "Brugernavn", -1, 40, 66, 50, 10
+ LTEXT "Kodeord", -1, 40, 86, 50, 10
+ LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0
+ LTEXT "" IDC_REALM, 80, 46, 150, 14, 0
+ EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP
+ EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD
+ CHECKBOX "&Gem dette kodeord (usikkert)", IDC_SAVEPASSWORD,
+ 80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON
+ PUSHBUTTON "Annuller", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP
+}
+
+STRINGTABLE DISCARDABLE
+{
+ IDS_LANCONNECTION "Lokal netværksforbindelse"
+}
{
LTEXT "Ââåäèòå èìÿ ïîëüçîâàòåëÿ è ïàðîëü:", -1, 40, 6, 150, 15
LTEXT "Ïðîêñè", -1, 40, 26, 50, 10
- LTEXT "Realm", -1, 40, 46, 50, 10
+ LTEXT "Äîìåí", -1, 40, 46, 50, 10
LTEXT "Ïîëüçîâàòåëü", -1, 40, 66, 50, 10
LTEXT "Ïàðîëü", -1, 40, 86, 50, 10
LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0
PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON
PUSHBUTTON "Îòìåíà", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP
}
+
+STRINGTABLE DISCARDABLE
+{
+ IDS_LANCONNECTION "Ñåòåâîå ïîäêëþ÷åíèå"
+}
/*
- * Copyright 2003 Rok Mandeljc <rok.mandeljc@gimb.org>
+ * Copyright 2003, 2008 Rok Mandeljc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#pragma code_page(65001)
+
LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT
IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Vnos omre\9enega gesla"
+CAPTION "Vnos omrežnega gesla"
FONT 8, "MS Shell Dlg"
{
- LTEXT "Vnesite uporabni\9ako ime in geslo:", -1, 40, 6, 150, 15
- LTEXT "Proxy", -1, 40, 26, 50, 10
- LTEXT "Realm", -1, 40, 46, 50, 10
- LTEXT "Uporabni\9ako ime", -1, 40, 66, 50, 10
+ LTEXT "Vnesite uporabniško ime in geslo:", -1, 40, 6, 150, 15
+ LTEXT "Proksi", -1, 40, 26, 50, 10
+ LTEXT "Kraljestvo", -1, 40, 46, 50, 10
+ LTEXT "Uporabniško ime", -1, 40, 66, 50, 10
LTEXT "Geslo", -1, 40, 86, 50, 10
LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0
LTEXT "" IDC_REALM, 80, 46, 150, 14, 0
EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP
EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD
- CHECKBOX "&Shrani geslo (neza\9aèiteno)", IDC_SAVEPASSWORD,
+ CHECKBOX "&Shrani geslo (nezaščiteno)", IDC_SAVEPASSWORD,
80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
PUSHBUTTON "V redu", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON
- PUSHBUTTON "Preklièi", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Prekliči", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP
}
+
+STRINGTABLE DISCARDABLE
+{
+ IDS_LANCONNECTION "LAN povezava"
+}
+
+#pragma code_page(default)
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-LANGUAGE LANG_SWEDISH, SUBLANG_DEFAULT
+LANGUAGE LANG_SWEDISH, SUBLANG_NEUTRAL
IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
-Index: ftp.c
-===================================================================
---- ftp.c (revision 30893)
-+++ ftp.c (working copy)
-@@ -58,6 +58,7 @@
-
- #include "wine/debug.h"
- #include "internet.h"
-+typedef size_t socklen_t;
-
- WINE_DEFAULT_DEBUG_CHANNEL(wininet);
-
-Index: http.c
-===================================================================
---- http.c (revision 30893)
-+++ http.c (working copy)
-@@ -60,6 +60,8 @@
+--- D:/Wine-CVS/wine/dlls/wininet/http.c Wed May 28 14:33:28 2008
++++ D:/ReactOS-Trunk/reactos/dll/win32/wininet/http.c Sat May 31 11:59:23 2008
+@@ -61,6 +61,8 @@
#include "wine/debug.h"
#include "wine/unicode.h"
+
WINE_DEFAULT_DEBUG_CHANNEL(wininet);
- static const WCHAR g_szHttp1_0[] = {' ','H','T','T','P','/','1','.','0',0 };
-@@ -3010,7 +3011,11 @@
- /*
- * HACK peek at the buffer
- */
-+#if 0
-+ /* This is Wine code, we don't support MSG_PEEK yet so we have to do it
-+ a bit different */
- NETCON_recv(&lpwhr->netConnection, buffer, buflen, MSG_PEEK, &rc);
-+#endif
+ static const WCHAR g_szHttp1_0[] = {'H','T','T','P','/','1','.','0',0};
+@@ -1617,8 +1619,9 @@
- /*
- * We should first receive 'HTTP/1.x nnn OK' where nnn is the status code.
-@@ -3019,6 +3024,9 @@
- memset(buffer, 0, MAX_REPLY_LEN);
- if (!NETCON_getNextLine(&lpwhr->netConnection, bufferA, &buflen))
- goto lend;
-+#if 1
-+ rc = buflen;
-+#endif
- MultiByteToWideChar( CP_ACP, 0, bufferA, buflen, buffer, MAX_REPLY_LEN );
+ if(req->lpszCacheFile) {
+ BOOL res;
++ DWORD dwBytesWritten;
- /* regenerate raw headers */
-Index: inet_ntop.c
-===================================================================
---- inet_ntop.c (revision 30893)
-+++ inet_ntop.c (working copy)
-@@ -0,0 +1,189 @@
-+/* from NetBSD: inet_ntop.c,v 1.9 2000/01/22 22:19:16 mycroft Exp */
-+
-+/* Copyright (c) 1996 by Internet Software Consortium.
-+ *
-+ * Permission to use, copy, modify, and distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
-+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
-+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
-+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
-+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
-+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-+ * SOFTWARE.
-+ */
-+
-+#define ENOSPC 28
-+#define EAFNOSUPPORT 52
-+
-+#ifndef IN6ADDRSZ
-+#define IN6ADDRSZ 16
-+#endif
-+
-+#ifndef INT16SZ
-+#define INT16SZ 2
-+#endif
-+
-+#ifdef SPRINTF_CHAR
-+# define SPRINTF(x) strlen(sprintf/**/x)
-+#else
-+# define SPRINTF(x) ((size_t)sprintf x)
-+#endif
-+
-+/*
-+ * WARNING: Don't even consider trying to compile this on a system where
-+ * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
-+ */
-+
-+static const char *inet_ntop4(const u_char *src, char *dst, size_t size);
-+static const char *inet_ntop6(const u_char *src, char *dst, size_t size);
-+
-+/* char *
-+ * inet_ntop(af, src, dst, size)
-+ * convert a network format address to presentation format.
-+ * return:
-+ * pointer to presentation format address (`dst'), or NULL (see errno).
-+ * author:
-+ * Paul Vixie, 1996.
-+ */
-+const char *
-+inet_ntop(int af, const void *src, char *dst, size_t size)
-+{
-+
-+ switch (af) {
-+ case AF_INET:
-+ return (inet_ntop4(src, dst, size));
-+#ifdef INET6
-+ case AF_INET6:
-+ return (inet_ntop6(src, dst, size));
-+#endif
-+ default:
-+ errno = EAFNOSUPPORT;
-+ return (NULL);
-+ }
-+ /* NOTREACHED */
-+}
-+
-+/* const char *
-+ * inet_ntop4(src, dst, size)
-+ * format an IPv4 address, more or less like inet_ntoa()
-+ * return:
-+ * `dst' (as a const)
-+ * notes:
-+ * (1) uses no statics
-+ * (2) takes a u_char* not an in_addr as input
-+ * author:
-+ * Paul Vixie, 1996.
-+ */
-+static const char *
-+inet_ntop4(const u_char *src, char *dst, size_t size)
-+{
-+ static const char fmt[] = "%u.%u.%u.%u";
-+ char tmp[sizeof "255.255.255.255"];
-+
-+ if (SPRINTF((tmp, fmt, src[0], src[1], src[2], src[3])) > size) {
-+ errno = ENOSPC;
-+ return (NULL);
-+ }
-+ strcpy(dst, tmp);
-+ return (dst);
-+}
-+
-+#ifdef INET6
-+/* const char *
-+ * inet_ntop6(src, dst, size)
-+ * convert IPv6 binary address into presentation (printable) format
-+ * author:
-+ * Paul Vixie, 1996.
-+ */
-+static const char *
-+inet_ntop6(const u_char *src, char *dst, size_t size)
-+{
-+ /*
-+ * Note that int32_t and int16_t need only be "at least" large enough
-+ * to contain a value of the specified size. On some systems, like
-+ * Crays, there is no such thing as an integer variable with 16 bits.
-+ * Keep this in mind if you think this function should have been coded
-+ * to use pointer overlays. All the world's not a VAX.
-+ */
-+ char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
-+ struct { int base, len; } best, cur;
-+ u_int words[IN6ADDRSZ / INT16SZ];
-+ int i;
-+
-+ /*
-+ * Preprocess:
-+ * Copy the input (bytewise) array into a wordwise array.
-+ * Find the longest run of 0x00's in src[] for :: shorthanding.
-+ */
-+ memset(words, '\0', sizeof words);
-+ for (i = 0; i < IN6ADDRSZ; i++)
-+ words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
-+ best.base = -1;
-+ cur.base = -1;
-+ for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
-+ if (words[i] == 0) {
-+ if (cur.base == -1)
-+ cur.base = i, cur.len = 1;
-+ else
-+ cur.len++;
-+ } else {
-+ if (cur.base != -1) {
-+ if (best.base == -1 || cur.len > best.len)
-+ best = cur;
-+ cur.base = -1;
-+ }
-+ }
-+ }
-+ if (cur.base != -1) {
-+ if (best.base == -1 || cur.len > best.len)
-+ best = cur;
-+ }
-+ if (best.base != -1 && best.len < 2)
-+ best.base = -1;
-+
-+ /*
-+ * Format the result.
-+ */
-+ tp = tmp;
-+ for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
-+ /* Are we inside the best run of 0x00's? */
-+ if (best.base != -1 && i >= best.base &&
-+ i < (best.base + best.len)) {
-+ if (i == best.base)
-+ *tp++ = ':';
-+ continue;
-+ }
-+ /* Are we following an initial run of 0x00s or any real hex? */
-+ if (i != 0)
-+ *tp++ = ':';
-+ /* Is this address an encapsulated IPv4? */
-+ if (i == 6 && best.base == 0 &&
-+ (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
-+ if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
-+ return (NULL);
-+ tp += strlen(tp);
-+ break;
-+ }
-+ tp += SPRINTF((tp, "%x", words[i]));
-+ }
-+ /* Was it a trailing run of 0x00's? */
-+ if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
-+ *tp++ = ':';
-+ *tp++ = '\0';
-+
-+ /*
-+ * Check for overflow, copy, and we're done.
-+ */
-+ if ((size_t)(tp - tmp) > size) {
-+ errno = ENOSPC;
-+ return (NULL);
-+ }
-+ strcpy(dst, tmp);
-+ return (dst);
-+}
-+#endif
-+
-Index: internet.c
-===================================================================
---- internet.c (revision 30893)
-+++ internet.c (working copy)
-@@ -67,6 +67,7 @@
- #include "resource.h"
-
- #include "wine/unicode.h"
-+#define CP_UNIXCP CP_THREAD_ACP
-
- WINE_DEFAULT_DEBUG_CHANNEL(wininet);
+- res = WriteFile(req->hCacheFile, buffer, bytes_read, NULL, NULL);
++ res = WriteFile(req->hCacheFile, buffer, bytes_read, &dwBytesWritten, NULL);
+ if(!res)
+ WARN("WriteFile failed: %u\n", GetLastError());
+ }
+--- D:/Wine-CVS/wine/dlls/wininet/internet.c Wed May 28 14:33:28 2008
++++ D:/ReactOS-Trunk/reactos/dll/win32/wininet/internet.c Fri May 30 18:04:29 2008
+@@ -3101,19 +3101,22 @@
-Index: netconnection.c
-===================================================================
---- netconnection.c (revision 30893)
-+++ netconnection.c (working copy)
-@@ -58,6 +58,8 @@
- #include "internet.h"
+ LPSTR INTERNET_GetNextLine(INT nSocket, LPDWORD dwLen)
+ {
+- struct pollfd pfd;
++ struct timeval tv;
++ fd_set infd;
+ BOOL bSuccess = FALSE;
+ INT nRecv = 0;
+ LPSTR lpszBuffer = INTERNET_GetResponseBuffer();
+
+ TRACE("\n");
+
+- pfd.fd = nSocket;
+- pfd.events = POLLIN;
++ FD_ZERO(&infd);
++ FD_SET(nSocket, &infd);
++ tv.tv_sec=RESPONSE_TIMEOUT;
++ tv.tv_usec=0;
+
+ while (nRecv < MAX_REPLY_LEN)
+ {
+- if (poll(&pfd,1, RESPONSE_TIMEOUT * 1000) > 0)
++ if (select(nSocket+1,&infd,NULL,NULL,&tv) > 0)
+ {
+ if (recv(nSocket, &lpszBuffer[nRecv], 1, 0) <= 0)
+ {
+--- D:/Wine-CVS/wine/dlls/wininet/internet.h Fri Mar 28 20:13:36 2008
++++ D:/ReactOS-Trunk/reactos/dll/win32/wininet/internet.h Thu May 29 19:01:31 2008
+@@ -23,6 +23,9 @@
+ #ifndef _WINE_INTERNET_H_
+ #define _WINE_INTERNET_H_
+
++/* ReactOS-specific definitions */
++#define CP_UNIXCP CP_THREAD_ACP
++
+ #ifndef __WINE_CONFIG_H
+ # error You must include config.h to use this header
+ #endif
+--- D:/Wine-CVS/wine/dlls/wininet/netconnection.c Sat May 17 12:09:49 2008
++++ D:/ReactOS-Trunk/reactos/dll/win32/wininet/netconnection.c Sat May 31 12:01:55 2008
+@@ -64,7 +64,7 @@
+ #include "winsock2.h"
#define RESPONSE_TIMEOUT 30 /* FROM internet.c */
+-
+#define sock_get_error(x) WSAGetLastError()
-+#undef FIONREAD
-
WINE_DEFAULT_DEBUG_CHANNEL(wininet);
-@@ -200,6 +202,7 @@
+
+@@ -206,6 +206,7 @@
return TRUE;
}
-+#ifndef __REACTOS__
++#if 0
/* translate a unix error code into a winsock one */
static int sock_get_error( int err )
{
-@@ -263,6 +266,7 @@
- default: errno=err; perror("sock_set_error"); return WSAEFAULT;
- }
+@@ -272,6 +273,7 @@
+ #endif
+ return err;
}
+#endif
/******************************************************************************
* NETCON_create
-Index: rsrc.rc
-===================================================================
---- rsrc.rc (revision 30893)
-+++ rsrc.rc (working copy)
-@@ -60,3 +60,4 @@
+@@ -616,16 +618,19 @@
+
+ if (!connection->useSSL)
+ {
+- struct pollfd pfd;
++ struct timeval tv;
++ fd_set infd;
+ BOOL bSuccess = FALSE;
+ DWORD nRecv = 0;
+
+- pfd.fd = connection->socketFD;
+- pfd.events = POLLIN;
++ FD_ZERO(&infd);
++ FD_SET(connection->socketFD, &infd);
++ tv.tv_sec=RESPONSE_TIMEOUT;
++ tv.tv_usec=0;
+
+ while (nRecv < *dwBuffer)
+ {
+- if (poll(&pfd,1, RESPONSE_TIMEOUT * 1000) > 0)
++ if (select(connection->socketFD+1,&infd,NULL,NULL,&tv) > 0)
+ {
+ if (recv(connection->socketFD, &lpszBuffer[nRecv], 1, 0) <= 0)
+ {
+--- D:/Wine-CVS/wine/dlls/wininet/rsrc.rc Thu May 08 21:26:20 2008
++++ D:/ReactOS-Trunk/reactos/dll/win32/wininet/rsrc.rc Thu May 29 18:57:29 2008
+@@ -60,4 +60,5 @@
+ #include "wininet_Ru.rc"
#include "wininet_Si.rc"
#include "wininet_Sv.rc"
- #include "wininet_Tr.rc"
+#include "wininet_Uk.rc"
-Index: utility.c
-===================================================================
---- utility.c (revision 30893)
-+++ utility.c (working copy)
-@@ -37,6 +37,7 @@
-
- #include "wine/debug.h"
- #include "internet.h"
-+#define CP_UNIXCP CP_THREAD_ACP
-
- WINE_DEFAULT_DEBUG_CHANNEL(wininet);
-
-Index: wininet.rbuild
-===================================================================
---- wininet.rbuild (revision 30893)
-+++ wininet.rbuild (working copy)
-@@ -19,6 +19,7 @@
- <library>ntdll</library>
- <library>secur32</library>
- <library>crypt32</library>
-+ <library>ws2_32</library>
- <file>cookie.c</file>
- <file>dialogs.c</file>
- <file>ftp.c</file>
-Index: wininet_Uk.rc
-===================================================================
---- wininet_Uk.rc (revision 30893)
-+++ wininet_Uk.rc (working copy)
-@@ -0,0 +1,46 @@
-+/*
-+ * wininet.dll (Ukrainian resources)
-+ *
-+ * Copyright 2006 Artem Reznikov
-+ *
-+ * 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
-+ */
-+
-+LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT
-+
-+IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154
-+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
-+CAPTION "Ââåä³òü Ìåðåæíèé Ïàðîëü"
-+FONT 8, "MS Shell Dlg"
-+{
-+ LTEXT "Áóäü ëàñêà, ââåä³òü Âàø³ ³ì'ÿ òà ïàðîëü:", -1, 40, 6, 150, 15
-+ LTEXT "Ïðîêñ³", -1, 40, 26, 50, 10
-+ LTEXT "Îáëàñòü", -1, 40, 46, 50, 10
-+ LTEXT "Êîðèñòóâà÷", -1, 40, 66, 50, 10
-+ LTEXT "Ïàðîëü", -1, 40, 86, 50, 10
-+ LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0
-+ LTEXT "" IDC_REALM, 80, 46, 150, 14, 0
-+ EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP
-+ EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD
-+ CHECKBOX "&Çáåðåãòè öåé ïàðîëü (íåáåçïå÷íî)", IDC_SAVEPASSWORD,
-+ 80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
-+ PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON
-+ PUSHBUTTON "Ñêàñóâàòè", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP
-+}
-+
-+STRINGTABLE DISCARDABLE
-+{
-+ IDS_LANCONNECTION "ϳäêëþ÷åííÿ ïî ëîêàëüí³é ìåðåæ³"
-+}
+ #include "wininet_Tr.rc"
*
* 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
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _WINE_WININET_H_
} INTERNET_SCHEME,* LPINTERNET_SCHEME;
typedef struct {
- DWORD dwResult;
+ DWORD_PTR dwResult;
DWORD dwError;
} INTERNET_ASYNC_RESULT,* LPINTERNET_ASYNC_RESULT;
DECL_WINELIB_TYPE_AW(INTERNET_CACHE_GROUP_INFO)
DECL_WINELIB_TYPE_AW(LPINTERNET_CACHE_GROUP_INFO)
+typedef struct _INTERNET_PER_CONN_OPTIONA {
+ DWORD dwOption;
+ union {
+ DWORD dwValue;
+ LPSTR pszValue;
+ FILETIME ftValue;
+ } Value;
+} INTERNET_PER_CONN_OPTIONA, *LPINTERNET_PER_CONN_OPTIONA;
+
+typedef struct _INTERNET_PER_CONN_OPTIONW {
+ DWORD dwOption;
+ union {
+ DWORD dwValue;
+ LPWSTR pszValue;
+ FILETIME ftValue;
+ } Value;
+} INTERNET_PER_CONN_OPTIONW, *LPINTERNET_PER_CONN_OPTIONW;
+
+DECL_WINELIB_TYPE_AW(INTERNET_PER_CONN_OPTION)
+DECL_WINELIB_TYPE_AW(LPINTERNET_PER_CONN_OPTION)
+
+#define INTERNET_PER_CONN_FLAGS 1
+#define INTERNET_PER_CONN_PROXY_SERVER 2
+#define INTERNET_PER_CONN_PROXY_BYPASS 3
+#define INTERNET_PER_CONN_AUTOCONFIG_URL 4
+#define INTERNET_PER_CONN_AUTODISCOVERY_FLAGS 5
+#define INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL 6
+#define INTERNET_PER_CONN_AUTOCONFIG_RELOAD_DELAY_MINS 7
+#define INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_TIME 8
+#define INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_URL 9
+
+/* Values for INTERNET_PER_CONN_FLAGS */
+#define PROXY_TYPE_DIRECT 0x00000001
+#define PROXY_TYPE_PROXY 0x00000002
+#define PROXY_TYPE_AUTO_PROXY_URL 0x00000004
+#define PROXY_TYPE_AUTO_DETECT 0x00000008
+/* Values for INTERNET_PER_CONN_AUTODISCOVERY_FLAGS */
+#define AUTO_PROXY_FLAG_USER_SET 0x00000001
+#define AUTO_PROXY_FLAG_ALWAYS_DETECT 0x00000002
+#define AUTO_PROXY_FLAG_DETECTION_RUN 0x00000004
+#define AUTO_PROXY_FLAG_MIGRATED 0x00000008
+#define AUTO_PROXY_FLAG_DONT_CACHE_PROXY_RESULT 0x00000010
+#define AUTO_PROXY_FLAG_CACHE_INIT_RUN 0x00000020
+#define AUTO_PROXY_FLAG_DETECTION_SUSPECT 0x00000040
+
+typedef struct _INTERNET_PER_CONN_OPTION_LISTA {
+ DWORD dwSize;
+ LPSTR pszConnection;
+ DWORD dwOptionCount;
+ DWORD dwOptionError;
+ LPINTERNET_PER_CONN_OPTIONA pOptions;
+} INTERNET_PER_CONN_OPTION_LISTA, *LPINTERNET_PER_CONN_OPTION_LISTA;
+
+typedef struct _INTERNET_PER_CONN_OPTION_LISTW {
+ DWORD dwSize;
+ LPWSTR pszConnection;
+ DWORD dwOptionCount;
+ DWORD dwOptionError;
+ LPINTERNET_PER_CONN_OPTIONW pOptions;
+} INTERNET_PER_CONN_OPTION_LISTW, *LPINTERNET_PER_CONN_OPTION_LISTW;
+
+DECL_WINELIB_TYPE_AW(INTERNET_PER_CONN_OPTION_LIST)
+DECL_WINELIB_TYPE_AW(LPINTERNET_PER_CONN_OPTION_LIST)
+
BOOLAPI InternetTimeFromSystemTimeA(CONST SYSTEMTIME *,DWORD ,LPSTR ,DWORD);
BOOLAPI InternetTimeFromSystemTimeW(CONST SYSTEMTIME *,DWORD ,LPWSTR ,DWORD);
#define InternetTimeFromSystemTime WINELIB_NAME_AW(InternetTimeFromSystemTime)
#define ICU_ENCODE_SPACES_ONLY 0x04000000
#define ICU_BROWSER_MODE 0x02000000
-INTERNETAPI HINTERNET WINAPI InternetOpenA(LPCSTR ,DWORD ,LPCSTR lpszProxy ,LPCSTR lpszProxyBypass ,DWORD);
-INTERNETAPI HINTERNET WINAPI InternetOpenW(LPCWSTR ,DWORD ,LPCWSTR lpszProxy ,LPCWSTR lpszProxyBypass ,DWORD);
+INTERNETAPI HINTERNET WINAPI InternetOpenA(LPCSTR ,DWORD ,LPCSTR ,LPCSTR ,DWORD);
+INTERNETAPI HINTERNET WINAPI InternetOpenW(LPCWSTR ,DWORD ,LPCWSTR ,LPCWSTR ,DWORD);
#define InternetOpen WINELIB_NAME_AW(InternetOpen)
#define INTERNET_OPEN_TYPE_PRECONFIG 0
BOOLAPI InternetCloseHandle(HINTERNET);
INTERNETAPI HINTERNET WINAPI InternetConnectA(HINTERNET ,LPCSTR ,INTERNET_PORT ,
- LPCSTR lpszUserName ,LPCSTR lpszPassword ,DWORD ,DWORD ,DWORD );
+ LPCSTR ,LPCSTR ,DWORD ,DWORD ,DWORD_PTR );
INTERNETAPI HINTERNET WINAPI InternetConnectW(HINTERNET ,LPCWSTR ,INTERNET_PORT ,
- LPCWSTR lpszUserName ,LPCWSTR lpszPassword ,DWORD ,DWORD ,DWORD );
+ LPCWSTR ,LPCWSTR ,DWORD ,DWORD ,DWORD_PTR );
#define InternetConnect WINELIB_NAME_AW(InternetConnect)
#define INTERNET_SERVICE_URL 0
dwContext \
)
-INTERNETAPI HINTERNET WINAPI InternetOpenUrlA(HINTERNET ,LPCSTR ,LPCSTR lpszHeaders ,DWORD ,DWORD ,DWORD);
-INTERNETAPI HINTERNET WINAPI InternetOpenUrlW(HINTERNET ,LPCWSTR ,LPCWSTR lpszHeaders ,DWORD ,DWORD ,DWORD);
+INTERNETAPI HINTERNET WINAPI InternetOpenUrlA(HINTERNET ,LPCSTR ,LPCSTR ,DWORD ,DWORD ,DWORD_PTR);
+INTERNETAPI HINTERNET WINAPI InternetOpenUrlW(HINTERNET ,LPCWSTR ,LPCWSTR ,DWORD ,DWORD ,DWORD_PTR);
#define InternetOpenUrl WINELIB_NAME_AW(InternetOpenUrl)
BOOLAPI InternetReadFile( HINTERNET ,LPVOID ,DWORD ,LPDWORD );
-INTERNETAPI BOOL WINAPI InternetReadFileExA( HINTERNET ,LPINTERNET_BUFFERSA ,DWORD ,DWORD );
-INTERNETAPI BOOL WINAPI InternetReadFileExW( HINTERNET ,LPINTERNET_BUFFERSW ,DWORD ,DWORD );
+INTERNETAPI BOOL WINAPI InternetReadFileExA( HINTERNET ,LPINTERNET_BUFFERSA ,DWORD ,DWORD_PTR );
+INTERNETAPI BOOL WINAPI InternetReadFileExW( HINTERNET ,LPINTERNET_BUFFERSW ,DWORD ,DWORD_PTR );
#define InternetReadFileEx WINELIB_NAME_AW(InternetReadFileEx)
#define IRF_ASYNC WININET_API_FLAG_ASYNC
#define IRF_USE_CONTEXT WININET_API_FLAG_USE_CONTEXT
#define IRF_NO_WAIT 0x00000008
-INTERNETAPI DWORD WINAPI InternetSetFilePointer(HINTERNET ,LONG ,PVOID ,DWORD ,DWORD);
+INTERNETAPI DWORD WINAPI InternetSetFilePointer(HINTERNET ,LONG ,PVOID ,DWORD ,DWORD_PTR);
BOOLAPI InternetWriteFile(HINTERNET ,LPCVOID ,DWORD ,LPDWORD);
-BOOLAPI InternetQueryDataAvailable(HINTERNET ,LPDWORD lpdwNumberOfBytesAvailable ,DWORD ,DWORD);
+BOOLAPI InternetQueryDataAvailable(HINTERNET ,LPDWORD ,DWORD ,DWORD_PTR);
BOOLAPI InternetFindNextFileA(HINTERNET ,LPVOID);
BOOLAPI InternetFindNextFileW(HINTERNET ,LPVOID);
#define InternetFindNextFile WINELIB_NAME_AW(InternetFindNextFile)
-BOOLAPI InternetQueryOptionA(HINTERNET hInternet ,DWORD ,LPVOID lpBuffer ,LPDWORD);
-BOOLAPI InternetQueryOptionW(HINTERNET hInternet ,DWORD ,LPVOID lpBuffer ,LPDWORD);
+BOOLAPI InternetQueryOptionA(HINTERNET ,DWORD ,LPVOID ,LPDWORD);
+BOOLAPI InternetQueryOptionW(HINTERNET ,DWORD ,LPVOID ,LPDWORD);
#define InternetQueryOption WINELIB_NAME_AW(InternetQueryOption)
-BOOLAPI InternetSetOptionA(HINTERNET hInternet ,DWORD ,LPVOID ,DWORD);
-BOOLAPI InternetSetOptionW(HINTERNET hInternet ,DWORD ,LPVOID ,DWORD);
+BOOLAPI InternetSetOptionA(HINTERNET ,DWORD ,LPVOID ,DWORD);
+BOOLAPI InternetSetOptionW(HINTERNET ,DWORD ,LPVOID ,DWORD);
#define InternetSetOption WINELIB_NAME_AW(InternetSetOption)
-BOOLAPI InternetSetOptionExA(HINTERNET hInternet ,DWORD ,LPVOID ,DWORD ,DWORD);
-BOOLAPI InternetSetOptionExW(HINTERNET hInternet ,DWORD ,LPVOID ,DWORD ,DWORD);
+BOOLAPI InternetSetOptionExA(HINTERNET ,DWORD ,LPVOID ,DWORD ,DWORD);
+BOOLAPI InternetSetOptionExW(HINTERNET ,DWORD ,LPVOID ,DWORD ,DWORD);
#define InternetSetOptionEx WINELIB_NAME_AW(InternetSetOptionEx)
BOOLAPI InternetLockRequestFile(HINTERNET ,HANDLE *);
#define INTERNET_OPTION_CLIENT_CERT_CONTEXT 84
#define INTERNET_OPTION_AUTH_FLAGS 85
#define INTERNET_OPTION_COOKIES_3RD_PARTY 86
-#define INTERNET_OPTION_COOKIES_3RD_PARTY 86
#define INTERNET_OPTION_DISABLE_PASSPORT_AUTH 87
#define INTERNET_OPTION_SEND_UTF8_SERVERNAME_TO_PROXY 88
#define INTERNET_OPTION_EXEMPT_CONNECTION_LIMIT 89
-BOOLAPI InternetGetLastResponseInfoA(LPDWORD ,LPSTR lpszBuffer ,LPDWORD);
-BOOLAPI InternetGetLastResponseInfoW(LPDWORD ,LPWSTR lpszBuffer ,LPDWORD);
+BOOLAPI InternetGetLastResponseInfoA(LPDWORD ,LPSTR ,LPDWORD);
+BOOLAPI InternetGetLastResponseInfoW(LPDWORD ,LPWSTR ,LPDWORD);
#define InternetGetLastResponseInfo WINELIB_NAME_AW(InternetGetLastResponseInfo)
-typedef VOID (CALLBACK *INTERNET_STATUS_CALLBACK)(HINTERNET ,DWORD ,DWORD ,
- LPVOID lpvStatusInformation ,DWORD);
+typedef VOID (CALLBACK *INTERNET_STATUS_CALLBACK)(HINTERNET ,DWORD_PTR ,DWORD ,
+ LPVOID ,DWORD);
typedef INTERNET_STATUS_CALLBACK * LPINTERNET_STATUS_CALLBACK;
BOOLAPI FtpCommandW(HINTERNET, BOOL, DWORD, LPCWSTR, DWORD_PTR, HINTERNET *);
#define FtpCommand WINELIB_NAME_AW(FtpCommand)
-INTERNETAPI HINTERNET WINAPI FtpFindFirstFileA(HINTERNET ,LPCSTR lpszSearchFile ,
- LPWIN32_FIND_DATAA lpFindFileData ,DWORD ,DWORD);
-INTERNETAPI HINTERNET WINAPI FtpFindFirstFileW(HINTERNET ,LPCWSTR lpszSearchFile ,
- LPWIN32_FIND_DATAW lpFindFileData ,DWORD ,DWORD);
+INTERNETAPI HINTERNET WINAPI FtpFindFirstFileA(HINTERNET ,LPCSTR ,
+ LPWIN32_FIND_DATAA ,DWORD ,DWORD_PTR);
+INTERNETAPI HINTERNET WINAPI FtpFindFirstFileW(HINTERNET ,LPCWSTR ,
+ LPWIN32_FIND_DATAW ,DWORD ,DWORD_PTR);
#define FtpFindFirstFile WINELIB_NAME_AW(FtpFindFirstFile)
-BOOLAPI FtpGetFileA(HINTERNET ,LPCSTR ,LPCSTR ,BOOL ,DWORD ,DWORD ,DWORD);
-BOOLAPI FtpGetFileW(HINTERNET ,LPCWSTR ,LPCWSTR ,BOOL ,DWORD ,DWORD ,DWORD);
+BOOLAPI FtpGetFileA(HINTERNET ,LPCSTR ,LPCSTR ,BOOL ,DWORD ,DWORD ,DWORD_PTR);
+BOOLAPI FtpGetFileW(HINTERNET ,LPCWSTR ,LPCWSTR ,BOOL ,DWORD ,DWORD ,DWORD_PTR);
#define FtpGetFile WINELIB_NAME_AW(FtpGetFile)
-BOOLAPI FtpPutFileA(HINTERNET ,LPCSTR ,LPCSTR ,DWORD ,DWORD);
-BOOLAPI FtpPutFileW(HINTERNET ,LPCWSTR ,LPCWSTR ,DWORD ,DWORD);
+DWORD WINAPI FtpGetFileSize(HINTERNET, LPDWORD);
+
+BOOLAPI FtpPutFileA(HINTERNET ,LPCSTR ,LPCSTR ,DWORD ,DWORD_PTR);
+BOOLAPI FtpPutFileW(HINTERNET ,LPCWSTR ,LPCWSTR ,DWORD ,DWORD_PTR);
#define FtpPutFile WINELIB_NAME_AW(FtpPutFile)
BOOLAPI FtpDeleteFileA(HINTERNET ,LPCSTR);
BOOLAPI FtpRenameFileW(HINTERNET ,LPCWSTR ,LPCWSTR);
#define FtpRenameFile WINELIB_NAME_AW(FtpRenameFile)
-INTERNETAPI HINTERNET WINAPI FtpOpenFileA(HINTERNET ,LPCSTR ,DWORD ,DWORD ,DWORD);
-INTERNETAPI HINTERNET WINAPI FtpOpenFileW(HINTERNET ,LPCWSTR ,DWORD ,DWORD ,DWORD);
+INTERNETAPI HINTERNET WINAPI FtpOpenFileA(HINTERNET ,LPCSTR ,DWORD ,DWORD ,DWORD_PTR);
+INTERNETAPI HINTERNET WINAPI FtpOpenFileW(HINTERNET ,LPCWSTR ,DWORD ,DWORD ,DWORD_PTR);
#define FtpOpenFile WINELIB_NAME_AW(FtpOpenFile)
BOOLAPI FtpCreateDirectoryA(HINTERNET ,LPCSTR);
#define GOPHER_ATTRIBUTE_ID_TREEWALK (GOPHER_ATTRIBUTE_ID_BASE + 24)
#define GOPHER_ATTRIBUTE_ID_UNKNOWN (GOPHER_ATTRIBUTE_ID_BASE + 25)
-BOOLAPI GopherCreateLocatorA(LPCSTR ,INTERNET_PORT ,LPCSTR lpszDisplayString ,
- LPCSTR lpszSelectorString ,DWORD ,LPSTR lpszLocator ,LPDWORD);
-BOOLAPI GopherCreateLocatorW(LPCWSTR ,INTERNET_PORT ,LPCWSTR lpszDisplayString ,
- LPCWSTR lpszSelectorString ,DWORD ,LPWSTR lpszLocator ,LPDWORD);
+BOOLAPI GopherCreateLocatorA(LPCSTR ,INTERNET_PORT ,LPCSTR ,
+ LPCSTR ,DWORD ,LPSTR ,LPDWORD);
+BOOLAPI GopherCreateLocatorW(LPCWSTR ,INTERNET_PORT ,LPCWSTR ,
+ LPCWSTR ,DWORD ,LPWSTR ,LPDWORD);
#define GopherCreateLocator WINELIB_NAME_AW(GopherCreateLocator)
BOOLAPI GopherGetLocatorTypeA(LPCSTR ,LPDWORD);
BOOLAPI GopherGetLocatorTypeW(LPCWSTR ,LPDWORD);
#define GopherGetLocatorType WINELIB_NAME_AW(GopherGetLocatorType)
-INTERNETAPI HINTERNET WINAPI GopherFindFirstFileA(HINTERNET ,LPCSTR lpszLocator ,
- LPCSTR lpszSearchString ,LPGOPHER_FIND_DATAA lpFindData ,DWORD ,DWORD);
-INTERNETAPI HINTERNET WINAPI GopherFindFirstFileW(HINTERNET ,LPCWSTR lpszLocator ,
- LPCWSTR lpszSearchString ,LPGOPHER_FIND_DATAW lpFindData ,DWORD ,DWORD);
+INTERNETAPI HINTERNET WINAPI GopherFindFirstFileA(HINTERNET ,LPCSTR ,
+ LPCSTR ,LPGOPHER_FIND_DATAA ,DWORD ,DWORD_PTR);
+INTERNETAPI HINTERNET WINAPI GopherFindFirstFileW(HINTERNET ,LPCWSTR ,
+ LPCWSTR ,LPGOPHER_FIND_DATAW ,DWORD ,DWORD_PTR);
#define GopherFindFirstFile WINELIB_NAME_AW(GopherFindFirstFile)
-INTERNETAPI HINTERNET WINAPI GopherOpenFileA(HINTERNET ,LPCSTR ,LPCSTR lpszView ,DWORD ,DWORD);
-INTERNETAPI HINTERNET WINAPI GopherOpenFileW(HINTERNET ,LPCWSTR ,LPCWSTR lpszView ,DWORD ,DWORD);
+INTERNETAPI HINTERNET WINAPI GopherOpenFileA(HINTERNET ,LPCSTR ,LPCSTR ,DWORD ,DWORD_PTR);
+INTERNETAPI HINTERNET WINAPI GopherOpenFileW(HINTERNET ,LPCWSTR ,LPCWSTR ,DWORD ,DWORD_PTR);
#define GopherOpenFile WINELIB_NAME_AW(GopherOpenFile)
typedef BOOL (CALLBACK *GOPHER_ATTRIBUTE_ENUMERATORA)(LPGOPHER_ATTRIBUTE_TYPEA ,DWORD);
DECL_WINELIB_TYPE_AW(GOPHER_ATTRIBUTE_ENUMERATOR)
-BOOLAPI GopherGetAttributeA(HINTERNET ,LPCSTR ,LPCSTR lpszAttributeName ,LPBYTE ,
- DWORD ,LPDWORD ,GOPHER_ATTRIBUTE_ENUMERATORA lpfnEnumerator ,DWORD);
-BOOLAPI GopherGetAttributeW(HINTERNET ,LPCWSTR ,LPCWSTR lpszAttributeName ,LPBYTE ,
- DWORD ,LPDWORD ,GOPHER_ATTRIBUTE_ENUMERATORW lpfnEnumerator ,DWORD);
+BOOLAPI GopherGetAttributeA(HINTERNET ,LPCSTR ,LPCSTR ,LPBYTE ,
+ DWORD ,LPDWORD ,GOPHER_ATTRIBUTE_ENUMERATORA ,DWORD_PTR);
+BOOLAPI GopherGetAttributeW(HINTERNET ,LPCWSTR ,LPCWSTR ,LPBYTE ,
+ DWORD ,LPDWORD ,GOPHER_ATTRIBUTE_ENUMERATORW ,DWORD_PTR);
#define GopherGetAttribute WINELIB_NAME_AW(GopherGetAttribute)
#define HTTP_MAJOR_VERSION 1
INTERNETAPI HINTERNET WINAPI HttpOpenRequestA(HINTERNET ,LPCSTR ,LPCSTR ,LPCSTR ,
- LPCSTR lpszReferrer ,LPCSTR * ,DWORD ,DWORD);
+ LPCSTR ,LPCSTR * ,DWORD ,DWORD_PTR);
INTERNETAPI HINTERNET WINAPI HttpOpenRequestW(HINTERNET ,LPCWSTR ,LPCWSTR ,LPCWSTR ,
- LPCWSTR lpszReferrer ,LPCWSTR * ,DWORD ,DWORD);
+ LPCWSTR ,LPCWSTR * ,DWORD ,DWORD_PTR);
#define HttpOpenRequest WINELIB_NAME_AW(HttpOpenRequest)
BOOLAPI HttpAddRequestHeadersA(HINTERNET ,LPCSTR ,DWORD ,DWORD);
#define HTTP_ADDREQ_FLAG_COALESCE HTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA
#define HTTP_ADDREQ_FLAG_REPLACE 0x80000000
-BOOLAPI HttpSendRequestA(HINTERNET ,LPCSTR lpszHeaders ,DWORD ,LPVOID lpOptional ,DWORD);
-BOOLAPI HttpSendRequestW(HINTERNET ,LPCWSTR lpszHeaders ,DWORD ,LPVOID lpOptional ,DWORD);
+BOOLAPI HttpSendRequestA(HINTERNET ,LPCSTR ,DWORD ,LPVOID ,DWORD);
+BOOLAPI HttpSendRequestW(HINTERNET ,LPCWSTR ,DWORD ,LPVOID ,DWORD);
#define HttpSendRequest WINELIB_NAME_AW(HttpSendRequest)
-INTERNETAPI BOOL WINAPI HttpSendRequestExA(HINTERNET ,LPINTERNET_BUFFERSA lpBuffersIn ,
- LPINTERNET_BUFFERSA lpBuffersOut ,DWORD ,DWORD);
-INTERNETAPI BOOL WINAPI HttpSendRequestExW(HINTERNET ,LPINTERNET_BUFFERSW lpBuffersIn ,
- LPINTERNET_BUFFERSW lpBuffersOut ,DWORD ,DWORD);
+INTERNETAPI BOOL WINAPI HttpSendRequestExA(HINTERNET ,LPINTERNET_BUFFERSA ,
+ LPINTERNET_BUFFERSA ,DWORD ,DWORD_PTR);
+INTERNETAPI BOOL WINAPI HttpSendRequestExW(HINTERNET ,LPINTERNET_BUFFERSW ,
+ LPINTERNET_BUFFERSW ,DWORD ,DWORD_PTR);
#define HttpSendRequestEx WINELIB_NAME_AW(HttpSendRequestEx)
#define HSR_ASYNC WININET_API_FLAG_ASYNC
#define HSR_DOWNLOAD 0x00000010
#define HSR_CHUNKED 0x00000020
-INTERNETAPI BOOL WINAPI HttpEndRequestA(HINTERNET ,LPINTERNET_BUFFERSA lpBuffersOut ,DWORD ,DWORD);
-INTERNETAPI BOOL WINAPI HttpEndRequestW(HINTERNET ,LPINTERNET_BUFFERSW lpBuffersOut ,DWORD ,DWORD);
+INTERNETAPI BOOL WINAPI HttpEndRequestA(HINTERNET ,LPINTERNET_BUFFERSA ,DWORD ,DWORD_PTR);
+INTERNETAPI BOOL WINAPI HttpEndRequestW(HINTERNET ,LPINTERNET_BUFFERSW ,DWORD ,DWORD_PTR);
#define HttpEndRequest WINELIB_NAME_AW(HttpEndRequest)
-BOOLAPI HttpQueryInfoA(HINTERNET ,DWORD ,LPVOID lpBuffer ,LPDWORD ,LPDWORD lpdwIndex);
-BOOLAPI HttpQueryInfoW(HINTERNET ,DWORD ,LPVOID lpBuffer ,LPDWORD ,LPDWORD lpdwIndex);
+BOOLAPI HttpQueryInfoA(HINTERNET ,DWORD ,LPVOID ,LPDWORD ,LPDWORD);
+BOOLAPI HttpQueryInfoW(HINTERNET ,DWORD ,LPVOID ,LPDWORD ,LPDWORD);
#define HttpQueryInfo WINELIB_NAME_AW(HttpQueryInfo)
BOOLAPI InternetClearAllPerSiteCookieDecisions(VOID);
BOOLAPI InternetEnumPerSiteCookieDecisionW(LPWSTR,unsigned long *,unsigned long *,unsigned long);
#define InternetEnumPerSiteCookieDecision WINELIB_NAME_AW(InternetEnumPerSiteCookieDecision)
+#define INTERNET_COOKIE_IS_SECURE 0x00000001
+#define INTERNET_COOKIE_IS_SESSION 0x00000002
+#define INTERNET_COOKIE_THIRD_PARTY 0x00000010
+#define INTERNET_COOKIE_PROMPT_REQUIRED 0x00000020
+#define INTERNET_COOKIE_EVALUATE_P3P 0x00000040
+#define INTERNET_COOKIE_APPLY_P3P 0x00000080
+#define INTERNET_COOKIE_P3P_ENABLED 0x00000100
+#define INTERNET_COOKIE_IS_RESTRICTED 0x00000200
+#define INTERNET_COOKIE_IE6 0x00000400
+#define INTERNET_COOKIE_IS_LEGACY 0x00000800
+
BOOLAPI InternetGetCookieExA(LPCSTR,LPCSTR,LPSTR,LPDWORD,DWORD,LPVOID);
BOOLAPI InternetGetCookieExW(LPCWSTR,LPCWSTR,LPWSTR,LPDWORD,DWORD,LPVOID);
#define InternetGetCookieEx WINELIB_NAME_AW(InternetGetCookieEx)
#define FLAGS_ERROR_UI_FLAGS_NO_UI 0x08
#define FLAGS_ERROR_UI_SERIALIZE_DIALOGS 0x10
-DWORD InternetAuthNotifyCallback ( DWORD ,DWORD ,LPVOID );
-typedef DWORD (CALLBACK *PFN_AUTH_NOTIFY) (DWORD,DWORD,LPVOID);
+DWORD InternetAuthNotifyCallback ( DWORD_PTR ,DWORD ,LPVOID );
+typedef DWORD (CALLBACK *PFN_AUTH_NOTIFY) (DWORD_PTR,DWORD,LPVOID);
typedef struct
{
DWORD cbStruct;
DWORD dwOptions;
PFN_AUTH_NOTIFY pfnNotify;
- DWORD dwContext;
+ DWORD_PTR dwContext;
}
INTERNET_AUTH_NOTIFY_DATA;
#define ERROR_INTERNET_RETRY_DIALOG (INTERNET_ERROR_BASE + 50)
#define ERROR_INTERNET_HTTPS_HTTP_SUBMIT_REDIR (INTERNET_ERROR_BASE + 52)
#define ERROR_INTERNET_INSERT_CDROM (INTERNET_ERROR_BASE + 53)
+#define ERROR_INTERNET_SEC_CERT_ERRORS (INTERNET_ERROR_BASE + 55)
+#define ERROR_INTERNET_SEC_CERT_NO_REV (INTERNET_ERROR_BASE + 56)
+#define ERROR_INTERNET_SEC_CERT_REV_FAILED (INTERNET_ERROR_BASE + 57)
#define ERROR_FTP_TRANSFER_IN_PROGRESS (INTERNET_ERROR_BASE + 110)
#define ERROR_FTP_DROPPED (INTERNET_ERROR_BASE + 111)
#define ERROR_FTP_NO_PASSIVE_MODE (INTERNET_ERROR_BASE + 112)
#define ERROR_INTERNET_SEC_INVALID_CERT (INTERNET_ERROR_BASE + 169)
#define ERROR_INTERNET_SEC_CERT_REVOKED (INTERNET_ERROR_BASE + 170)
#define ERROR_INTERNET_FAILED_DUETOSECURITYCHECK (INTERNET_ERROR_BASE + 171)
-#define ERROR_INTERNET_NOT_INITIALIZED (INTERNET_ERROR_BASE + 172)
+#define ERROR_INTERNET_NOT_INITIALIZED (INTERNET_ERROR_BASE + 172)
#define INTERNET_ERROR_LAST ERROR_INTERNET_NOT_INITIALIZED
#define NORMAL_CACHE_ENTRY 0x00000001
+#define STICKY_CACHE_ENTRY 0x00000004
+#define EDITED_CACHE_ENTRY 0x00000008
#define COOKIE_CACHE_ENTRY 0x00100000
#define URLHISTORY_CACHE_ENTRY 0x00200000
#define TRACK_OFFLINE_CACHE_ENTRY 0x00000010
#define TRACK_ONLINE_CACHE_ENTRY 0x00000020
-#define STICKY_CACHE_ENTRY 0x00000004
#define SPARSE_CACHE_ENTRY 0x00010000
#define URLCACHE_FIND_DEFAULT_FILTER NORMAL_CACHE_ENTRY \
BOOLAPI DeleteUrlCacheEntryW(LPCWSTR);
#define DeleteUrlCacheEntry WINELIB_NAME_AW(DeleteUrlCacheEntry)
-INTERNETAPI DWORD WINAPI InternetDialA(HWND ,LPSTR ,DWORD ,LPDWORD ,DWORD);
-INTERNETAPI DWORD WINAPI InternetDialW(HWND ,LPWSTR ,DWORD ,LPDWORD ,DWORD);
+INTERNETAPI DWORD WINAPI InternetDialA(HWND ,LPSTR ,DWORD ,DWORD_PTR* ,DWORD);
+INTERNETAPI DWORD WINAPI InternetDialW(HWND ,LPWSTR ,DWORD ,DWORD_PTR* ,DWORD);
#define InternetDial WINELIB_NAME_AW(InternetDial)
#define INTERNET_DIAL_UNATTENDED 0x8000
-INTERNETAPI DWORD WINAPI InternetHangUp(DWORD ,DWORD);
+INTERNETAPI DWORD WINAPI InternetHangUp(DWORD_PTR ,DWORD);
BOOLAPI CreateMD5SSOHash(PWSTR,PWSTR,PWSTR,PBYTE);
#define INTERENT_GOONLINE_REFRESH 0x00000001
#define InternetSetDialState WINELIB_NAME_AW(InternetSetDialState)
#define INTERNET_DIALSTATE_DISCONNECTED 1
-BOOLAPI InternetCheckConnectionA(LPCSTR lpszUrl,DWORD dwFlags,DWORD dwReserved);
-BOOLAPI InternetCheckConnectionW(LPCWSTR lpszUrl,DWORD dwFlags,DWORD dwReserved);
-#define InternetCheckConnection WINELIB_NAME_AW(InternetCheckConnection)
+BOOL WINAPI InternetGetConnectedStateExA(LPDWORD, LPSTR, DWORD, DWORD);
+BOOL WINAPI InternetGetConnectedStateExW(LPDWORD, LPWSTR, DWORD, DWORD);
+#define InternetGetConnectedStateEx WINELIB_NAME_AW(InternetGetConnectedStateEx)
+
+BOOL WINAPI InternetInitializeAutoProxyDll(DWORD);
+BOOL WINAPI DetectAutoProxyUrl(LPSTR, DWORD, DWORD);
#ifdef __cplusplus
}