Implement InternetReadFileExA (based on a patch by Brian Gerst).

This commit is contained in:
Robert Shearman 2005-11-12 19:10:56 +00:00 committed by Alexandre Julliard
parent c02aee8b8f
commit 01e91e5f6c
2 changed files with 149 additions and 31 deletions

View File

@ -1702,37 +1702,21 @@ BOOL WINAPI InternetWriteFile(HINTERNET hFile, LPCVOID lpBuffer ,
} }
/*********************************************************************** static BOOL INTERNET_ReadFile(LPWININETHANDLEHEADER lpwh, LPVOID lpBuffer,
* InternetReadFile (WININET.@) DWORD dwNumOfBytesToRead, LPDWORD pdwNumOfBytesRead,
* BOOL bWait, BOOL bSendCompletionStatus)
* Read data from an open internet file
*
* RETURNS
* TRUE on success
* FALSE on failure
*
*/
BOOL WINAPI InternetReadFile(HINTERNET hFile, LPVOID lpBuffer,
DWORD dwNumOfBytesToRead, LPDWORD dwNumOfBytesRead)
{ {
BOOL retval = FALSE; BOOL retval = FALSE;
int nSocket = -1; int nSocket = -1;
LPWININETHANDLEHEADER lpwh;
TRACE("%p %p %ld %p\n", hFile, lpBuffer, dwNumOfBytesToRead, dwNumOfBytesRead);
lpwh = (LPWININETHANDLEHEADER) WININET_GetObject( hFile );
if (NULL == lpwh)
return FALSE;
/* FIXME: this should use NETCON functions! */ /* FIXME: this should use NETCON functions! */
switch (lpwh->htype) switch (lpwh->htype)
{ {
case WH_HHTTPREQ: case WH_HHTTPREQ:
if (!NETCON_recv(&((LPWININETHTTPREQW)lpwh)->netConnection, lpBuffer, if (!NETCON_recv(&((LPWININETHTTPREQW)lpwh)->netConnection, lpBuffer,
dwNumOfBytesToRead, MSG_WAITALL, (int *)dwNumOfBytesRead)) dwNumOfBytesToRead, bWait ? MSG_WAITALL : 0, (int *)pdwNumOfBytesRead))
{ {
*dwNumOfBytesRead = 0; *pdwNumOfBytesRead = 0;
retval = TRUE; /* Under windows, it seems to return 0 even if nothing was read... */ retval = TRUE; /* Under windows, it seems to return 0 even if nothing was read... */
} }
else else
@ -1744,18 +1728,60 @@ BOOL WINAPI InternetReadFile(HINTERNET hFile, LPVOID lpBuffer,
nSocket = ((LPWININETFILE)lpwh)->nDataSocket; nSocket = ((LPWININETFILE)lpwh)->nDataSocket;
if (nSocket != -1) if (nSocket != -1)
{ {
int res = recv(nSocket, lpBuffer, dwNumOfBytesToRead, MSG_WAITALL); int res = recv(nSocket, lpBuffer, dwNumOfBytesToRead, bWait ? MSG_WAITALL : 0);
retval = (res >= 0); retval = (res >= 0);
*dwNumOfBytesRead = retval ? res : 0; *pdwNumOfBytesRead = retval ? res : 0;
} }
break; break;
default: default:
break; break;
} }
if (bSendCompletionStatus)
{
INTERNET_ASYNC_RESULT iar;
iar.dwResult = retval;
iar.dwError = iar.dwError = retval ? ERROR_SUCCESS :
INTERNET_GetLastError();
SendAsyncCallback(lpwh, lpwh->dwContext,
INTERNET_STATUS_REQUEST_COMPLETE, &iar,
sizeof(INTERNET_ASYNC_RESULT));
}
return retval;
}
/***********************************************************************
* InternetReadFile (WININET.@)
*
* Read data from an open internet file
*
* RETURNS
* TRUE on success
* FALSE on failure
*
*/
BOOL WINAPI InternetReadFile(HINTERNET hFile, LPVOID lpBuffer,
DWORD dwNumOfBytesToRead, LPDWORD pdwNumOfBytesRead)
{
LPWININETHANDLEHEADER lpwh;
BOOL retval;
TRACE("%p %p %ld %p\n", hFile, lpBuffer, dwNumOfBytesToRead, pdwNumOfBytesRead);
lpwh = WININET_GetObject( hFile );
if (!lpwh)
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
retval = INTERNET_ReadFile(lpwh, lpBuffer, dwNumOfBytesToRead, pdwNumOfBytesRead, TRUE, FALSE);
WININET_Release( lpwh ); WININET_Release( lpwh );
TRACE("-- %s (bytes read: %ld)\n", retval ? "TRUE": "FALSE", dwNumOfBytesRead ? *dwNumOfBytesRead : -1); TRACE("-- %s (bytes read: %ld)\n", retval ? "TRUE": "FALSE", pdwNumOfBytesRead ? *pdwNumOfBytesRead : -1);
return retval; return retval;
} }
@ -1764,32 +1790,106 @@ BOOL WINAPI InternetReadFile(HINTERNET hFile, LPVOID lpBuffer,
* *
* Read data from an open internet file * Read data from an open internet file
* *
* PARAMS
* hFile [I] Handle returned by InternetOpenUrl or HttpOpenRequest.
* lpBuffersOut [I/O] Buffer.
* dwFlags [I] Flags. See notes.
* dwContext [I] Context for callbacks.
*
* RETURNS * RETURNS
* TRUE on success * TRUE on success
* FALSE on failure * FALSE on failure
* *
* NOTES
* The parameter dwFlags include zero or more of the following flags:
*|IRF_ASYNC - Makes the call asynchronous.
*|IRF_SYNC - Makes the call synchronous.
*|IRF_USE_CONTEXT - Forces dwContext to be used.
*|IRF_NO_WAIT - Don't block if the data is not available, just return what is available.
*
* However, in testing IRF_USE_CONTEXT seems to have no effect - dwContext isn't used.
*
* SEE
* InternetOpenUrlA(), HttpOpenRequestA()
*/ */
BOOL WINAPI InternetReadFileExA(HINTERNET hFile, LPINTERNET_BUFFERSA lpBuffer, BOOL WINAPI InternetReadFileExA(HINTERNET hFile, LPINTERNET_BUFFERSA lpBuffersOut,
DWORD dwFlags, DWORD dwContext) DWORD dwFlags, DWORD dwContext)
{ {
FIXME("stub\n"); BOOL retval = FALSE;
return FALSE; LPWININETHANDLEHEADER lpwh;
TRACE("(%p %p 0x%lx 0x%lx)\n", hFile, lpBuffersOut, dwFlags, dwContext);
if (dwFlags & ~(IRF_ASYNC|IRF_NO_WAIT))
FIXME("these dwFlags aren't implemented: 0x%lx\n", dwFlags & ~(IRF_ASYNC|IRF_NO_WAIT));
if (lpBuffersOut->dwStructSize != sizeof(*lpBuffersOut))
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
lpwh = (LPWININETHANDLEHEADER) WININET_GetObject( hFile );
if (!lpwh)
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
/* FIXME: native only does it asynchronously if the amount of data
* requested isn't available. See NtReadFile. */
/* FIXME: IRF_ASYNC may not be the right thing to test here;
* hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC is probably better, but
* we should implement the above first */
if (dwFlags & IRF_ASYNC)
{
WORKREQUEST workRequest;
struct WORKREQ_INTERNETREADFILEEXA *req;
workRequest.asyncall = INTERNETREADFILEEXA;
workRequest.hdr = WININET_AddRef( lpwh );
req = &workRequest.u.InternetReadFileExA;
req->lpBuffersOut = lpBuffersOut;
retval = INTERNET_AsyncCall(&workRequest);
if (!retval) return FALSE;
SetLastError(ERROR_IO_PENDING);
return FALSE;
}
retval = INTERNET_ReadFile(lpwh, lpBuffersOut->lpvBuffer,
lpBuffersOut->dwBufferLength, &lpBuffersOut->dwBufferLength,
!(dwFlags & IRF_NO_WAIT), FALSE);
WININET_Release( lpwh );
TRACE("-- %s (bytes read: %ld)\n", retval ? "TRUE": "FALSE", lpBuffersOut->dwBufferLength);
return retval;
} }
/*********************************************************************** /***********************************************************************
* InternetReadFileExW (WININET.@) * InternetReadFileExW (WININET.@)
* *
* Read data from an open internet file * 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 * RETURNS
* TRUE on success * FALSE, last error is set to ERROR_CALL_NOT_IMPLEMENTED
* FALSE on failure *
* NOTES
* Not implemented in Wine or native either (as of IE6 SP2).
* *
*/ */
BOOL WINAPI InternetReadFileExW(HINTERNET hFile, LPINTERNET_BUFFERSW lpBuffer, BOOL WINAPI InternetReadFileExW(HINTERNET hFile, LPINTERNET_BUFFERSW lpBuffer,
DWORD dwFlags, DWORD dwContext) DWORD dwFlags, DWORD dwContext)
{ {
FIXME("stub\n"); ERR("(%p, %p, 0x%lx, 0x%lx): not implemented in native\n", hFile, lpBuffer, dwFlags, dwContext);
INTERNET_SetLastError(ERROR_CALL_NOT_IMPLEMENTED); INTERNET_SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE; return FALSE;
@ -3183,6 +3283,17 @@ static VOID INTERNET_ExecuteWork(void)
HeapFree(GetProcessHeap(), 0, req->lpszHeaders); HeapFree(GetProcessHeap(), 0, req->lpszHeaders);
} }
break; break;
case INTERNETREADFILEEXA:
{
struct WORKREQ_INTERNETREADFILEEXA *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);
}
break;
} }
WININET_Release( workRequest.hdr ); WININET_Release( workRequest.hdr );
} }

View File

@ -256,6 +256,7 @@ typedef enum
HTTPOPENREQUESTW, HTTPOPENREQUESTW,
SENDCALLBACK, SENDCALLBACK,
INTERNETOPENURLW, INTERNETOPENURLW,
INTERNETREADFILEEXA,
} ASYNC_FUNC; } ASYNC_FUNC;
struct WORKREQ_FTPPUTFILEW struct WORKREQ_FTPPUTFILEW
@ -366,6 +367,11 @@ struct WORKREQ_INTERNETOPENURLW
DWORD dwContext; DWORD dwContext;
}; };
struct WORKREQ_INTERNETREADFILEEXA
{
LPINTERNET_BUFFERSA lpBuffersOut;
};
typedef struct WORKREQ typedef struct WORKREQ
{ {
ASYNC_FUNC asyncall; ASYNC_FUNC asyncall;
@ -387,6 +393,7 @@ typedef struct WORKREQ
struct WORKREQ_HTTPSENDREQUESTW HttpSendRequestW; struct WORKREQ_HTTPSENDREQUESTW HttpSendRequestW;
struct WORKREQ_SENDCALLBACK SendCallback; struct WORKREQ_SENDCALLBACK SendCallback;
struct WORKREQ_INTERNETOPENURLW InternetOpenUrlW; struct WORKREQ_INTERNETOPENURLW InternetOpenUrlW;
struct WORKREQ_INTERNETREADFILEEXA InternetReadFileExA;
} u; } u;
struct WORKREQ *next; struct WORKREQ *next;