Module: wine Branch: master Commit: b013ad168b6da81ae418ce5546941370296407db URL: http://source.winehq.org/git/wine.git/?a=commit;h=b013ad168b6da81ae418ce5546...
Author: Hans Leidekker hans@codeweavers.com Date: Thu Jan 15 16:41:42 2009 +0100
wininet: Implement InternetReadFileExW.
---
dlls/wininet/ftp.c | 2 + dlls/wininet/http.c | 70 +++++++++++++++++++++++++++++++++++++++++++++- dlls/wininet/internet.c | 41 +++++++++++++++------------ dlls/wininet/internet.h | 9 +++++- 4 files changed, 101 insertions(+), 21 deletions(-)
diff --git a/dlls/wininet/ftp.c b/dlls/wininet/ftp.c index 21ce434..0289300 100644 --- a/dlls/wininet/ftp.c +++ b/dlls/wininet/ftp.c @@ -1267,6 +1267,7 @@ static const HANDLEHEADERVtbl FTPFILEVtbl = { NULL, FTPFILE_ReadFile, NULL, + NULL, FTPFILE_WriteFile, NULL, NULL @@ -3312,6 +3313,7 @@ static const HANDLEHEADERVtbl FTPFINDNEXTVtbl = { NULL, NULL, NULL, + NULL, FTPFINDNEXT_FindNextFileW };
diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c index a5352e4..ea4e456 100644 --- a/dlls/wininet/http.c +++ b/dlls/wininet/http.c @@ -1795,7 +1795,7 @@ static DWORD HTTPREQ_ReadFile(WININETHANDLEHEADER *hdr, void *buffer, DWORD size return HTTPREQ_Read(req, buffer, size, read, TRUE); }
-static void HTTPREQ_AsyncReadFileExProc(WORKREQUEST *workRequest) +static void HTTPREQ_AsyncReadFileExAProc(WORKREQUEST *workRequest) { struct WORKREQ_INTERNETREADFILEEXA const *data = &workRequest->u.InternetReadFileExA; WININETHTTPREQW *req = (WININETHTTPREQW*)workRequest->hdr; @@ -1838,7 +1838,7 @@ static DWORD HTTPREQ_ReadFileExA(WININETHANDLEHEADER *hdr, INTERNET_BUFFERSA *bu { WORKREQUEST workRequest;
- workRequest.asyncproc = HTTPREQ_AsyncReadFileExProc; + workRequest.asyncproc = HTTPREQ_AsyncReadFileExAProc; workRequest.hdr = WININET_AddRef(&req->hdr); workRequest.u.InternetReadFileExA.lpBuffersOut = buffers;
@@ -1860,6 +1860,71 @@ static DWORD HTTPREQ_ReadFileExA(WININETHANDLEHEADER *hdr, INTERNET_BUFFERSA *bu return res; }
+static void HTTPREQ_AsyncReadFileExWProc(WORKREQUEST *workRequest) +{ + struct WORKREQ_INTERNETREADFILEEXW const *data = &workRequest->u.InternetReadFileExW; + WININETHTTPREQW *req = (WININETHTTPREQW*)workRequest->hdr; + INTERNET_ASYNC_RESULT iar; + DWORD res; + + TRACE("INTERNETREADFILEEXW %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_ReadFileExW(WININETHANDLEHEADER *hdr, INTERNET_BUFFERSW *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_AsyncReadFileExWProc; + workRequest.hdr = WININET_AddRef(&req->hdr); + workRequest.u.InternetReadFileExW.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; @@ -1915,6 +1980,7 @@ static const HANDLEHEADERVtbl HTTPREQVtbl = { HTTPREQ_SetOption, HTTPREQ_ReadFile, HTTPREQ_ReadFileExA, + HTTPREQ_ReadFileExW, HTTPREQ_WriteFile, HTTPREQ_QueryDataAvailable, NULL diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c index 03e9e74..6f67c3d 100644 --- a/dlls/wininet/internet.c +++ b/dlls/wininet/internet.c @@ -2005,29 +2005,34 @@ BOOL WINAPI InternetReadFileExA(HINTERNET hFile, LPINTERNET_BUFFERSA lpBuffersOu
/*********************************************************************** * InternetReadFileExW (WININET.@) - * - * Read data from an open internet file. - * - * PARAMS - * hFile [I] Handle returned by InternetOpenUrl() or HttpOpenRequest(). - * lpBuffersOut [I/O] Buffer. - * dwFlags [I] Flags. - * dwContext [I] Context for callbacks. - * - * RETURNS - * FALSE, last error is set to ERROR_CALL_NOT_IMPLEMENTED - * - * NOTES - * Not implemented in Wine or native either (as of IE6 SP2). - * + * SEE + * InternetReadFileExA() */ BOOL WINAPI InternetReadFileExW(HINTERNET hFile, LPINTERNET_BUFFERSW lpBuffer, DWORD dwFlags, DWORD_PTR dwContext) { - ERR("(%p, %p, 0x%x, 0x%lx): not implemented in native\n", hFile, lpBuffer, dwFlags, dwContext); + LPWININETHANDLEHEADER hdr; + DWORD res = ERROR_INTERNET_INCORRECT_HANDLE_TYPE; + + TRACE("(%p %p 0x%x 0x%lx)\n", hFile, lpBuffer, dwFlags, dwContext);
- INTERNET_SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + hdr = WININET_GetObject(hFile); + if (!hdr) { + INTERNET_SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + + if(hdr->vtbl->ReadFileExW) + res = hdr->vtbl->ReadFileExW(hdr, lpBuffer, dwFlags, dwContext); + + WININET_Release(hdr); + + TRACE("-- %s (%u, bytes read: %d)\n", res == ERROR_SUCCESS ? "TRUE": "FALSE", + res, lpBuffer->dwBufferLength); + + if(res != ERROR_SUCCESS) + SetLastError(res); + return res == ERROR_SUCCESS; }
DWORD INET_QueryOption(DWORD option, void *buffer, DWORD *size, BOOL unicode) diff --git a/dlls/wininet/internet.h b/dlls/wininet/internet.h index 8de85ff..dc57214 100644 --- a/dlls/wininet/internet.h +++ b/dlls/wininet/internet.h @@ -124,6 +124,7 @@ typedef struct { DWORD (*SetOption)(WININETHANDLEHEADER*,DWORD,void*,DWORD); DWORD (*ReadFile)(WININETHANDLEHEADER*,void*,DWORD,DWORD*); DWORD (*ReadFileExA)(WININETHANDLEHEADER*,INTERNET_BUFFERSA*,DWORD,DWORD_PTR); + DWORD (*ReadFileExW)(WININETHANDLEHEADER*,INTERNET_BUFFERSW*,DWORD,DWORD_PTR); BOOL (*WriteFile)(WININETHANDLEHEADER*,const void*,DWORD,DWORD*); DWORD (*QueryDataAvailable)(WININETHANDLEHEADER*,DWORD*,DWORD,DWORD_PTR); DWORD (*FindNextFileW)(WININETHANDLEHEADER*,void*); @@ -311,6 +312,11 @@ struct WORKREQ_INTERNETREADFILEEXA LPINTERNET_BUFFERSA lpBuffersOut; };
+struct WORKREQ_INTERNETREADFILEEXW +{ + LPINTERNET_BUFFERSW lpBuffersOut; +}; + typedef struct WORKREQ { void (*asyncproc)(struct WORKREQ*); @@ -330,8 +336,9 @@ typedef struct WORKREQ struct WORKREQ_FTPFINDNEXTW FtpFindNextW; struct WORKREQ_HTTPSENDREQUESTW HttpSendRequestW; struct WORKREQ_SENDCALLBACK SendCallback; - struct WORKREQ_INTERNETOPENURLW InternetOpenUrlW; + struct WORKREQ_INTERNETOPENURLW InternetOpenUrlW; struct WORKREQ_INTERNETREADFILEEXA InternetReadFileExA; + struct WORKREQ_INTERNETREADFILEEXW InternetReadFileExW; } u;
} WORKREQUEST, *LPWORKREQUEST;