Learning to Use the Win32 Internet API Library
The Win32 Internet API is designed to handle the
client side of the Internet connection. A familiar application that uses client-side
technology is your browser. Unlike the ISAPI Server API, the Internet API (also know as
WinInet) can be used in any normal application. The executable file does not have to be
placed in a special directory with special permissions. In this chapter, you will learn
the general functionality offered by this WinInet API and learn how to use the Microsoft
programming classes to use this WinInet API.
Using the Internet requires a connection from a
client (your browser, for example) to a server. The API supports a connection that can be
a request to a server that understands HTTP, FTP, or Gopher. While there are other kinds
of Internet connections, these three are currently the most widely used. Each kind of
connection has a different but similar use.
What is the File Transfer Protocol (FTP)?
FTP is a File Transfer Protocol. It allows servers
to make files available to clients, and it lets the client give the server files. It
transfers files from one computer to another, regardless of the operating system on either
machine. This was important because operating systems that didn't know how to talk to each
other could use the FTP service to place or get files to each other. For example, a
student in Texas using a Macintosh computer could retrieve or put files on a UNIX machine
in California. FTP files are generally laid out in a tree structure, just like a directory
system. This allows the client to place or retrieve files from the appropriate location.
In the Windows NT and Windows 95 operating systems,
FTP commands are supported at the command prompt. The Microsoft Internet Explorer
(Microsoft's browser) support for FTP is built in the address box. It can be accessed by
Figure 13.1 is an example of an FTP site. Notice the
name and explanation of the site. They appear to use HTML, but in fact it is Internet
Explorer doing the formatting. Look at how the files list the date and time of last
modification as well as the file size. The directories are also listed. When using FTP,
you have to know what file you are looking for and where to find it. There is no searching
The Gopher Protocol
Compared to FTP, Gopher offers a little more to the
client but also requires more of the server. FTP does not have any ability to jump from
one server to another, but Gopher and HTTP do have the ability to jump to other servers
using links. Gopher also offers the ability to annotate files and directories, and create
custom menus. However, it does not allow the client to place files on the server.
Gopher servers have a tag file. This tag file keeps
the name of the file the directory system uses: a "friendly" name that would be
useful to the client (the administrator's name, modification date, and type of file, such
as a text file or binary executable file). An example of a friendly name would be
The 1996 Acme Stock Report, where the file name is actually
1996stpt.txt. The client doesn't see the tag file, but information in the tag
file can be sent back to the client along with the file itself. The tag file has to be
constructed by an administrator of the Gopher site. The Microsoft Internet Information
Server uses the command line application GDSSET.EXE to make tag files for the Gopher
server it supports. A tag file would have to be built for each file retrievable by Gopher.
Gopher allows searches through the Wide Area
Information Search (WAIS) index searching. WAIS is a full-text information retrieval
system. In order for the file to be searchable, the server administrator has to create a
The Microsoft Internet Explorer's (Microsoft's
browser) support for Gopher is built in the address box. It can be access by typing
Figure 13.2 is an example of a Gopher site. Notice
the name and explanation of the site. This page appears to use HTML, but in fact it is
Internet Explorer doing the formatting. This site offers directories and searches to
clients. The Gopher server differentiates between files, directories, and searches. This
particular Gopher site doesn't have any files at the root directory, but it does have
several directories and searches.
HTTP and HTML
Both FTP and Gopher offer useful services, but they
lack of few qualities. Both are basically file systems with only files and searches to
offer. To see the information, the client must download the file to his computer and open
it with the correct application. HTTP and HTML offer the client the information without
having to open the file. Actually, the concept choosing files is replaced with the concept
of moving to other pages. At this point in the guide, you should know how to move between
pages in your browser.
HTTP servers offer much more to a client. While FTP
and Gopher are file server systems, HTTP can be a complete server system. It can offer
unlimited capabilities such as database access, true search engines, and calculations. The
list is only limited by your imagination. The HTTP server does its work and then sends the
client's browser a file to display the result of whatever work it was requested to do.
The HTTP servers work is far more versatile than FTP and Gopher because it can act on the request. An example (one of many) is the request for information, such as the Yellow Pages on the Web. The request goes from your browser to the server. The server can filter the request for valid data or passwords. If the request is invalid, the server returns an HTML page notifying you. If the request is valid, the server can look through a file server, look through an email server, look through a database, or do just about anything else.
FTP and Gopher in the Future
The services offered by FTP and Gopher are quickly
being replaced by Web pages served up by HTTP and written in HTML. If you search for
Gopher or FTP pages, you are probably using a search engine behind an HTML form. Why would
someone keep these servers around? Converting an existing (and probably extensive) server
to HTML is not hard, but there are several costs involved. These costs can involve
hardware, software, labor, training, and administration of the new system. Many of these
systems reside in governments or schools, and the resources to update the systems are not
How Does the WinInet API Fit In?
The WinInet API is designed to allow applications
access to Internet (or intranet) information, without requiring detailed knowledge of how
the connection works (such as TCP/IP or sockets). The API makes reading a file from the
Internet as easy as reading a file from your hard drive. If you are familiar with other
Win32 APIs then the buffer and error handling of this API should look familiar. If you
want to have all the detailed information of the WinInet specification, you can find the
document at http://www.microsoft.com/intdev/sdk/docs/wininet/.
The difficulty with Internet technology is that it
changes very quickly. Who wants to learn a set of functions that will soon be obsolete?
The WinInet API is written to flexibly change the underlying technology and yet have a
consistent set of functions for programmers to use.
Microsoft has written a set of classes that
incorporate the WinInet API functionality into the Microsoft Foundation Class (MFC)
classes. The benefit of these classes is that they fit nicely into the MFC hierarchy of
classes, thereby giving the programmer more functionality than just what the WinInet API
functions can afford. If you are familiar with MFC, learning these new classes will be a
snap. In order to use these classes, you have to use the Microsoft Visual C++ version 4.2.
Prior versions of Visual C++ will not have these classes.
The API Functions
Before looking at the MFC classes, let's first take
a look at the functions in the WinInet API. The main functions a client should be
concerned with are connecting to the server, having the server do something, and closing
the connection to the server.
Please check to see if the hardware and software in
your operating system are correctly configured before you begin programming with this API.
Connecting to a Web site with your browser would be a good test of whether your machine's
hardware and software are working correctly. This API takes advantage of the software you
already have installed on your system. So instead of having to install the protocols and
software to use this API, the API assumes that you already have connectivity with these
While there are only three technologies supported by
the API, there are several functions that you need to accomplish regardless of which
protocol you use. The general functions are:
To get to specific files or other information, you
will have to use the functions that coincide with your particular need. There are
functions specific to each of the three connections supported: HTTP, FTP, and Gopher.
The HTTP functions are
The FTP functions include the following:
The Gopher functions include the following:
Notice that once you get the files enumerated, based
on your connection type, the rest of the enumeration is used with InternetFindNextFile.
Examples of function calls it would take to download
from an HTTP server include
The MFC Classes and WinInet
If a programmer wanted to write an application using
this API, a lot of programming would be required to handle non-WinInet aspects of the
application, such as the graphical user interface (GUI), any database connectivity, and
just about anything else the application needs to do. You could write a WinInet program
without MFC (or some other programming class library), but for rapid application
development (RAD), this is probably unrealistic. Knowledge of C++ class usage is mandatory
for using these classes.
The MFC classes that work with this functionality
Global functions for the WinInet in MFC include the
Programming with MFC
In order to follow the code snippets and exercises
in the rest of the chapter, you need to make sure that the Internet connectivity to HTTP
and FTP is working. You can use your browser to verify this. You also need to have
Microsoft Visual C++ version 4.2 or later installed. The help files and sample application
of Microsoft Visual C++ go into great detail about what these new classes do. Please see
these resources for additional information.
The First Example Program
This first example program will connect to a HTTP
server and read the HTML file (default.asp). As it reads the file, the application will
print the information to a screen. This is not a sophisticated program, but you will
actually connect to a server and read a file. There are three types of operations you will
be doing. You will open a connection to the server, make a request of the server, and read
a file. As you go through this example, look for the differences between these three
You will need to find a Web server that has a Web
page in the root directory to exchange for the names I use in this example. In the example
code, I chose a server I could get to at the time this chapter was written. The danger in
this is that the server might not be working now. Before you begin, you need to find a Web
server (any will do) that has the default.asp document. Some of the more advanced servers
don't have this file. As long as you know the name of a server and the name of a file in
the root directory of that server, you can exchange those names for the ones I use in the
In order to start, let's create an application. Open
up Microsoft Visual C++, and make a new project workspace. Name the workspace HTTPexam.
Make sure the project is a console application. The reason it should be a console
application is because I don't want you to be confused by seeing any classes that are not
closely related to these WinInet classes. Because a console application doesn't use MFC by
default, you need to change the project so that it does use MFC. In your project, change
your project settings (Build Menu/Settings) to use MFC in a shared dll (General Tab/MFC
drop-down list). If you don't let the project know you need to use the MFC dll, when you
build, you will get linker errors regarding beginthread and endthread functions.
Create a header file httpex.h that looks like
Listing 13.1. httpex.h (create a header file).
Create a code file httpex.cpp that looks like
Listing 13.2. httpex.cpp (write bare
Make sure httpex.cpp has been added to the project
files, and update project dependencies. The CHttpExample class's only base class is
CInternetSession. The derived class you made (CHttpExample) only has one method. You don't
need anything more in your header file to make a connection and to retrieve information
from a server.
Now let's add the implementation code that is
associated with the function defined in the header file. Add Listing 13.3 to httpex.cpp
after the line //CHttpExample class implementation.
Listing 13.3. httpex.cpp (add class
There is no code in the constructor for your
CHttpExample class because the base class does everything you need. All you have to do is
pass this information to it when you declare a variable of CHttpExample type.
At this point, the project should build with no
errors or warnings. If it does have errors or warnings, now is a good time to fix your
project settings and debug your code. However, the main function is still empty, so the
program will do nothing. Let's add some useful code to make the program do something.
You need to declare a few variables that you want to
work with. The first and most obvious is to instantiate your class by having a variable of
CHttpExample type. The second variable you need is for your connection type and will be of
type CHttpConnection. The third variable you need will help you read the file and will
need to be of type CHttpFile. You also need to add a few character strings to handle the
server name, filename, header information you send, header information you request, and
the text of the file in which you are interested. The last variables will hold the status
of functions you are executing. Add Listing 13.4 below the line with // variables on it.
Listing 13.4. httpex.cpp (declare variables).
The way you declared the session variable will pass
the information from the CHttpExample class to the CInternetSession class. A CString can
be either initialized when it is declared or later. Both methods are used here. The two
variables pServer and pFile will be initialized in the code. Also notice that the server
does not have to be prefixed with the http://. If you did prefix the name, a connection
would not be established.
The second parameter to the constructor for your
session variable is the type of Internet access you want. This has nothing to do with the
server you are trying to get to. This parameter tells the software how to configure our
machine's side of the connection. You have three choices here. I chose the one that will
work with my machine. If you are not running on a Windows NT or Windows 95 operating
system, you will have to choose the flag that is best for you. The three flags are
If you do not know what type of access you have, you
will need to contact your system administrator or Internet service provider (ISP).
Now let's write some code to get you connected. Add
Listing 13.5 to your main function just below the // running code implementation line.
Listing 13.5. httpex.cpp (add connection and
Let's look at each line of code. The first line of
code initializes your connection to the name of the HTTP server and returns a pointer to a
CHttpConnection object. But what if the server had some sort of security? The code didn't
pass a username or password, so a secured connection would fail. The function parameters
for GetHttpConnection are (serverName,portNumber,userName,password). But because I'm using
the default system registry, I don't need to set the port number. The function definition
defaults this to INTERNET_INVALID_PORT_NUMBER. The username and password also default to
NULL so if I don't need them, I don't need to pass them as parameters. If a connection to
the server could not be established, the pServer pointer would be null. It is a good idea
to check that the pointer is not null before continuing; however, I don't do that here.
Any a real-world program, you would want to check the pointer before proceeding. This will
save you from possible exceptions in your code.
The second line of code requests the file
default.asp from the server. The first parameter CHttpExample::HTTP_VERB_GET tells the
server what kind of request you are making of it. If you pass this parameter as NULL, the
HTTP_VERB_GET is used. The other choices correspond with normal requests that can be made
to a Web server:
The object or filename you are interested in is the
second parameter. The rest of the parameters take default values, but to let you know what
they are I included them in the function call. The other parameters handle issues such as
what type of file you can accept (text-only is an example), what the URL address of the
object is (if the object is not in the Web's root directory), and how you want to handle
the file returned (don't cache, make it secure with encryption, and so on).
The last few lines of code close the connection to
the server and gracefully close down your CInternetSession object. You should be able to
build and run the code. The application at this point connects to the server, requests the
file, and then closes down. In order to look at the file, you need to add more code.
Insert Listing 13.6 just below the line //connection to server.
Listing 13.6. httpex.cpp (add file handling
You have now written the entire application to read
an HTML file and write it to the screen. Let's look at the code from Listing 13.6 in
The first line adds information to the header you
send to the server. You would use this if you wanted control over the exact request sent
to the server. Our CString variable headerInfo tells the server you accept text
information, and it tells the server the name of the application making the request. If
the function fails, it returns a 0 into fSuccess. You need to check every function that
returns a success code before continuing.
The second line sends the request. The function is
empty because you have already set the filename and location. However, if you were
executing a CGI script or ISAPI filter on the server, this is the function you would pass
the information to. This information could include the name of the script and parameters
to that script.
The next line returns information on how well our
request was satisfied. This is important because if there was a problem, you would need to
find out why. The return code dwReturnCode will be a number representing that success or
failure. In the code, I only check for 200 (the request was fulfilled without any errors)
because that means my request was satisfied. The return codes are broken down in Table
Table 13.1 Return codes.
The next line of code in Listing 13.6 uses the
QueryInfo method from the CHttpFile class. This method retrieves information from the
header that was returned from the server. The server can supply you with different kinds
of information that may be useful to a client application. The complete list is
The last two methods of code to discuss are the
SetReadBufferSize and ReadString. The SetReadBufferSize lets MFC know how large a buffer
of information you want each time you look at the file. ReadString reads the number of
bytes you specified in SetReadBufferSize.
In this example the program connected to a server,
read a file and header information returned from the server, and printed to the screen.
Figure 13.5 is a screen shot of this application. Notice the header information and then
the body of the HTML. The HTML isn't formatted because the ReadString method doesn't know
or care about formatting.
The program only used three functions from the
CInternetSession class in the HTTP example: the constructor, GetHttpConnection, and Close.
This class is flexible enough to handle all three connection types, set any options, and
handle any call backs. CInternetSession inherits from the MFC's CObject class. The CObject
class has nothing to do with the Internet, but it does have the methods necessary for
memory allocation, debugging, and serialization including new, delete, and the equals
operator (=). These are basic functions, but they are helpful here because you don't have
to write them yourself.
CInternetConnection and the Connection Classes
CInternetConnection is the base class for
CHttpConnection, CFtpConnection, and CGopherConnection. It provides methods to get the
server name, server context number, and session object. The CHttpConnection class doesn't
do much more. It only has two methods: a constructor and OpenRequest. The same is true for
the CGopherConnection class. These classes don't need many functions because most of the
work is done on the server.
Why would a programmer write an application for HTTP
or Gopher when they probably already have a Web browser or Gopher reader? There are a
variety of reasons, only limited by your needs. The interesting capabilities of these
classes are not getting a file to display the information as a browser would. However, if
that is what you want to do, go for it. Imagine you are a Web site administrator and you
need to check all the links on your pages to see if those pages, images, audio files, and
so on are working. You could write a program to anaylize the links on each page. You could
do this by finding the reference to the file and then attempting to retrieve that file. If
you can't get the file, neither can your browser. Another example is that many Web sites
want the current information on their Web pages to be attractive. It would be easy to
write a program that lists all files that have not been modified in the last 30 days.
These applications can be anywhere, not necessarily on the Web server.
The CFtpConnection Class
Although the classes for HTTP and Gopher do not have
many methods, the CFtpConnection class does because the client has more control and
choices about what he does on the server when he uses FTP. He can create or delete files
and directories. This is a powerful class because it allows greater flexibility that can
Imagine you know you will need every file and
subdirectory underneath the \computer-club directory. With a browser such as Microsoft
Internet Explorer, you would just have to click on each subdirectory and pull down each
file. Wouldn't it be nice if you could start one program and then go onto more interesting
things? When the program is finished, the files would appear on your hard drive just as
they appeared on the server. This would save you the time and the trouble of having to do
it yourself. Your program could even check to see if you had enough space on your hard
drive before bringing down each file.
The FTP Sample Application
This sample application will connect to an FTP
server, read all the files and directories in the root, and get a file named Welcome.txt.
The output of the application should look something like Figure 13.6.
As with the previous example, you will need to find
an FTP server and a file you want to retrieve from that server. If you have permissions to
write to that server, try to put a file on the server instead of getting a file.
In order to start, first create an application. We
need to create the application in the same manner as the previous example. Open up
Microsoft Visual C++, and make a new project workspace. Name the workspace FTPexam. Make
sure the project is a console application. The reason it is a console application is that
I don't want you to be confused by seeing any classes that are not closely related to
these WinInet classes. Because a console application doesn't use MFC by default, you need
to change the project so that it does use MFC. In your project, change your project
settings (Build Menu/Settings) to use MFC in a shared dll (General Tab/MFC drop-down
list). If you don't let the project know you need to use the MFC dll, when you build, you
will get linker errors regarding beginthread and endthread functions.
Because you have already written one application,
enter all the code for the second application. The general flow of the application should
make sense to you.
Create a header file ftpex.h that looks like Listing
Listing 13.7. ftpex.h (create header file).
The connection code is very similar to the HTTP
example's connection code. The major differences between this example and the previous one
are the use of CFtpFindFile and the methods used from CFtpConnection.
The CFtpConnection class has quite a few functions
for manipulating where the client is and what the client is doing on the server. The
methods of CFTPConnection are
Also notice that instead of using CInternetFile (as
in the CHTTP example), you used the CFtpFindFile class. Its members are
What about some of the functions we used to
manipulate the file that are not in the preceding class method list for CFtpFindFile, such
as IsDir? Because CFtpFindFile inherits from CFileFind, the codes get all the
functionality of this base class. The class is used by the Gopher and FTP connection
types. It gives the code some neat such as is the file really a directory or is the file
marked with the read-only attribute, when was the last time the file was accessed, and how
big is the file. These are just a few of our choices; the rest of the methods of CFileFind
I'll leave for you to discover.
Notice that the GetFile function's first two
parameters in Listing 13.8 were both fileName. The first variable defines the name of the
file I want to retrieve and the second variable defines the file on the local hard drive I
want. The fourth and fifth parameters are flags. The fourth parameter is what attributes
we want the file to have on our hard drive. Your choices are
The fifth parameter specifies the condition of the
transfer of the file. Your choices are text or binary:
Listing 13. 9 displays the httpex.cpp file in its
Listing 13.9. The HTTP example (entire httpex.cpp
In this chapter you learned about the Win32 Internet
API and the MFC classes corresponding to this API. These functions allow the client to
make a connection to a server. With these MFC classes, a programmer can make a connection
to a server and manipulate files. The neat feature of these classes is that a programmer
doesn't have to understand TCP/IP programming or any other low level functionality because
they abstract and manipulate this work for you.
The HTTP classes help you get files from a Web
server. The FTP classes let you do all the file and directory manipulation that an FTP
server will allow. The Gopher classes cover a little of the other two classes.
In your own browser, try to connect to an FTP site.
You may have to change the options of your browser. Also try to connect to the FTP site
through any commands supported by your operating system. Once you are connected, try
downloading a file. If you have a Web server, configure it for FTP, connect to it, and put
a file in its directory. Next, try to connect to a Gopher site. You may have to change the
options of your browser. Also try to connect to the Gopher site through any commands
supported by your operating system. Once you are connected, try downloading a file. If you
have a Web server, configure it for Gopher, connect to it, and get a file from its
directory. Try to use a search engine. Attempt to create a WAIS search on your Web server
(if you have one).