Windows2003-3790/inetcore/wininet/dll/inetapiu.cxx
2020-09-30 16:53:55 +02:00

382 lines
9.9 KiB
C++
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
inetapiu.cxx
Abstract:
Contains WinInet API utility & sub-API functions
Contents:
wInternetQueryDataAvailable
Author:
Richard L Firth (rfirth) 16-Feb-1996
Environment:
Win32 user-level
Revision History:
16-Feb-1996 rfirth
Created
--*/
#include <wininetp.h>
#include "inetapiu.h"
DWORD
InbLocalEndCacheWrite(
IN HINTERNET hFtpFile,
IN LPSTR lpszFileExtension,
IN BOOL fNormal
);
DWORD
InbGopherLocalEndCacheWrite(
IN HINTERNET hGopherFile,
IN LPSTR lpszFileExtension,
IN BOOL fNormal
);
//
// functions
//
BOOL
wInternetQueryDataAvailable(
IN LPVOID hFileMapped,
OUT LPDWORD lpdwNumberOfBytesAvailable,
IN DWORD dwFlags,
IN DWORD_PTR dwContext
)
/*++
Routine Description:
Part 2 of InternetQueryDataAvailabe. This function is called by the async
worker thread in order to resume InternetQueryDataAvailable(), and by the
app as the worker part of the API, post validation
We can query available data for handle types that return data, either from
a socket, or from a cache file:
- HTTP request
- FTP file
- FTP find
- FTP find HTML
- gopher file
- gopher find
- gopher find HTML
Arguments:
hFileMapped - the mapped HINTERNET
lpdwNumberOfBytesAvailable - where the number of bytes is returned
dwFlags - flags controlling operation
dwContext - context value for callbacks
Return Value:
DWORD
Success - ERROR_SUCCESS
Failure -
--*/
{
DEBUG_ENTER((DBG_INET,
Bool,
"wInternetQueryDataAvailable",
"%#x, %#x, %#x, %#x",
hFileMapped,
lpdwNumberOfBytesAvailable,
dwFlags,
dwContext
));
LPINTERNET_THREAD_INFO lpThreadInfo = InternetGetThreadInfo();
DWORD error;
HINTERNET_HANDLE_TYPE handleType;
INET_ASSERT(hFileMapped);
//
// as usual, grab the per-thread info block
//
if (lpThreadInfo == NULL) {
INET_ASSERT(FALSE);
error = ERROR_INTERNET_INTERNAL_ERROR;
goto quit;
}
//
// if this is the async worker thread then set the context, handle, and
// last-error info in the per-thread data block before we go any further
// (we already did this on the sync path)
//
if (lpThreadInfo->IsAsyncWorkerThread) {
_InternetSetContext(lpThreadInfo,
((INTERNET_HANDLE_OBJECT *)hFileMapped)->GetContext()
);
_InternetSetObjectHandle(lpThreadInfo,
((HANDLE_OBJECT *)hFileMapped)->GetPseudoHandle(),
hFileMapped
);
_InternetClearLastError(lpThreadInfo);
//
// we should only be here in async mode if there was no data immediately
// available
//
INET_ASSERT(!((INTERNET_HANDLE_OBJECT *)hFileMapped)->IsDataAvailable());
}
//
// get the local handle for FTP & gopher
//
HINTERNET hLocal;
error = RGetLocalHandle(hFileMapped, &hLocal);
if (error != ERROR_SUCCESS) {
goto quit;
}
//
// we copy the number of bytes available to a local variable first, and
// only update the caller's variable if we succeed
//
DWORD bytesAvailable;
//
// get the current data available, based on the handle type
//
switch (handleType = ((HANDLE_OBJECT *)hFileMapped)->GetHandleType()) {
case TypeHttpRequestHandle:
error = ((HTTP_REQUEST_HANDLE_OBJECT *)hFileMapped)
->QueryDataAvailable(&bytesAvailable);
break;
case TypeFtpFileHandle:
case TypeFtpFindHandle:
error = wFtpQueryDataAvailable(hLocal, &bytesAvailable);
break;
case TypeGopherFileHandle:
case TypeGopherFindHandle:
error = wGopherQueryDataAvailable(hLocal, &bytesAvailable);
break;
case TypeFtpFindHandleHtml:
case TypeGopherFindHandleHtml:
error = QueryHtmlDataAvailable(hFileMapped, &bytesAvailable);
if (((INTERNET_CONNECT_HANDLE_OBJECT *)hFileMapped)->
IsCacheWriteInProgress()) {
DWORD errorCache = error;
if ((errorCache == ERROR_SUCCESS) && (bytesAvailable == 0)) {
errorCache = ERROR_NO_MORE_FILES;
}
if (errorCache != ERROR_SUCCESS) {
if (handleType == TypeFtpFindHandleHtml) {
InbLocalEndCacheWrite( hFileMapped,
"htm",
(errorCache == ERROR_NO_MORE_FILES)
);
}
else {
InbGopherLocalEndCacheWrite( hFileMapped,
"htm",
(errorCache == ERROR_NO_MORE_FILES)
);
}
}
}
break;
#ifdef EXTENDED_ERROR_HTML
case TypeFtpFileHandleHtml:
error = QueryHtmlDataAvailable(hFileMapped, &bytesAvailable);
break;
#endif
default:
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
break;
}
quit:
BOOL success;
if (error == ERROR_SUCCESS) {
((INTERNET_HANDLE_OBJECT *)hFileMapped)->SetAvailableDataLength(bytesAvailable);
*lpdwNumberOfBytesAvailable = bytesAvailable;
success = TRUE;
DEBUG_PRINT(INET,
INFO,
("%d bytes available\n",
bytesAvailable
));
DEBUG_PRINT_API(API,
INFO,
("*lpdwNumberOfBytesAvailable (%#x) = %d\n",
lpdwNumberOfBytesAvailable,
bytesAvailable
));
} else {
success = FALSE;
DEBUG_ERROR(INET, error);
}
SetLastError(error);
DEBUG_LEAVE(success);
return success;
}
STDAPI_(BOOL) ForceNexusLookupExW(
IN BOOL fForce,
IN PWSTR pwszRegUrl, // user supplied buffer ...
IN OUT PDWORD pdwRegUrlLen, // ... and length (will be updated to actual length
// on successful return)
IN PWSTR pwszDARealm, // user supplied buffer ...
IN OUT PDWORD pdwDARealmLen // ... and length (will be updated to actual length
// on successful return)
)
{
PP_CONTEXT hPP = 0;
hPP = ::PP_InitContext(L"WinInet.Dll", NULL);
BOOL RetVal = ::PP_ForceNexusLookup (hPP,
fForce,
pwszRegUrl,
pdwRegUrlLen,
pwszDARealm,
pdwDARealmLen );
::PP_FreeContext ( hPP );
return RetVal;
}
STDAPI_(VOID) ForceNexusLookup(void)
{
PP_CONTEXT hPP = 0;
hPP = ::PP_InitContext(L"WinInet.Dll", NULL);
::PP_ForceNexusLookup (hPP,
FALSE, // don't force connection establishment if nexus not reachable
NULL,
0,
NULL,
0 );
::PP_FreeContext ( hPP );
}
BOOL
GetMD5Result(PSTR pszChallengeInfo, PSTR pszPassword, PBYTE pbHexHash);
///////////////
// This routine gets the default passport password and does an MD5 hash of it with
// the supplied ChallengeInfo and returns the result in hex string format.
//
// pwszRealm = realm to get the password for. If NULL, uses default. Ignored if pwszTarget is not null.
//
// pwszTarget = target to get the password for. If NULL, uses realm
//
// pbHexHash = output buffer to receive the MD5 result in hex string format,
// MUST BE AT LEAST MD5DIGESTLEN * 2 + 1 IN SIZE
//
// Returns TRUE if success, FALSE if failure.
//
//
STDAPI_(BOOL) CreateMD5SSOHash (
IN PWSTR pszChallengeInfo,
IN PWSTR pwszRealm,
IN PWSTR pwszTarget,
OUT PBYTE pbHexHash
)
{
PP_CONTEXT hPP = 0;
BOOL bRetVal = FALSE;
hPP = ::PP_InitContext(L"WinInet.Dll", NULL);
if ( hPP )
{
WCHAR pszPassword[INTERNET_MAX_PASSWORD_LENGTH];
// Check for cached creds in the session
if (::PP_GetCachedCredential ( hPP, pwszRealm, pwszTarget, NULL, pszPassword) )
{
DWORD dwChallengeInfoLen = wcslen(pszChallengeInfo) + 1;
PSTR pszChallengeInfoA = (PSTR) LocalAlloc (LPTR, dwChallengeInfoLen );
DWORD dwPasswordLen = wcslen(pszPassword) + 1;
PSTR pszPasswordA = (PSTR) LocalAlloc (LPTR, dwPasswordLen );
if ( pszChallengeInfoA != NULL && pszPasswordA != NULL )
{
// convert to asci
::WideCharToMultiByte(CP_ACP, 0, pszChallengeInfo, -1, pszChallengeInfoA, dwChallengeInfoLen, NULL, NULL);
::WideCharToMultiByte(CP_ACP, 0, pszPassword, -1, pszPasswordA, dwPasswordLen, NULL, NULL);
bRetVal = GetMD5Result ( pszChallengeInfoA, pszPasswordA, pbHexHash );
ZeroMemory ( pszPassword, INTERNET_MAX_PASSWORD_LENGTH * sizeof(WCHAR) );
ZeroMemory ( pszPasswordA, dwPasswordLen );
}
if ( pszChallengeInfoA )
LocalFree ( pszChallengeInfoA );
if ( pszPasswordA )
LocalFree ( pszPasswordA );
}
::PP_FreeContext ( hPP );
}
return bRetVal;
}