📄 internet.c
字号:
/***********************************************************************
* InternetSetStatusCallbackW (WININET.@)
*
* Sets up a callback function which is called as progress is made
* during an operation.
*
* RETURNS
* Previous callback or NULL on success
* INTERNET_INVALID_STATUS_CALLBACK on failure
*
*/
INTERNET_STATUS_CALLBACK WINAPI InternetSetStatusCallbackW(
HINTERNET hInternet ,INTERNET_STATUS_CALLBACK lpfnIntCB)
{
INTERNET_STATUS_CALLBACK retVal;
LPWININETHANDLEHEADER lpwh;
TRACE("0x%08lx\n", (ULONG)hInternet);
lpwh = WININET_GetObject(hInternet);
if (!lpwh)
return INTERNET_INVALID_STATUS_CALLBACK;
lpwh->dwInternalFlags |= INET_CALLBACKW;
retVal = lpwh->lpfnStatusCB;
lpwh->lpfnStatusCB = lpfnIntCB;
WININET_Release( lpwh );
return retVal;
}
/***********************************************************************
* InternetSetFilePointer (WININET.@)
*/
DWORD WINAPI InternetSetFilePointer(HINTERNET hFile, LONG lDistanceToMove,
PVOID pReserved, DWORD dwMoveContext, DWORD dwContext)
{
FIXME("stub\n");
return FALSE;
}
/***********************************************************************
* InternetWriteFile (WININET.@)
*
* Write data to an open internet file
*
* RETURNS
* TRUE on success
* FALSE on failure
*
*/
BOOL WINAPI InternetWriteFile(HINTERNET hFile, LPCVOID lpBuffer ,
DWORD dwNumOfBytesToWrite, LPDWORD lpdwNumOfBytesWritten)
{
BOOL retval = FALSE;
int nSocket = -1;
LPWININETHANDLEHEADER lpwh;
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 %li\n",dwNumOfBytesToWrite);
retval = NETCON_send(&lpwhr->netConnection, lpBuffer,
dwNumOfBytesToWrite, 0, (LPINT)lpdwNumOfBytesWritten);
WININET_Release( lpwh );
return retval;
}
break;
case WH_HFILE:
nSocket = ((LPWININETFILE)lpwh)->nDataSocket;
break;
default:
break;
}
if (nSocket != -1)
{
int res = send(nSocket, lpBuffer, dwNumOfBytesToWrite, 0);
retval = (res >= 0);
*lpdwNumOfBytesWritten = retval ? res : 0;
}
WININET_Release( lpwh );
return retval;
}
static BOOL INTERNET_ReadFile(LPWININETHANDLEHEADER lpwh, LPVOID lpBuffer,
DWORD dwNumOfBytesToRead, LPDWORD pdwNumOfBytesRead,
BOOL bWait, BOOL bSendCompletionStatus)
{
BOOL retval = FALSE;
int nSocket = -1;
/* FIXME: this should use NETCON functions! */
switch (lpwh->htype)
{
case WH_HHTTPREQ:
if (!NETCON_recv(&((LPWININETHTTPREQW)lpwh)->netConnection, lpBuffer,
dwNumOfBytesToRead, bWait ? MSG_WAITALL : 0, (int *)pdwNumOfBytesRead))
{
*pdwNumOfBytesRead = 0;
retval = TRUE; /* Under windows, it seems to return 0 even if nothing was read... */
}
else
retval = TRUE;
break;
case WH_HFILE:
/* FIXME: FTP should use NETCON_ stuff */
nSocket = ((LPWININETFILE)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.@)
*
* 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 );
TRACE("-- %s (bytes read: %ld)\n", retval ? "TRUE": "FALSE", pdwNumOfBytesRead ? *pdwNumOfBytesRead : -1);
return retval;
}
/***********************************************************************
* InternetReadFileExA (WININET.@)
*
* 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
* TRUE on success
* 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 lpBuffersOut,
DWORD dwFlags, DWORD dwContext)
{
BOOL retval = 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.@)
*
* 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).
*
*/
BOOL WINAPI InternetReadFileExW(HINTERNET hFile, LPINTERNET_BUFFERSW lpBuffer,
DWORD dwFlags, DWORD dwContext)
{
ERR("(%p, %p, 0x%lx, 0x%lx): not implemented in native\n", hFile, lpBuffer, dwFlags, dwContext);
INTERNET_SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/***********************************************************************
* INET_QueryOptionHelper (internal)
*/
static BOOL INET_QueryOptionHelper(BOOL bIsUnicode, HINTERNET hInternet, DWORD dwOption,
LPVOID lpBuffer, LPDWORD lpdwBufferLength)
{
LPWININETHANDLEHEADER lpwhh;
BOOL bSuccess = FALSE;
TRACE("(%p, 0x%08lx, %p, %p)\n", hInternet, dwOption, lpBuffer, lpdwBufferLength);
lpwhh = (LPWININETHANDLEHEADER) WININET_GetObject( hInternet );
switch (dwOption)
{
case INTERNET_OPTION_HANDLE_TYPE:
{
ULONG type;
if (!lpwhh)
{
WARN("Invalid hInternet handle\n");
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
type = lpwhh->htype;
TRACE("INTERNET_OPTION_HANDLE_TYPE: %ld\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;
TRACE("INTERNET_OPTION_REQUEST_FLAGS: %ld\n", flags);
if (*lpdwBufferLength < sizeof(ULONG))
INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER);
else
{
memcpy(lpBuffer, &flags, sizeof(ULONG));
bSuccess = TRUE;
}
*lpdwBufferLength = sizeof(ULONG);
break;
}
case INTERNET_OPTION_URL:
case INTERNET_OPTION_DATAFILE_NAME:
{
if (!lpwhh)
{
WARN("Invalid hInternet handle\n");
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (lpwhh->htype == WH_HHTTPREQ)
{
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)
{
sizeRequired = WideCharToMultiByte(CP_ACP,0,url,-1,
lpBuffer,*lpdwBufferLength,NULL,NULL);
if (sizeRequired > *lpdwBufferLength)
INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER);
else
bSuccess = TRUE;
*lpdwBufferLength = sizeRequired;
}
else
{
sizeRequired = (lstrlenW(url)+1) * sizeof(WCHAR);
if (*lpdwBufferLength < sizeRequired)
INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER);
else
{
strcpyW(lpBuffer, url);
bSuccess = TRUE;
}
*lpdwBufferLength = sizeRequired;
}
}
break;
}
case INTERNET_OPTION_HTTP_VERSION:
{
if (*lpdwBufferLength < sizeof(HTTP_VERSION_INFO))
INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER);
else
{
/*
* Presently hardcoded to 1.1
*/
((HTTP_VERSION_INFO*)lpBuffer)->dwMajorVersion = 1;
((HTTP_VERSION_INFO*)lpBuffer)->dwMinorVersion = 1;
bSuccess = TRUE;
}
*lpdwBufferLength = sizeof(HTTP_VERSION_INFO);
break;
}
case INTERNET_OPTION_CONNECTED_STATE:
{
DWORD *pdwConnectedState = (DWORD *)lpBuffer;
FIXME("INTERNET_OPTION_CONNECTED_STATE: semi-stub\n");
if (
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -