Introduction

Other ATL7 changes are covered here and here. First let's go over some of the new classes added for simplifying the ATL Server development. These classes can be used anywhere you need them not just for ATL Server development.

Regular Expressions:

CAtlRegExp<> regexp;
CAtlREMatchContext<> mc;
// match any line that starts with any number of digits,
// has a dash, and ends with any number of digits
if(regexp.Parse("^\\d+-\\d+$") == REPARSE_ERROR_OK)
{
constchar* szNumDashNum="5663-4662";
if(regexp.Match(szNumDashNum, &mc))
{
ATLTRACE("Matched");
}
}

Debugging:

ISAPI Filter/Extension Overview:

ISAPI stands for Internet Server Application Programming Interface. ISAPI programming is divided into Filters and Extensions. Both are DLLs with specific exported functions. ISAPI filters are loaded with the IIS and stay in memory until HTTP Web service shuts down. ISAPI Extensions are loaded on demand and provide extended functionality to web applications. ISAPI filters are useful for examining/filtering incoming and outgoing HTTP requests under IIS (for example, implementing custom authentication, encryption, compression, logging, etc). ISAPI extensions are useful for developing dynamic web pages and work per URL reference.

There is no class for ISAPI filter under ATL7. ATL Server provides support for ISAPI extensions in form of DLL cache, file cache, page cache, memory cache, data source cache, thread pool, remote management with web based or web service based interfaces, predefined performance counters, session support, etc. As you can see that's quite a lot of functionality/services. In addition it's easy to add your own services to the existing ones.

ATL7 Web Application is a combination of ISAPI extension and a handler DLL (or both can be combined into one dll) to create dynamic web pages. ISAPI extension is a DLL that exports three functions: HttpExtensionProc, GetExtensionVersion, TerminateExtension. The Handler DLL/Web Application DLL also exports three predefined functions for ATL: InitializeAtlHandlers, GetAtlHandlerByName, UninitializeAtlHandlers.

ATL7 web applications are built upon stencils. Stencil is a text file normally with .srf extension, resides in the virtual directory of ISAPI extension, and can have a mixed content of static html and dynamic/run-time replaceable tags. In GetExtensionVersion, ATL initializes the heap it uses, predefined performance monitors, worker thread, thread pool, dllcache, page cache, and stencil cache. TerminateExtension does the opposite.

The main function that does all the work is HttpExtensionProc. The class responsible for implementing it is CIsapiExtension. The CIsapiExtension::HttpExtensionProc queues the incoming request unto an I/O completion port. This completion port is checked by the worker threads that run in the thread pool (CThreadPool). All these worker threads do is block on the GetQueuedCompletionStatus on the afore mentioned completion port (on which requests were queued from HttpExtensionProc). By default there are 2 threads started in the pool (controlled by the ATLS_DEFAULT_THREADSPERPROC or IThreadPoolConfig which CThreadPool implements).

So when any of these worker threads get the chance and successfully dequeue the completion request from the port, they execute the request. Executing request means processing the stencil file, first the whole processed page is looked up in page cache (controlled by overriding CachePage() method and returning TRUE from the CRequestHandlerT derived class). If found the whole page file simply gets transmitted to user and all is done. Otherwise, the stencil file is looked up in stencil cache. If it's not in the cache, the (.srf) file is read from disk, the Handler DLL tag is parsed, and DLL loaded (if it's not in DLL cache already).

The handler's DLL entry point is called, that is InitializeAtlHandlers, and the handler class that handles the request is found through GetAtlHandlerByName. Then all remaining replacement tags are parsed out of stencil file. The stencil file is Rendered, meaning, for all the tags that represent methods the address of the method in handler class is found through the GetAttrReplacementMethodMap defined by tag_name if using attributes or REPLACEMENT_METHOD_MAP in the CRequestHandlerT derived class. Then methods are called and generate the dynamic content for the web page. The generated content is sent back to user. It's nice to go through in debugger to see the sequence of events and suggest you do the same. It's interesting to see how it works internally.

To step through the ATL code place breakpoints at HttpExtensionProc and step through up to PostQueuedCompletionStatus. The other place to put breakpoint is in the while loop for GetQueuedCompletionStatus. Now you can hit F5 and follow the whole sequence of steps.

The wizard generated code (when you choose Data Source Cache, you're free to do it yourself also, but this can serve as an example) also produces a custom CIsapiWorker derived class for per-thread services. This is the class that is created for each thread in the thread pool. What this allows is to add your own methods and data members per thread. This means it doesn't need to be synchronized, and your request handler class can get the pointer to this per-thread worker by calling IIsapiExtension::GetThreadWorker (link has an example on using it also).

ATL Server also provides a number of ways to control and configure your web application. It provides default implementation for remotely controlling the Thread Pool, SRF file cache, and Web App DLL Cache. All you do is define the appropriate symbols for whatever service you want to expose through HTML web interface or Web services, restrict to specific users, etc and you get the full implementation for free! You can follow the steps described in Extension Management Services on how to do it step by step!Extension Management XML Web Service Client

The services that you choose when you create new project: Blob cache, File Cache, Data Source Cache, Browser capabilities, Session services and in addition the framework provided services: DllCache, StencilCache, ThreadPoolConfig, and AtlMemMgr are all exposed through IServiceProvider::QueryService, which CIsapiExtension derived class implements. You can also add any of your own services at runtime through IIsapiExtension::AddService and later QueryService for them. The code for first group of services will be added for you to the request handler class and will be commented out. All you need to do is uncomment it and apply it to your needs.

ATL Web service support is also implemented as ISAPI extension. You can either use the wizard or try it manually for learning purposes. Create simple Win32 DLL project. Add .def file to export the 3 ISAPI extension functions. Then in its most simplest form the web service implemented with ATL7 can look as follows:

Either use the VC++.NET project properties for Web Deployment and add .dll extension under Application Mappings or create the virtual directory and register the App mappings manually under IIS. After that you can access the WSDL of the web service in web browser as follows http://localhost/websvc/WebSvc.dll?Handler=WSDL WebSvc.dll has the implementation of your Web Service, and WSDL is the compiler generated handler that you specified in request_handler for sdl parameter.

Now when you access it again as in Web Application in previous section, HttpExtensionProc will be called by IIS. It will delegate to CIsapiExtension. CIsapiExtension will queue the request on I/O completion port. One of the worker threads will dequeue the request. Then the Handler DLL will be loaded (websvc.dll). Handler will be initialized. What it does is, it gets all the functions exposed by your web service class to write the info about them to WSDL. ATL already has the template for generating the WSDL for your web service. It can be found in atlspriv.h (constchar * const s_szAtlsWSDLSrf). You'll see that it's a simple stencil text suitable for Stencil processing (with replaceable tags). So this string is loaded using CStencil::LoadFromString and all the tags are parsed and replaced/rendered.

Now this WSDL output can be used to generate the client to your web service. You can either use VS.NET built-in support for adding Web Services, by running wsdl.exe manually for .NET clients, or running ATL7 provided tool called sproxy.exe to produce proxy client file. For example: sproxy /out:client.h http://localhost/websvc/WebSvc.dll?Handler=WSDL

If using sproxy.exe, the generated file will have the methods exposed by your Web Service nicely wrapped in a C++ class. To use it, simply include the generated file (for example client.h) file in your project:

Thanks for posting such great sample code for other developers, I’m new in cryptograph field, now I need help from you, what library and headers that I need to add in my project so I can use the section “Encryption”? I have included the followings in my project:
…\MICROSOFT VISUAL STUDIO .NET 2003\VC7\ATLMFC\INCLUDE
…\Microsoft Visual Studio\VC98\INCLUDE
…\Microsoft Visual Studio\VC98\MFC\INCLUDE
…\Microsoft Visual Studio\VC98\ATL\INCLUDE
More specifically, I need to use TripleDES (3DES) to hash the password to format type 3 message which is needed for POP3 – “AUTH NTLM” command. This project is developed under VC++6.0.

//let's use md5 hash to hash the password for the file to be encrypted
//normally you would use sha, this is only to show how you can easily use //md5 if needed
CCryptMD5Hash md5;
hr = md5.Initialize(prov);
//hash file password
md5.AddString(szPassword);

//initialize the key to use TripleDES and md5 based hash of the password
hr = derKey.Initialize(prov,md5,CALG_3DES);

I hit the same problem; the solution may come a bit late for the original poster of the question, but hopefully can help the next readers. And, thanks to Leon for putting the whole thing together.

1. Encryption.
Just above the 'while....' line in encryption block you have to write to file the IV content (and you want to read it when decrypting) like this:
-------------------------
fwrite(iv, 1, IV_SIZE, pFileEn); //write our iv into stream
while(!feof(pFilePl))
-----------rest is same--------------

2. Decryption
Locate line that says "//set IV, MODE, Padding like before". You actually want to set these after opening the files - just bellow this comment, in order to get the original IV (initialization vector) from the "testenc.txt"
----------------------
//set IV, MODE, Padding like before
FILE* pFileEn = fopen("testenc.txt", "rb"); //encrypted file
FILE* pFileDec = fopen("testdec.txt", "wb");//to be decrypted file
DWORD dwEncLen = 0;

Hi,
i've just started to learn ATL Server. now i am trying consume a atl server web service. I create a atl server web service using vs 2003 with all the default setting and build and compile it. fine. and i try to create another console application to consume it. I use the add web reference dialog box to generate a proxy class. Browsing through local machine and found my service discovery page. When i try to click the add reference button, it gives message " unable to download following files from http//localhost/ .....?handler=GenAtlConverterWSDL...Do you want to skip the file and continue?
bla bla... whats the problem??! I have tried to add web reference to asp.net web service before! it works fine!
please help! all i want is to run a simplest atl server web service! thx

First one : When I compile the sample OpenGL of msdn, I can't access the methods when I test with test container, It says me "This control has no methods"

Second one : More difficult to explain, I made an atl which works as I want except that when I want to inculde it in an application (under 7.1) "the control is not registered, register it", but It works fine under 6.0.

I am facing a problem in using the attributed ATL COM component under Microsoft Visual Studio .NET 2003 (VC++ 7.1). When I try to instantiate an interface of this COM component, it generates an error 0x80040154 "Class Not Registered".

I am facing this problem even with standard samples on ATL attributes from MSDN. I have downloaded sources of "ATLTangram" sample from MSDN. Then I compiled it on my machine under VS.NET2003. After succesful compilation, I tried to run MFCTangram... but it returned me the same error as above "class not registered".

What can be the problem.. is it something to do with my machine or some software? Or do I need to change some attributes in the program before running it on my machine. I am having Windows 2000 Version 5.00.2195 operating system. Thanx in advance.

As you said, I rebuilt the ATLModel project and then, it started working fine.

However, I am unable to get as what to be done in my own project so that I am able to instantiate the COM object succesfully !.

OK, my steps:
1. I make a new ATL Project in VC7.1 called as "MyATL".
2. Then, add an interface (ATL object) called "MyInterface to this project"
3. Build the project. It gets built successfully.

4. Now, I add a new MFC Application Project called as "TestATL" to the current solution. I change from MDI to Dialog-based in the properties of this new project. It generates default files including TestATLDlg.cpp.

5. Add the following statement at the top of TestATLDlg.cpp after #includes.
#import "d:\projects\myatl\_myatl.tlb"

6. Now, I double click OK button on the dialog to add function "OnBnClickedOK()". In this function, I just add following lines:

I am developing an attributed ATL COM component in Visual Studio .NET 2003 (VC++ 7.1). Everything works fine until I add a web reference. When I add a web reference to some webservice, the BUILD process of ATL COM component generates an error while performing registration. The point is that if I make the same ATL COM component without using Attributes, the BUILD process returns no error even after adding the web-reference to the web service.

To simplify the bug, I follow following steps:
1. Make a new ATL project in Visual Studio .NET 2003 (VC++ 7.1).
2. Accept all the default project settings (Dynamic Link Library, Attributed)
3. It will generate default classes and gets successfully compiled and registered.
4. Now add following one include line at the end of "stdafx.h".
#include "atlsoap.h"

The inclusion of this one file starts giving build errors at the time of registration.
It generates following error: