⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch26.htm

📁 好书《C++ Builder高级编程技术》
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<P>Most of the body of the function is taken up with simple HTML code 
that provides
basic information to the user:</P>
<PRE><FONT COLOR="#0066FF">char *HtmlInfo =

    &quot;&lt;HTML&gt;&quot;

    &quot;&lt;HEAD&gt;&lt;TITLE&gt;C++ Builder ISAPI DLL &lt;/TITLE&gt;&lt;/HEAD&gt;&quot;

    &quot;&lt;H1&gt;ISAPI1 Test 
Results&lt;/H1&gt;&quot;

    &quot;&lt;BODY bgcolor=\&quot;#0000FF\&quot; text=\&quot;#00FFFF\&quot;&gt;&quot;

    &quot;Hello from a C++ Builder ISAPI DLL!&lt;BR&gt;&lt;/BODY&gt;&quot;

    &quot;&lt;/HTML&gt;&quot;;

</FONT></PRE>
<P>You also need 
to fill in a few fields of the <TT>EXTENSION_CONTROL_BLOCK</TT>:</P>
<PRE><FONT COLOR="#0066FF">char *IsapiLogText = &quot;ISAPI1 - Simple ISAPI Extension DLL&quot;;

strcpy(pECB-&gt;lpszLogData, IsapiLogText);

pECB-&gt;dwHttpStatusCode = 200;


</FONT></PRE>
<P>The <TT>lpszLogData</TT> field contains the string that will be written to the
log on your server. With the Personal Web Server, this log is kept by default in
the <TT>Windows</TT> directory, though you can change this in the 
Administration
section of the server applet found in the Control Panel.</P>
<P>The status code in this example is set to <TT>200</TT>, which means &quot;OK.&quot;
Other possible values include the following:</P>
<PRE><FONT 
COLOR="#0066FF">HTTP_STATUS_BAD_REQUEST

HTTP_STATUS_AUTH_REQUIRED

HTTP_STATUS_FORBIDDEN

HTTP_STATUS_NOT_FOUND

HTTP_STATUS_SERVER_ERROR

HTTP_STATUS_NOT_IMPLEMENTED

</FONT></PRE>
<P>More information on the <TT>EXTENSION_CONTROL_BLOCK</TT> is 
provided in the section
called &quot;Working with the <TT>EXTENSION_CONTROL_BLOCK</TT>.&quot;</P>
<P>Notice the function pointer called <TT>WriteClient</TT> in the struct. You can
call this function to send information back to the browser. When 
calling this function,
you use the value in the <TT>ConnID</TT> field of the <TT>EXTENSION_CONTROL_BLOCK</TT>
struct. <TT>ConnID</TT> is filled in for you automatically when the <TT>HttpExtensionProc</TT>
function is called.</P>
<P>Before you look at 
the <TT>EXTENSION_CONTROL_BLOCK</TT> struct, let me show you
a complete ISAPI DLL that uses the <TT>HttpExtensionProc</TT> function shown in this
section.
<H3><A NAME="Heading10"></A><FONT COLOR="#000077">A Stripped-Down ISAPI Example</FONT></H3>

<P>The source code in Listing 26.1 shows how to create the simplest possible ISAPI
DLL. The goal is to remove all the complications from the code, and just include
enough information to make sure everything is working correctly.<BR>
<BR>
<A 
NAME="Heading11"></A><FONT COLOR="#000077"><B>Listing 26.1. The ISAPI1 example.</B></FONT></P>
<PRE><FONT COLOR="#0066FF">///////////////////////////////////////

// FILE: ISAPI1.CPP

// PROJECT: ISAPI1.DLL

// copyright (3) 1996 by Charlie Calvert


//

// This example shows how to use ISAPI, which is similar to creating a

// CGI application. The code should return a simple string to an HTML

// browser such as the Internet Explorer.

//

// Here is the HTML you output in a browser to call this 
ISAPI DLL:

//

// &lt;HTML&gt;

// &lt;HEAD&gt;

// &lt;TITLE&gt;CharlieC Home Page&lt;/TITLE&gt;

// &lt;/HEAD&gt;

// &lt;BODY&gt;

// &lt;H1&gt;My Home Page &lt;/H1&gt;

// &lt;P&gt;

// This is the home page for my home computer.

// &lt;P&gt;


// &lt;A HREF=&quot;/scripts/isapi1.dll&quot; &gt;ISAPI One&lt;/A&gt;&lt;BR&gt;

// &lt;/BODY&gt;

// &lt;/HTML&gt;

#include &lt;vcl\vcl.h&gt;

#include &lt;string.h&gt;

#include &lt;stdio.h&gt;

#pragma hdrstop

#include 
&quot;..\..\utils\Httpext.h&quot;

USERES(&quot;Isapi1.res&quot;);

FILE *out;

// GetExtensionVersion callback definition

BOOL WINAPI GetExtensionVersion(HSE_VERSION_INFO *pVer)

{

  fputs(&quot;Version&quot;, out);

  pVer-&gt;dwExtensionVersion = 
MAKELONG(HSE_VERSION_MINOR, HSE_VERSION_MAJOR);

  strcpy(pVer-&gt;lpszExtensionDesc, &quot;C++ Builder ISAPI DLL&quot;);

  return (TRUE);

};

DWORD WINAPI HttpExtensionProc(EXTENSION_CONTROL_BLOCK *pECB)

{

  AnsiString ResultString;

  DWORD 
resultLen;

  AnsiString IsapiLogText = &quot;ISAPI1 - Simple ISAPI Extension DLL&quot;;

  strcpy(pECB-&gt;lpszLogData, IsapiLogText.c_str());

  AnsiString HtmlInfo =

    &quot;&lt;HTML&gt;&quot;

    &quot;&lt;HEAD&gt;&lt;TITLE&gt;C++ Builder 
ISAPI DLL &lt;/TITLE&gt;&lt;/HEAD&gt;&quot;

    &quot;&lt;H1&gt;ISAPI1 Test Results&lt;/H1&gt;&quot;

    &quot;&lt;BODY bgcolor=\&quot;#0000FF\&quot; text=\&quot;#00FFFF\&quot;&gt;&quot;

    &quot;You are talking to a C++Builder ISAPI DLL.&quot;

    
&quot;&lt;BR&gt;&lt;/BODY&gt;&quot;

    &quot;&lt;/HTML&gt;&quot;;

  pECB-&gt;dwHttpStatusCode = 200;

  ResultString = Format(

    &quot;HTTP/1.0 200 OK\nContent-Type: text/html\n&quot;

    &quot;Content-Length: %d\nContent:\n\n %s&quot;,

    
OPENARRAY(TVarRec, (HtmlInfo.Length(), HtmlInfo)));

  resultLen = ResultString.Length();

  fprintf(out, ResultString.c_str());

  pECB-&gt;WriteClient(pECB-&gt;ConnID, ResultString.c_str(), &amp;resultLen, 0);

  return (HSE_STATUS_SUCCESS);

}


#pragma argsused

int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*)

{

  switch (reason)

  {

    case DLL_PROCESS_ATTACH:

      out = fopen(&quot;c:\\test.txt&quot;, &quot;w+&quot;);

      fprintf(out,&quot;hello&quot;);

      
break;

    case DLL_PROCESS_DETACH:

      fprintf(out,&quot;goodbye&quot;);

      fclose(out);

      break;

    default:

      break;

  }

  return (TRUE);

}

</FONT></PRE>
<P>To use this DLL, you should copy it into a subdirectory of the 
<TT>scripts</TT>
directory beneath the root for your Web. On my NT 4.0 machine, the subdirectory looks
like this:</P>
<PRE><FONT COLOR="#0066FF">c:\winnt\system32\inetsrv\scripts\mystuff\isapi1.dll

</FONT></PRE>
<P>In this case, I have created the 
directory called <TT>MYSTUFF</TT>, and it is
used solely for storing ISAPI DLLs I have created. Your mileage may, of course, differ
on your machine, depending on where you put the <TT>InetSrv</TT> directory and various
other factors.</P>
<P>To call 
this DLL, you should add the following hyperlink to one of your HTML pages:</P>
<PRE><FONT COLOR="#0066FF">&lt;A HREF=&quot;/scripts/mystuff/isapi1.dll&quot; &gt;ISAPI One&lt;/A&gt;&lt;BR&gt;

</FONT></PRE>
<P>For example, here is a complete sample 
page:</P>
<PRE><FONT COLOR="#0066FF">&lt;HTML&gt;

&lt;HEAD&gt;&lt;TITLE&gt;An ISAPI Page&lt;/TITLE&gt;&lt;/HEAD&gt;

&lt;BODY&gt;

&lt;H1&gt;My ISAPI Page&lt;/H1&gt;

&lt;P&gt;This is the home page for ISAPI on my computer.&lt;P&gt;

&lt;A 
HREF=&quot;/scripts/mystuff/isapi1.dll&quot; &gt;ISAPI One&lt;/A&gt;&lt;BR&gt;

&lt;/BODY&gt;

&lt;/HTML&gt;

</FONT></PRE>
<P>When the user clicks the hyperlink, the ISAPI1 DLL will be called and the string
<TT>&quot;Hello from C++ Builder&quot;</TT> 
will appear in the user's browser. If
you did not put the <TT>ISAPI1.DLL</TT> in the <TT>MYSTUFF</TT> directory, then you
should change the preceding HTML code to reflect that fact. Notice that the path
you assign is relative to the <TT>InetSrv</TT> 
directory and does not, and should
not, contain the entire path to your DLL.</P>
<P>Note that if you copy the <TT>ISAPI1.DLL</TT> into the <TT>MYSTUFF</TT> directory
multiple times, you will need to shut down the WWW portion of the Internet server

before each copy. The rule is that you can copy the DLL the first time for free,
but after you have used it, it belongs to the server, and you need to shut down the
WWW services on the server before you can copy an updated version of the file over
the 
first copy. You can use the Internet Service Manager application to shut down
the WWW services on the NT Server. This application should be in the Microsoft Internet
Server group created in Windows Explorer or Program Manager (NT 3.51) at the time
of 
the installation of the Internet Information Server. You can use the PWS applet
in the Control Panel if you're using the Personal Web Server on Windows 95 or on
the Windows NT Workstation.
<H3><A NAME="Heading12"></A><FONT COLOR="#000077">Working with 
the EXTENSION_CONTROL_BLOCK</FONT></H3>
<P>By this point in the chapter, you should be able to create your first ISAPI DLL
and call it from a Web browser on a second machine. The rest of this chapter explores
ISAPI in more depth.</P>
<P>The following 
fairly complex record is passed as the sole parameter to <TT>HttpExtensionProc</TT>:</P>
<PRE><FONT COLOR="#0066FF">typedef struct _EXTENSION_CONTROL_BLOCK {

  DWORD     cbSize;                 // size of this struct.

  DWORD     dwVersion;              
// version info of this spec

  HCONN     ConnID;                 // Context number not to be modified!

  DWORD     dwHttpStatusCode;       // HTTP Status code

  CHAR      lpszLogData[HSE_LOG_BUFFER_LEN];// log info

  LPSTR     lpszMethod;             
// REQUEST_METHOD

  LPSTR     lpszQueryString;        // QUERY_STRING

  LPSTR     lpszPathInfo;           // PATH_INFO

  LPSTR     lpszPathTranslated;     // PATH_TRANSLATED

  DWORD     cbTotalBytes;           // Total bytes indicated from client

  
DWORD     cbAvailable;            // Available number of bytes

  LPBYTE    lpbData;                // pointer to cbAvailable bytes

  LPSTR     lpszContentType;        // Content type of client data

  BOOL (WINAPI * GetServerVariable) ( HCONN       
hConn,

                                      LPSTR       lpszVariableName,

                                      LPVOID      lpvBuffer,

                                      LPDWORD     lpdwSize );

  BOOL (WINAPI * WriteClient)  ( HCONN      
ConnID,

                                 LPVOID     Buffer,

                                 LPDWORD    lpdwBytes,

                                 DWORD      dwReserved );

  BOOL (WINAPI * ReadClient)  ( HCONN      ConnID,

                                
LPVOID     lpvBuffer,

                                LPDWORD    lpdwSize );

  BOOL (WINAPI * ServerSupportFunction)( HCONN      hConn,

                                         DWORD      dwHSERRequest,

                                         
LPVOID     lpvBuffer,

                                         LPDWORD    lpdwSize,

                                         LPDWORD    lpdwDataType );

} EXTENSION_CONTROL_BLOCK, *LPEXTENSION_CONTROL_BLOCK;

</FONT></PRE>
<P>Notice that this record 
contains the <TT>ConnID</TT> field referenced previously
and passed as the first parameter to <TT>WriteClient</TT>.</P>
<P>The first parameter of this record is used for version control. It should be set
to the size of the 
<TT>EXTENSION_CONTROL_BLOCK</TT>. If Microsoft changes this structure,
then they can tell which version of the structure they are dealing with by checking
the size of the record as recorded in this field. You should never change any of
the first three 
fields of this record; these fields are filled out ahead of time
by ISAPI and can only be referenced, not changed, by your program.</P>
<P>The most important field of this record is probably the <TT>lpszQueryString</TT>,
which contains information 
about the query passed in from the server. For example,
suppose you have created a DLL called <TT>ISAPI1.DLL</TT>. To call this DLL, you
would create an <TT>HREF</TT> that looks like this in one of your browser pages:</P>
<PRE><FONT 
COLOR="#0066FF">&lt;A HREF=&quot;/scripts/mystuff/test1.dll&quot;&gt;Test One&lt;/A&gt;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -