[1/2] wininet: Implement InternetReadFileExW.
Hans Leidekker
hans at codeweavers.com
Thu Jan 15 09:41:42 CST 2009
I chose not to forward InternetReadFileExA because conversion of the
buffer list seemed too expensive to me.
IE7 calls this function.
-Hans
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;
More information about the wine-patches
mailing list