Are you a world traveler? ZoneTick is a cool utility that'll help you stay in touch over multiple time zones!
 
Writing Form Processing ISAPI Extension DLLs  
Nik Okuntseff  MS Exchange Server Programming 

Writing Form Processing ISAPI Extension DLLs

The real power of HTML forms is that they allow for client-server processing over the Internet. For example, a survey form may be filled in by clients, and results can be put into an SQL database. I have described HTML tags used in HTML form design in previous topic. As you can see, the process is simple and straightforward. However, to process the results of the form submit operation, we need to write something for the server side.

As it turns out, with Microsoft Internet Information Server (IIS) this is possible and relatively easy to do. In this section I will demonstrate how this can be accomplished. I will describe steps that you need to do, present a trivial working sample, and give a few hints that will perhaps help you to avoid some problems.
 

Before You Start

  • Install IIS on a Windows NT server. IIS comes as part of Back Office. To install: start with disk 1 of Microsoft Back Office, select IIS and follow instructions on the screen. It would be a good idea to install IIS on a "quiet" server. It is likely that during development you will need to reboot your server a few times. You also have an option to install IIS on a Windows NT workstation. This setup is known as Microsoft Peer Web Services. To do it you need to run Inetstp.exe in I386\Inetsrv subdirectory on the Windows NT Workstation 4.0 disk.
  • Your network should have TCP/IP protocol correctly configured. For example, you need to be able to ping the server by name from other workstations.
  • IIS comes with some documentation on-line. It would be beneficial if you browse through it to get the idea how everything works.
ISAPI versus CGI

It is possible to do Internet server programming with different means. For example, you can write Common Gateway Interface (CGI) programs, execute batch files in response to requests via the Internet, or write ISAPI (Internet Server API) extension DLLs. Each of this methods has its own pros and contras. The benefit of using ISAPI extension DLLs is that they are DLLs. They are loaded in IIS process space and stay there. This is good for performance, because there is no extra overhead associated with launching a new process (as with CGI programs). In order to write ISAPI code you need to learn a few things and follow some rules. This is realistic. You can set yourself up and running in a matter of a day or so. For your reference Microsoft has provided a nice collection of documentation about ISAPI in MSDN Library.
 

Writing ISAPI Extension DLL to Process Logon Requests

Let us write a trivial ISAPI extension DLL that processes logon requests in response to the following HTML form:

<HTML>
<HEAD>
   <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
   <META NAME="Author" CONTENT="Nik Okuntseff">
   <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (WinNT; I) [Netscape]">
   <TITLE>LogonForm</TITLE>
</HEAD>
<BODY>

<FORM ACTION="http://mig/scripts/logon.dll" METHOD=POST>
<INPUT TYPE=HIDDEN NAME=MfcISAPICommand VALUE=LogonProc>
<P>Name<BR>
<INPUT TYPE=TEXT NAME=id VALUE="Your Name">
<P>Password<BR>
<INPUT TYPE=PASSWORD NAME=pw>
<P><INPUT TYPE=SUBMIT VALUE=OK><INPUT TYPE=RESET VALUE=Reset>
</FORM>

</BODY>
</HTML>

The MfcISAPICommand is a hidden control on the form to define a handler function to be used to process the form on the server. You can read more about it in Microsoft Technical Note 69: "TN069: Processing HTML Forms Using Internet Server Extension DLLs and Command Handlers".

The DLL should generate different outputs depending on password supplied. Thus, a browser user will see whether he or she supplied correct password. This is how you can accomplish this:

  • Use you Visual C++ Development Studio to create a new project. Use ISAPI Extension Wizard option when selecting the type for your project. Give your project a name: Logon. Use default options. The Wizard will create a skeleton DLL for you. Build it. Examine source files. They are very simple.
  • Put you DLL in the "scripts" subdirectory of your IIS installation.
  • Now verify whether this DLL actually works by using a browser on other computer pointing to http://computer_name/sScripts/logon.dll (for example, in my case the URL is: http://mig/scripts/logon.dll. In case of problems verify whether you can ping the server, and whether World Wide Web Publishing Service is running there. The DLL generates this default HTML text in response: "This default message was produced by the Internet Server DLL Wizard. Edit your CLogonExtension::Default() implementation to change it."
  • Edit default implementation by putting your own message string. For example, make it look like the code below and verify whether it actually produces the required output. You will need to stop World Wide Web Publishing Service to replace the DLL, because it keeps the DLL loaded.
void CLogonExtension::Default(CHttpServerContext* pCtxt)
{
    StartContent(pCtxt);
    WriteTitle(pCtxt);

    *pCtxt << _T("Response from my DLL...");
 
    EndContent(pCtxt);
}

  • As you can see, we can easily modify code to alter the DLL behavior. At this point it would be useful to learn how to debug ISAPI DLLs. You need to do this to be able to run your DLL under debugger to trace errors. A non-functional DLL may harm the service. For example, I have tried to pop up a message box with the AfxMessageBox function from my DLL. This lead to reboot because neither the DLL nor the World Wide Web Publishing Service were functional anymore. The DLL popped up the message box onto a hidden desktop that I could not see and interact with, and the service would not shut down for the same reason. Don't use AfxMessageBox and learn how to run the DLL under debugger. The technique is described in MFC Technical Note #63 "TN063: Debugging Internet Extension DLL".
  • Add LogonProc command handler to the DLL now.
    • Introduce the LogonProc function in CLogonExtension class. Do it right before the Default function:

    • void LogonProc(CHttpServerContext* pCtxt,
          LPCTSTR pszName,
          LPCTSTR pszPassword);
    • Add CommandProc handler to the parse map:

    • ON_PARSE_COMMAND(LogonProc, CLogonExtension, ITS_PSTR ITS_PSTR)
      ON_PARSE_COMMAND_PARAMS("id=~ pw=~")
    • Write code for the LogonProc function:

    • void CLogonExtension::LogonProc(CHttpServerContext* pCtxt,
              LPCTSTR pszName,
              LPCTSTR pszPassword)
      {
          StartContent(pCtxt);
          WriteTitle(pCtxt);

          CString strPassword = pszPassword;
          if ("password" == strPassword)
              *pCtxt << _T("Access granted!");
          else
              *pCtxt << _T("Incorrect password... Please try again...");
       
          EndContent(pCtxt);
      }

  • Build the DLL and put it into the scripts subdirectory.
  • Verify whether it is functional by providing two URLs below in your browser. One of them should result in Access Granted! screen, another - in Incorrect password... Please try again... In case of problems run your DLL under debugger, set up breakpoints and trace the program execution to locate the bug. For your convenience I am providing the code for this DLL in my collection of samples (Forms/Logon), as well as the DLL itself (in Bin subdirectory).
    • http://computer_name/scripts/logon.dll?MfcISAPICommand=LogonProc&id=Nik&pw=password
    • http://computer_name/scripts/logon.dll?MfcISAPICommand=LogonProc&id=Nik&pw=123
  • Verify whether the DLL may be invoked from the form. Unless your server name is MIG you will need to change the computer name of ACTION attribute in the form before you do this. I have included the LogonForm.htm file in the Forms/Logon subdirectory, which you can use as a starting point. Launch the form and make sure it works as expected.
  • As a final step in our exercise you can publish the form on your server (put it in appropriate directory), and perhaps try it over the Internet. In this case the computer name should be something like www.MyCompany.com, and you'll need to modify the ACTION attribute accordingly.

 
[ Contents | Home ]

Send comments and suggestions to niko@wrconsulting.com
Copyright © 1997-1998 by Nik Okuntseff