Export (0) Print
Expand All

Walkthrough: Creating a Request-Level HTTP Module By Using Native Code

IIS 7.0

This walkthrough demonstrates how to use C++ to create a sample request-level HTTP module that implements the new request-processing architecture in IIS 7. This new architecture extends the capabilities of native-code programming when you are writing IIS applications over earlier versions of ASP.NET HTTP modules and ISAPI filters or extensions. For more information about designing HTTP modules using the new request-processing architecture, see Designing Native-Code HTTP Modules.

In this walkthrough, you will create a C++ project for your HTTP module, add the required code for a "Hello World" project, and then compile and test the module.

The following software is required to complete the steps in the example:

  • IIS 7.

  • Visual Studio 2005.

  • Windows Software Development Kit (SDK).

Note   You can use Visual Studio .NET 2003 or earlier, although the walkthrough steps may not be identical.

In this part of the walkthrough, you will create an empty C++ DLL project for your HTTP module.

To create a new C++ DLL project

  1. Open Visual Studio 2005.

  2. Verify that the global options have all the right paths to the SDK include files:

    1. On the Tools menu, click Options.

    2. Expand the Projects and Solutions node in the tree view, and then click VC++ Directories.

    3. In the Show directories for drop-down box, select Include files.

    4. Verify that the path where you installed the Windows SDK include files is listed. If the path is not listed, click the New Line icon, and then add the path where you installed the SDK include files. The default installation directory is $(VCInstallDir)PlatformSDK\bin.

    5. Click OK.

  3. Create a new C++ project:

    1. On the File menu, point to New, and then click Project.

      The New Project dialog box opens.

    2. In the Project Types pane, expand the Visual C++ node, and then click Win32.

    3. In the Templates pane, select Win32 Project.

    4. In the Name box, type HelloWorld.

    5. In the Location box, type the path for the sample.

    6. Click OK.

      The Win32 Application Wizard opens.

    7. Click Application Settings.

    8. Under Application type, click DLL.

    9. Under Additional options, click Empty project.

    10. Click Finish.

The next step is to add the required C++ and module-definition files to the project.

To add the source files to the project

  1. Create the module-definition file to export the RegisterModule function:

    1. In Solution Explorer, right-click Source Files, point to Add, and then click New Item.

      The Add New Item dialog box opens.

    2. Expand the Visual C++ node in the Categories pane, and then click Code.

    3. In the Templates pane, select the Module-Definition File template.

    4. In the Name box, type HelloWorld, and leave the default path for the file in the Location box.

    5. Click Add.

    6. Add a line with EXPORTS and RegisterModule. Your file should look like the code below:

      LIBRARY"HelloWorld"
      EXPORTS
          RegisterModule
      
      NoteNote:

      Instead of creating a module-definition file, you can export the RegisterModule function by using the /EXPORT:RegisterModule switch.

  2. Create the C++ file:

    1. In Solution Explorer, right-click Source Files, point to Add, and then click New Item.

      The Add New Item dialog box opens.

    2. Expand the Visual C++ node in the Categories pane, and then click Code.

    3. In the Templates pane, select the C++ File template.

    4. In the Name box, type HelloWorld, and leave the default path for the file in the Location box.

    5. Click Add.

    6. Add the following code:

      #define _WINSOCKAPI_
      #include <windows.h>
      #include <sal.h>
      #include <httpserv.h>
      
      // Create the module's global class.
      class MyGlobalModule : public CGlobalModule
      {
      public:
      
          // Process a GL_APPLICATION_START notification.
          GLOBAL_NOTIFICATION_STATUS
          OnGlobalPreBeginRequest(
              IN IPreBeginRequestProvider * pProvider
          )
          {
              UNREFERENCED_PARAMETER( pProvider );
              WriteEventViewerLog( "Hello World!" );
              return GL_NOTIFICATION_CONTINUE;
          }
      
          VOID Terminate()
          {
              // Remove the class from memory.
              delete this;
          }
      
          MyGlobalModule()
          {
              // Open a handle to the Event Viewer.
              m_hEventLog = RegisterEventSource( NULL,"IISADMIN" );
          }
      
          ~MyGlobalModule()
          {
              // Test whether the handle for the Event Viewer is open.
              if (NULL != m_hEventLog)
              {
                  // Close the handle to the Event Viewer.
                  DeregisterEventSource( m_hEventLog );
                  m_hEventLog = NULL;
              }
          }
      
      private:
      
          // Create a handle for the event viewer.
          HANDLE m_hEventLog;
      
          // Define a method that writes to the Event Viewer.
          BOOL WriteEventViewerLog(LPCSTR szNotification)
          {
              // Test whether the handle for the Event Viewer is open.
              if (NULL != m_hEventLog)
              {
                  // Write any strings to the Event Viewer and return.
                  return ReportEvent(
                      m_hEventLog,
                      EVENTLOG_INFORMATION_TYPE, 0, 0,
                      NULL, 1, 0, &szNotification, NULL );
              }
              return FALSE;
          }
      };
      
      // Create the module's exported registration function.
      HRESULT
      __stdcall
      RegisterModule(
          DWORD dwServerVersion,
          IHttpModuleRegistrationInfo * pModuleInfo,
          IHttpServer * pGlobalInfo
      )
      {
          UNREFERENCED_PARAMETER( dwServerVersion );
          UNREFERENCED_PARAMETER( pGlobalInfo );
      
          // Create an instance of the global module class.
          MyGlobalModule * pGlobalModule = new MyGlobalModule;
          // Test for an error.
          if (NULL == pGlobalModule)
          {
              return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
          }
          // Set the global notifications and exit.
          return pModuleInfo->SetGlobalNotifications(
              pGlobalModule, GL_PRE_BEGIN_REQUEST );
      }
      
      

To compile and test the project

  1. Compile the HTTP module:

    1. On the Build menu, click Build Solution.

    2. Verify that Visual Studio did not return any errors or warnings.

    3. Add the HelloWorld.dll module (with the complete path) to the globalModules section of %windir%\system32\inetsrv\config\applicationHost.config file.

  2. Use Internet Explorer to browse to your Web site; you should see "Begin Request sample " with the request count displayed.

NoteNote:

You will need to stop IIS before you link your project on subsequent builds.

If your module does not compile or does not work as expected, here are several areas that you can check:

  • Ensure that you have specified __stdcall for your exported functions, or that you have configured compilation by using the __stdcall (/Gz) calling convention.

  • Ensure that IIS has loaded HelloWorld.dll:

    1. In IIS Manager, click Default Web Site in the Connections pane.

    2. In the workspace (the center pane), select Features View.

    3. In the Group by box, select Category.

    4. In the Server Components category, double-click Modules.

    5. Verify that HelloWorld module is listed.

  • Ensure that you have added the correct RegisterModule export to your definition file.

  • Ensure that you have added the definition file to the project settings. To add the file to the project settings, complete the following steps:

    1. On the Project menu, click Properties.

    2. Expand the Configuration Properties node in the tree view, expand the Linker node, and then click Input.

    3. For the Module Definition File settings, ensure that your definition file is listed.

Was this page helpful?
(1500 characters remaining)
Thank you for your feedback

Community Additions

Show:
© 2014 Microsoft