⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 internet.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
/***********************************************************************
 *           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 + -