CACHE.CPP
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:6k
源码类别:
Windows编程
开发平台:
Visual C++
- // ===========================================================================
- // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
- // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
- // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
- // PARTICULAR PURPOSE.
- //
- // Copyright 1996 Microsoft Corporation. All Rights Reserved.
- // ===========================================================================
- #include <windows.h>
- #include <wininet.h>
- #include "range.h"
- //==============================================================================
- BOOL QueryHeaders
- (
- HANDLE hRequest,
- PHTTP_REQUESTCB_PARAM pCBParam,
- SYSTEMTIME* pstLastModified
- )
- {
- DWORD cbBuf;
- BOOL fRet;
- pCBParam->CallbackType = REQUESTCB_STARTED;
- pCBParam->fdwRequestFlags = HTTP_REQUEST_FROM_CACHE;
- // Get if the server supports ranges from the response headers.
- static char szBytes[] ="bytes";
- char szBuf[sizeof(szBytes)];
- cbBuf = sizeof(szBytes);
- fRet = HttpQueryInfo
- (hRequest, HTTP_QUERY_ACCEPT_RANGES, szBuf, &cbBuf, 0);
- if (fRet && !lstrcmpi (szBuf, szBytes))
- pCBParam->fdwRequestFlags |= HTTP_REQUEST_ACCEPT_RANGES;
- // Get the response code.
- cbBuf = sizeof(pCBParam->dwResponseCode);
- fRet = HttpQueryInfo
- (
- hRequest,
- HTTP_QUERY_FLAG_NUMBER | HTTP_QUERY_STATUS_CODE,
- &pCBParam->dwResponseCode,
- &cbBuf,
- NULL
- );
- if (!fRet)
- pCBParam->dwResponseCode = 0;
- // Get the last modified time from the response headers.
- cbBuf = sizeof(*pstLastModified);
- fRet = HttpQueryInfo
- (
- hRequest,
- HTTP_QUERY_FLAG_SYSTEMTIME | HTTP_QUERY_LAST_MODIFIED,
- pstLastModified,
- &cbBuf,
- NULL
- );
- pCBParam->pstLastModified = fRet? pstLastModified : NULL;
- // Get the content length from the cache file size.
- pCBParam->dwContentLength =
- InternetSetFilePointer (hRequest, NULL, 0, FILE_END, 0);
- return TRUE;
- }
- //==============================================================================
- BOOL HttpReadFromCache (PHTTP_REQUEST_PARAM pParam)
- {
- // Locals that must be initialized before goto done.
- BOOL fSuccess = FALSE;
- HANDLE hInternet = NULL;
- HANDLE hConnect = NULL;
- HANDLE hRequest = NULL;
- PVOID pRead = NULL;
- HRESULT hrRequest = S_OK;
- // Initialize wininet
- hInternet = InternetOpen
- ("RR", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, INTERNET_FLAG_OFFLINE);
- if (!hInternet)
- goto done;
- hRequest = InternetOpenUrl
- (hInternet, pParam->pszUrl, NULL, 0, INTERNET_FLAG_OFFLINE, 0);
- if (!hRequest)
- goto done;
- // Initialize callback parameters.
- HTTP_REQUESTCB_PARAM CBParam;
- CBParam.cbStruct = sizeof(CBParam);
- CBParam.dwRequestCtx = pParam->dwRequestCtx;
- // Allocate read buffer
- DWORD cbRead;
- cbRead = 4096;
- pRead = LocalAlloc (LMEM_FIXED, cbRead);
- if (!pRead)
- {
- SetLastError (ERROR_NOT_ENOUGH_MEMORY);
- goto done;
- }
- SYSTEMTIME st;
- if (!QueryHeaders (hRequest, &CBParam, &st))
- goto done;
- fSuccess = TRUE;
- // Notify the client that request is started.
- if (!(*pParam->pfnRequestCB) (&CBParam))
- goto notify;
- // Set up ranges to read.
- HTTP_REQUEST_RANGE EntireRange;
- PHTTP_REQUEST_RANGE pRanges;
- DWORD cRanges;
- if (pParam->cRanges)
- {
- pRanges = pParam->pRanges;
- cRanges = pParam->cRanges;
- }
- else
- {
- EntireRange.dwOffset = 0;
- EntireRange.dwSize = CBParam.dwContentLength;
- pRanges = &EntireRange;
- cRanges = 1;
- }
- // Loop over the ranges, reading into the buffer.
- CBParam.CallbackType = REQUESTCB_DATA;
- CBParam.lpDataBuffer = pRead;
- while (cRanges--)
- {
- CBParam.dwDataOffset = pRanges->dwOffset;
- DWORD cbRange = pRanges->dwSize;
- if (!cbRange)
- cbRange = InternetSetFilePointer (hRequest, 0, NULL, FILE_END, 0)
- - pRanges->dwOffset;
- while (cbRange) // Loop until we have all the data for the range.
- {
- InternetSetFilePointer
- (hRequest, CBParam.dwDataOffset, NULL, FILE_BEGIN, 0);
- if (!InternetReadFile
- (hRequest, pRead, min(cbRead, cbRange), &CBParam.cbDataLength))
- {
- hrRequest = E_FAIL;
- goto notify;
- }
- // Check for EOF
- if (!CBParam.cbDataLength)
- break;
- // Call the client with data.
- if (!(*pParam->pfnRequestCB) (&CBParam))
- goto notify;
- CBParam.dwDataOffset += CBParam.cbDataLength;
- cbRange -= CBParam.cbDataLength;
- }
- // Advance to next range.
- pRanges++;
- } // end while (cRanges--)
- notify:
- // Notify the client we are done.
- CBParam.CallbackType = REQUESTCB_DONE;
- CBParam.hrRequest = hrRequest;
- (*pParam->pfnRequestCB) (&CBParam);
- done:
- if (pRead)
- LocalFree ((HLOCAL) pRead);
- if (hRequest)
- InternetCloseHandle (hRequest);
- if (hConnect)
- InternetCloseHandle (hConnect);
- if (hInternet)
- InternetCloseHandle (hInternet);
- return fSuccess;
- }
- //==============================================================================
- BOOL HttpReadRequest (PHTTP_REQUEST_PARAM pParam)
- {
- if (pParam->cbStruct != sizeof(HTTP_REQUEST_PARAM))
- {
- SetLastError (ERROR_INVALID_PARAMETER);
- return FALSE;
- }
- if (HttpReadFromCache (pParam))
- return TRUE;
- return HttpReadFromServer (pParam);
- }