// // Microsoft Corporation - Copyright 1997 // // // RESPONSE.CPP - Contains possible responses // #include "pch.h" // Globals const char g_cszTableHeader[] = "%s \ \ \ \ \ "; const char g_cszTableEnd[] = "
Variable NameValue
"; // List of known server variables LPSTR g_lpServerVars[] = { "AUTH_TYPE", "CONTENT_LENGTH", "CONTENT_TYPE", "GATEWAY_INTERFACE", "LOGON_USER", "PATH_INFO", "PATH_TRANSLATED", "QUERY_STRING", "REMOTE_ADDR", "REMOTE_HOST", "REQUEST_METHOD", "SCRIPT_MAP", "SCRIPT_NAME", "SERVER_NAME", "SERVER_PORT", "SERVER_PORT_SECURE", "SERVER_SOFTWARE", "URL" }; #define FROMHEX( _v ) \ ( ( _v >= 48 ) && ( _v <= 57 ) ? _v - 48 : \ ( ( _v >= 65 ) && ( _v <= 70 ) ? _v + 10 - 65 : 0 ) ) // // What: UnCanonicalize // // Desc: Un-escapes strings // BOOL UnCanonicalize( LPSTR lpszStart, LPSTR lpszUnURL , LPDWORD lpdwSize ) { LPSTR lps = lpszStart; DWORD cb = 0; while (( *lps ) && ( cb < *lpdwSize )) { if ( *lps == '%' ) { lps++; lpszUnURL[ cb ] = 16 * FROMHEX( *lps); lps++; lpszUnURL[ cb ] += FROMHEX( *lps); } else if ( *lps == '+' ) { lpszUnURL[ cb ] = 32; } else { lpszUnURL[ cb ] = *lps; } cb++; lps++; } lpszUnURL[ cb ] = 0; // paranoid *lpdwSize = cb; return TRUE; } // UnCanonicalize( ) // // What: DumpFormDataFromPost // // Desc: Dumps the fields and values in a form from a POST. // BOOL DumpFormDataFromPost( LPECB lpEcb ) { BOOL fReturn = TRUE; DWORD dwSize; static char szUnparsed[] = "The unparsed Form submit string is: "; static char szUnFont[] = ""; TraceMsg( TF_FUNC | TF_RESPONSE, "DumpFormDataFromPost()" ); if ( fReturn ) { // header and the beginning of the table CHAR szBuffer[ 512 ]; dwSize = wsprintf( szBuffer, g_cszTableHeader, "

Form Data (METHOD=POST)

", "TBLPOST" ); fReturn = WriteClient( lpEcb->ConnID, szBuffer, &dwSize, HSE_IO_ASYNC ); } if ( fReturn ) { int i = 0; LPSTR lpszStart = (LPSTR) lpEcb->lpbData; while (( fReturn ) && ( lpszStart )) { CHAR cTmpEnd; LPSTR lpszEquals = StrChr( lpszStart, '=' ); if ( !lpszEquals ) break; // no more data LPSTR lpszEnd = StrChr( lpszEquals, '&' ); if ( lpszEnd ) { cTmpEnd = *lpszEnd; // save *lpszEnd = 0; } CHAR cTmp = *lpszEquals; // save *lpszEquals = 0; CHAR szBuffer[ 4096 ]; CHAR szUnURL[ 2048 ]; dwSize = sizeof( szUnURL ); fReturn = UnCanonicalize( lpszEquals + 1, szUnURL, &dwSize ); if ( fReturn ) { dwSize = wsprintf( szBuffer, "%s%s", i, i, lpszStart, lpszStart, szUnURL ); fReturn = WriteClient( lpEcb->ConnID, szBuffer, &dwSize, HSE_IO_ASYNC ); } *lpszEquals = cTmp; // restore if ( lpszEnd ) { *lpszEnd = cTmpEnd; // restore lpszEnd++; } lpszStart = lpszEnd; i++; } } // end of the table if ( fReturn ) { dwSize = 1 + lstrlen( g_cszTableEnd ); fReturn = WriteClient( lpEcb->ConnID, (LPVOID) g_cszTableEnd, &dwSize, HSE_IO_ASYNC ); } // display unparsed information if ( fReturn ) { dwSize = 1 + lstrlen( szUnparsed ); fReturn = WriteClient( lpEcb->ConnID, szUnparsed, &dwSize, HSE_IO_ASYNC ); } if ( fReturn ) { dwSize = 1 + lstrlen( (LPSTR) lpEcb->lpbData ); fReturn = WriteClient( lpEcb->ConnID, lpEcb->lpbData, &dwSize, HSE_IO_ASYNC ); } // end FONT tag if ( fReturn ) { dwSize = 1 + lstrlen( szUnFont ); fReturn = WriteClient( lpEcb->ConnID, szUnFont, &dwSize, HSE_IO_ASYNC ); } TraceMsg( TF_FUNC | TF_RESPONSE, "DumpFormDataFromPost() Exit = %s", BOOLTOSTRING( fReturn ) ); return fReturn; } // DumpFormDataFromPost( ) // // What: DumpQueryStringDataFromGet // // Desc: Dumps the fields and values in a form from a GET. // BOOL DumpQueryStringDataFromGet( LPECB lpEcb ) { BOOL fReturn = TRUE; LPSTR lpszBuffer; DWORD dwSize; static char szUnparsed[] = "The unparsed QueryString is: "; static char szUnFont[] = ""; TraceMsg( TF_FUNC | TF_RESPONSE, "DumpQueryStringDataFromGet()" ); if ( fReturn ) fReturn = GetServerVarString( lpEcb, "QUERY_STRING", &lpszBuffer, NULL ); if ( fReturn ) { // header and the beginning of the table CHAR szBuffer[ 512 ]; dwSize = wsprintf( szBuffer, g_cszTableHeader, "

QueryString Data(METHOD=GET)

", "TBLGET" ); fReturn = WriteClient( lpEcb->ConnID, szBuffer, &dwSize, HSE_IO_ASYNC ); } if ( fReturn ) { int i = 0; LPSTR lpszStart = lpszBuffer; while (( fReturn ) && ( lpszStart )) { CHAR cTmpEnd; LPSTR lpszEquals = StrChr( lpszStart, '=' ); LPSTR lpszEnd = StrChr( lpszEquals, '&' ); if ( lpszEnd ) { cTmpEnd = *lpszEnd; // save *lpszEnd = 0; } CHAR cTmp = *lpszEquals; // save *lpszEquals = 0; CHAR szBuffer[ 4096 ]; CHAR szUnURL[ 2048 ]; dwSize = sizeof( szUnURL ); fReturn = UnCanonicalize( lpszEquals + 1, szUnURL, &dwSize ); if ( fReturn ) { dwSize = wsprintf( szBuffer, "%s%s", i, i, lpszStart, lpszStart, szUnURL ); fReturn = WriteClient( lpEcb->ConnID, szBuffer, &dwSize, HSE_IO_ASYNC ); } *lpszEquals = cTmp; // restore if ( lpszEnd ) { *lpszEnd = cTmpEnd; // restore lpszEnd++; } lpszStart = lpszEnd; i++; } } // end the table if ( fReturn ) { dwSize = 1 + lstrlen( g_cszTableEnd ); fReturn = WriteClient( lpEcb->ConnID, (LPVOID) g_cszTableEnd, &dwSize, HSE_IO_ASYNC ); } // display unparsed information if ( fReturn ) { dwSize = 1 + lstrlen( szUnparsed ); fReturn = WriteClient( lpEcb->ConnID, szUnparsed, &dwSize, HSE_IO_ASYNC ); } if ( fReturn ) { dwSize = 1 + lstrlen( lpszBuffer ); fReturn = WriteClient( lpEcb->ConnID, lpszBuffer, &dwSize, HSE_IO_ASYNC ); } // end font tag if ( fReturn ) { dwSize = 1 + lstrlen( szUnFont ); fReturn = WriteClient( lpEcb->ConnID, szUnFont, &dwSize, HSE_IO_ASYNC ); } // clean up if ( lpszBuffer ) GlobalFree( lpszBuffer ); TraceMsg( TF_FUNC | TF_RESPONSE, "DumpQueryStringDataFromGet() Exit = %s", BOOLTOSTRING( fReturn ) ); return fReturn; } // DumpQueryStringDataFromGet( ) // // What: DumpServerVariables // // Desc: Dumps the current server variable settings from the result of // a form submission. // BOOL DumpServerVariables( LPECB lpEcb ) { BOOL fReturn = TRUE; LPSTR lpszBuffer; DWORD dwSize; int i = 0; // counter TraceMsg( TF_FUNC | TF_RESPONSE, "DumpServerVariables()" ); if ( fReturn ) { // header and the begging of the table CHAR szBuffer[ 512 ]; dwSize = wsprintf( szBuffer, g_cszTableHeader, "

Server Variables

", "TBLSERVERVARS" ); fReturn = WriteClient( lpEcb->ConnID, szBuffer, &dwSize, HSE_IO_ASYNC ); } // try the known ones for( ; ( fReturn ) && ( i < ARRAYOF( g_lpServerVars ) ); i++ ) { GetServerVarString( lpEcb, g_lpServerVars[ i ], &lpszBuffer, NULL ); if ( lpszBuffer ) { CHAR szBuffer[ 512 ]; dwSize = wsprintf( szBuffer, "%s%s", i, i, g_lpServerVars[ i ], g_lpServerVars[ i ], lpszBuffer ); fReturn = WriteClient( lpEcb->ConnID, szBuffer, &dwSize, HSE_IO_ASYNC ); } GlobalFree( lpszBuffer ); lpszBuffer = NULL; } // try the HTTP_ALL from header that the server ignores if ( fReturn ) fReturn = GetServerVarString( lpEcb, "ALL_HTTP", &lpszBuffer, NULL ); if (( fReturn ) && ( lpszBuffer )) { LPSTR lpszStart = lpszBuffer; while (( fReturn ) && ( lpszStart )) { char cTmpEnd; LPSTR lpszColon = StrChr( lpszStart, ':' ); LPSTR lpszEnd = StrStr( lpszColon, "HTTP_" ); if ( lpszEnd ) { cTmpEnd = *lpszEnd; // save *lpszEnd = 0; } char cTmp = *lpszColon; // save *lpszColon = 0; CHAR szBuffer[ 4096 ]; dwSize = wsprintf( szBuffer, "%s%s", i, i, lpszStart, lpszStart, lpszColon + 1 ); fReturn = WriteClient( lpEcb->ConnID, szBuffer, &dwSize, HSE_IO_ASYNC ); *lpszColon = cTmp; // restore if ( lpszEnd ) *lpszEnd = cTmpEnd; // restore lpszStart = lpszEnd; i++; } } // end the table if ( fReturn ) { dwSize = 1 + lstrlen( g_cszTableEnd ); fReturn = WriteClient( lpEcb->ConnID, (LPVOID) g_cszTableEnd, &dwSize, HSE_IO_ASYNC ); } // clean up GlobalFree( lpszBuffer ); lpszBuffer = NULL; TraceMsg( TF_FUNC | TF_RESPONSE, "DumpServerVariables() Exit = %s", BOOLTOSTRING( fReturn ) ); return fReturn; } // ( ) // // What: DumpOutput // // Desc: Generate reponse body page after headers and the HTML header // has been. // BOOL DumpOutput( QUERYMETHOD eMethod, LPECB lpEcb, LPSTR lpszOut, LPSTR lpszDebug ) { BOOL fReturn; DWORD dwSize; char szBuffer[ RESPONSE_BUF_SIZE ]; TraceMsg( TF_FUNC | TF_RESPONSE, "DumpOutput()" ); // Display form data switch ( eMethod ) { case METHOD_POST: fReturn = DumpFormDataFromPost( lpEcb ); break; case METHOD_GET: fReturn = DumpQueryStringDataFromGet( lpEcb ); break; case METHOD_POSTTEXTPLAIN: case METHOD_POSTMULTIPART: if ( lpszOut ) { dwSize = 1 + lstrlen( lpszOut ); fReturn = WriteClient( lpEcb->ConnID, lpszOut, &dwSize, HSE_IO_ASYNC ); } break; default: StrCpy( szBuffer, "

???? (METHOD=UNKNOWN)

" ); dwSize = 1 + lstrlen( szBuffer ); fReturn = WriteClient( lpEcb->ConnID, szBuffer, &dwSize, HSE_IO_ASYNC ); } // Dump the server variables if ( fReturn ) fReturn = DumpServerVariables( lpEcb ); // Dump any debugging messages if (( fReturn ) && ( lpszDebug )) { StrCpy( szBuffer, "

Debugging Output

" ); dwSize = 1 + lstrlen( szBuffer ); fReturn = WriteClient( lpEcb->ConnID, szBuffer, &dwSize, HSE_IO_ASYNC ); if ( fReturn ) fReturn = OutputHTMLString( lpEcb, lpszDebug ); } // Dump any server log entries if (( fReturn ) && ( lpEcb->lpszLogData[ 0 ] )) { StrCpy( szBuffer, "

Server Log Entry

" ); dwSize = 1 + lstrlen( szBuffer ); fReturn = WriteClient( lpEcb->ConnID, szBuffer, &dwSize, HSE_IO_ASYNC ); if ( fReturn ) { dwSize = 1 + lstrlen( lpEcb->lpszLogData ); fReturn = WriteClient( lpEcb->ConnID, lpEcb->lpszLogData, &dwSize, HSE_IO_ASYNC ); } } TraceMsg( TF_FUNC | TF_RESPONSE, "DumpOutput() Exit = %s", BOOLTOSTRING( fReturn ) ); return fReturn; } // DumpOutput( ) // // What: SendSuccess // // Desc: Sends client an HTML response for a successful upload. Just a // green screen with "SUCCESS!" in a big header. // // In: lpEcb is the EXTENDED_CONTROL_BLOCK that the server sent us. // BOOL SendSuccess( QUERYMETHOD eMethod, LPECB lpEcb, LPSTR lpszOut, LPSTR lpszDebug, LPBYTE lpbData, DWORD dwParsed, LPDUMPTABLE lpDT ) { BOOL fReturn = TRUE; // assume success CHAR szBuffer[ RESPONSE_BUF_SIZE ]; DWORD dwSize; BOOL fDebug = FALSE; TraceMsg( TF_FUNC | TF_RESPONSE, "SendSuccess( )" ); // Generate on the fly so // fReturn = SendServerHeader( lpEcb ); if ( fReturn ) { StrCpy( szBuffer, "\ \ \ Form Submission Reflector\ \ \ \ Submission Result " ); dwSize = 1 + lstrlen( szBuffer ); fReturn = WriteClient( lpEcb->ConnID, szBuffer, &dwSize, HSE_IO_ASYNC ); } if ( fReturn ) fReturn = CheckForDebug( lpEcb, &fDebug ); if ( fReturn ) { if ( fDebug ) fReturn = DumpOutput( eMethod, lpEcb, lpszOut, lpszDebug ); else fReturn = DumpOutput( eMethod, lpEcb, lpszOut, NULL ); } if (( fReturn ) && ( fDebug )) fReturn = HexDump( lpEcb, lpbData, dwParsed, lpDT ); if ( fReturn ) { StrCpy( szBuffer, "" ); dwSize = 1 + lstrlen( szBuffer ); fReturn = WriteClient( lpEcb->ConnID, szBuffer, &dwSize, HSE_IO_ASYNC ); } TraceMsg( TF_FUNC | TF_RESPONSE, "SendSuccess( ) Exit = %s", BOOLTOSTRING( fReturn ) ); return fReturn; } // SendSuccess( ) // // What: SendFailure // // Desc: Sends client an HTML response for a failed upload. Just a // red screen with "FAILED!" in a big header. // // In: lpEcb is the EXTENDED_CONTROL_BLOCK that the server sent us. // BOOL SendFailure( QUERYMETHOD eMethod, LPECB lpEcb, LPSTR lpszOut, LPSTR lpszDebug, LPBYTE lpbData, DWORD dwParsed, LPDUMPTABLE lpDT ) { BOOL fReturn = TRUE; // assume success CHAR szBuffer[ RESPONSE_BUF_SIZE ]; DWORD dwSize; BOOL fDebug = FALSE; TraceMsg( TF_FUNC | TF_RESPONSE, "SendFailure( )" ); // fReturn = SendServerHeader( lpEcb ); if ( fReturn ) { StrCpy( szBuffer, "\ \ \ Form Submission Reflector\ \ \ \ Submission Result " ); dwSize = 1 + lstrlen( szBuffer ); fReturn = WriteClient( lpEcb->ConnID, szBuffer, &dwSize, HSE_IO_ASYNC ); } if ( fReturn ) fReturn = CheckForDebug( lpEcb, &fDebug ); if ( fReturn ) { if ( fDebug ) fReturn = DumpOutput( eMethod, lpEcb, lpszOut, lpszDebug ); else fReturn = DumpOutput( eMethod, lpEcb, lpszOut, NULL ); } if (( fReturn ) && ( fDebug )) fReturn = HexDump( lpEcb, lpbData, dwParsed, lpDT ); if ( fReturn ) { StrCpy( szBuffer, "" ); dwSize = 1 + lstrlen( szBuffer ); fReturn = WriteClient( lpEcb->ConnID, szBuffer, &dwSize, HSE_IO_ASYNC ); } TraceMsg( TF_FUNC | TF_RESPONSE, "SendFailure( ) Exit = %s", BOOLTOSTRING( fReturn ) ); return fReturn; } // SendSuccess( ) // // What: SendRedirect // // Desc: Redirects to another URL. // // In: lpEcb is the EXTENDED_CONTROL_BLOCK that the server sent us. // BOOL SendRedirect( LPECB lpEcb, LPSTR lpszURL ) { BOOL fReturn = TRUE; // assume success CHAR szBuffer[ RESPONSE_BUF_SIZE ]; DWORD dwSize = 1 + lstrlen( lpszURL ); DWORD dw; TraceMsg( TF_FUNC | TF_RESPONSE, "SendRedirect( )" ); fReturn = ServerSupportFunction( lpEcb->ConnID, HSE_REQ_SEND_URL_REDIRECT_RESP, lpszURL, &dwSize, &dw ); TraceMsg( TF_FUNC | TF_RESPONSE, "SendRedirect( ) Exit = %s", BOOLTOSTRING( fReturn ) ); return fReturn; } // SendSuccess( ) // // What: SendEcho // // Desc: Sends client an echo for everything that it sent to us. // // In: lpEcb is the EXTENDED_CONTROL_BLOCK // BOOL SendEcho( LPECB lpEcb ) { BOOL fReturn = TRUE; // assume success CHAR szBuffer[ RESPONSE_BUF_SIZE ]; DWORD dwSize; LPVOID lpMoreData = NULL; TraceMsg( TF_FUNC | TF_RESPONSE, "SendEcho( )" ); BOOL fDownloadComplete = (lpEcb->cbTotalBytes == lpEcb->cbAvailable ); TraceMsg( TF_RESPONSE, "Does cbTotalBytes(%u) == cbAvailable(%u)? %s", lpEcb->cbTotalBytes, lpEcb->cbAvailable, BOOLTOSTRING( fDownloadComplete ) ); if ( !fDownloadComplete ) { // Get the rest of the data dwSize = lpEcb->cbTotalBytes - lpEcb->cbAvailable; lpMoreData = (LPVOID) GlobalAlloc( GPTR, dwSize ); fReturn = ReadData( lpEcb, lpMoreData, dwSize ); if ( !fReturn ) goto Cleanup; } TraceMsg( TF_RESPONSE, "Total Bytes: %u\n%s", lpEcb->cbAvailable, lpEcb->lpbData ); // Server header info... fReturn = SendServerHeader( lpEcb ); if ( !fReturn ) goto Cleanup; // Create top part of response and send it StrCpy( szBuffer, "
" );
    dwSize = 1 + lstrlen( szBuffer );
    fReturn = WriteClient( lpEcb->ConnID, szBuffer, &dwSize, HSE_IO_ASYNC );
    if ( !fReturn )
        goto Cleanup;

    // and echo it back...
    dwSize = lpEcb->cbAvailable;
    fReturn = WriteClient( lpEcb->ConnID, lpEcb->lpbData, &dwSize, HSE_IO_ASYNC );
    if ( !fReturn )
        goto Cleanup;

    // and anything else that was sent...
    if ( lpMoreData ) 
    {
        dwSize = lpEcb->cbTotalBytes - lpEcb->cbAvailable;
        fReturn = WriteClient( lpEcb->ConnID, lpMoreData, &dwSize, HSE_IO_ASYNC );
        if ( !fReturn )
            goto Cleanup;
    }

    // Create bottom part of response and send it
    StrCpy( szBuffer, "
" ); dwSize = 1 + lstrlen( szBuffer ); fReturn = WriteClient( lpEcb->ConnID, szBuffer, &dwSize, HSE_IO_ASYNC ); if ( !fReturn ) goto Cleanup; Cleanup: if ( lpMoreData ) GlobalFree( lpMoreData ); TraceMsg( TF_FUNC | TF_RESPONSE, "SendEcho( ) Exit = %s", BOOLTOSTRING( fReturn ) ); return fReturn; } // SendEcho( ) // // What: SendServerHeader // // Desc: This sends a complete HTTP server response header including the // status, server version, message time, and MIME version. The ISAPI // application should append other HTTP headers such as the content // type and content length, followed by an extra "\r\n". This function // only takes textual data, up to the first '\0' terminator // // In: lpEcb is the EXTENDED_CONTROL_BLOCK // BOOL SendServerHeader( LPECB lpEcb ) { BOOL fReturn; CHAR szBuffer[ RESPONSE_BUF_SIZE ]; DWORD dwSize, dwParam; TraceMsg( TF_FUNC | TF_RESPONSE, "SendServerHeader( )" ); TraceMsg( TF_RESPONSE, "Sending Pre Header: %s", szBuffer ); dwSize = wsprintf( szBuffer, "200 OK" ); dwParam = 0; fReturn = ServerSupportFunction( lpEcb->ConnID, HSE_REQ_SEND_RESPONSE_HEADER, szBuffer, &dwSize, &dwParam ); if ( !fReturn ) goto Cleanup; TraceMsg( TF_RESPONSE, "Sending Post Header: %s", szBuffer ); dwSize = wsprintf( szBuffer, "Content-Type: text/html\r\n" ); fReturn = WriteClient( lpEcb->ConnID, szBuffer, &dwSize, HSE_IO_ASYNC ); if ( !fReturn ) goto Cleanup; Cleanup: TraceMsg( TF_FUNC | TF_RESPONSE, "SendServerHeader( ) Exit = %s", BOOLTOSTRING( fReturn ) ); return fReturn; } // SendServerHeader( ) // // What: OutputHTMLString // // Desc: Outputs HTML to client. Simply changes '\n's to
s. // // In: lpEcb is the EXTENDED_CONTROL_BLOCK // lpszOut string to translate to HTML. // BOOL OutputHTMLString( LPECB lpEcb, LPSTR lpszOut ) { BOOL fReturn = TRUE; LPSTR lpstr; DWORD dwSize; TraceMsg( TF_FUNC | TF_RESPONSE, "OutputHTMLString()" ); if( *lpszOut ) { lpstr = lpszOut; while (( *lpstr ) && ( fReturn)) { lpszOut = lpstr; lpstr++; while (( *lpstr ) && ( *lpstr != '\n' )) lpstr++; CHAR cTmp = *lpstr; // save *lpstr = 0; dwSize = 1 + lstrlen( lpszOut ); fReturn = WriteClient( lpEcb->ConnID, lpszOut, &dwSize, HSE_IO_ASYNC ); *lpstr = cTmp; // restore if ( fReturn ) { dwSize = 4; fReturn = WriteClient( lpEcb->ConnID, "
", &dwSize, HSE_IO_ASYNC ); } } } TraceMsg( TF_FUNC | TF_RESPONSE, "OutputHTMLString() Exit = %s", BOOLTOSTRING( fReturn ) ); return fReturn; } // OutputHTMLString( ) // // What: HexDump // // Desc: Dumps a HEX dump to the client using HTML. (16-byte rows) // // In: lpEcb is the EXTENDED_CONTROL_BLOCK // lpbData is the data to be dumped // dwLength is the length of the dump. // lpDT is DUMPTABLE which contains information about what the // parser found while parsing. The end of the DT is indicated // by a NULL lpAddr. // // Return: Return a pointer to the formatted output buffer. // BOOL HexDump( LPECB lpEcb, LPBYTE lpbData, DWORD dwLength, LPDUMPTABLE lpDT ) { BOOL fReturn; DWORD cb = 0; // number of bytes processed DWORD cbDT = 0; // number of DTs processed DWORD cbComment = 0; // number of DT comments processed LPBYTE lpb = lpbData; // current data byte to be processed DWORD dwColor = 0x000000; // color to output text in LPBYTE lpbStartLine = lpb; // keeps track of where this line begins // for the string dump BOOL fKeepGoing = TRUE; // exit flag CHAR szBuffer[ 4096 ]; // output buffer CHAR szString[ 512 ]; // "String Dump" output buffer DWORD cbBuf, cbStr; // helper count bytes for buffers // Output Dump Header cbBuf = wsprintf( szBuffer, "\

Parser Commented Request Dump

\ \ \ " ); fReturn = WriteClient( lpEcb->ConnID, szBuffer, &cbBuf, HSE_IO_ASYNC ); while (( fReturn ) && ( fKeepGoing )) { if ( cb == 0 ) { // beginning of every row.... if (( cbDT ) && ( ( lpDT[ cbDT ].lpAddr - lpb ) > 64 )) { // eliminates "big" body data (like binary files) cbBuf = wsprintf( szBuffer, "" ); // jump to one row before the next DT point lpb = (LPBYTE) ( ( ( (DWORD) lpDT[ cbDT ].lpAddr / 16 ) - 1 ) * 16 ); } else { cbBuf = 0; } // Output 0xXXXXXXXX (NNNNNN): and change the color cbBuf += wsprintf( &szBuffer[ cbBuf ], "", szString ); // skip NULL comments while (( lpDT[ cbComment ].lpAddr ) && ( !lpDT[ cbComment ].lpszComment )) cbComment++; // don't allow comments to get ahead of the bits if (( lpDT[ cbComment ].lpAddr ) && ( cbComment < cbDT )) { cbBuf += wsprintf( &szBuffer[ cbBuf ], "", lpDT[ cbComment ].dwColor, lpDT[ cbComment ].lpszComment ); cbComment++; } else { cbBuf += wsprintf( &szBuffer[ cbBuf ], "" ); } fReturn = WriteClient( lpEcb->ConnID, szBuffer, &cbBuf, HSE_IO_ASYNC ); cb = 0; lpbStartLine = lpb; if ( lpb >= lpbData + dwLength ) fKeepGoing = FALSE; } } // end the table if ( fReturn ) { cbBuf = wsprintf( szBuffer, "
OffsetHex DumpString DumpComments
Skipping......
0x%-8.8x (%-6.6u):", lpb - lpbData, lpb - lpbData, dwColor ); // starting color on "String Dump" cbStr = wsprintf( szString, "", dwColor ); } if ( lpb < lpbData + dwLength ) { // middle of every row... // color change if needed while (( lpDT[ cbDT ].lpAddr ) && ( lpb >= lpDT[ cbDT ].lpAddr )) { dwColor = lpDT[ cbDT ].dwColor; cbBuf += wsprintf( &szBuffer[ cbBuf ], "", dwColor ); cbStr += wsprintf( &szString[ cbStr ], "", dwColor ); cbDT++; } // output hex number cbBuf += wsprintf( &szBuffer[ cbBuf ], "%-2.2x ", *lpb ); // output "String Dump" character cbStr += wsprintf( &szString[ cbStr ], "%c", ( ( *lpb < 32 || *lpb == 127 ) ? '.' : ( ( *lpb == 32 ) ? '_' : *lpb ) ) ); lpb++; } cb++; // always count even if there is no more data if ( cb == 16 ) { // end of every row... // terminate FONT tags and append "String Dump" cbStr += wsprintf( &szString[ cbStr ], "" ); cbBuf += wsprintf( &szBuffer[ cbBuf ], "%s%s

" ); fReturn = WriteClient( lpEcb->ConnID, szBuffer, &cbBuf, HSE_IO_ASYNC ); } return fReturn; } // HexDump( )