Note: This is not the complete source code--just the main source file.
You can download the full source (with include files) from our sample code archive by clicking on the diskette icons.
<% '// Browser Mirror engine '// version 2002-02-16 '// '// Displays information that your browser reveals to servers. '// '// Inputs (form variables): '// none '// '// HexGadgets (components) required: '// none '// '// Other dependencies: '// - VBScript 5.0 or later '// Get the latest at http://msdn.microsoft.com/scripting/ '// '// History: '// 2002-02-16 Created '// '// Copyright 2002 Hexillion Technologies. All rights reserved. '// '// 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 MERCHANTIBILITY AND/OR '// FITNESS FOR A PARTICULAR PURPOSE. const sBrowserMirrorSession = "BrowserMirrorSession" const sBrowserMirrorPersistent = "BrowserMirrorPersistent" const sHexUtilityVars = "HexUtilityVars" const sAspSession = "ASPSESSIONID" class BrowserMirror private m_dtCookie property Get Name() Name = "Browser Mirror" end property property Get Desc() Desc = "See what your browser reveals" end property property Get ViewSourceURL() ViewSourceURL = "http://www.hexillion.com/samples/view_src.asp?name=BrowserMirror.inc.vbs.asp" end property property Get DownloadSourceURL() DownloadSourceURL = "http://www.hexillion.com/samples/#BrowserMirror" end property Private Sub Class_Initialize() '// Get date for designating current cookies m_dtCookie = now() end sub Private Sub Class_Terminate() end sub public function GetHead() '// Returns a string to put between the <head></head> tags '// Build cookie strings dim sSession, sPersist sPersist = "BrowserMirrorPersistent=" & _ server.URLEncode( m_dtCookie ) & _ "; expires=" & FormatGMT( DateAdd( "yyyy", 1, m_dtCookie ) ) & _ "; path=/" sSession = "BrowserMirrorSession=" & _ server.URLEncode( m_dtCookie ) & _ "; path=/" '// Set cookies with meta tags and JavaScript to try to circumvent HTTP header filtering GetHead = "<meta http-equiv=""Set-Cookie"" content=""" & sPersist & """>" & vbcrlf & _ "<meta http-equiv=""Set-Cookie"" content=""" & sSession & """>" & vbcrlf & _ "<SCRIPT LANGUAGE=""JavaScript"" TYPE=""text/javascript""><!--" & vbcrlf & _ " // Intentional obfuscation to evade JavaScript ""sanitizers""" & vbcrlf & _ " var d1 = document;" & vbcrlf & _ " var c1 = 'c' + 'o' + 'o' + 'k' + 'i' + 'e';" & vbcrlf & _ " d1[c1] = '" & sPersist & "';" & vbcrlf & _ " d1[c1] = '" & sSession & "';" & vbcrlf & _ "//--></SCRIPT>" end function private function FormatGMT( dt ) '// Put date into string format appropriate for cookie expiration dates FormatGMT = WeekdayName( Weekday( dt ), true ) & ", " & _ Format00( Day( dt ) ) & "-" & _ MonthName( Month( dt ), true ) & "-" & _ cstr( Year( dt ) ) & " " & _ Format00( Hour( dt ) ) & ":" & _ Format00( Minute( dt ) ) & ":" & _ Format00( Second( dt ) ) & " GMT" end function private function Format00( i ) if i < 10 then Format00 = "0" + cstr( i ) else Format00 = cstr( i ) end if end function Sub WriteForm() '// No input form needed end sub sub WriteOutput() '// Grab incoming test cookies first because setting them in '// the response will change them in the request. (ASP bug?) dim sCookieSession, sCookiePersistent sCookieSession = Request.Cookies( sBrowserMirrorSession ) sCookiePersistent = Request.Cookies( sBrowserMirrorPersistent ) '// Set test cookies before flushing output Response.Cookies( sBrowserMirrorSession ) = m_dtCookie Response.Cookies( sBrowserMirrorSession ).Path = "/" Response.Cookies( sBrowserMirrorPersistent ) = m_dtCookie Response.Cookies( sBrowserMirrorPersistent ).Expires = DateAdd( "yyyy", 1, m_dtCookie ) Response.Cookies( sBrowserMirrorPersistent ).Path = "/" '// Display any output so far Response.Flush ShowConnectionInfo ShowHeaders ShowCookies m_dtCookie, sCookieSession, sCookiePersistent ShowScripting end sub private sub ShowConnectionInfo '// Write heading WriteLn "<h3>Connection</h3>" dim sRequest sRequest = request( "REQUEST_METHOD" ) & " " & request( "URL" ) if "" <> request( "QUERY_STRING" ) then sRequest = sRequest & "?" & request( "QUERY_STRING" ) sRequest = sRequest & " " & request( "SERVER_PROTOCOL" ) dim sCrypto if "on" = request( "HTTPS" ) then sCrypto = request( "HTTPS_KEYSIZE" ) & "-bit session key" else sCrypto = "none" end if dim sDomDoss sDomDoss = "DomainDossier.vbs.asp?dom_whois=1&net_whois=1&dom_dns=1&addr=" & request( "REMOTE_ADDR" ) '// Write connection info WriteLn "<table border=""0"" cellpadding=""5"" cellspacing=""0"">" WriteLn " <tr>" WriteLn " <td valign=""baseline"" align=""right"">client IP address:</td>" WriteLn " <td valign=""baseline"">" WriteLn " <span class=""ipaddr"">" & request( "REMOTE_ADDR" ) & "</span> " WriteLn " <a href=""" & sDomDoss & """>[see what this reveals]</a>" WriteLn " </td>" WriteLn " </tr>" WriteLn " <tr>" WriteLn " <td valign=""baseline"" align=""right"">server port:</td>" WriteLn " <td valign=""baseline""><b>" & request( "SERVER_PORT" ) & "</b></td>" WriteLn " </tr>" WriteLn " <tr>" WriteLn " <td valign=""baseline"" align=""right"">request:</td>" WriteLn " <td valign=""baseline""><b>" & sRequest & "</b></td>" WriteLn " </tr>" WriteLn " <tr>" WriteLn " <td valign=""baseline"" align=""right"">encryption:</td>" WriteLn " <td valign=""baseline""><b>" & sCrypto & "</b></td>" WriteLn " </tr>" if "" <> request( "AUTH_TYPE" ) then WriteLn " <tr>" WriteLn " <td valign=""baseline"" align=""right"">authentication:</td>" WriteLn " <td valign=""baseline""><b>" & request( "AUTH_TYPE" ) & "</b></td>" WriteLn " </tr>" WriteLn " <tr>" WriteLn " <td valign=""baseline"" align=""right"">username:</td>" WriteLn " <td valign=""baseline""><b>" & request( "AUTH_USER" ) & "</b></td>" WriteLn " </tr>" if "basic" = lcase( request( "AUTH_TYPE" ) ) then WriteLn " <tr>" WriteLn " <td valign=""baseline"" align=""right"">password:</td>" WriteLn " <td valign=""baseline""><b>" & request( "AUTH_PASSWORD" ) & "</b></td>" WriteLn " </tr>" end if else WriteLn " <tr>" WriteLn " <td valign=""baseline"" align=""right"">authentication:</td>" WriteLn " <td valign=""baseline""><b>none</b></td>" WriteLn " </tr>" end if WriteLn "</table>" Response.Flush end sub private sub ShowHeaders '// Write heading WriteLn "<h3>HTTP headers</h3>" '// Write HTTP headers WriteLn "<pre>" & server.HTMLEncode( Request.ServerVariables( "ALL_RAW" ) ) & "</pre>" Response.Flush end sub private sub ShowCookies( dtNew, sCookieSession, sCookiePersistent ) '// Write heading WriteLn "<h3>Cookies</h3>" dim sAcceptSession, sAcceptPersist, sSendSession, sSendPersist, sAspSession dim sButton sAcceptSession = "?" sAcceptPersist = "?" sSendSession = "?" sSendPersist = "?" sButton = "complete test" '// If this is a postback... if "" <> Request.Form( "key" ) then dim sDate sDate = Request.Form( "key" ) '// If we got the session cookie we just set... if sDate = sCookieSession then sAcceptSession = "yes" sSendSession = "yes" '// Else if we at least got an old session cookie... elseif 0 <> len( sCookieSession ) then sAcceptSession = "no" sSendSession = "yes" else '// Cookie was neither received nor sent sAcceptSession = "no" sSendSession = "no" end if '// If we got the persistent cookie we just set... if sDate = sCookiePersistent then sAcceptPersist = "yes" sSendPersist = "yes" '// Else if we at least got an old persistent cookie... elseif 0 <> len( sCookiePersistent ) then sAcceptPersist = "no" sSendPersist = "yes" else '// Cookie was neither received nor sent sAcceptPersist = "no" sSendPersist = "no" end if sButton = "test again" end if '// Search for known cookies dim s, aCookies '// Use HTTP_Cookie because we've already set the Response '// cookies and ASP has put them in the Request.Cookies aCookies = split( request( "HTTP_Cookie" ), " " ) for each s in aCookies if left( s, len( sBrowserMirrorSession ) ) = sBrowserMirrorSession then sSendSession = "yes" elseif left( s, len( sBrowserMirrorPersistent ) ) = sBrowserMirrorPersistent then sSendPersist = "yes" elseif left( s, len( sHexUtilityVars ) ) = sHexUtilityVars then sSendSession = "yes" elseif left( s, len( sAspSession ) ) = sAspSession then sSendSession = "yes" end if next WriteLn "<table border=""0"" cellpadding=""5"" cellspacing=""0"">" WriteLn " <tr>" WriteLn " <td valign=""baseline"" align=""right""> </td>" WriteLn " <td valign=""baseline"" align=""center"">accepting</td>" WriteLn " <td valign=""baseline"" align=""center"">sending</td>" WriteLn " </tr>" WriteLn " <tr>" WriteLn " <td valign=""baseline"" align=""right"">session</td>" WriteLn " <td valign=""baseline"" align=""center""><b>" & sAcceptSession & "</b></td>" WriteLn " <td valign=""baseline"" align=""center""><b>" & sSendSession & "</b></td>" WriteLn " </tr>" WriteLn " <tr>" WriteLn " <td valign=""baseline"" align=""right"">persistent</td>" WriteLn " <td valign=""baseline"" align=""center""><b>" & sAcceptPersist & "</b></td>" WriteLn " <td valign=""baseline"" align=""center""><b>" & sSendPersist & "</b></td>" WriteLn " </tr>" WriteLn "</table>" WriteLn "<form name=""cookieform"" method=""POST"" action=""" & request( "SCRIPT_NAME" ) & """>" WriteLn " <input type=""hidden"" name=""key"" value=""" & dtNew & """>" WriteLn " <input id=""cookietest"" type=""submit"" value=""" & sButton & """>" WriteLn "</form>" Response.Flush end sub private sub ShowScripting '// This isn't meant to be an exhaustive list of all that can '// be obtained via client-side scripting. It just samples some '// of the more interesting items. '// Notice the obfuscation. The SafeWeb.com anonymizing service '// (which PrivaSec.com licenses) tries to "sanitize" JavaScript '// instead of stripping it out entirely. It breaks blocks of JS '// that it finds suspicious. The obfuscation tries to circumvent '// the sanitizing, though in some cases it's overkill--the sanitizing '// just doesn't work very well. It's also quite erratic, breaking '// innocent code while letting evil stuff slip right by. '// Observations about the SafeWeb sanitizing: '// '// - Suspicious assignments are flagged with extra semicolons on the end: '// var suspect = 'suspicious';; '// '// - In the vicinity of suspicious code, any function calls get broken '// with extra parentheses: '// document.writeln()('My innocent text'); '// '// - Javascript comments are stripped out everywhere *except* suspicious blocks. '// '// - For all the effort that the SafeWeb people apparently put into the '// sanitizer, they missed a number of obvious security holes. For example, '// Netscape browsers can still reveal the user's true IP address via '// java.net.InetAddress.getLocalHost().getHostAddress(); '// Duh. '// '// - SafeWeb's "paranoid" mode does little more than modify all document.write '// and document.writeln calls to write blanks. This will break a lot of '// innocent code but is easily circumvented. And Netscape will still display '// the true IP address. So much for paranoia. '// '// More about SafeWeb: '// http://www.safeweb.com/ '// http://www.privasec.com/ '// http://www.wired.com/news/politics/0,1283,50371,00.html '// http://www.cs.bu.edu/techreports/pdf/2002-003-deanonymizing-safeweb.pdf %> <h3>Client-side scripting</h3> <script language="JavaScript"><!-- var version = '1.0'; var d = document; var n = navigator; var w = 'w' + 'r' + 'i' + 't' + 'e' + 'l' + 'n'; // SafeWeb's paranoid mode makes *any* VBScript // method called write or writeln shoot blanks, so // we've made this handy little function that // VBScript can call to display its output. function jsdw( s ) { d[w]( s ); } //--></script> <script language="JavaScript1.1"><!-- var version = '1.1'; // Turn off error reporting window.onerror = null; //--></SCRIPT> <script language="JavaScript1.2"><!-- var version = '1.2'; //--></script> <script language="JavaScript1.3"><!-- var version = '1.3'; //--></script> <script language="JavaScript1.4"><!-- var version = '1.4'; //--></script> <script language="JavaScript1.5"><!-- var version = '1.5'; //--></script> <script language="JavaScript1.6"><!-- var version = '1.6'; //--></script> <script language="JavaScript2.0"><!-- var version = '2.0'; //--></script> <table border="0" cellpadding="5" cellspacing="0"> <tr> <td valign="baseline" align="right">JavaScript:</td> <td valign="baseline"> <b> <SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript"><!-- d[w]( 'version ' + version ); //--></SCRIPT> <noscript>disabled/not supported</noscript> </b> </td> </tr> <tr> <td valign="baseline" align="right">VBScript:</td> <td valign="baseline"><b ID="vbs">disabled/not supported</b></td> <SCRIPT LANGUAGE="VBScript" TYPE="text/vbscript"><!-- '// This technique won't work for IE 3. document.all( "vbs" ).firstChild.nodeValue = "version " & ScriptEngineMajorVersion & "." & ScriptEngineMinorVersion & "." & ScriptEngineBuildVersion '--></SCRIPT> </tr> <tr> <td valign="baseline" align="right">Java:</td> <td valign="baseline"> <b> <SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript"><!-- // SafeWeb/PrivaSec is suspicious of this block and breaks it. // By leaving this block in, however, the next block escapes breakage. document.writeln( '' ); //--></SCRIPT> <SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript"><!-- var je = 'j' + 'a' + 'v' + 'a' + 'E' + 'n' + 'a' + 'b' + 'l' + 'e' + 'd'; if( n[je]() ) { d[w]( 'enabled' ); } //--></SCRIPT> <applet height="0" width="0">disabled/not supported</applet> </b> </td> </tr> <SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript"><!-- // Personal profile /* var n = navigator; if( "undefined" != typeof( n['userProfile'] ) ) { var profile = n['userProfile']; profile.clearRequest(); profile.addReadRequest("Vcard.FirstName"); profile.addReadRequest("Vcard.LastName"); profile.addReadRequest("Vcard.Email"); profile.addReadRequest("Vcard.Home.Phone"); profile.doReadRequest(1,"Browser Mirror"); var name = profile.getAttribute("Vcard.FirstName") + ' ' + profile.getAttribute("Vcard.LastName" ); var email = profile.getAttribute("Vcard.Email"); var phone = profile.getAttribute("Vcard.Home.Phone"); if( ' ' != name ) { d[w]( '<tr>' ); d[w]( '<td valign="baseline" align="right">name:</td>' ); d[w]( '<td valign="baseline"><b>' + name + '</b></td>' ); d[w]( '</tr>' ); } if( '' != email ) { d[w]( '<tr>' ); d[w]( '<td valign="baseline" align="right">email:</td>' ); d[w]( '<td valign="baseline"><b>' + email + '</b></td>' ); d[w]( '</tr>' ); } if( '' != phone ) { d[w]( '<tr>' ); d[w]( '<td valign="baseline" align="right">home phone:</td>' ); d[w]( '<td valign="baseline"><b>' + phone + '</b></td>' ); d[w]( '</tr>' ); } } */ //--></SCRIPT> <SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript"><!-- // Try to get IP address if( "undefined" != typeof( java ) ) { var j = java; var IPAddress = j.net.InetAddress.getLocalHost().getHostAddress(); } // Close and reopen script block--a Java exception could kill this block //--></SCRIPT> <SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript"><!-- // IP Address if( IPAddress ) { d[w]( '<tr>' ); d[w]( '<td valign="baseline" align="right">IP address:</td>' ); d[w]( '<td valign="baseline"><span class="ipaddr">' + IPAddress + '</span>' ); d[w]( '<a href="DomainDossier.vbs.asp?dom_whois=1&net_whois=1&dom_dns=1&addr=' + IPAddress + '"> [see what this reveals]</a></td>' ); d[w]( '</tr>' ); } //--></SCRIPT> <SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript"><!-- // Cookies // SafeWeb/PrivaSec and other services aggregate cookies from *all* sites // you visit into one master cookie, which the following will reveal. var c = 'c' + 'o' + 'o' + 'k' + 'i' + 'e'; var gotcha = d[c]; if( gotcha ) { d[w]( '<tr>' ); d[w]( '<td valign="baseline" align="right">cookies:</td>' ); d[w]( '<td valign="baseline"><b>' + gotcha + '</b></td>' ); d[w]( '</tr>' ); } //--></SCRIPT> <SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript"><!-- // Referrer if( d['referrer'] ) { d[w]( '<tr>' ); d[w]( '<td valign="baseline" align="right">referrer:</td>' ); d[w]( '<td valign="baseline"><b>' + d['referrer'] + '</b></td>' ); d[w]( '</tr>' ); } //--></SCRIPT> <SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript"><!-- // Browser var n = navigator; var ua = 'u' + 's' + 'e' + 'r' + 'A' + 'g' + 'e' + 'n' + 't'; var browser = n[ua]; d[w]( '<tr>' ); d[w]( '<td valign="baseline" align="right">browser:</td>' ); d[w]( '<td valign="baseline"><b>' + browser + '</b></td>' ); d[w]( '</tr>' ); //--></SCRIPT> <SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript"><!-- // Plugins - Netscape var pi = 'p' + 'l' + 'u' + 'g' + 'i' + 'n' + 's'; if( "undefined" != typeof( n[pi] ) ) { var ps = n[pi]; if( ps.length > 0 ) { d[w]( '<tr>' ); d[w]( '<td valign="top" align="right">plugins:</td>' ); d[w]( '<td valign="top">' ); d[w]( '<table border="0" cellpadding="5" cellspacing="0">' ); for( var i=0; i<ps.length; i++ ) { d[w]( '<tr>' ); d[w]( '<td valign="baseline"><b>' + ps[i].name + '</b></td>' ); d[w]( '<td valign="baseline"><b>' + ps[i].description + '</b></td>' ); d[w]( '<td valign="baseline"><b>' ); for( var i2=0; i2<ps[i].length; i2++ ) { d[w]( ps[i][i2].type + '<br>' ); } d[w]( '</b></td>' ); d[w]( '<td valign="baseline"><b>' + ps[i].filename + '</b></td>' ); d[w]( '</tr>' ); } d[w]( '</table>' ); d[w]( '</td></tr>' ); } } //--></SCRIPT> <SCRIPT LANGUAGE="VBScript" TYPE="text/vbscript"><!-- '// ActiveX plugins - IE sub Detect( ProgID, Description ) On Error resume next dim o if ScriptEngineMajorVersion() >= 2 then set o = CreateObject( ProgID ) if Err = 0 then jsdw Description & "<br>" end if end sub jsdw "<tr>" jsdw "<td valign=""baseline"" align=""right"">ActiveX:</td>" jsdw "<td valign=""baseline""><b>" Detect "ShockwaveFlash.ShockwaveFlash", "Macromedia Flash Player" Detect "SWCtl.SWCtl", "Macromedia Shockwave Player" Detect "Macromedia.ActiveShockwave.1", "Active Shockwave" Detect "RealPlayer.RealPlayer(tm) ActiveX Control (32-bit)", "RealPlayer" Detect "rmocx.RealPlayer G2 Control", "RealPlayer G2" Detect "IERJCtl.IERJCtl.1", "RealJukebox" Detect "MediaPlayer.MediaPlayer.1", "MediaPlayer" Detect "PDF.PdfCtrl.1", "Adobe Acrobat 1.0 Reader" Detect "PDF.PdfCtrl.2", "Adobe Acrobat 2.0 Reader" Detect "PDF.PdfCtrl.3", "Adobe Acrobat 3.0 Reader" Detect "PDF.PdfCtrl.4", "Adobe Acrobat 4.0 Reader" Detect "PDF.PdfCtrl.5", "Adobe Acrobat 5.0 Reader" Detect "Agent.Control.1", "MS Agent 1.5" Detect "Agent.Control.2", "MS Agent 2.0" Detect "MSComCtl2.Animation", "MS Animation" Detect "DirectAnimation.DirectAnimationIntegratedMediaControl.1", "MS DirectAnimation" Detect "MSVRML2C.VRMLBrowserCtl.1", "MS VRML 2.0 Viewer" jsdw "</b></td>" jsdw "</tr>" '--></SCRIPT> <SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript"><!-- // SafeWeb/PrivaSec is suspicious of this block and breaks it. // By leaving this block in, however, the next block escapes breakage. document.writeln( '' ); //--></SCRIPT> <SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript"><!-- // Clipboard var ec = 'e' + 'x' + 'e' + 'c' + 'C' + 'o' + 'm' + 'm' + 'a' + 'n' + 'd'; var pste = 'p' + 'a' + 's' + 't' + 'e'; var ctr = 'c' + 'r' + 'e' + 'a' + 't' + 'e' + 'T' + 'e' + 'x' + 't' + 'R' + 'a' + 'n' + 'g' + 'e'; if( "undefined" != typeof( d[ec] ) ) { d[w]( '<tr>' ); d[w]( '<td valign="top" align="right">clipboard:</td>' ); d[w]( '<td><form name="clipform">' ); d[w]( '<textarea id="cliptext" rows="5" cols="50"></textarea>' ); d[w]( '</form></td>' ); d[w]( '</tr>' ); d['clipform']['cliptext']['focus'](); d['clipform']['cliptext'][ctr]()[ec]( pste ); window['scroll']( 0, 0 ); } //--></SCRIPT> <SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript"><!-- // Local time d[w]( '<tr>' ); d[w]( '<td valign="baseline" align="right">local time:</td>' ); d[w]( '<td valign="baseline"><b>' + (new Date()) + '</b></td>' ); d[w]( '</tr>' ); //--></SCRIPT> <SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript"><!-- // Screen dimensions if( "undefined" != typeof( screen ) ) { d[w]( '<tr>' ); d[w]( '<td valign="baseline" align="right">screen:</td>' ); d[w]( '<td valign="baseline"><b>' + screen.width + 'x' + screen.height + ' ' + screen.colorDepth + ' bits/pixel</b></td>' ); d[w]( '</tr>' ); } //--></SCRIPT> <SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript"><!-- // Browser window dimensions if( "undefined" != typeof( window.screenX ) && "undefined" != typeof( window.screenY ) && "undefined" != typeof( window.outerWidth ) && "undefined" != typeof( window.outerHeight ) ) { d[w]( '<tr>' ); d[w]( '<td valign="baseline" align="right">window:</td>' ); d[w]( '<td valign="baseline"><b>' + window.outerWidth + 'x' + window.outerHeight + ' (' + window.screenX + ',' + window.screenY + ')</b></td>' ); d[w]( '</tr>' ); } //--></SCRIPT> <SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript"><!-- // Web page dimensions if( "undefined" != typeof( window.innerWidth ) && "undefined" != typeof( window.innerHeight ) ) { d[w]( '<tr>' ); d[w]( '<td valign="baseline" align="right">page:</td>' ); d[w]( '<td valign="baseline"><b>' + window.innerWidth + 'x' + window.innerHeight + '</b></td>' ); d[w]( '</tr>' ); } else if( "undefined" != typeof( document.body ) ) { if( "undefined" != typeof( document.body.clientWidth ) && "undefined" != typeof( document.body.clientHeight ) ) { d[w]( '<tr>' ); d[w]( '<td valign="baseline" align="right">page:</td>' ); d[w]( '<td valign="baseline"><b>' + document.body.clientWidth + 'x' + document.body.clientHeight + '</b></td>' ); d[w]( '</tr>' ); } } //--></SCRIPT> </table> <% end sub private sub WriteLn( s ) Response.Write s & vbcrlf end sub end class %>