|
|
/*++
Copyright (c) 1994 Microsoft Corporation
Module Name:
inetapiw.cxx
Abstract:
Contains the wide-character Internet APIs
Contents: InternetCrackUrlW InternetCreateUrlW InternetCanonicalizeUrlW InternetCombineUrlW InternetOpenW InternetConnectW InternetOpenUrlW InternetReadFileExW InternetWriteFileExW InternetFindNextFileW InternetQueryOptionW InternetSetOptionW InternetGetLastResponseInfoW InternetSetStatusCallbackW
Author:
Richard L Firth (rfirth) 02-Mar-1995
Environment:
Win32(s) user-mode DLL
Revision History:
02-Mar-1995 rfirth Created
--*/
#include <wininetp.h>
// because wininet doesnt know about IStream
#define NO_SHLWAPI_STREAM
#include <shlwapi.h>
#include <shlwapip.h>
extern BOOL TransformFtpFindDataToW(LPWIN32_FIND_DATAA pfdA, LPWIN32_FIND_DATAW pfdW); extern BOOL TransformGopherFindDataToW(LPGOPHER_FIND_DATAA pgfdA, LPGOPHER_FIND_DATAW pgfdW);
// -- FixStrings ------
// Used in InternetCrackUrlW only.
// Either
// (a) If we have an ansi string, AND a unicode buffer, convert from ansi to unicode
// (b) If we have an ansi string, but NO unicode buffer, determine where the ansi string
// occurs in the unicode URL, and point the component there.
VOID FixStrings( LPSTR& pszA, DWORD cbA, LPWSTR& pszW, DWORD& ccW, LPSTR pszUrlA, LPCWSTR pszUrlW) { if (!pszA) return;
if (pszW) { ccW = MultiByteToWideChar(CP_ACP, 0, pszA, cbA+1, pszW, ccW) - 1; } else { pszW = (LPWSTR)(pszUrlW + MultiByteToWideChar(CP_ACP, 0, pszUrlA, (int) (pszA-pszUrlA), NULL, 0)); ccW = MultiByteToWideChar(CP_ACP, 0, pszA, cbA, NULL, 0); } }
//
// functions
//
INTERNETAPI_(BOOL) InternetCrackUrlW( IN LPCWSTR pszUrlW, IN DWORD dwUrlLengthW, IN DWORD dwFlags, IN OUT LPURL_COMPONENTSW pUCW )
/*++
Routine Description:
Cracks an URL into its constituent parts. Optionally escapes the url-path. We assume that the user has supplied large enough buffers for the various URL parts
Arguments:
pszUrl - pointer to URL to crack
dwUrlLength - 0 if pszUrl is ASCIIZ string, else length of pszUrl
dwFlags - flags controlling operation
lpUrlComponents - pointer to URL_COMPONENTS
Return Value:
BOOL Success - TRUE
Failure - FALSE. Call GetLastError() for more info
--*/
{ DEBUG_ENTER_API((DBG_API, Bool, "InternetCrackUrlW", "%wq, %#x, %#x, %#x", pszUrlW, dwUrlLengthW, dwFlags, pUCW ));
INET_ASSERT(pszUrlW); INET_ASSERT(pUCW);
DWORD dwErr = ERROR_SUCCESS; BOOL fResult = FALSE; BOOL fContinue; DWORD c; MEMORYPACKET mpUrlA, mpHostName, mpUserName, mpScheme, mpPassword, mpUrlPath, mpExtraInfo; URL_COMPONENTSA UCA;
if (!(pszUrlW && pUCW)) { dwErr = ERROR_INVALID_PARAMETER; goto cleanup; }
UCA.dwStructSize = sizeof(URL_COMPONENTSA); ALLOC_MB(pszUrlW, dwUrlLengthW, mpUrlA); if (!mpUrlA.psStr) { dwErr = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } UNICODE_TO_ANSI(pszUrlW, mpUrlA);
for (c=0; c<=5; c++) { LPWSTR pszWorker; DWORD ccLen; MEMORYPACKET* pmpWorker; switch(c) { case 0: pszWorker = pUCW->lpszScheme; ccLen = pUCW->dwSchemeLength; pmpWorker = &mpScheme; break;
case 1: pszWorker = pUCW->lpszHostName; ccLen = pUCW->dwHostNameLength; pmpWorker = &mpHostName; break;
case 2: pszWorker = pUCW->lpszUserName; ccLen = pUCW->dwUserNameLength; pmpWorker = &mpUserName; break;
case 3: pszWorker = pUCW->lpszPassword; ccLen = pUCW->dwPasswordLength; pmpWorker = &mpPassword; break;
case 4: pszWorker = pUCW->lpszUrlPath; ccLen = pUCW->dwUrlPathLength; pmpWorker = &mpUrlPath; break;
case 5: pszWorker = pUCW->lpszExtraInfo; ccLen = pUCW->dwExtraInfoLength; pmpWorker = &mpExtraInfo; break; }
if (pszWorker) { ALLOC_MB(pszWorker,ccLen,(*pmpWorker)); if (!pmpWorker->psStr) { dwErr = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } } else { pmpWorker->dwAlloc = ccLen; } };
REASSIGN_ALLOC(mpScheme,UCA.lpszScheme,UCA.dwSchemeLength); REASSIGN_ALLOC(mpHostName, UCA.lpszHostName,UCA.dwHostNameLength); REASSIGN_ALLOC(mpUserName, UCA.lpszUserName,UCA.dwUserNameLength); REASSIGN_ALLOC(mpPassword,UCA.lpszPassword,UCA.dwPasswordLength); REASSIGN_ALLOC(mpUrlPath,UCA.lpszUrlPath,UCA.dwUrlPathLength); REASSIGN_ALLOC(mpExtraInfo,UCA.lpszExtraInfo,UCA.dwExtraInfoLength); fResult = InternetCrackUrlA(mpUrlA.psStr, mpUrlA.dwSize, dwFlags, &UCA); if (fResult) { FixStrings(UCA.lpszScheme, UCA.dwSchemeLength, pUCW->lpszScheme, pUCW->dwSchemeLength, mpUrlA.psStr, pszUrlW); FixStrings(UCA.lpszHostName, UCA.dwHostNameLength, pUCW->lpszHostName, pUCW->dwHostNameLength, mpUrlA.psStr, pszUrlW); FixStrings(UCA.lpszUserName, UCA.dwUserNameLength, pUCW->lpszUserName, pUCW->dwUserNameLength, mpUrlA.psStr, pszUrlW); FixStrings(UCA.lpszPassword, UCA.dwPasswordLength, pUCW->lpszPassword, pUCW->dwPasswordLength, mpUrlA.psStr, pszUrlW); FixStrings(UCA.lpszUrlPath, UCA.dwUrlPathLength, pUCW->lpszUrlPath, pUCW->dwUrlPathLength, mpUrlA.psStr, pszUrlW); FixStrings(UCA.lpszExtraInfo, UCA.dwExtraInfoLength, pUCW->lpszExtraInfo, pUCW->dwExtraInfoLength, mpUrlA.psStr, pszUrlW); pUCW->nScheme = UCA.nScheme; pUCW->nPort = UCA.nPort; pUCW->dwStructSize = sizeof(URL_COMPONENTSW); }
cleanup: if (dwErr!=ERROR_SUCCESS) { SetLastError(dwErr); DEBUG_ERROR(API, dwErr); } DEBUG_LEAVE_API(fResult); return fResult; }
INTERNETAPI_(BOOL) InternetCreateUrlW( IN LPURL_COMPONENTSW pUCW, IN DWORD dwFlags, OUT LPWSTR pszUrlW, IN OUT LPDWORD pdwUrlLengthW )
/*++
Routine Description:
Creates an URL from its constituent parts
Arguments:
Return Value:
BOOL Success - URL written to pszUrl
Failure - call GetLastError() for more info
--*/
{ DEBUG_ENTER_API((DBG_API, Bool, "InternetCreateUrlW", "%#x, %#x, %#x, %#x", pUCW, dwFlags, pszUrlW, pdwUrlLengthW ));
// INET_ASSERT(pszUrlW);
INET_ASSERT(pUCW);
DWORD dwErr = ERROR_SUCCESS; BOOL fResult = FALSE; MEMORYPACKET mpUrlA, mpHostName, mpUserName, mpScheme, mpPassword, mpUrlPath, mpExtraInfo; URL_COMPONENTSA UCA;
if (!pdwUrlLengthW || (pUCW==NULL) || IsBadWritePtr(pUCW, sizeof(*pUCW)) || (pUCW->dwStructSize != sizeof(*pUCW)) || (pszUrlW && IsBadWritePtr(pszUrlW, *pdwUrlLengthW*sizeof(WCHAR)))) { dwErr = ERROR_INVALID_PARAMETER; goto cleanup; } if (pszUrlW) { ALLOC_MB(pszUrlW, *pdwUrlLengthW, mpUrlA); if (!mpUrlA.psStr) { dwErr = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } } mpUrlA.dwSize = mpUrlA.dwAlloc; UCA.dwStructSize = sizeof(URL_COMPONENTSA);
UCA.nScheme = pUCW->nScheme; UCA.nPort = pUCW->nPort; if (pUCW->lpszScheme) { ALLOC_MB(pUCW->lpszScheme, pUCW->dwSchemeLength, mpScheme); if (!mpScheme.psStr) { dwErr = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } UNICODE_TO_ANSI(pUCW->lpszScheme, mpScheme); } REASSIGN_SIZE(mpScheme, UCA.lpszScheme, UCA.dwSchemeLength); if (pUCW->lpszHostName) { ALLOC_MB(pUCW->lpszHostName, pUCW->dwHostNameLength, mpHostName); if (!mpHostName.psStr) { dwErr = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } UNICODE_TO_ANSI(pUCW->lpszHostName, mpHostName); } REASSIGN_SIZE(mpHostName, UCA.lpszHostName, UCA.dwHostNameLength); if (pUCW->lpszUserName) { ALLOC_MB(pUCW->lpszUserName, pUCW->dwUserNameLength, mpUserName); if (!mpUserName.psStr) { dwErr = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } UNICODE_TO_ANSI(pUCW->lpszUserName, mpUserName); } REASSIGN_SIZE(mpUserName, UCA.lpszUserName, UCA.dwUserNameLength); if (pUCW->lpszPassword) { ALLOC_MB(pUCW->lpszPassword, pUCW->dwPasswordLength, mpPassword); if (!mpPassword.psStr) { dwErr = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } UNICODE_TO_ANSI(pUCW->lpszPassword, mpPassword); } REASSIGN_SIZE(mpPassword, UCA.lpszPassword, UCA.dwPasswordLength); if (pUCW->lpszUrlPath) { ALLOC_MB(pUCW->lpszUrlPath, pUCW->dwUrlPathLength, mpUrlPath); if (!mpUrlPath.psStr) { dwErr = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } UNICODE_TO_ANSI(pUCW->lpszUrlPath, mpUrlPath); } REASSIGN_SIZE(mpUrlPath, UCA.lpszUrlPath, UCA.dwUrlPathLength); if (pUCW->lpszExtraInfo) { ALLOC_MB(pUCW->lpszExtraInfo, pUCW->dwExtraInfoLength, mpExtraInfo); if (!mpExtraInfo.psStr) { dwErr = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } UNICODE_TO_ANSI(pUCW->lpszExtraInfo, mpExtraInfo); } REASSIGN_SIZE(mpExtraInfo, UCA.lpszExtraInfo, UCA.dwExtraInfoLength); fResult = InternetCreateUrlA(&UCA, dwFlags, mpUrlA.psStr, &mpUrlA.dwSize); if (fResult) { MAYBE_COPY_ANSI(mpUrlA, pszUrlW, *pdwUrlLengthW); } else { *pdwUrlLengthW = mpUrlA.dwSize*sizeof(WCHAR); }
cleanup: if (dwErr!=ERROR_SUCCESS) { SetLastError(dwErr); DEBUG_ERROR(API, dwErr); }
DEBUG_LEAVE_API(fResult); return fResult; }
// implemented in inetapia.cxx
DWORD ICUHrToWin32Error(HRESULT);
INTERNETAPI_(BOOL) InternetCanonicalizeUrlW( IN LPCWSTR pszUrl, OUT LPWSTR pszBuffer, IN OUT LPDWORD lpdwBufferLength, IN DWORD dwFlags )
/*++
Routine Description:
Combines a relative URL with a base URL to form a new full URL.
Arguments:
pszUrl - pointer to URL to be canonicalize
pszBuffer - pointer to buffer where new URL is written
lpdwBufferLength - size of buffer on entry, length of new URL on exit
dwFlags - flags controlling operation
Return Value:
BOOL - TRUE if successful, FALSE if not
--*/
{ DEBUG_ENTER_API((DBG_API, Bool, "InternetCanonicalizeUrlW", "%wq, %#x, %#x [%d], %#x", pszUrl, pszBuffer, lpdwBufferLength, lpdwBufferLength ? *lpdwBufferLength : 0, dwFlags ));
HRESULT hr ; BOOL bRet;
// We don't need no stinkin asserts
// INET_ASSERT(pszUrl);
// INET_ASSERT(pszBuffer);
// INET_ASSERT(lpdwBufferLength && (*lpdwBufferLength > 0));
//
// the flags for the Url* APIs in shlwapi should be the same
// except that NO_ENCODE is on by default. so we need to flip it
//
dwFlags ^= ICU_NO_ENCODE;
// Check for invalid parameters
if (!pszUrl || !pszBuffer || !lpdwBufferLength || IsBadWritePtr(lpdwBufferLength, sizeof(lpdwBufferLength)) || *lpdwBufferLength == 0 || IsBadWritePtr(pszBuffer, *lpdwBufferLength*sizeof(WCHAR)) || IsBadStringPtrW(pszUrl, INTERNET_MAX_URL_LENGTH)) { hr = E_INVALIDARG; } else { hr = UrlCanonicalizeW(pszUrl, pszBuffer, lpdwBufferLength, dwFlags | URL_WININET_COMPATIBILITY); }
if(FAILED(hr)) { DWORD dw = ICUHrToWin32Error(hr);
bRet = FALSE;
DEBUG_ERROR(INET, dw);
SetLastError(dw); } else bRet = TRUE;
DEBUG_LEAVE_API(bRet); return bRet; }
INTERNETAPI_(BOOL) InternetCombineUrlW( IN LPCWSTR pszBaseUrl, IN LPCWSTR pszRelativeUrl, OUT LPWSTR pszBuffer, IN OUT LPDWORD lpdwBufferLength, IN DWORD dwFlags )
/*++
Routine Description:
Combines a relative URL with a base URL to form a new full URL.
Arguments:
pszBaseUrl - pointer to base URL
pszRelativeUrl - pointer to relative URL
pszBuffer - pointer to buffer where new URL is written
lpdwBufferLength - size of buffer on entry, length of new URL on exit
dwFlags - flags controlling operation
Return Value:
BOOL - TRUE if successful, FALSE if not
--*/ { DEBUG_ENTER_API((DBG_API, Bool, "InternetCombineUrlW", "%wq, %wq, %#x, %#x [%d], %#x", pszBaseUrl, pszRelativeUrl, pszBuffer, lpdwBufferLength, lpdwBufferLength ? *lpdwBufferLength : 0, dwFlags ));
HRESULT hr ; BOOL bRet;
// We don't need no stinkin' asserts
// INET_ASSERT(pszBaseUrl);
// INET_ASSERT(pszRelativeUrl);
// INET_ASSERT(lpdwBufferLength);
//
// the flags for the Url* APIs in shlwapi should be the same
// except that NO_ENCODE is on by default. so we need to flip it
//
dwFlags ^= ICU_NO_ENCODE;
// Check for invalid parameters
if (!pszBaseUrl || !pszRelativeUrl || !lpdwBufferLength || IsBadWritePtr(lpdwBufferLength, sizeof(*lpdwBufferLength)) || (pszBuffer && IsBadWritePtr(pszBuffer, *lpdwBufferLength*sizeof(WCHAR))) || IsBadStringPtrW(pszBaseUrl, INTERNET_MAX_URL_LENGTH) || IsBadStringPtrW(pszRelativeUrl, INTERNET_MAX_URL_LENGTH)) { hr = E_INVALIDARG; } else { hr = UrlCombineW(pszBaseUrl, pszRelativeUrl, pszBuffer, lpdwBufferLength, dwFlags | URL_WININET_COMPATIBILITY); }
if(FAILED(hr)) { DWORD dw = ICUHrToWin32Error(hr);
bRet = FALSE;
DEBUG_ERROR(INET, dw);
SetLastError(dw); } else bRet = TRUE;
DEBUG_LEAVE_API(bRet); return bRet; }
INTERNETAPI_(HINTERNET) InternetOpenW( IN LPCWSTR pszAgentW, IN DWORD dwAccessType, IN LPCWSTR pszProxyW OPTIONAL, IN LPCWSTR pszProxyBypassW OPTIONAL, IN DWORD dwFlags )
/*++
Routine Description:
description-of-function.
Arguments:
pszAgent -
dwAccessType -
pszProxy -
pszProxyBypass -
dwFlags -
Return Value:
HINTERNET
--*/
{ DEBUG_ENTER_API((DBG_API, Handle, "InternetOpenW", "%wq, %s (%d), %wq, %wq, %#x", pszAgentW, InternetMapOpenType(dwAccessType), dwAccessType, pszProxyW, pszProxyBypassW, dwFlags ));
DWORD dwErr = ERROR_SUCCESS; HINTERNET hInternet = NULL; MEMORYPACKET mpAgentA, mpProxyA, mpProxyBypassA;
ALLOC_MB(pszAgentW,0,mpAgentA); if (!mpAgentA.psStr) { dwErr = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } UNICODE_TO_ANSI(pszAgentW,mpAgentA); if (pszProxyW) { ALLOC_MB(pszProxyW,0,mpProxyA); if (!mpProxyA.psStr) { dwErr = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } UNICODE_TO_ANSI(pszProxyW,mpProxyA); } if (pszProxyBypassW) { ALLOC_MB(pszProxyBypassW,0,mpProxyBypassA); if (!mpProxyBypassA.psStr) { dwErr = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } UNICODE_TO_ANSI(pszProxyBypassW,mpProxyBypassA); }
hInternet = InternetOpenA(mpAgentA.psStr, dwAccessType, mpProxyA.psStr, mpProxyBypassA.psStr, dwFlags);
cleanup: if (dwErr!=ERROR_SUCCESS) { SetLastError(dwErr); DEBUG_ERROR(API, dwErr); }
DEBUG_LEAVE_API(hInternet); return hInternet; }
INTERNETAPI_(HINTERNET) InternetConnectW( IN HINTERNET hInternetSession, IN LPCWSTR pszServerNameW, IN INTERNET_PORT nServerPort, IN LPCWSTR pszUserNameW, IN LPCWSTR pszPasswordW, IN DWORD dwService, IN DWORD dwFlags, IN DWORD_PTR dwContext )
/*++
Routine Description:
description-of-function.
Arguments:
hInternetSession - pszServerName - nServerPort - pszUserName - pszPassword - dwService - dwFlags - dwContext -
Return Value:
HINTERNET
--*/
{ DEBUG_ENTER_API((DBG_API, Handle, "InternetConnectW", "%#x, %wq, %d, %wq, %wq, %s (%d), %#08x, %#x", hInternetSession, pszServerNameW, nServerPort, pszUserNameW, pszPasswordW, InternetMapService(dwService), dwService, dwFlags, dwContext ));
DWORD dwErr = ERROR_SUCCESS; MEMORYPACKET mpServerNameA, mpUserNameA, mpPasswordA; HINTERNET hInternet = NULL;
if (!pszServerNameW) { dwErr = ERROR_INVALID_PARAMETER; goto cleanup; } ALLOC_MB(pszServerNameW, 0, mpServerNameA); if (!mpServerNameA.psStr) { dwErr = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } UNICODE_TO_ANSI(pszServerNameW, mpServerNameA); if (pszUserNameW) { ALLOC_MB(pszUserNameW, 0, mpUserNameA); if (!mpUserNameA.psStr) { dwErr = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } UNICODE_TO_ANSI(pszUserNameW, mpUserNameA); } if (pszPasswordW) { ALLOC_MB(pszPasswordW, 0, mpPasswordA); if (!mpPasswordA.psStr) { dwErr = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } UNICODE_TO_ANSI(pszPasswordW, mpPasswordA); } hInternet = InternetConnectA(hInternetSession, mpServerNameA.psStr, nServerPort, mpUserNameA.psStr, mpPasswordA.psStr, dwService, dwFlags, dwContext);
cleanup: if (dwErr!=ERROR_SUCCESS) { SetLastError(dwErr); DEBUG_ERROR(API, dwErr); }
DEBUG_LEAVE_API(hInternet); return hInternet; }
INTERNETAPI_(HINTERNET) InternetOpenUrlW( IN HINTERNET hInternetSession, IN LPCWSTR pszUrlW, IN LPCWSTR pszHeadersW, IN DWORD dwHeadersLengthW, IN DWORD dwFlags, IN DWORD_PTR dwContext )
/*++
Routine Description:
description-of-function.
Arguments:
hInternetSession - pszUrl - pszHeaders - dwHeadersLength - dwFlags - dwContext -
Return Value:
HINTERNET
--*/
{ DEBUG_ENTER_API((DBG_API, Handle, "InternetOpenUrlW", "%#x, %wq, %.80wq, %d, %#08x, %#x", hInternetSession, pszUrlW, pszHeadersW, dwHeadersLengthW, dwFlags, dwContext ));
DWORD dwErr = ERROR_SUCCESS; MEMORYPACKET mpHeadersA, mpUrlA; HINTERNET hInternet = NULL; if (!pszUrlW || (*pszUrlW==L'\0')) { dwErr = ERROR_INVALID_PARAMETER; goto cleanup; } ALLOC_MB(pszUrlW, 0, mpUrlA); if (!mpUrlA.psStr) { dwErr = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } UNICODE_TO_ANSI(pszUrlW, mpUrlA); if (pszHeadersW) { ALLOC_MB(pszHeadersW, (dwHeadersLengthW==-1L? 0 : dwHeadersLengthW), mpHeadersA); if (!mpHeadersA.psStr) { dwErr = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } UNICODE_TO_ANSI(pszHeadersW, mpHeadersA); } hInternet = InternetOpenUrlA(hInternetSession, mpUrlA.psStr, mpHeadersA.psStr, mpHeadersA.dwSize, dwFlags, dwContext);
cleanup: if (dwErr!=ERROR_SUCCESS) { SetLastError(dwErr); DEBUG_ERROR(API, dwErr); }
DEBUG_LEAVE_API(hInternet); return hInternet; }
INTERNETAPI_(BOOL) InternetReadFileExW( IN HINTERNET hFile, OUT LPINTERNET_BUFFERSW lpBuffersOut, IN DWORD dwFlags, IN DWORD_PTR dwContext ) { SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return FALSE; }
INTERNETAPI_(BOOL) InternetWriteFileExW( IN HINTERNET hFile, IN LPINTERNET_BUFFERSW lpBuffersIn, IN DWORD dwFlags, IN DWORD_PTR dwContext ) { SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return FALSE; }
INTERNETAPI_(BOOL) InternetFindNextFileW( IN HINTERNET hFind, OUT LPVOID lpvFindData )
/*++
Routine Description:
This function retrieves the next block of data from the server. Currently it supports the following protocol data :
FtpFindNextFile GopherFindNext
Arguments:
hFind - handle that was obtained by a FindFirst call
lpvFindData - pointer to buffer where the next block of data is copied
Return Value:
TRUE if the function successfully returns next block of data. FALSE otherwise. GetLastError() will return the error code.
--*/
{ DEBUG_ENTER_API((DBG_API, Bool, "InternetFindNextFileW", "%#x, %#x", hFind, lpvFindData ));
DWORD dwErr = ERROR_SUCCESS; HINTERNET hFindMapped; HINTERNET_HANDLE_TYPE handleType; BOOL fResult = FALSE; dwErr = MapHandleToAddress(hFind, (LPVOID *)&hFindMapped, FALSE); if (dwErr!=ERROR_SUCCESS) { goto cleanup; } dwErr = RGetHandleType(hFindMapped, &handleType); DereferenceObject(hFindMapped); if (dwErr!=ERROR_SUCCESS) { goto cleanup; } if ((handleType != TypeFtpFindHandle) && (handleType != TypeGopherFindHandle)) { dwErr = ERROR_INTERNET_INVALID_OPERATION; goto cleanup; }
if (handleType == TypeFtpFindHandle) { WIN32_FIND_DATAA fdA; dwErr = ProbeWriteBuffer(lpvFindData, sizeof(WIN32_FIND_DATAW)); if (dwErr!=ERROR_SUCCESS) { goto cleanup; } if (InternetFindNextFileA(hFind,(LPVOID)&fdA)) fResult = TransformFtpFindDataToW(&fdA,(LPWIN32_FIND_DATAW)lpvFindData); } else { GOPHER_FIND_DATAA gfdA; dwErr = ProbeWriteBuffer(lpvFindData, sizeof(GOPHER_FIND_DATAW)); if (dwErr!=ERROR_SUCCESS) { goto cleanup; } if (InternetFindNextFileA(hFind,(LPVOID)&gfdA)) fResult = TransformGopherFindDataToW(&gfdA,(LPGOPHER_FIND_DATAW)lpvFindData); }
cleanup: if (dwErr!=ERROR_SUCCESS) { SetLastError(dwErr); DEBUG_ERROR(API, dwErr); } DEBUG_LEAVE_API(fResult); return fResult; }
INTERNETAPI_(BOOL) InternetGetLastResponseInfoW( OUT LPDWORD lpdwErrorCategory, IN LPWSTR pszBufferW, IN OUT LPDWORD lpdwBufferLengthW )
/*++
Routine Description:
description-of-function.
Arguments:
lpdwErrorCategory - pszBuffer - lpdwBufferLength -
Return Value:
BOOL
--*/
{ DEBUG_ENTER_API((DBG_API, Bool, "InternetGetLastResponseInfoW", "%#x, %ws, %#x [%d]", lpdwErrorCategory, pszBufferW, lpdwBufferLengthW, lpdwBufferLengthW ? *lpdwBufferLengthW : 0 ));
DWORD dwErr = ERROR_SUCCESS; BOOL fResult = FALSE; MEMORYPACKET mpBufferA;
if (pszBufferW) { ALLOC_MB(pszBufferW,*lpdwBufferLengthW,mpBufferA); if (!mpBufferA.psStr) { dwErr = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } } mpBufferA.dwSize = mpBufferA.dwAlloc; fResult = InternetGetLastResponseInfoA(lpdwErrorCategory, mpBufferA.psStr, &mpBufferA.dwSize); if (fResult) { MAYBE_COPY_ANSI(mpBufferA, pszBufferW, *lpdwBufferLengthW); } else { *lpdwBufferLengthW = mpBufferA.dwSize*sizeof(WCHAR); }
cleanup: if (dwErr!=ERROR_SUCCESS) { SetLastError(dwErr); DEBUG_ERROR(API, dwErr); }
DEBUG_LEAVE_API(fResult); return fResult; }
INTERNETAPI_(BOOL) InternetCheckConnectionW( IN LPCWSTR pszUrlW, IN DWORD dwFlags, IN DWORD dwReserved )
/*++
Routine Description:
This routine tells the caller whether he can establish a connection to the network.
Arguments:
pszUrl this parameter is an indication to the API to attempt a specific host. The use of this parameter is based on the flags set in the dwFlags parameter
dwFlags a bitwise OR of the following flags
INTERNET_FLAG_ICC_FORCE_CONNECTION - force a connection if cannot find one already established
INTERNET_FLAG_ICC_CONNECT_SPECIFIC_HOST - try the connection to the specific host. If this flag is not set then the host name is used if a quicker method is not avilable.
dwReserved reserved
Return Value:
TRUE - Success FALSE - failure, GetLastError returns the error code
--*/ { DEBUG_ENTER_API((DBG_API, Bool, "InternetCheckConnectionW", "%ws %x", pszUrlW, dwFlags ));
DWORD dwErr = ERROR_SUCCESS; MEMORYPACKET mpUrlA; BOOL fResult = FALSE; if (pszUrlW) { ALLOC_MB(pszUrlW,0,mpUrlA); if (!mpUrlA.psStr) { dwErr = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } UNICODE_TO_ANSI(pszUrlW,mpUrlA); } fResult = InternetCheckConnectionA(mpUrlA.psStr, dwFlags, dwReserved);
cleanup: if (dwErr!=ERROR_SUCCESS) { SetLastError(dwErr); DEBUG_ERROR(API, dwErr); }
DEBUG_LEAVE_API(fResult); return fResult; }
INTERNETAPI_(INTERNET_STATUS_CALLBACK) InternetSetStatusCallbackCore( IN HINTERNET hInternet, IN INTERNET_STATUS_CALLBACK lpfnInternetCallback, IN BOOL fType );
INTERNETAPI_(INTERNET_STATUS_CALLBACK) InternetSetStatusCallbackW( IN HINTERNET hInternet, IN INTERNET_STATUS_CALLBACK lpfnInternetCallback )
/*++
Routine Description:
Sets the status callback function for the DLL or the handle object
Arguments:
hInternet - handle of the object for which we wish to set the status callback
lpfnInternetCallback - pointer to caller-supplied status function
Return Value:
FARPROC Success - previous status callback function address
Failure - INTERNET_INVALID_STATUS_CALLBACK. Call GetLastErrorInfo() for more information:
ERROR_INVALID_PARAMETER The callback function is invalid
ERROR_INTERNET_INCORRECT_HANDLE_TYPE Cannot set the callback on the supplied handle (probably a NULL handle - per-process callbacks no longer supported)
--*/
{ DEBUG_ENTER((DBG_INET, Pointer, "InternetSetStatusCallbackW", "%#x, %#x", hInternet, lpfnInternetCallback ));
INTERNET_STATUS_CALLBACK pfn = InternetSetStatusCallbackCore(hInternet,lpfnInternetCallback,TRUE);
DEBUG_LEAVE(pfn); return pfn; }
#ifdef IGCURLW
INTERNETAPI_(BOOL) InternetGetCertByURLW( IN LPWSTR lpszURL, IN OUT LPWSTR lpszCertText, OUT DWORD dwcbCertText ) { SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return FALSE; return InternetGetCertByURLA(lpszURL,lpszCertText,dwcbCertText); }
#endif
INTERNETAPI_(BOOL) InternetShowSecurityInfoByURLW( IN LPWSTR pszUrlW, IN HWND hwndRootWindow ) /*++
Routine Description:
Does a high-level lookup against the Certificate Cache. Searches by URL (broken down into hostname) for the Certificate, and returns it in a formatted (&localized) string.
Arguments:
lpszUrl - pointer to URL to crack
lpszCertText - Output of formatted certifcate
dwcbCertText - Size of lpszCertText
Return Value:
BOOL Success - TRUE
Failure - FALSE. Call GetLastError() for more info
--*/
{ DEBUG_ENTER_API((DBG_INET, Bool, "InternetShowSecurityInfoW", "%wq, %#x", pszUrlW, hwndRootWindow ));
BOOL fResult = FALSE; DWORD dwErr = ERROR_SUCCESS; MEMORYPACKET mpUrlA; if (pszUrlW) { ALLOC_MB(pszUrlW,0,mpUrlA); if (!mpUrlA.psStr) { dwErr = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } UNICODE_TO_ANSI(pszUrlW,mpUrlA); } fResult = InternetShowSecurityInfoByURLA(mpUrlA.psStr, hwndRootWindow);
cleanup: if (dwErr!=ERROR_SUCCESS) { SetLastError(dwErr); DEBUG_ERROR(API, dwErr); } DEBUG_LEAVE_API(fResult); return fResult; }
INTERNETAPI_(BOOL) InternetAlgIdToStringW( IN ALG_ID ai, IN LPWSTR lpstr, IN OUT LPDWORD lpdwstrLength, IN DWORD dwReserved /* Must be 0 */ ) /*++
Routine Description:
Converts a algid to a user-displayable string.
Arguments: ai - Algorithm identifiers ( defined in wincrypt.h)
lpstr - Buffer to copy string into.
lpdwstrLength - pass in num of characters, return no of characters copied if successful, else no of chars required (including null terminator) dwReserved = Must be 0
Return Value: DWORD Win32 or WININET error code. --*/ { DEBUG_ENTER_API((DBG_API, Bool, "InternetAlgIdToStringW", "%#x, %wq, %#x, %#x", ai, lpstr, lpdwstrLength, dwReserved ));
DWORD dwErr = ERROR_SUCCESS; MEMORYPACKET mpBuffer; BOOL fResult = FALSE;
if (dwReserved!=0) { dwErr = ERROR_INVALID_PARAMETER; goto cleanup; } if (lpstr) { mpBuffer.dwAlloc = mpBuffer.dwSize = *lpdwstrLength; mpBuffer.psStr = (LPSTR)ALLOC_BYTES(mpBuffer.dwAlloc*sizeof(CHAR));
if (!mpBuffer.psStr) { dwErr = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } }
if (InternetAlgIdToStringA(ai, (LPSTR)mpBuffer.psStr, &mpBuffer.dwSize, dwReserved)) { *lpdwstrLength = MultiByteToWideChar(CP_ACP, 0, mpBuffer.psStr, mpBuffer.dwSize + 1, NULL, 0); if (*lpdwstrLength*sizeof(WCHAR) <= mpBuffer.dwAlloc && lpstr) { MultiByteToWideChar(CP_ACP, 0, mpBuffer.psStr, mpBuffer.dwSize + 1, lpstr, *lpdwstrLength); (*lpdwstrLength)--; fResult = TRUE; } else { dwErr = ERROR_INSUFFICIENT_BUFFER; } } else { dwErr = GetLastError();
if (dwErr == ERROR_INSUFFICIENT_BUFFER) { *lpdwstrLength = mpBuffer.dwSize * sizeof(WCHAR); } }
cleanup: if (dwErr!=ERROR_SUCCESS) { SetLastError(dwErr); DEBUG_ERROR(API, dwErr); } DEBUG_LEAVE_API(fResult); return fResult; }
INTERNETAPI_(BOOL) InternetSecurityProtocolToStringW( IN DWORD dwProtocol, IN LPWSTR lpstr, IN OUT LPDWORD lpdwstrLength, IN DWORD dwReserved /* Must be 0 */ ) /*++
Routine Description:
Converts a security protocol to a user-displayable string.
Arguments: dwProtocol - Security protocol identifier ( defined in wincrypt.h)
lpstr - Buffer to copy string into.
lpdwstrLength - pass in num of characters, return no of characters copied if successful, else no of chars required (including null terminator) dwReserved = Must be 0
Return Value: DWORD Win32 or WININET error code. --*/ { DEBUG_ENTER_API((DBG_API, Bool, "InternetSecurityProtocolToStringW", "%d, %wq, %#x, %#x", dwProtocol, lpstr, lpdwstrLength, dwReserved ));
DWORD dwErr = ERROR_SUCCESS; MEMORYPACKET mpBuffer; BOOL fResult = FALSE;
if (dwReserved!=0) { dwErr = ERROR_INVALID_PARAMETER; goto cleanup; } if (lpstr) { mpBuffer.dwAlloc = mpBuffer.dwSize = *lpdwstrLength; mpBuffer.psStr = (LPSTR)ALLOC_BYTES(mpBuffer.dwAlloc*sizeof(CHAR)); if (!mpBuffer.psStr) { dwErr = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } }
if (InternetSecurityProtocolToStringA(dwProtocol, (LPSTR)mpBuffer.psStr, &mpBuffer.dwSize, dwReserved)) { *lpdwstrLength = MultiByteToWideChar(CP_ACP, 0, mpBuffer.psStr, mpBuffer.dwSize + 1, NULL, 0); if (*lpdwstrLength*sizeof(WCHAR) <= mpBuffer.dwAlloc && lpstr) { MultiByteToWideChar(CP_ACP, 0, mpBuffer.psStr, mpBuffer.dwSize + 1, lpstr, *lpdwstrLength); (*lpdwstrLength)--; fResult = TRUE; } else { dwErr = ERROR_INSUFFICIENT_BUFFER; } } else { dwErr = GetLastError();
if (dwErr == ERROR_INSUFFICIENT_BUFFER) { *lpdwstrLength = mpBuffer.dwSize * sizeof(WCHAR); } }
cleanup: if (dwErr!=ERROR_SUCCESS) { SetLastError(dwErr); DEBUG_ERROR(API, dwErr); } DEBUG_LEAVE_API(fResult); return fResult; }
|