Implement InternetReadFileExA (based on a patch by Brian Gerst).
This commit is contained in:
parent
c02aee8b8f
commit
01e91e5f6c
@ -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 );
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user