Figure 1   WININETSPY.CPP


//==========================================
// Matt Pietrek
// Microsoft Systems Journal, September 1997
// FILE: WININETSPY.CPP
//==========================================
#include <windows.h>
#include <stdio.h>

#pragma warning( disable:4005 )         // Ignore macro redefinition

#define SPYMACRO( x ) FARPROC g_pfn##x;
#include "wininet_functions.inc"

HANDLE g_hOutputFile = INVALID_HANDLE_VALUE;

#define SPYCALL( pfn, cArgs )           \
    __asm lea   edi, [esp - cArgs*4]    \
    __asm lea   esi, [ebp+8]            \
    __asm mov   ecx, cArgs              \
    __asm rep   movsd                   \
    __asm sub   esp, cArgs * 4          \
    __asm call  dword ptr [pfn]         \
    __asm mov   [retValue], EAX 

//=============================================================================
// Start of custom code
//=============================================================================
BOOL WINAPI DllMain(
    HINSTANCE hinstDLL,    // handle to DLL module 
    DWORD fdwReason,       // reason for calling function 
    LPVOID lpvReserved)    // reserved 
{
    if ( fdwReason == DLL_PROCESS_ATTACH )  // When initializing....
    {
        // We don't need thread notifications for what we're doing.  Thus, get
        // rid of them, thereby eliminating some of the overhead of this DLL,
        // which will end up in nearly every GUI process anyhow.
        DisableThreadLibraryCalls( hinstDLL );

        char szRealWININET[ MAX_PATH ];
        
        GetSystemDirectory( szRealWININET, sizeof(szRealWININET) );
        strcat( szRealWININET, "\\WININET.DLL" );
        
        HMODULE hModWininet = LoadLibrary( szRealWININET );
        if ( 0 == hModWininet )
        {
            MessageBox( 0, "Unable to load real WININET.DLL", 0, MB_OK );
            return FALSE;
        }

        //
        // Call GetProcAddress for each WININET function, and store the return
        // value into the appropriately named g_pfnXXX pointer
        //      
        #define SPYMACRO( x )  \
            g_pfn##x = GetProcAddress( hModWininet, #x );
        #include "wininet_functions.inc"

        // Open the output file.  Lines with "//" comments include replacement
        // parameters that can be used if you want to write output to a file,
        // rather than to a mailslot.
        g_hOutputFile = CreateFile(
                "\\\\.\\mailslot\\wininetspymon_mailslot", // "WININETSPY.TXT", 
                GENERIC_WRITE,
                FILE_SHARE_READ, // 0,
                0, 
                OPEN_EXISTING,  // CREATE_ALWAYS,
                FILE_ATTRIBUTE_NORMAL,
                0 );

        if ( INVALID_HANDLE_VALUE == g_hOutputFile )
        {
            MessageBox( 0, "Unable to open logging output file", 0, MB_OK );
            return FALSE;
        }
    }
    else if ( fdwReason == DLL_PROCESS_DETACH ) // When shutting down...
    {
        if ( INVALID_HANDLE_VALUE != g_hOutputFile )
            CloseHandle( g_hOutputFile );
    }   
    return TRUE;
}

//
// Our own, custom printf that writes to the file handle opened in DllMain
//
int __cdecl printf(const char * format, ...)
{
    char szBuff[1024];
    int retValue;
    DWORD cbWritten;
    va_list argptr;
          
    if ( INVALID_HANDLE_VALUE == g_hOutputFile )
        return 0;
                
    va_start( argptr, format );
    retValue = wvsprintf( szBuff, format, argptr );
    va_end( argptr );

    WriteFile(  g_hOutputFile, szBuff, retValue, &cbWritten, 0 );

    return retValue;
}

//=============================================================================
// Start of WININET API stubs
//=============================================================================

#define _WINX32_        // Fake the compiler into thinking it's compiling the
                        // real WININET.DLL
#include <wininet.h>    // Include this to get all the definitions

#define SAFESTR( x ) ( x ? x : "" ) // Macro that converts null pointers to ""

extern "C"              // begin - extern "C"
{

INTERNETAPI BOOL WINAPI InternetCanonicalizeUrlA(
    IN LPCSTR lpszUrl,
    OUT LPSTR lpszBuffer,
    IN OUT LPDWORD lpdwBufferLength,
    IN DWORD dwFlags )
{
    BOOL retValue;
    
    SPYCALL( g_pfnInternetCanonicalizeUrlA, 4 )

    printf( "InternetCanonicalizeUrlA( In:\"%s\"  Out:\"%s\" )",
            lpszUrl, lpszBuffer );
        
    return retValue;
}
    
INTERNETAPI BOOL WINAPI InternetCombineUrlA(
    IN LPCSTR lpszBaseUrl,
    IN LPCSTR lpszRelativeUrl,
    OUT LPSTR lpszBuffer,
    IN OUT LPDWORD lpdwBufferLength,
    IN DWORD dwFlags )
{
    BOOL retValue;

    SPYCALL( g_pfnInternetCombineUrlA, 5 )

    printf( "InternetCombineUrlA( Base:\"%s\"  Relative:\"%s\"  Out:\"%s\"",
            SAFESTR(lpszBaseUrl), SAFESTR(lpszRelativeUrl),
            SAFESTR(lpszBuffer) );
        
    return retValue;
}
    
INTERNETAPI BOOL WINAPI InternetCrackUrlA(
    IN LPCSTR lpszUrl,
    IN DWORD dwUrlLength,
    IN DWORD dwFlags,
    IN OUT LPURL_COMPONENTSA lpUrlComponents )
{
    BOOL retValue;

    SPYCALL( g_pfnInternetCrackUrlA, 4 )

    printf( "InternetCrackUrlA( Url:\"%s\" )", SAFESTR(lpszUrl) );
        
    return retValue;
}
    
INTERNETAPI BOOL WINAPI InternetTimeFromSystemTime(
    IN  CONST SYSTEMTIME *pst,  // input GMT time
    IN  DWORD dwRFC,            // RFC format
    OUT LPSTR lpszTime,         // output string buffer
    IN  DWORD cbTime )          // output buffer size 
{
    BOOL retValue;

    SPYCALL( g_pfnInternetTimeFromSystemTime, 4 )

    printf( "InternetTimeFromSystemTime" );
        
    return retValue;
}
    
INTERNETAPI HINTERNET WINAPI InternetOpenUrlA(
    IN HINTERNET hInternet,
    IN LPCSTR lpszUrl,
    IN LPCSTR lpszHeaders OPTIONAL,
    IN DWORD dwHeadersLength,
    IN DWORD dwFlags,
    IN DWORD dwContext )
{
    HINTERNET retValue;

    SPYCALL( g_pfnInternetOpenUrlA, 6 )

    printf( "InternetOpenUrlA( Url:\"%s\" Headers:\"%s\")",
            SAFESTR(lpszUrl), SAFESTR(lpszHeaders) );
        
    return retValue;
}
    
INTERNETAPI BOOL WINAPI HttpSendRequestA(
    IN HINTERNET hRequest,
    IN LPCSTR lpszHeaders OPTIONAL,
    IN DWORD dwHeadersLength,
    IN LPVOID lpOptional OPTIONAL,
    IN DWORD dwOptionalLength )
{
    BOOL retValue;

    SPYCALL( g_pfnHttpSendRequestA,  5)

    printf( "HttpSendRequestA( header:\"%s\" )", SAFESTR(lpszHeaders) );
        
    return retValue;
}
    
INTERNETAPI HINTERNET WINAPI HttpOpenRequestA(
    IN HINTERNET hConnect,
    IN LPCSTR lpszVerb,
    IN LPCSTR lpszObjectName,
    IN LPCSTR lpszVersion,
    IN LPCSTR lpszReferrer OPTIONAL,
    IN LPCSTR FAR * lplpszAcceptTypes OPTIONAL,
    IN DWORD dwFlags,
    IN DWORD dwContext )
{
    HINTERNET retValue;

    SPYCALL( g_pfnHttpOpenRequestA, 8 )

    printf( "HttpOpenRequestA( verb:\"%s\"  object:\"%s\"  version:\"%s\""
            "  referrer:\"%s\"  flags:%X )",
            SAFESTR(lpszVerb), SAFESTR(lpszObjectName), SAFESTR( lpszVersion),
            SAFESTR(lpszReferrer), dwFlags  );

    if ( lplpszAcceptTypes )
    {
        while ( *lplpszAcceptTypes )
        {
            printf( "  AcceptType: %s", SAFESTR(*lplpszAcceptTypes) );
            lplpszAcceptTypes++;
        }
    }
    
    return retValue;
}
    
INTERNETAPI BOOL WINAPI HttpQueryInfoA(
    IN HINTERNET hRequest,
    IN DWORD dwInfoLevel,
    IN OUT LPVOID lpBuffer OPTIONAL,
    IN OUT LPDWORD lpdwBufferLength,
    IN OUT LPDWORD lpdwIndex OPTIONAL )
{
    BOOL retValue;

    SPYCALL( g_pfnHttpQueryInfoA,  5)

    printf( "HttpQueryInfoA" );
        
    return retValue;
}
    
URLCACHEAPI BOOL WINAPI UnlockUrlCacheEntryFile(
    IN LPCSTR lpszUrlName,
    IN DWORD dwReserved )
{
    BOOL retValue;

    SPYCALL( g_pfnUnlockUrlCacheEntryFile, 2 )

    printf( "UnlockUrlCacheEntryFile" );
        
    return retValue;
}

URLCACHEAPI BOOL WINAPI CreateUrlCacheEntryA(
    IN LPCSTR lpszUrlName,
    IN DWORD dwExpectedFileSize,
    IN LPCSTR lpszFileExtension,
    OUT LPSTR lpszFileName,
    IN DWORD dwReserved )
{
    BOOL retValue;

    SPYCALL( g_pfnCreateUrlCacheEntryA, 5 )

    printf( "CreateUrlCacheEntryA( Url:\"%s\"  Filename:\"%s\")",
            SAFESTR(lpszUrlName), SAFESTR(lpszFileName) );
            
    return retValue;
}

INTERNETAPI BOOL WINAPI InternetUnlockRequestFile(
    IN HINTERNET hFile )
{
    BOOL retValue;

    SPYCALL( g_pfnInternetUnlockRequestFile, 1 )

    printf( "InternetUnlockRequestFile" );
        
    return retValue;
}

URLCACHEAPI BOOL WINAPI RetrieveUrlCacheEntryFileA(
    IN LPCSTR  lpszUrlName,
    OUT LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntryInfo,
    IN OUT LPDWORD lpdwCacheEntryInfoBufferSize,
    IN DWORD dwReserved )
{
    BOOL retValue;

    SPYCALL( g_pfnRetrieveUrlCacheEntryFileA, 4 )

    printf( "RetrieveUrlCacheEntryFileA( Url:\"%s\" )", SAFESTR(lpszUrlName) );
        
    return retValue;
}

INTERNETAPI BOOL WINAPI InternetLockRequestFile(
    IN HINTERNET hFile,
    IN DWORD unknown )
{
    BOOL retValue;

    SPYCALL( g_pfnInternetLockRequestFile, 2 )

    printf( "InternetLockRequestFile" );
        
    return retValue;
}


URLCACHEAPI BOOL WINAPI GetUrlCacheEntryInfoA(
    IN LPCSTR lpszUrlName,
    OUT LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntryInfo,
    IN OUT LPDWORD lpdwCacheEntryInfoBufferSize )
{
    BOOL retValue;

    SPYCALL( g_pfnGetUrlCacheEntryInfoA,  3)

    printf( "GetUrlCacheEntryInfoA( Url:\"%s\" ) ", SAFESTR(lpszUrlName) );
        
    return retValue;
}
    
INTERNETAPI DWORD WINAPI InternetErrorDlg(
     IN HWND hWnd,
     IN OUT HINTERNET hRequest,
     IN DWORD dwError,
     IN DWORD dwFlags,
     IN OUT LPVOID * lppvData )
{
    DWORD retValue;

    SPYCALL( g_pfnInternetErrorDlg, 5 )

    printf( "InternetErrorDlg" );
        
    return retValue;
}
     
INTERNETAPI BOOL WINAPI InternetQueryDataAvailable(
    IN HINTERNET hFile,
    OUT LPDWORD lpdwNumberOfBytesAvailable,
    IN DWORD dwFlags,
    IN DWORD dwContext )
{
    BOOL retValue;

    SPYCALL( g_pfnInternetQueryDataAvailable, 4 )

    printf( "InternetQueryDataAvailable" );
        
    return retValue;
}
    
INTERNETAPI BOOL WINAPI InternetCloseHandle(
    IN HINTERNET hInternet )
{
    BOOL retValue;

    SPYCALL( g_pfnInternetCloseHandle, 1 )

    printf( "InternetCloseHandle" );
        
    return retValue;
}
    
INTERNETAPI HINTERNET WINAPI InternetConnectA(
    IN HINTERNET hInternet,
    IN LPCSTR lpszServerName,
    IN INTERNET_PORT nServerPort,
    IN LPCSTR lpszUserName OPTIONAL,
    IN LPCSTR lpszPassword OPTIONAL,
    IN DWORD dwService,
    IN DWORD dwFlags,
    IN DWORD dwContext )
{
    HINTERNET retValue;

    SPYCALL( g_pfnInternetConnectA, 8 )

    printf( "InternetConnectA( Server:\"%s\"  Username:\"%s\"  Password:\"%s\""
            "nServerPort:%X  Service:%X  Flags:%X )",
            SAFESTR( lpszServerName ),
            SAFESTR( lpszUserName ),
            SAFESTR( lpszPassword),
            nServerPort,
            dwService,
            dwFlags );
        
    return retValue;
}
    
INTERNETAPI HINTERNET WINAPI InternetOpenA(
    IN LPCSTR lpszAgent,
    IN DWORD  dwAccessType,
    IN LPCSTR lpszProxy OPTIONAL,
    IN LPCSTR lpszProxyBypass OPTIONAL,
    IN DWORD dwFlags )
{
    HINTERNET retValue;

    SPYCALL( g_pfnInternetOpenA, 5 )

    printf( "InternetOpenA( Agent:\"%s\"  AccessType:%X  Proxy:\"%s\""
            "  Bypass:\"%s\"  Flags:%X)",
            SAFESTR(lpszAgent),
            dwAccessType,
            SAFESTR(lpszProxy),
            SAFESTR(lpszProxyBypass),
            dwFlags );
        
    return retValue;
}
    
INTERNETAPI INTERNET_STATUS_CALLBACK WINAPI InternetSetStatusCallback(
    IN HINTERNET hInternet,
    IN INTERNET_STATUS_CALLBACK lpfnInternetCallback )
{
    INTERNET_STATUS_CALLBACK retValue;

    SPYCALL( g_pfnInternetSetStatusCallback, 2 )

    printf( "InternetSetStatusCallback" );
        
    return retValue;
}
    
INTERNETAPI BOOL WINAPI InternetSetOptionA(
    IN HINTERNET hInternet OPTIONAL,
    IN DWORD dwOption,
    IN LPVOID lpBuffer,
    IN DWORD dwBufferLength )
{
    BOOL retValue;

    SPYCALL( g_pfnInternetSetOptionA, 4 )

    printf( "InternetSetOptionA" );
        
    return retValue;
}
    
INTERNETAPI BOOL WINAPI InternetQueryOptionA(
    IN HINTERNET hInternet OPTIONAL,
    IN DWORD dwOption,
    OUT LPVOID lpBuffer OPTIONAL,
    IN OUT LPDWORD lpdwBufferLength )
{
    BOOL retValue;

    SPYCALL( g_pfnInternetQueryOptionA, 4 )

    printf( "InternetQueryOptionA" );
        
    return retValue;
}
    
INTERNETAPI BOOL WINAPI InternetReadFile(
    IN HINTERNET hFile,
    IN LPVOID lpBuffer,
    IN DWORD dwNumberOfBytesToRead,
    OUT LPDWORD lpdwNumberOfBytesRead )
{
    BOOL retValue;

    SPYCALL( g_pfnInternetReadFile, 4 )

    printf( "InternetReadFile( hFile:%X  dwNumberToRead:%u )",
            hFile, dwNumberOfBytesToRead );
        
    return retValue;
}
    
INTERNETAPI BOOL WINAPI HttpAddRequestHeadersA(
    IN HINTERNET hRequest,
    IN LPCSTR lpszHeaders,
    IN DWORD dwHeadersLength,
    IN DWORD dwModifiers )
{
    BOOL retValue;

    SPYCALL( g_pfnHttpAddRequestHeadersA, 4 )

    printf( "HttpAddRequestHeadersA( Headers:\"%s\" )", SAFESTR(lpszHeaders) );
        
    return retValue;
}

INTERNETAPI DWORD WINAPI InternetConfirmZoneCrossing(
     IN HWND hWnd,
     IN LPSTR szUrlPrev,
     IN LPSTR szUrlNew,
     IN BOOL bPost )
{
    DWORD retValue;

    SPYCALL( g_pfnInternetConfirmZoneCrossing, 4 )

    printf( "InternetConfirmZoneCrossing( Prev:\"%s\"  New:\"%s\") ",
            SAFESTR(szUrlPrev), SAFESTR(szUrlNew) );
    
    return retValue;
}

URLCACHEAPI BOOL WINAPI SetUrlCacheEntryInfoA(
    IN LPCSTR lpszUrlName,
    IN LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntryInfo,
    IN DWORD dwFieldControl )
{
    BOOL retValue;
    
    SPYCALL( g_pfnSetUrlCacheEntryInfoA, 3 );

    printf( "SetUrlCacheEntryInfoA" );
        
    return retValue;
}


INTERNETAPI BOOL WINAPI InternetGetCookieA(
    IN LPCSTR lpszUrl,
    IN LPCSTR lpszCookieName,
    OUT LPSTR lpCookieData,
    IN OUT LPDWORD lpdwSize )
{
    BOOL retValue;

    SPYCALL( g_pfnInternetGetCookieA, 4 )

    printf( "InternetGetCookieA( Url:\"%s\"  Cookie:\"%s\" )",
            SAFESTR(lpszUrl), SAFESTR(lpszCookieName) );
    
    return retValue;
}

INTERNETAPI BOOL WINAPI InternetSetCookieA(
    IN LPCSTR lpszUrl,
    IN LPCSTR lpszCookieName,
    IN LPCSTR lpszCookieData )
{
    BOOL retValue;

    SPYCALL( g_pfnInternetSetCookieA, 3 )

    printf( "InternetSetCookieA( Url:\"%s\"  Cookie:\"%s\" )",
            SAFESTR(lpszUrl), SAFESTR(lpszCookieName) );
    
    return retValue;
}


INTERNETAPI BOOL WINAPI InternetTimeToSystemTime(
    IN  LPCSTR lpszTime,         // NULL terminated string
    OUT SYSTEMTIME *pst,         // output in GMT time
    IN  DWORD dwReserved )
{
    BOOL retValue;

    SPYCALL( g_pfnInternetTimeToSystemTime, 3 )

    printf( "InternetTimeToSystemTime( Time:\"%s\" )", SAFESTR(lpszTime) );
    
    return retValue;
}

URLCACHEAPI BOOL WINAPI CommitUrlCacheEntryA(
    IN LPCSTR lpszUrlName,
    IN LPCSTR lpszLocalFileName,
    IN FILETIME ExpireTime,
    IN FILETIME LastModifiedTime,
    IN DWORD CacheEntryType,
    IN LPBYTE lpHeaderInfo,
    IN DWORD dwHeaderSize,
    IN LPCSTR lpszFileExtension,
    IN DWORD dwReserved )
{
    BOOL retValue;

    // 11 = 7 DWORDS + 2 (8 byte) FILETIMES 
    SPYCALL( g_pfnCommitUrlCacheEntryA, 11 )

    printf( "CommitUrlCacheEntryA( Url:\"%s\" )", SAFESTR(lpszUrlName) );
    
    return retValue;
}

INTERNETAPI BOOL WINAPI InternetCreateUrlA(
    IN LPURL_COMPONENTSA lpUrlComponents,
    IN DWORD dwFlags,
    OUT LPSTR lpszUrl,
    IN OUT LPDWORD lpdwUrlLength )
{
    BOOL retValue;

    SPYCALL( g_pfnInternetCreateUrlA, 4 )

    printf( "InternetCreateUrlA( Url:\"%s\" )", SAFESTR(lpszUrl) );
    
    return retValue;
}

INTERNETAPI BOOL WINAPI GetUrlCacheConfigInfoA(
    IN DWORD unknown1,
    IN DWORD unknown2,
    IN DWORD unknown3 )
{
    BOOL retValue;

    SPYCALL( g_pfnGetUrlCacheConfigInfoA    , 3 )

    printf( "GetUrlCacheConfigInfoA " );
    
    return retValue;
}
    
INTERNETAPI BOOL WINAPI InternetGetCertByURL(
    IN DWORD unknown1,
    IN DWORD unknown2,
    IN DWORD unknown3 )
{
    BOOL retValue;

    SPYCALL( g_pfnInternetGetCertByURL , 3 )

    printf( "InternetGetCertByURL" );
    return retValue;
}

}   // end - extern "C"