Editing the System Registry
Chapter 21
Creating an ActiveX
Control
In this chapter you will be exposed to some of the
advanced features of COM and DCOM OLE programming. First, you should know just what those
two words mean.
Until now, you have been learning how to use OLE
features within programs, and to use controls written by other people. For example, you used
the marquee control, but you did not create the marquee control. Programs such as
of Visual Basic (the next version) and Visual C++ enable you to create class objects
(objects that are derived from classes) and OCX controls that others can use in their own
applications.
A survey of the technologies that go into creating
an OLE control would fill a much larger volume than this one. However, for those of you
who will go on to creating these controls, this chapter reviews some of the features of
control creation and how they apply to ActiveX. You will learn
- How and why to edit the system registry
- Some of the features and requirements of a COM/DCOM
control
- OLE interface design for objects and classes
Editing the System
Registry
The system registry is the location for all the
system settings on an NT or Win95 machine. Actually, any system that supports OLE will
need to have some sort of equivalent to the system registry. When Microsoft introduced it
in Windows 3.0, it allowed third-party programmers to write applications for Windows,
which allowed Microsoft to sell more Windows, and so on.
Windows 3.0
Windows 3.0 has two sections of the Win.INI to
enable OLE-like features[Embedding] and [Extensions]. These sections tell the OLE
system what features are enabled and what file extensions are associated with those
features, respectively.
The format for the [Extensions] section follows a
standard keyname = value format. An example section would look like this:
[Extensions]
crd=cardfile.exe ^.crd
doc=C:\MSOFFICE\WINWORD\WINWORD.EXE ^.doc
MDB=C:\MSOFFICE\ACCESS\MSACCESS.EXE ^.MDB
mpp=C:\MSOFFICE\WINPROJ\winproj.exe ^.mpp
msg=C:\PROGRA~1\MICROS~1\exchng32.exe /f ^.msg
ppt=C:\MSOFFICE\POWERPNT\POWERPNT.EXE ^.ppt
qry=C:\WINDOWS\MSAPPS\MSQUERY\msquery.exe ^.qry
vbp=C:\VB\vb.exe ^.vbp
wri=write.exe ^.wri
The Win.INI [Extensions] Section
Extension = Application FilePath ^.Extension
The [Extensions] section of the Win.INI file defines
the application that is automatically associated with a given file extension. The INI file
itself takes precedence over any similar settings in the system registry.
foo = C:\FooDir\FooApp.exe ^.foo
In this example, an entry is made that will cause the computer to use the FooApp.exe
program to handle FOO files.
The format in the [Embedding] section of the Win.INI
tells the system the name of the control, the name of the object, the path to the control,
and the type of object. An example [Embedding] section would look like this:
[embedding]
Mplayer = Media Clip, Media Clip, mplayer.exe, picture
ComicChat.Room.1 = Comic Chat Room, Comic Chat Room, C:\MSN\CCHAT\CHAT.EXE, picture
The [Embedding] section of the Win.INI file defines
the OLE servers that can manipulate a given object. This file is only used for
backwards-compatibility with older Windows 3.0-style programs.
Example:
My Object = My Object, My Object, C:\MyAppDir\MyApp.exe, picture
In this example, an entry is made that tells the operating system about a new type of
server object called, My Object [ServerObject].
Next it gives the creatable object two descriptions. The first is a general name for the
object; the second is a more generally readable description for it that will appear in
menus and dialogs that refer to the object.
It also tells the system where there is an OLE server that is capable of creating one of
these server objects [OLE Server].
Finally, it says what kind of file the data file will be. This is almost always picture.
Windows 3.1
Windows 3.1 added speed and OLE features to the
access of the system registry components. Instead of keeping the information in diverse
sections of multiple files, it keeps the most important parts of the registry in few
fast-access binary files. Also, in response to the glut of programs being written for the
Windows brand of OLE, Microsoft pre-added entries for several third-party OLE applications
to the distribution copies of Windows 3.1. This made the installation of OLE-capable
programs go more easily.
Windows 95,98
In Windows 98, access to the registry files is sped
up considerably. This is to allow for the network feature of having dynamic keys. These
keys make it possible for counters and various other real-time and metered data to be kept
close to the processing environment.
Registry Components
The system registry is made up of information from
three files. These files contain user-specific, computer-specific, and system-specific
information. It would be difficult to show just what these files look like. They are not
very human-readable, but they still contain the binary representation of a whole data
structure. You have to use a tool like the RegEdit utility to read and manipulate the
registry database.
System.DAT
The System.DAT file contains the system-specific
information for the system, such as what type of monitor is installed, and how many keys
are on your keyboard.
Reg.DAT
The Reg.DAT file is the computer-specific
registration database of information for the system. It is through this database that
changes to the registry are made. It is where support for OLE happens in Windows 95. Drag
and Drop, OLE, and Compound Documents all refer to this database to perform their
operations.
User.DAT
The User.DAT file contains the user-specific
information about the user profile. This magic little feature of Windows 95 enables each
user of a machine to have a Desktop customized to his/her own taste.
The information for each user's particular setup is
contained in the policy settings portion of this file. User profiles make it possible for
Mom to access her newsgroups that are pointed to her favorites, and Dad's are still
pointed to his when he logs on to the system. They can also manage the ratings for Junior.
One computer, multiple configurations.
The last registries file to be loaded during boot-up
is the Policy.POL (System Policies) file. It can be edited with the System Policy Editor
(distributed with the Windows 95 Resource Kit). The settings in the system policy override
all other policies. It is usually loaded from the network so that all the systems can be
managed in one way.
Editing the Registry
Database
There are several good utilities that come with the
Windows 3.1, 95,98, and NT systems that can assist you in editing the registry settings.
RegEdit
Windows 3.1 and 98 come with RegEdit.exe (see Figure
21.1, usually in the \Windows\ directory. In Windows 3.1 you had the command line option
of /v to toggle between normal and advanced mode. In Windows 95 there is just one mode:
Power User.
Warning
For you diagnosticians out there, when you trace a
problem with a client machine to a "mysterious" registry problem, try to find
out if they did not go running around lose in the RegEdit program. It's a good place for
someone who does not know what they are doing to really hurt themselves.
Figure 21.1. The Windows 95
Registration Editor.
The RegEdit utility is handy for editing the way OLE
is carried out on a system. The functions that can be customized through RegEdit include
Open, Close, Delete, Print, Edit, and other functions you might find on the File menu of
an application.
When you have an OLE application on your system, you
will want to make sure that it's registered in the registration database. Ideally, the
software author included processes to automatically register and unregister their OLE
server.
If the author did not include this process, or if
the program somehow becomes unregistered on your system, there should be a REG file
somewhere. These files are associated with the RegEdit utility to register the software
component. This can also be done from the RegEdit Merge-Registration Info menu.
Here is a sample REG file for the Windows Media
Player (also see Figure 21.2:
REGEDIT
HKEY_CLASSES_ROOT\mplayer = Media Clip
HKEY_CLASSES_ROOT\mplayer\protocol\StdExecute\server = mplayer.exe
HKEY_CLASSES_ROOT\mplayer\protocol\StdFileEditing\Handler = mciole.dll
HKEY_CLASSES_ROOT\mplayer\protocol\StdFileEditing\server = mplayer.exe
HKEY_CLASSES_ROOT\mplayer\protocol\StdFileEditing\PackageObjects =
HKEY_CLASSES_ROOT\mplayer\protocol\StdFileEditing\verb\1 = &Edit
HKEY_CLASSES_ROOT\mplayer\protocol\StdFileEditing\verb\0 = &Play
HKEY_CLASSES_ROOT\mplayer\shell\open\command = mplayer.exe /play /close %1
;OLE2 Compatibility entries.
HKEY_CLASSES_ROOT\MPlayer\CLSID = {0003000E-0000-0000-C000-000000000046}
HKEY_CLASSES_ROOT\CLSID\
{0003000E-0000-0000-C000-000000000046} = Media Clip
HKEY_CLASSES_ROOT\CLSID\
{0003000E-0000-0000-C000-000000000046} \InprocHandler = mciole.dll
HKEY_CLASSES_ROOT\CLSID\
{0003000E-0000-0000-C000-000000000046}\ProgID = MPlayer
HKEY_CLASSES_ROOT\CLSID\
{0003000E-0000-0000-C000-000000000046} \Ole1Class = MPlayer
HKEY_CLASSES_ROOT\.avi = mplayer
HKEY_CLASSES_ROOT\.mmm = mplayer
HKEY_CLASSES_ROOT\.mid = mplayer
HKEY_CLASSES_ROOT\.rmi = mplayer
Figure 21.2. The registry
entries for MPLAYER from the MPlayer registry file .
For the truly advanced or daring administrator, the
RegEdit utility includes a menu option, Add | File Type, which enables you to manually add
the OLE registration information that should have been in the REG fileor to modify
it to your own preferences. It is very similar to Windows 95's Menu, View | Options | File
Types.
RegSvr32
You may have seen the RegSvr32.exe utility being
distributed in the setup disks for different programs. This is the command line utility to
register the OLE server features of an OCX or DLL file.
By typing RegSvr32 and the filename of an OLE
Server, you can register that item in the system registry. This registration process will
make its features available to all the other OLE-capable programs on your system.
The RegSvr32 Utility
RegSvr32.exe [/u] [/s] [/c] [OLE Server]
The 32-bit server registration utility is used to register and unregister OLE servers
(such as OCX and DLL files) in the system registry.
RegSvr32.exe /c MyServer.DLL
This will register the OLE server MyServer.DLL and output the results to the console
(monitor).
RegSvr32.exe /u /s MyServer.OCX
This will unregister the OLE server MyServer.OCX and will do it in silent mode (no output
to the console).
RegClean
The RegClean utility (See figure 21.3) is available
from Microsoft's Software Library (ftp://ftp.microsoft.com/SoftLib/MSLFiles).
It includes a Registry Cleanup utility that, among other things, will remove entries in
your system registry for components or OCX files that are no longer available to your
system.
Figure 21.3. Microsoft's
Registry Cleaning Wizard.
ActiveX and the System
Registry
There are many OLE controls out there that work just
fine as they are, ActiveX environment or not. To attain the title ActiveX Control, your
OCX or DLL file must support certain featureswhich the following sections introduce.
Note
This following sections introduce you to the APIs and SDKs involved in creating an ActiveX
control . There are a variety of these tools that you may wish to use (such as security
and versioning). Each can be quite complex and are included here for the truly daring
programmer.
Microsoft makes their Internet APIs and SDKs publicly available on its Web site. Also,
most of the documentation files on these tools were installed on your computer by the
ActiveX SDK in the \IntDev\ directory.
Self-Registering and
Versioning
An ActiveX Control's API must support the standard
calls for registering and unregistering a control.
The DLL Register Server Standard API feature (STDAPI
DLLRegisterServer()) loads all the .CLASS information (from the DLL or OCX file) into the
system registry.
The DLL UnRegister Server Standard API feature
(STDAPI DLLUnRegister Server()) removes all the previously loaded .CLASS information from
the System Registry.
Ver.DLL
Ver.DLL contains the Windows versioning features. It
supports three important functions:
- GetFileVersionInfoSize Returns the size (in bytes) of
the versioning information. This is useful to the programmer for reserving an appropriate
buffer into which he should retrieve this data. For instance, if you were working in
Visual Basic and retrieved this data into a string value (for whatever reason), you could
reserve a three-character string variable instead of a memory-hogging variant.
- GetFileVersionInfo Whether or not you make use of the
size of the versioning information, you can retrieve the data itself with this
function.
- VerQueryValue After you have retrieved the versioning
information, you use this function to retrieve VersionInfo that contains, among other
things, FileVersion, ProductVersion and two additional blocks of data. These two blocks
work together to identify the self-registering properties of the control.
- VarFileInfo Contains a pointer to the location of the
OLESelfRegister key within StringFileInfo.
Remote Procedure Calls
(RPCs)
RPCs provide the programmer with a series of
functions to access the Win32 registry. At this level, network functions such as SNMP
procedures can be used. The client machine would need to have the Microsoft RPC service
installed (from the \Admin\NetTools\ directory of the Windows 95 CD-ROM). Use of this
feature is not required for ActiveX Controls, but it sure is powerful.
Programmers add utility for users whose machines are
running the RPC service. If the user with whom you wish to interact is running the Windows
RPC service (included with the Windows 95 CD-ROM in \Admin\NetTools) this allows
programmatic access to the OLE procedure calls within Windows API. This is how features
such as SNMP can be accessed.
Base Security Layer SDK
Another feature which programmers can make use of is
the Base Security Layer of Windows. You were introduced to various parts of this feature
in earlier chapters. What should be made clear here is that much of the information that
is read from, and written to, ActiveX objects, is stored in the system registry. This goes
for all ActiveX security features such as code signing, ratings, trust verification, and
user locator services.
ActiveX Control Features
In order for a control to be truly
ActiveX/OLE-enabled, it must support the central features of OLEaggregation,
marshaling, and reference countingand support IUnknown interfaces. Briefly, these
can be defined as follows:
- Aggregation This feature enables one control to
incorporate the features of another into itself. Without aggregation, the control code
must be recompiled for each instance of the object (in other words, one objectone
control). With aggregation, you only need one control to manage any number of instances of
an object. This is an overly simplified definition, since there are all kinds of different
things that must go on in order to perform this function.
Note
The Java Virtual Machine (VM) uses a Garbage Collector rather than reference counting to
determine if it is being used and how many times.
Microsoft's implementation of the Java Virtual Machine combines OLE Reference Counting
with the Java Garbage Collector. This relieves the programmer of the burden of coding when
a reference to a control should be added or deleted, and of when a control needs to be
loaded or unloaded. Also Java allows for exception handling, whereas COM does not. These
are perfect examples of how Java makes OLE programming a lot easier!
- Marshaling Marshaling is the process in which select
features from one object are used within another object.
- Reference counting This feature helps to manage
memory use. When a COM object is loaded, it can be used to manipulate any number of
instances of that object. By keeping count of how many different ways it is being used,
the object can be unloaded when all other instances are cleared from use. (For you C++
programmers, that means you must use the AddRef and Release member functions when
instantiating your controls.)
- IUnknown All COM interfaces are based on this basic
interface. It is through these interfaces that OLE applications talk with each other. The
three primary interfaces implemented through IUnknown are QueryInterface, AddRef, and
Release.
To actually compile your control for use, you need
to use an OLE-aware programming environment such as Visual C++, Visual Basic, or Visual
Java++.
Visual J++ (Jakarta)
Visual J++ (which Microsoft codenamed
"Jakarta") is the first full-blown IDE to make Internet programming fully
available to OLE developers. (Refer to Figure 21.4 for a view of the Jakarta IDE.) This
programming language is based on the Java language developed by Sun Microsystems and
integrates the features of OLE.
In this marriage, COM objects are exposed to Java as
Java objects, and a public Java class is exposed to OLE as COM objects. Although you can
program COM objects in a variety of languages, you still must use a Java compiler to
create Java objects. This, however, may not be true for other Java compilers besides
Jakarta, since this one is based on the Microsoft Java VM.
One security feature for running Java applets in
ActiveX browsers is that they are hobbled. Hobbling restricts the control from
calling code or classes that cannot be verified by the Java byte code verifier. Also, any
interface that cannot be defined in a type library (TLB file) will be hobbled.
You can find more information about Visual J++ at
Microsoft's Web site, http://www.microsoft.com/visualj.
Figure 21.4. Microsoft's
Visual JAVA++ IDE.
Visual Basic
Visual Basic (Figure 21.5) supports various levels
of OLE connectivity with COM objects, depending on the version of VB you are using. Even
Visual Basic 4 enables you to program against a previously registered object.
A powerful feature of Visual Basic is its capability
to make API calls to OLE servers. This feature enables 16-bit VB applications to make
calls to 32-bit OLE out-of-process servers, and 32-bit VB applications to make calls to
16-bit OLE out-of-process servers. When using in-process servers, you still must consider
bitness.
Figure 21.5. Microsoft's
Visual Basic IDE.
You can find out more about Visual Basic at
Microsoft's Web site, http://www.microsoft.com/vbasic.
Warning
When making API calls over a distributed network
(such as with the Microsoft RPC Service API), performance is slowed considerably as remote
connections are established and disconnected.
VB is wonderful for using OLE servers. On the
enclosed CD-ROM, you should find a sample VB application, MyServer, for creating an OLE
server in VB4. It does not do anything, but if you view the source code with
Notepad, you will see that each contains nothing but comments about what should be
done in a particular part.
Visual C++
Visual C++ has always (until now, anyway) been the
language of choice for OLE programmers. Versions 4 and later enable you to program with
foundation classes (predefined OLE classes) or templates (programming language-specific
code snippets). Each has its own features for accessing COM.
Microsoft Foundation
Classes (MFCs)
C programmers do most of their OLE programming with
the classes supported in Microsoft's Foundation Classes Library. You must be sure to
include the dependent files with your distribution disks. These include
- MFC40.DLL May be different depending on your MFC
version
- MSVCRT.DLL Visual C++ RunTime libraries
- OLEPro32.DLL Required for OLE
ActiveX Template Library
(ATL)
The ATL is distributed by Microsoft to enable
programmers to use API calls instead of relying on foundation classes. The most current
version can be found at http://www.microsoft.com/visualc/v42/atl/default.asp.
This thing is a set of Visual C++ templates that
enable quick and easy programmatic access to the ActiveX OLE features. This library is not
at all a comprehensive library of functions, but it will enable you to create
redistributable functioning COM Class objects.
Dual Interfaces
The ATL enables you to add support for dual
interfaces to your C++ program. This makes possible access to features by way of both the
IDispatch interface and vtable entries. This enables interaction through third-party
features such as scripting.
Tear-Off Interfaces
This library also allows for support of Tear-Off
Interfaces. This means that an object can be enumerated (defined) within the system with
an IEnum... interface BUT you do not have to worry about the resource demand on your OLE
connection. The OLE connection is not actually instantiated (loaded) until it is used. It
can be used many times after that, and will stay loaded. When all the objects that were
using it report that they are no longer using it (that is, the reference count hits 0), it
is unloaded (uninstantiated).
IUnknownThe Center
of ActiveX OLE
When you create an OLE interface for an object,
there is one standard, IUnknown , with which most of your calls will work. (For a
graphical representation of how IUnknown is used as an interface, refer to figure 21.6.)
Determining the number of references (current implementations of this interface) and
querying the interface (asking about a specific implementation) is determined by the
processes that occur through this interface.
The basic model of the IUnknown interface would
support the QueryInterface, AddRef, and Release methods:
Interface IUnknown {
Virtual HResult QueryInterface(REFID, VOID FAR *) = 0;
Virtual ULong AddRef()=0;
Virtual ULong Release()=0;
};
An example of C++ code that would implement a
DragDrop function by way of the IUnknown interface would look like this:
Interface IDropTarget:IUnknown {
Virtual HResult DragDrop()=0;
Virtual HResult DragEnter()=0;
Virtual HResult DragLeave()=0;
Virtual HResult DragOver()=0;
};
Note
Make sure your program makes AddRef and Release calls as necessary. This will inform the
system when it is using an object and when it's not. Then the system can load and unload
it as necessary. If you keep opening interfaces and not closing them, you could easily run
out of memory and hang your system.
Every interface, IUnknown or not, implements three
methods:
- AddRef When an object is instantiated, it calls the
AddRef method to let COM increase the use count.
- QueryInterface Returns data based on a query from the
Interface Identification (IID) specified in a parameter.
- Release Informs COM that the object is no longer
needed and to decrease the use count for that interface. If the count is 0, the interface
will be uninstantiated altogether.
Figure 21.6. Graphical
representation of how programmers and their programs interact with COM.
OLE Definitions
OLE is a component technology (a theory).
COM is a convention for referring to computer objects.
A class is the definition of how one object behaves. The object it defines does not
exist until it is instantiated. Each has a 128-bit Uniform Unique Identifier property
(UUID).
An interface is any class based on the IUnknown class. This class will be the
contract under which any objects created with it will operate.
The IUnknown class provides the details of a user-defined object, but it can
not be loaded itself. It only provides the definitions by which other objects are loaded.
An ActiveX IDE (Integrated Design Environment) is a program that enables
interaction with COM objects.
A language is the syntax and vocabulary used in an IDE to reference objects and
procedures.
An object is the instantiation of an interface. It is usually contained in an EXE
or a DLL file, but can be on a remote machine altogether (using RPC) .
Summary
Taken as a whole, these features are a bit much to
swallow in one gulp. However, whether you are a control programmer who uses controls or a
control programmer who creates them, it is important to have an exposure to the design
considerations in ActiveX Controls.
Your ActiveX Controls will be working closely with
your system registry, and you may have to use a utility such as RegEdit or RegClean to fix
something. Also, if other programmers' controls are running rampant in your registry, you
may find it necessary to remove or edit them manually.
If you do design ActiveX Controls, you have a wide
choice of programming languages with which to work. Microsoft makes Visual Basic, Visual
C++, and Visual J++ with control creation features.
Also, you will need to include certain interfaces,
based on the IUnknown interface. They will need to be self-registering, using the API
calls for DLLRegisterServer and DLLUnRegisterServer. The controls will also need to
support versioning through API calls to Ver.DLL. Several additional, optional interfaces
can be added to the control to enable enhanced features such as RPCs (Remote Procedure
Calls) and code signing.
Q&A
- Q What's the difference between a class, a
control, and an object?
- A A class is a description of how an
OLE object works (a contract).
A control is the code, usually compiled into a DLL or an OCX file, that contains
the machine-level instructions (in other words, Mac-, PC-, or UNIX-specific) on how an
object interacts with the system (a transaction manager).
An object is created when a program tells a control to create one, following the
rules defined in a class.
- Q Can I change the system registry by editing the
[Embedding] and [Extensions] sections of my Win.INI file?
- A No. Only older programs that cannot use OLE
reference those sections. They expose a default Open process.
- Q Can I assign two or more programs to one file
extension in the [Extensions] section?
- A No. You can use the FileTypes tab from
Explorer to do this, but not the Win.INI file. An example would be that you cannot assign
both Notepad and Write to open a text file.
- Q Can I assign two or more file extensions to one
program in the [Extensions] section?
- A Yes. One program may be capable of opening
up a variety of files. An example would be that you can use Word to open DOC files as well
as RTF, TXT, and even HTML files.
- Q How can I back up my system registry alone?
- A Archive the three registry
filesReg.DAT, User.DAT, and System.DAT to a safe place. You might also want to
include your Autoexec.BAT and your Config.SYS as well as your Win.INI and System.INI while
you are at it, since they affect how your system registry will react.
- Q How does automatic registration work for the
user?
- A When a program, such as the Setup utility,
installs its controls, it should make an API call to the DLL and OCX files to tell them to
register themselves. This can also be done manually in one of two ways:
Using the RegSvr32.exe utility, included with Windows, run RegSvr32 [Filename] and the
control, if it supports self-registration, should be added to your system registry.
If the control author did not include self-registration interfaces in the control, it will
need to have a REG file with it. This file should have the information necessary to add
the OLE Server to the system registry. The filename for this can be used as a command-line
parameter for the RegEdit.exe utility (for example, RegEdit [Filename]).
If the control is not self-registering, and does not have a REG file, other programs will
only be able to access it while it is running.
- Q What, exactly, will RegClean.exe do to my
system?
- A Fix it. You can select options to allow or
disallow such features as the following:
- Validation of unrecognized or obsolete entries
- Validation of optional keys
- Check for empty keys
- Validation of type libraries
- Validation of cross-references
- Check OLE servers
- Check ProgIDs ClassIDs, and Handlers
- Check OLE conversions
- Check remote automation
Workshop
Create an OLE server that supports self-registering
and versioning using any or all the following IDEs:
- Visual C++ w/MFC
- Visual C++ w/ATL
- Visual Basic
- Visual J++
Quiz
- What section of the Win.INI file identifies OLE
objects?
- Which file, used by the system registry, identifies
the hardware that is installed on a local machine?
- Which utility is used to remove invalid and obsolete
entries from the system registry?
- What two interfaces must a control support to be
considered self-registering?
- What DLL file supports the API calls used in
versioning?
- Which programs will create both Java and COM objects?
- What dependent files must be installed on a user's
machine to use an ActiveX control that is based on MFCs (Microsoft Foundation Classes)?
- What COM interfaces are derived from IUnknown?
- What three methods must be supported by any interface
based on IUnknown?
- An object is an _____________
of an interface.
|