<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1192972388107063553</id><updated>2012-02-16T03:02:02.010-08:00</updated><category term='&quot;using&quot; C#'/><category term='.NET 3.0/Vista'/><category term='Audit'/><title type='text'>chamildezoysa</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://chamildz.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1192972388107063553/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://chamildz.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Chamil</name><uri>http://www.blogger.com/profile/00204727013782891667</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>10</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1192972388107063553.post-8854543893172380530</id><published>2007-04-24T23:08:00.000-07:00</published><updated>2007-04-24T23:10:07.183-07:00</updated><title type='text'>Good Bye MFC!! (Throwing MFC Out of Windows)</title><content type='html'>For years, Qt has advertised itself as a better MFC than MFC. Thanks to the Qt 4 Visual Studio Integration, it is now easier than ever for a Windows developer to develop cross-platform, high-performance &lt;span class="i"&gt;C++&lt;/span&gt; graphical user interface applications from his favorite IDE. &lt;p&gt;Qt is a C++ application development framework developed by Trolltech, a Norwegian software company. While Qt mainly focuses on enabing the development of graphical user interfaces, it also provides excellent support for networking, multithreading, &lt;span class="i"&gt;SQL&lt;/span&gt; operations (including &lt;span class="i"&gt;ODBC&lt;/span&gt;), &lt;span class="i"&gt;XML&lt;/span&gt;, and &lt;span class="i"&gt;Unicode.&lt;/span&gt;&lt;/p&gt; &lt;p&gt;For Windows developers, Qt offers the following advantages:&lt;/p&gt; &lt;p&gt;&lt;span class="enumeration"&gt;*&lt;/span&gt;&lt;span class="b"&gt;Enhanced C++performance.&lt;/span&gt; Qt is written in C/C++ (with parts in assembly language) and is highly-optimized to minimize memory usage and maximize speed. Applications based on Qt are native, compiled C++ applications that outperform those applications developed with &lt;span class="i"&gt;Java&lt;/span&gt; and &lt;span class="i"&gt;C#.&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span class="enumeration"&gt;*&lt;/span&gt;&lt;span class="b"&gt;Stability.&lt;/span&gt; Since its introduction in 1995, Qt has been actively developed and maintained by Trolltech. The current version, &lt;span class="i"&gt;Qt 4.1,&lt;/span&gt; was released in December 2005 and supports advanced features, such as semi-transparent controls, antialiased drawing, and bidirectional text rendering.&lt;/p&gt; &lt;p&gt;&lt;span class="enumeration"&gt;*&lt;/span&gt;&lt;span class="b"&gt;Ease of use.&lt;/span&gt; Qt has a clean, object-oriented, C++ design, and provides a powerful &lt;span class="i"&gt;signal and slot&lt;/span&gt; mechanism similar to C#’ s events and delegates. Signals and slots are flexible, fully object-oriented and implemented in C++ through a separate tool called moc (the meta-object compiler).&lt;/p&gt; &lt;p&gt;&lt;span class="enumeration"&gt;*&lt;/span&gt;&lt;span class="b"&gt;Portability.&lt;/span&gt; Qt provides a uniform application programming interface for Microsoft Windows, from &lt;span class="i"&gt;Windows 98&lt;/span&gt; to &lt;span class="i"&gt;Windows XP, Mac OS X, Linux, Solaris, HP-UX, IRIX, AIX,&lt;/span&gt; and many other &lt;span class="i"&gt;Unix&lt;/span&gt; variants. Qt’s" write once, compile everywhere" philosophy lets you develop applications on Windows and deploy them later on other platforms.&lt;/p&gt; &lt;p&gt;Internally, Qt emulates the various platforms’ controls using platform-specific APIs such as &lt;span class="i"&gt;GDI+&lt;/span&gt; and the Windows XP theming engine. This enables Qt to accurately reproduce the look-and-feel of each supported platform, and allows programmers to extend or customize Qt’s built-in controls by re-implementing virtual functions. It’s even possible to implement a custom style to give all controls a custom look-and-feel, and to distribute it as a plug-in.&lt;/p&gt; &lt;p&gt;Although Qt is cross-platform, it includes a few Windows-specific modules, notably an MFC-to-Qt migration framework and a COM/ActiveX integration (to create and embed ActiveX controls). Today, Qt is used by companies as diverse as AT&amp; T, IBM, NASA and Xerox, and mass-market applications such as Adobe Photoshop Album and Google Earth are developed using it. In addition, the open source edition of Qt is the foundation of KDE, one of the two major Linux/Unix desktop environments.&lt;/p&gt; &lt;p class="subhead"&gt;Overview of the Qt 4 Visual Studio Integration&lt;/p&gt; &lt;p&gt;The Visual Studio integration, introduced with Qt 4.0, takes advantage of Visual Studio’s highly extensible architecture to make C++ application development on Windows faster, easier, and more intuitive than ever before. The integration includes the following features:&lt;/p&gt; &lt;p&gt;&lt;span class="enumeration"&gt;*&lt;/span&gt;&lt;span class="b"&gt;Fully integrated form editor with layout support.&lt;/span&gt; Since version 2.2, Qt includes a powerful visual user interface design tool called &lt;span class="i"&gt;Qt Designer,&lt;/span&gt; with support for automatic layouts and dynamic, XML-based user interfaces. The integration encapsulates Qt Designer in Visual Studio, with Qt properties displayed in the standard Property Browser (see &lt;span class="i"&gt;Figure One&lt;/span&gt;).&lt;/p&gt; &lt;div class="figure"&gt; &lt;div class="sidebartitle"&gt;&lt;span class="callout"&gt;FIGURE ONE:&lt;/span&gt; &lt;span class="caption"&gt;The integrated form editor&lt;/span&gt;&lt;br /&gt;&lt;/div&gt; &lt;a href="http://www.linux-mag.com/images/2006-12/qt/vs_14.jpg" class="story_image"&gt;&lt;img src="http://www.linux-mag.com/images/2006-12/qt/vs_14.jpg" class="story_image" /&gt;&lt;/a&gt;&lt;/div&gt; &lt;p&gt;&lt;span class="enumeration"&gt;*&lt;/span&gt;&lt;span class="b"&gt;Wizards for creating new Qt projects.&lt;/span&gt; The wizards let you specify the Qt modules you want to use and generate skeleton classes to get you started (see Figure 2).&lt;/p&gt; &lt;div class="figure"&gt; &lt;div class="sidebartitle"&gt;&lt;span class="callout"&gt;FIGURE TWO:&lt;/span&gt; &lt;span class="caption"&gt;The Qt Application wizard&lt;/span&gt;&lt;br /&gt;&lt;/div&gt; &lt;a href="http://www.linux-mag.com/images/2006-12/qt/vs_03.jpg" class="story_image"&gt;&lt;img src="http://www.linux-mag.com/images/2006-12/qt/vs_03.jpg" class="story_image" /&gt;&lt;/a&gt;&lt;/div&gt; &lt;p&gt;&lt;span class="enumeration"&gt;*&lt;/span&gt;&lt;span class="b"&gt;Automated build setup for Qt-specific build steps.&lt;/span&gt; Qt includes three tools that generate C++ code behind the scenes: &lt;span class="i"&gt;moc&lt;/span&gt; (the meta-object compiler), &lt;span class="i"&gt;uic&lt;/span&gt; (the user interface compiler), and &lt;span class="i"&gt;rcc&lt;/span&gt; (the resource compiler). These are invoked automatically by the integration when necessary.&lt;/p&gt; &lt;p&gt;&lt;span class="enumeration"&gt;*&lt;/span&gt;&lt;span class="b"&gt;An integrated resource management system.&lt;/span&gt; Adding new resources to a Qt project is comparable to adding resources to a standard C++ project. The main difference is that cross-platform &lt;span class="i"&gt;.qrc&lt;/span&gt; files (Qt resource files) are used rather than Windows &lt;span class="i"&gt;.rc&lt;/span&gt; files.&lt;/p&gt; &lt;p&gt;&lt;span class="enumeration"&gt;*&lt;/span&gt;Integrated Qt documentation. Qt’s comprehensive API documentation is integrated with the Visual Studio online help (see &lt;span class="i"&gt;Figure Three&lt;/span&gt;).&lt;/p&gt; &lt;div class="figure"&gt; &lt;div class="sidebartitle"&gt;&lt;span class="callout"&gt;FIGURE THREE:&lt;/span&gt; &lt;span class="caption"&gt;The Qt reference documentation&lt;/span&gt;&lt;br /&gt;&lt;/div&gt; &lt;a href="http://www.linux-mag.com/images/2006-12/qt/vs_12.jpg" class="story_image"&gt;&lt;img src="http://www.linux-mag.com/images/2006-12/qt/vs_12.jpg" class="story_image" /&gt;&lt;/a&gt;&lt;/div&gt; &lt;p class="subhead"&gt;A Regular Expression Tester&lt;/p&gt; &lt;p&gt;To illustrate how the Visual Studio integration works, let’s create a very small application to let the user try a regular expression against a string. The application, depicted in &lt;span class="i"&gt;Figure Four,&lt;/span&gt; is a dialog box with three &lt;span class="i"&gt;QLabels,&lt;/span&gt; three &lt;span class="i"&gt;QLineEdits,&lt;/span&gt; and two &lt;span class="i"&gt;QPushButtons.&lt;/span&gt; The user can enter a regular expression pattern and some text on which the regular expression is run; the part of the text that matches is shown in the bottom-most QLineEdit.&lt;/p&gt; &lt;div class="figure"&gt; &lt;div class="sidebartitle"&gt;&lt;span class="callout"&gt;FIGURE FOUR:&lt;/span&gt; &lt;span class="caption"&gt;RegExpTester application&lt;/span&gt;&lt;br /&gt;&lt;/div&gt; &lt;a href="http://www.linux-mag.com/images/2006-12/qt/vs_11.jpg" class="story_image"&gt;&lt;img src="http://www.linux-mag.com/images/2006-12/qt/vs_11.jpg" class="story_image" /&gt;&lt;/a&gt;&lt;/div&gt; &lt;p&gt;The first step is to create a skeleton project. Invoke the New Project dialog in Visual Studio and click the Qt Projects folder (see &lt;span class="i"&gt;Figure Five&lt;/span&gt;). Next, select the Qt Application item and type" RegExpTexter" as the project name. This pops up the wizard shown in &lt;span class="i"&gt;Figure Two.&lt;/span&gt;&lt;/p&gt; &lt;div class="figure"&gt; &lt;div class="sidebartitle"&gt;&lt;span class="callout"&gt;FIGURE FIVE:&lt;/span&gt; &lt;span class="caption"&gt;Creating a new Qt project&lt;/span&gt;&lt;br /&gt;&lt;/div&gt; &lt;a href="http://www.linux-mag.com/images/2006-12/qt/vs_01.jpg" class="story_image"&gt;&lt;img src="http://www.linux-mag.com/images/2006-12/qt/vs_01.jpg" class="story_image" /&gt;&lt;/a&gt;&lt;/div&gt; &lt;p&gt;The wizard includes a page to specify which Qt modules you want to link against, followed by a page that enables you to specify the name of the skeleton class to be generated by the wizard. For this example, change the base class of the generated class so that it’s QDialog, not QMainWindow, because the application is a simple dialog-style application with no menus or toolbars.&lt;/p&gt; &lt;p&gt;We’ll now design the dialog using the integrated Qt Designer form editor. To invoke the form editor, we click on the regexptester.ui file in the Visual Studio Solution Explorer. Then we drag the controls we need from the Qt Toolbox onto the form and position them approximately as shown in Figure 6. (Qt’s layout system will lay them out precisely later on.)&lt;/p&gt; &lt;div class="figure"&gt; &lt;div class="sidebartitle"&gt;&lt;span class="callout"&gt;FIGURE SIX:&lt;/span&gt; &lt;span class="caption"&gt;Placing controls on a form&lt;/span&gt;&lt;br /&gt;&lt;/div&gt; &lt;a href="http://www.linux-mag.com/images/2006-12/qt/vs_04.jpg" class="story_image"&gt;&lt;img src="http://www.linux-mag.com/images/2006-12/qt/vs_04.jpg" class="story_image" /&gt;&lt;/a&gt;&lt;/div&gt; &lt;p&gt;The next step is to edit the controls’ properties using the Property Browser. &lt;span class="i"&gt;Table One&lt;/span&gt; lists the properties that need to be set.&lt;/p&gt; &lt;div class="table"&gt; &lt;div class="sidebartitle"&gt;&lt;span class="callout"&gt;TABLE ONE:&lt;/span&gt; &lt;span class="caption"&gt;Setting the controls’ properties&lt;/span&gt;&lt;br /&gt;&lt;/div&gt; &lt;table class="table"&gt; &lt;tbody&gt;&lt;tr&gt; &lt;th&gt;Control&lt;/th&gt; &lt;th&gt;Property&lt;/th&gt; &lt;th&gt;Value&lt;/th&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;First label&lt;/td&gt; &lt;td&gt;ObjectName&lt;/td&gt; &lt;td&gt;“patternLabel”&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;br /&gt;&lt;/td&gt; &lt;td&gt;Text&lt;/td&gt; &lt;td&gt;“Pattern:”&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Second label&lt;/td&gt; &lt;td&gt;ObjectName&lt;/td&gt; &lt;td&gt;“textLabel”&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;br /&gt;&lt;/td&gt; &lt;td&gt;Text&lt;/td&gt; &lt;td&gt;“Text:”&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Third label&lt;/td&gt; &lt;td&gt;ObjectName&lt;/td&gt; &lt;td&gt;“resultLabel”&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;br /&gt;&lt;/td&gt; &lt;td&gt;Text&lt;/td&gt; &lt;td&gt;“Result:”&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;First line edit&lt;/td&gt; &lt;td&gt;ObjectName&lt;/td&gt; &lt;td&gt;“patternLineEdit”&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Second line edit&lt;/td&gt; &lt;td&gt;ObjectName&lt;/td&gt; &lt;td&gt;“textLineEdit”&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Third line edit&lt;/td&gt; &lt;td&gt;ObjectName&lt;/td&gt; &lt;td&gt;“resultLineEdit”&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;br /&gt;&lt;/td&gt; &lt;td&gt;Editable&lt;/td&gt; &lt;td&gt;false&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;First button&lt;/td&gt; &lt;td&gt;ObjectName&lt;/td&gt; &lt;td&gt;“resetButton”&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;br /&gt;&lt;/td&gt; &lt;td&gt;Text&lt;/td&gt; &lt;td&gt;“Reset”&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Second button&lt;/td&gt; &lt;td&gt;ObjectName&lt;/td&gt; &lt;td&gt;“closeButton”&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;br /&gt;&lt;/td&gt; &lt;td&gt;Text&lt;/td&gt; &lt;td&gt;“Close”&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;/div&gt; &lt;p&gt;You need to add layouts to the form to make it look better and to make it resizable. First, add a horizontal layout to position the Reset and Close buttons side by side. You also need a spacer to push the buttons to the right of the layout. To add a spacer, drag the Vertical Spacer item from the Qt Toolbox onto the form, next to the push buttons. Then select the spacer and the buttons and click Form Editor|Layout Horizontally from the Qt entry in the menu bar.&lt;/p&gt; &lt;p&gt;The entire window also needs a layout that will take care of positioning the other controls as well as the button sub-layout. To add this layout, select the labels, the line edits, and the button layout, then click Form Editor&amp; gt; Layout in a Grid. This gives the form shown in &lt;span class="i"&gt;Figure Seven.&lt;/span&gt;&lt;/p&gt; &lt;div class="figure"&gt; &lt;div class="sidebartitle"&gt;&lt;span class="callout"&gt;FIGURE SEVEN:&lt;/span&gt; &lt;span class="caption"&gt;The form with layouts&lt;/span&gt;&lt;br /&gt;&lt;/div&gt; &lt;a href="http://www.linux-mag.com/images/2006-12/qt/vs_07.jpg" class="story_image"&gt;&lt;img src="http://www.linux-mag.com/images/2006-12/qt/vs_07.jpg" class="story_image" /&gt;&lt;/a&gt;&lt;/div&gt; &lt;p&gt;Qt’s layouts automatically assign reasonable positions and sizes to the controls they are responsible for, based on their needs. This is especially useful in internationalized applications: With fixed sizes and positions, the translation text is often truncated; with layouts, the child widgets are automatically resized. Layouts can also run right-to-left, to accommodate languages such as Arabic and Hebrew.&lt;/p&gt; &lt;p&gt;You can click Form Editor&amp; gt; Preview Form at any time to preview the form without compiling it. If you build the application now, the result is the dialog depicted in &lt;span class="i"&gt;Figure Four.&lt;/span&gt;&lt;/p&gt; &lt;p&gt;However, the dialog is inoperative. Let’s start by making the Close button work. You can connect the button’s &lt;span class="c"&gt;clicked()&lt;/span&gt; signal to the form’s &lt;span class="c"&gt;accept()&lt;/span&gt; slot. This can be done through the form editor.&lt;/p&gt; &lt;p&gt;&lt;span class="enumeration"&gt;1.&lt;/span&gt;Click the Edit Connections toolbar button to enter the connection mode.&lt;/p&gt; &lt;p&gt;&lt;span class="enumeration"&gt;2.&lt;/span&gt;Click the form’s Close button and hold the left mouse button pressed, then move the cursor to an empty area of the form and release the mouse button (see &lt;span class="i"&gt;Figure Eight&lt;/span&gt;). This invokes the Configure Connection dialog, which lists the available signals and slots.&lt;/p&gt; &lt;p&gt;&lt;span class="enumeration"&gt;3.&lt;/span&gt;Choose the &lt;span class="c"&gt;clicked()&lt;/span&gt; signal and the &lt;span class="c"&gt;accept()&lt;/span&gt; slot and click OK.&lt;/p&gt; &lt;div class="figure"&gt; &lt;div class="sidebartitle"&gt;&lt;span class="callout"&gt;FIGURE EIGHT:&lt;/span&gt; &lt;span class="caption"&gt;Connecting a signal to a slot visually&lt;/span&gt;&lt;br /&gt;&lt;/div&gt; &lt;a href="http://www.linux-mag.com/images/2006-12/qt/vs_09.jpg" class="story_image"&gt;&lt;img src="http://www.linux-mag.com/images/2006-12/qt/vs_09.jpg" class="story_image" /&gt;&lt;/a&gt; &lt;a href="http://www.linux-mag.com/images/2006-12/qt/vs_10.jpg" class="story_image"&gt;&lt;img src="http://www.linux-mag.com/images/2006-12/qt/vs_10.jpg" class="story_image" /&gt;&lt;/a&gt;&lt;/div&gt; &lt;p&gt;Qt controls emit" signals" when state changes take place, for example when the text changes in a line edit, or when a new item is selected in a list box. These signals can be" connected" to slots (member functions), so that when a signal is emitted, any slots it is connected to are called. Controls that are connected to one another are independent components since they don’t need to know anything about each other.&lt;/p&gt; &lt;p&gt;If you build and run the application now, the Close button closes the window and causes the application to terminate.&lt;/p&gt; &lt;p class="subhead"&gt;More Fun With Dialogs&lt;/p&gt; &lt;p&gt;Let’s continue and implement the rest of the dialog functionality. The contents of the Result line need to be updated whenever the user edits the text in one of the two other line edits. This is achieved by adding a slot called &lt;span class="c"&gt;updateResult()&lt;/span&gt; to the form and by connecting the two line edits’ &lt;span class="c"&gt;textChanged()&lt;/span&gt; signals to that slot. The signals are emitted whenever the text changes; the connection ensures that the slot is invoked to recompute the Result line edit’s contents based on the new text in the Pattern and Text fields.&lt;/p&gt; &lt;p&gt;For that, you must edit the &lt;span class="i"&gt;regexptester.h&lt;/span&gt; and &lt;span class="i"&gt;regexptester.cpp&lt;/span&gt; files that were generated by the Qt Application wizard. &lt;span class="i"&gt;Listing One&lt;/span&gt; shows the header file after adding the slot declaration. Notice the particular syntax for declaring a slot; this is Qt-specific and is converted into standard C++ by the C++ preprocessor.&lt;/p&gt; &lt;div class="listing"&gt; &lt;div class="sidebartitle"&gt;&lt;span class="callout"&gt;LISTING ONE:&lt;/span&gt; &lt;span class="caption"&gt;The form’s header file&lt;/span&gt;&lt;br /&gt;&lt;/div&gt; #ifndef REGEXPTESTER_H&lt;br /&gt;#define REGEXPTESTER_H&lt;br /&gt;&lt;br /&gt;#include &lt;qtgui/qdialog&gt;&lt;br /&gt;#include "ui_regexptester.h"&lt;br /&gt;&lt;br /&gt;class RegExpTester : public QDialog&lt;br /&gt;{&lt;br /&gt;Q_OBJECT&lt;br /&gt;&lt;br /&gt;public:&lt;br /&gt;RegExpTester(QWidget *parent = 0, Qt::WFlags flags = 0);&lt;br /&gt;~RegExpTester();&lt;br /&gt;&lt;br /&gt;private slots:&lt;br /&gt;void updateResult();&lt;br /&gt;&lt;br /&gt;private:&lt;br /&gt;Ui::RegExpTesterClass ui;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;#endif // REGEXPTESTER_H&lt;br /&gt;&lt;/div&gt; &lt;p&gt;The &lt;span class="c"&gt;RegExpTester&lt;/span&gt; class inherits from &lt;span class="c"&gt;QDialog&lt;/span&gt; (the class you specified in the project wizard) and represents the entire dialog.&lt;/p&gt; &lt;p&gt;The first unusual thing to notice about the class definition is the &lt;span class="c"&gt;Q_OBJECT&lt;/span&gt; macro. This signifies that the class has some Qt extensions to C++ that will be discussed shortly. The private slots are private member functions that can also be called by Qt’s signals and slots mechanism.&lt;/p&gt; &lt;p&gt;The header file includes a file called &lt;span class="i"&gt;ui_regexptester.h.&lt;/span&gt; That file is generated by the &lt;span class="i"&gt;uic&lt;/span&gt; program based on the &lt;span class="i"&gt;regexptester.ui,&lt;/span&gt; an XML file that stores the form we designed using the form editor. The &lt;span class="i"&gt;uic-&lt;/span&gt; generated &lt;span class="i"&gt;ui_regexptester.h&lt;/span&gt; file declares a class called &lt;span class="c"&gt;Ui::RegExpTester&lt;/span&gt;. In the private section of the &lt;span class="c"&gt;RegExpTester&lt;/span&gt; class, there is a member variable of type &lt;span class="c"&gt;Ui::RegExpTester&lt;/span&gt; called &lt;span class="c"&gt;ui&lt;/span&gt;.&lt;/p&gt; &lt;p&gt;The updateResult() slot needs to be implemented and connected to the Pattern and Text line edit’s textChanged() signals. This is done in the regexptester.cpp file, listed in &lt;span class="i"&gt;Listing Two.&lt;/span&gt; Again, the code that needs to be added to the wizard-generated skeleton is shown in bold.&lt;/p&gt; &lt;div class="listing"&gt; &lt;div class="sidebartitle"&gt;&lt;span class="callout"&gt;LISTING TWO:&lt;/span&gt; &lt;span class="caption"&gt;The form’s source file&lt;/span&gt;&lt;br /&gt;&lt;/div&gt; #include "regexptester.h"&lt;br /&gt;&lt;br /&gt;RegExpTester::RegExpTester(QWidget *parent, Qt::WFlags flags)&lt;br /&gt;: QDialog(parent, flags)&lt;br /&gt;{&lt;br /&gt;ui.setupUi(this);&lt;br /&gt;connect(ui.patternLineEdit, SIGNAL(textChanged(QString)),&lt;br /&gt;this, SLOT(updateResult()));&lt;br /&gt;connect(ui.textLineEdit, SIGNAL(textChanged(QString)),&lt;br /&gt;this, SLOT(updateResult()));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;RegExpTester::~RegExpTester()&lt;br /&gt;{&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void RegExpTester::updateResult()&lt;br /&gt;{&lt;br /&gt;QRegExp regExp(ui.patternLineEdit-&gt;text());&lt;br /&gt;if (regExp.indexIn(ui.textLineEdit-&gt;text()) != -1)&lt;br /&gt;ui.resultLineEdit-&gt;setText(regExp.cap(0));&lt;br /&gt;else&lt;br /&gt;ui.resultLineEdit-&gt;setText("&lt;no&gt;");&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt; &lt;p&gt;The constructor calls &lt;span class="c"&gt;setupUi()&lt;/span&gt; on the &lt;span class="c"&gt;Ui::RegExpTester&lt;/span&gt; object to create the form’s controls and layouts. Then, the Pattern line edit’s &lt;span class="c"&gt;textChanged()&lt;/span&gt; signal is connected to the &lt;span class="c"&gt;updateResult()&lt;/span&gt; slot. The same is done with the Text line edit.&lt;/p&gt; &lt;p&gt;In the &lt;span class="c"&gt;updateResult()&lt;/span&gt; slot, the regular expression pattern is applied to the specified text. If the regular expression matches, the matched text is shown in the Result line edit; otherwise, it shows"&amp; lt;no match&amp; gt;".&lt;/p&gt; &lt;p&gt;The dialog is almost fully functional. The only remaining issue is that the Reset button still does nothing. The solution is to add a &lt;span class="c"&gt;reset()&lt;/span&gt; slot and connect it to the Reset button’s &lt;span class="c"&gt;clicked()&lt;/span&gt; signal in the constructor. The slot is implemented as follows:&lt;/p&gt; &lt;pre&gt;void RegExpTester::reset()&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;   ui.patternLineEdit-&gt;clear();&lt;br /&gt;&lt;br /&gt;   ui.textLineEdit-&gt;clear();&lt;br /&gt;&lt;br /&gt;   updateResult();&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt; &lt;p&gt;This completes the small sample application. But what about &lt;span class="c"&gt;Q_OBJECT&lt;/span&gt;, private slots, and other Qt keywords? The C preprocessor turns them all into pure C++ so the compiler never sees them. The machinery to handle Qt’s extensions is generated behind the scenes by &lt;span class="i"&gt;moc&lt;/span&gt;, which reads your source files and generates some additional source files to implement what we’ve used.&lt;/p&gt; &lt;p class="subhead"&gt;Goodbye, MFC&lt;/p&gt; &lt;p&gt;Microsoft is giving up MFC and is preparing to replace its successor, Windows Forms, with the Avalon framework. The uncertainty surrounding these three APIs has alienated many Windows developers, who are now looking at Qt as a more stable alternative.&lt;/p&gt; &lt;p&gt;With the Qt 4 Visual Studio Integration, a Windows developer can easily leverage his or her existing C++ skills to develop cross-platform, high-performance object-oriented, GUI applications.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1192972388107063553-8854543893172380530?l=chamildz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chamildz.blogspot.com/feeds/8854543893172380530/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1192972388107063553&amp;postID=8854543893172380530' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1192972388107063553/posts/default/8854543893172380530'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1192972388107063553/posts/default/8854543893172380530'/><link rel='alternate' type='text/html' href='http://chamildz.blogspot.com/2007/04/good-bye-mfc-throwing-mfc-out-of.html' title='Good Bye MFC!! (Throwing MFC Out of Windows)'/><author><name>Chamil</name><uri>http://www.blogger.com/profile/00204727013782891667</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1192972388107063553.post-1381546018574899912</id><published>2007-02-02T02:24:00.000-08:00</published><updated>2007-02-02T02:33:59.147-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET 3.0/Vista'/><title type='text'>Moving to Windows Vista x64 - .NET 3.0</title><content type='html'>&lt;span name="intelliTxt" id="intelliTXT"&gt;&lt;ul class="download"&gt;&lt;li&gt;&lt;a href="http://www.codeproject.com/vista/vista_x64/test.zip"&gt;Download test.zip from here - 16 KB&lt;/a&gt;  &lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codeproject.com/vista/vista_x64/privileges.zip"&gt;Download privileges.zip from here - 8 KB&lt;/a&gt;  &lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codeproject.com/vista/vista_x64/RandTest.zip"&gt;Download RandTest.zip from here - 101 KB&lt;/a&gt;  &lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codeproject.com/vista/vista_x64/MyRegFilter.zip"&gt;Download MyRegFilter.zip from here - 9 KB&lt;/a&gt;  &lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codeproject.com/vista/vista_x64/Communication.zip"&gt;Download Communication.zip from here - 22 KB&lt;/a&gt;  &lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codeproject.com/vista/vista_x64/SmallWPF.zip"&gt;Download SmallWPF.zip from here - 374 KB&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;h2&gt;Contents&lt;/h2&gt; &lt;table border="0" width="100%"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="297"&gt; &lt;ul&gt;&lt;li&gt;&lt;a href="#Introduction"&gt;Introduction&lt;/a&gt;  &lt;/li&gt;&lt;li&gt;&lt;a href="#x64_Section"&gt;x64 Section&lt;/a&gt;  &lt;ul&gt;&lt;li&gt;&lt;a href="#x64_Assembly"&gt;x64 Assembly&lt;/a&gt;   &lt;/li&gt;&lt;li&gt;&lt;a href="#C/C++_Programming"&gt;C/C++ Programming &lt;/a&gt;  &lt;/li&gt;&lt;li&gt;&lt;a href="#Inline_Assembly"&gt;Inline Assembly&lt;/a&gt;   &lt;/li&gt;&lt;li&gt;&lt;a href="#Windows_On_Windows"&gt;Windows On Windows&lt;/a&gt;   &lt;/li&gt;&lt;li&gt;&lt;a href="#File_System_And_Registry_Redirection"&gt;File System And Registry Redirection&lt;/a&gt;   &lt;/li&gt;&lt;li&gt;&lt;a href="#Interprocess_Communication_"&gt;Interprocess Communication &lt;/a&gt;  &lt;/li&gt;&lt;li&gt;&lt;a href="#Portable_Executable"&gt;Portable Executable&lt;/a&gt;   &lt;/li&gt;&lt;li&gt;&lt;a href="#Exception_Handling"&gt;Exception Handling&lt;/a&gt;   &lt;/li&gt;&lt;li&gt;&lt;a href="#.NET_Framework"&gt;.NET Framework &lt;/a&gt; &lt;/li&gt;&lt;/ul&gt; &lt;/li&gt;&lt;li&gt;&lt;a href="#Vista_Section"&gt;Vista Section&lt;/a&gt;  &lt;ul&gt;&lt;li&gt;&lt;a href="#Editions_"&gt;Editions&lt;/a&gt;  &lt;/li&gt;&lt;li&gt;&lt;a href="#Microsoft_Visual_Studio"&gt;Microsoft Visual Studio&lt;/a&gt;   &lt;/li&gt;&lt;li&gt;&lt;a href="#User_Account_Control"&gt;User Account Control&lt;/a&gt;   &lt;/li&gt;&lt;li&gt;&lt;a href="#Compatibility_Verification"&gt;Compatibility Verification&lt;/a&gt;   &lt;/li&gt;&lt;li&gt;&lt;a href="#Obtaining_Admin_Rights"&gt;Obtaining Admin Rights&lt;/a&gt;   &lt;/li&gt;&lt;li&gt;&lt;a href="#Disable_It"&gt;Disable It&lt;/a&gt;   &lt;/li&gt;&lt;li&gt;&lt;a href="#Address_Space_Layout_Randomization"&gt;Address Space Layout Randomization&lt;/a&gt;  &lt;/li&gt;&lt;li&gt;&lt;a href="#Driver_Signing"&gt;Driver Signing&lt;/a&gt;   &lt;/li&gt;&lt;li&gt;&lt;a href="#Patch_Guard"&gt;Patch Guard&lt;/a&gt;   &lt;/li&gt;&lt;li&gt;&lt;a href="#Attacks"&gt;Attacks&lt;/a&gt;  &lt;/li&gt;&lt;li&gt;&lt;a href="#Registry_Filtering"&gt;Registry Filtering&lt;/a&gt;  &lt;/li&gt;&lt;li&gt;&lt;a href="#Power_Management_"&gt;Power Management&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;/li&gt;&lt;li&gt;&lt;a href="#.NET_Framework_3.0"&gt;.NET Framework 3.0&lt;/a&gt;  &lt;ul&gt;&lt;li&gt;&lt;a href="#Windows_Presentation_Foundation"&gt;Windows Presentation Foundation&lt;/a&gt;  &lt;/li&gt;&lt;li&gt;&lt;a href="#Windows_Communication_Foundation"&gt;Windows Communication Foundation&lt;/a&gt;   &lt;/li&gt;&lt;li&gt;&lt;a href="#Windows_Workflow_Foundation"&gt;Windows Workflow Foundation&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt; &lt;/li&gt;&lt;li&gt;&lt;a href="#Conclusions"&gt;Conclusions&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/td&gt; &lt;td&gt;&lt;img alt="Windows Vista x64 Logo" src="http://www.codeproject.com/vista/vista_x64/vistalogo.jpg" height="166" width="174" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;h2&gt;&lt;a name="Introduction"&gt;Introduction&lt;/a&gt;&lt;/h2&gt; &lt;p nd="1"&gt;This is an introduction to Windows Vista and the x64 architecture. Writing an article like this is always uneasy, because there's plenty to talk about, but on the other hand it's an article, not a book. I tried to focus on some important aspects, but it goes without saying it that I had to cut out a lot (e.g. the User-Mode Driver Framework, and I'm very sorry for that). This is just a general overview on certain topics, if you want to learn more, then you should really consider turning to specific guides. Also, I won't talk about some obvious matters of the x64 architecture, like the fact that applications can now access a larger memory range etc. This article should be considered a quick upgrade for x86/XP developers.&lt;/p&gt; &lt;p nd="2"&gt;At the time I write this article I've been using Windows Vista for a month and its official release is scheduled for January 30th (so, in another month). I moved to x64 with XP some months ago and at the time I did I was surprised that I found all the drivers for my devices. But, as we know, Windows Vista requires drivers to be certified, and in order to get the certification companies have to supply a x64 version of the driver. No certification will be released for x86-only drivers. However, at the moment I write, a lot of applications like virtual drive encrypters don't provide drivers for Vista (since x64 versions haven't got a certificate). If you didn't know about the certification, don't worry, I'll talk about it later and you'll see that it's still possible to run drivers without it. I just wanted to say that hardware compatibility is no longer an issue like it was one year ago, and by switching to Windows Vista x64 you're not taking too much chances. &lt;/p&gt; &lt;p nd="3"&gt;I tried to organize this article in two sections, one about the changes brought us by x64 and then by Vista. I tried as hard as possible to separate these two things, because the x64 technology already existed under Windows XP, so it was important to me that the reader was given a clear distinction between those things that affect only Vista and those ones which affect both topics.&lt;/p&gt; &lt;h2&gt;&lt;a name="x64_Section"&gt;x64 Section&lt;/a&gt;&lt;/h2&gt; &lt;h3&gt;&lt;a name="x64_Assembly"&gt;x64 Assembly&lt;/a&gt;&lt;/h3&gt; &lt;p nd="4"&gt;In this paragraph I'll try to explain the basics of x64 assembly. I assume the reader is already familiar with x86 assembly, otherwise he won't be able to make heads or tails of this paragraph. Moreover, since this is just a very (but very) brief guide, you'll have to look into the &lt;a href="http://www.amd.com/us-en/Processors/DevelopWithAMD/0,,30_2252_739_7044,00.html"&gt;AMD64 documentation&lt;/a&gt; for more advanced stuff. Some stuff I won't even mention, you'll see by yourself that some instructions are no longer in use: for instance, that the lea instruction has completely taken place of the mov offset.&lt;/p&gt; &lt;p nd="5"&gt;What you're going to notice at once is that there are some more registers in the x64 syntax:&lt;/p&gt; &lt;ul&gt;&lt;li nd="6"&gt;8 new general-purpose registers (GPRs).  &lt;/li&gt;&lt;li nd="7"&gt;8 new 128-bit XMM registers. &lt;/li&gt;&lt;/ul&gt; &lt;p nd="8"&gt;Of course, all general-purpose registers are 64 bits wide. The old ones we already knew are easy to recognize in their 64-bit form: rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp (and rip if we want to count the instruction pointer). These old registers can still be accessed in their smaller bit ranges, for instance: rax, eax, ax, ah, al. The new registers go from r8 to r15, and can be accessed in their various bit ranges like this: r8 (qword), r8d (dword), r8w (word), r8b (low byte).&lt;/p&gt; &lt;p nd="9"&gt;Here's a figure taken from the AMD docs:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.codeproject.com/vista/vista_x64/x64_registers.jpg" border="0" height="430" width="600" /&gt;&lt;/p&gt; &lt;p nd="10"&gt;Applications can still use segments registers as base for addressing, but the 64-bit mode only recognizes three of the old ones (and only two can be used for base address calculations). Here's another figure:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.codeproject.com/vista/vista_x64/x64_segments.jpg" border="0" height="277" width="295" /&gt;&lt;/p&gt; &lt;p nd="11"&gt;And now, the most important things. Calling convention and stack. x64 assembly uses FASTCALLs as calling convention, meaning it uses registers to pass the first 4 parameters (and then the stack). Thus, the stack frame is made of: the stack parameters, the registers parameters, the return address (which I remind you is a qword) and the local variables. The first parameter is the rcx register, the second one rdx, the third r8 and the fourth r9. Saying that the parameters registers are part of the stack frame, makes it also clear that any function that calls another child function has to initialize the stack providing space for these four registers, even if the parameters passed to the child function are less than four. The initialization of the stack pointer is done only in the prologue of a function, it has to be large enough to hold all the arguments passed to child functions and it's always a duty of the caller to clean the stack. Now, the most important thing to understand how the space is provided in the stack frame is that the stack has to be 16-byte aligned. In fact, the return address has to be aligned to 16 bytes. So, the stack space will always be something like 16n + 8, where n depends on the number of parameters. Here's a small figure of a stack frame:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.codeproject.com/vista/vista_x64/stackframe.jpg" border="0" height="177" width="246" /&gt;&lt;/p&gt; &lt;p nd="12"&gt;Don't worry if you haven't completely figured out how it works: now we will see a few code samples, which, in my opinion, always make the theory a lot easier to understand. Let us take for instance a hello-world application like:&lt;/p&gt;&lt;pre nd="13" lang="c++"&gt;&lt;span class="cpp-keyword"&gt;int&lt;/span&gt; WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,&lt;br /&gt;                   LPSTR szCmdLine, &lt;span class="cpp-keyword"&gt;int&lt;/span&gt; iCmdShow)&lt;br /&gt;{&lt;br /&gt;  MessageBox(NULL, _T(&lt;span nd="14" class="cpp-string"&gt;"Hello World!"&lt;/span&gt;), _T(&lt;span nd="15" class="cpp-string"&gt;"My First x64 Application"&lt;/span&gt;), &lt;span class="cpp-literal"&gt;0&lt;/span&gt;);&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;return&lt;/span&gt; &lt;span class="cpp-literal"&gt;0&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt; &lt;p nd="16"&gt;This code disassembled would look like:&lt;/p&gt;&lt;pre nd="17" lang="asm"&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401220&lt;/span&gt; sub_401220 proc near       &lt;span class="cpp-comment"&gt;; CODE XREF: start+10E p&lt;/span&gt;&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401220&lt;/span&gt;&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401220&lt;/span&gt; arg_0= qword &lt;span class="cpp-keyword"&gt;ptr&lt;/span&gt; &lt;span class="cpp-literal"&gt;8&lt;/span&gt;&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401220&lt;/span&gt; arg_8= qword &lt;span class="cpp-keyword"&gt;ptr&lt;/span&gt; 10h&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401220&lt;/span&gt; arg_10= qword &lt;span class="cpp-keyword"&gt;ptr&lt;/span&gt; 18h&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401220&lt;/span&gt; arg_18= &lt;span class="cpp-keyword"&gt;dword&lt;/span&gt; &lt;span class="cpp-keyword"&gt;ptr&lt;/span&gt; 20h&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401220&lt;/span&gt;&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401220&lt;/span&gt;    &lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; [rsp+arg_18], r9d&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401225&lt;/span&gt;    &lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; [rsp+arg_10], r8&lt;br /&gt;.text:000000000040122A    &lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; [rsp+arg_8], rdx&lt;br /&gt;.text:000000000040122F    &lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; [rsp+arg_0], rcx&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401234&lt;/span&gt;    &lt;span class="cpp-keyword"&gt;sub&lt;/span&gt; rsp, 28h&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401238&lt;/span&gt;    &lt;span class="cpp-keyword"&gt;xor&lt;/span&gt; r9d, r9d            &lt;span class="cpp-comment"&gt;; uType&lt;/span&gt;&lt;br /&gt;.text:000000000040123B    &lt;span class="cpp-keyword"&gt;lea&lt;/span&gt; r8, Caption         &lt;span class="cpp-comment"&gt;; "My First x64 Application"&lt;/span&gt;&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401242&lt;/span&gt;    &lt;span class="cpp-keyword"&gt;lea&lt;/span&gt; rdx, Text           &lt;span class="cpp-comment"&gt;; "Hello World!"&lt;/span&gt;&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401249&lt;/span&gt;    &lt;span class="cpp-keyword"&gt;xor&lt;/span&gt; &lt;span class="cpp-keyword"&gt;ecx&lt;/span&gt;, &lt;span class="cpp-keyword"&gt;ecx&lt;/span&gt;            &lt;span class="cpp-comment"&gt;; hWnd&lt;/span&gt;&lt;br /&gt;.text:000000000040124B    &lt;span class="cpp-keyword"&gt;call&lt;/span&gt; cs:MessageBoxA&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401251&lt;/span&gt;    &lt;span class="cpp-keyword"&gt;xor&lt;/span&gt; &lt;span class="cpp-keyword"&gt;eax&lt;/span&gt;, &lt;span class="cpp-keyword"&gt;eax&lt;/span&gt;&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401253&lt;/span&gt;    &lt;span class="cpp-keyword"&gt;add&lt;/span&gt; rsp, 28h&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401257&lt;/span&gt;    retn&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401257&lt;/span&gt; sub_401220 endp&lt;/pre&gt; &lt;p nd="18"&gt;The stack pointer initialization is all about the things I said earlier. Since we are calling a child-function with parameters we need the space for all four parameter registers (0x20, this value is already aligned to 16 byte) and the return address (0x08). Thus, we'll have 0x28. Remember that if the stack-value is too small or is not aligned, your code will crash at once. Also, don't wonder why there's no &lt;code nd="19"&gt;ExitProcess &lt;/code&gt;in this function: compiling the code above with Visual C++ adds always a stub (&lt;code nd="20"&gt;WinMainCRTStartup&lt;/code&gt;) which then calls our WinMain. So, the ExitProcess is in the stub code. But what happens when the code before the MessageBox calls a function which take seven parameters instead of four?&lt;/p&gt;&lt;pre nd="21" lang="asm"&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401180&lt;/span&gt; sub_401180 proc near        &lt;span class="cpp-comment"&gt;; CODE XREF: sub_4011F0+4 p&lt;/span&gt;&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401180&lt;/span&gt;                             &lt;span class="cpp-comment"&gt;; sub_4011F0+11 p&lt;/span&gt;&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401180&lt;/span&gt;&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401180&lt;/span&gt; var_28= qword &lt;span class="cpp-keyword"&gt;ptr&lt;/span&gt; -28h&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401180&lt;/span&gt; var_20= qword &lt;span class="cpp-keyword"&gt;ptr&lt;/span&gt; -20h&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401180&lt;/span&gt; var_18= qword &lt;span class="cpp-keyword"&gt;ptr&lt;/span&gt; -18h&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401180&lt;/span&gt;&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401180&lt;/span&gt;    &lt;span class="cpp-keyword"&gt;sub&lt;/span&gt; rsp, 48h&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401184&lt;/span&gt;    &lt;span class="cpp-keyword"&gt;lea&lt;/span&gt; rax, unk_402040&lt;br /&gt;.text:000000000040118B    &lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; [rsp+48h+var_18], rax&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401190&lt;/span&gt;    &lt;span class="cpp-keyword"&gt;lea&lt;/span&gt; rax, unk_402044&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401197&lt;/span&gt;    &lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; [rsp+48h+var_20], rax&lt;br /&gt;.text:000000000040119C    &lt;span class="cpp-keyword"&gt;lea&lt;/span&gt; rax, unk_402048&lt;br /&gt;.text:00000000004011A3    &lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; [rsp+48h+var_28], rax&lt;br /&gt;.text:00000000004011A8    &lt;span class="cpp-keyword"&gt;lea&lt;/span&gt; r9, qword_40204C   &lt;span class="cpp-comment"&gt;; __int64&lt;/span&gt;&lt;br /&gt;.text:00000000004011AF    &lt;span class="cpp-keyword"&gt;lea&lt;/span&gt; r8, qword_40204C+&lt;span class="cpp-literal"&gt;4&lt;/span&gt; &lt;span class="cpp-comment"&gt;; __int64&lt;/span&gt;&lt;br /&gt;.text:00000000004011B6    &lt;span class="cpp-keyword"&gt;lea&lt;/span&gt; rdx, unk_402054    &lt;span class="cpp-comment"&gt;; __int64&lt;/span&gt;&lt;br /&gt;.text:00000000004011BD    &lt;span class="cpp-keyword"&gt;lea&lt;/span&gt; rcx, aAa           &lt;span class="cpp-comment"&gt;; "ptr"&lt;/span&gt;&lt;br /&gt;.text:00000000004011C4    &lt;span class="cpp-keyword"&gt;call&lt;/span&gt; TakeSevenParameters&lt;br /&gt;.text:00000000004011C9    &lt;span class="cpp-keyword"&gt;xor&lt;/span&gt; r9d, r9d               &lt;span class="cpp-comment"&gt;; uType&lt;/span&gt;&lt;br /&gt;.text:00000000004011CC    &lt;span class="cpp-keyword"&gt;lea&lt;/span&gt; r8, Caption        &lt;span class="cpp-comment"&gt;; "My First x64 Application"&lt;/span&gt;&lt;br /&gt;.text:00000000004011D3    &lt;span class="cpp-keyword"&gt;lea&lt;/span&gt; rdx, Text          &lt;span class="cpp-comment"&gt;; "Hello World!"&lt;/span&gt;&lt;br /&gt;.text:00000000004011DA    &lt;span class="cpp-keyword"&gt;xor&lt;/span&gt; &lt;span class="cpp-keyword"&gt;ecx&lt;/span&gt;, &lt;span class="cpp-keyword"&gt;ecx&lt;/span&gt;           &lt;span class="cpp-comment"&gt;; hWnd&lt;/span&gt;&lt;br /&gt;.text:00000000004011DC    &lt;span class="cpp-keyword"&gt;call&lt;/span&gt; cs:MessageBoxA&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;00000000004011E2&lt;/span&gt;    &lt;span class="cpp-keyword"&gt;add&lt;/span&gt; rsp, 48h&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;00000000004011E6&lt;/span&gt;    retn&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;00000000004011E6&lt;/span&gt; sub_401180 endp&lt;/pre&gt;As said, the child function takes 7 parameters, making it necessary to provide space for 3 extra parameters on the stack. So, 7 * 8 = 0x38, which aligned to 16byte is 0x40. Providing, then, space for the return address makes it 0x48, our value indeed. I think you have understood the stack-frames logic by now, it's actually quite easy to understand it, but it needs a second to revert from the old x86/stdcall logic to this one. But now enough of this, now that we've seen how the x64 code works, we'll try compiling an assembly source by ourselves. &lt;p nd="23"&gt;Before we start, I have to make something clear. There are some assemblers over the internet which make the job easier, mainly because the initialize the stack by themselves or they create code that is easy to converto from/to x86. But I think that is not the point here in this article. In fact, I'm going to use the microsoft assembler (ml64.exe), which requires you to write everything down, just like in the disassembly. Another option could be compiling the with another assembler and then link it with ml64. I think the reader should really make these decisions on his own. As far as I am concerned, I don't believe that much code should be written in assembly and avoided whenever it could be done. This new x64 technology is a good opportunity to re-think about these matters. In the last years I always wrote 64-bit compatible code in C/C++ (I mean unmanaged, of course) and when I had to recompile a project of 70,000 lines of code for x64, I didn't had to change one single line of code (I'll talk about the C/C++ programming later). Despite of all the macros an assembler offers, I seriously doubt that people who wrote their whole code in assembly will be able to switch so easily to x64 (remember one day even the IA64 syntax could be adopted). I think in most cases the obvious choice will be not converting to the new technology and stick to x86, but this isn't always possible, it depends on the software category. &lt;/p&gt; &lt;p nd="24"&gt;The Microsoft assembler is contained in the SDK and in the DDK (WDK for Vista). Right now, I'm using Vista's WDK, which I freely downloaded from the msdn. The first sample of code I'm going to show you is a simple Hello-World messagebox application.&lt;/p&gt;&lt;pre nd="25"&gt;extrn MessageBoxA : proc&lt;br /&gt;extrn ExitProcess : proc&lt;br /&gt;&lt;br /&gt;.data&lt;br /&gt;body db 'Hello World!', &lt;span class="cpp-literal"&gt;0&lt;/span&gt;&lt;br /&gt;capt db 'My First x64 Application', &lt;span class="cpp-literal"&gt;0&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;.code&lt;br /&gt;Main proc&lt;br /&gt;sub rsp, 28h&lt;br /&gt;xor r9d, r9d        ; uType = &lt;span class="cpp-literal"&gt;0&lt;/span&gt;&lt;br /&gt;lea r8, capt        ; lpCaption&lt;br /&gt;lea rdx, body       ; lpText&lt;br /&gt;xor rcx, rcx        ; hWnd = NULL&lt;br /&gt;call MessageBoxA&lt;br /&gt;xorecx, ecx        ; exit code = &lt;span class="cpp-literal"&gt;0&lt;/span&gt;&lt;br /&gt;call ExitProcess&lt;br /&gt;Main endp&lt;br /&gt;&lt;br /&gt;end&lt;/pre&gt;&lt;br /&gt;As you can see, I didn't bother unwinding the stack, since I call ExitProcess. The syntax is very similar to the old MASM one, although there are a few dissimilarities. The ml64 console output should be something like this: &lt;p&gt;&lt;img src="http://www.codeproject.com/vista/vista_x64/ml64.jpg" border="0" height="301" width="600" /&gt;&lt;/p&gt; &lt;p nd="26"&gt;The command line to compile is:&lt;/p&gt;&lt;pre nd="27" lang="text"&gt;ml64 C:\...\test.asm /link /subsystem:windows&lt;br /&gt;  /defaultlib:C:\WinDDK\6000\lib\wnet\amd64\kernel32.lib&lt;br /&gt;  /defaultlib:C:\WinDDK\6000\lib\wnet\amd64\user32.lib /entry:Main&lt;/pre&gt; &lt;p nd="28"&gt;If the libs are not in the same directory as ml64.exe, you'll have to provide the path like I did. The entry has to be provided, otherwise you would have to use WinMainCRTStartup as main entry. &lt;/p&gt; &lt;p nd="29"&gt;The next sample of code I'm going to show you displays a window calling CreateWindowEx. What you're going to learn through this code is structure alignment and how integrating resources in your projects. Like I said earlier, I don't want to encourage you to write your windows in assembly, but I believe that this sort of code is good for learning. Now the code, afterwards the explanation.&lt;/p&gt;&lt;div class="smallText" id="premain5" style="width: 100%;"&gt;&lt;img preid="5" src="http://www.codeproject.com/images/minus.gif" id="preimg5" height="9" width="9" /&gt;&lt;span nd="30" preid="5" style="margin-bottom: 0pt;" id="precollapse5"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre nd="31" style="margin-top: 0pt;" id="pre5" lang="asm"&gt;extrn GetModuleHandleA : proc&lt;br /&gt;extrn MessageBoxA : proc&lt;br /&gt;extrn RegisterClassExA : proc&lt;br /&gt;extrn CreateWindowExA : proc&lt;br /&gt;extrn DefWindowProcA : proc&lt;br /&gt;extrn ShowWindow : proc&lt;br /&gt;extrn GetMessageA : proc&lt;br /&gt;extrn TranslateMessage : proc&lt;br /&gt;extrn DispatchMessageA : proc&lt;br /&gt;extrn PostQuitMessage : proc&lt;br /&gt;extrn DestroyWindow : proc&lt;br /&gt;extrn ExitProcess : proc&lt;br /&gt;&lt;br /&gt;WNDCLASSEX struct&lt;br /&gt;cbSize            dd      ?&lt;br /&gt;style             dd      ?&lt;br /&gt;lpfnWndProc       dq      ?&lt;br /&gt;cbClsExtra        dd      ?&lt;br /&gt;cbWndExtra        dd      ?&lt;br /&gt;hInstance         dq      ?&lt;br /&gt;hIcon             dq      ?&lt;br /&gt;hCursor           dq      ?&lt;br /&gt;hbrBackground     dq      ?&lt;br /&gt;lpszMenuName      dq      ?&lt;br /&gt;lpszClassName     dq      ?&lt;br /&gt;hIconSm           dq      ?&lt;br /&gt;WNDCLASSEX ends&lt;br /&gt;&lt;br /&gt;POINT struct&lt;br /&gt;x                 dd      ?&lt;br /&gt;y                 dd      ?&lt;br /&gt;POINT ends&lt;br /&gt;&lt;br /&gt;MSG struct    &lt;br /&gt;hwnd              dq      ?&lt;br /&gt;message           dd      ?&lt;br /&gt;padding1          dd      ?      &lt;span class="cpp-comment"&gt;; padding&lt;/span&gt;&lt;br /&gt;wParam            dq      ?&lt;br /&gt;lParam            dq      ?&lt;br /&gt;time              dd      ?&lt;br /&gt;pt                POINT   &lt;&lt;span class="cpp-comment"&gt;;&gt;&lt;/span&gt;&lt;br /&gt;padding2          dd      ?      &lt;span class="cpp-comment"&gt;; padding&lt;/span&gt;&lt;br /&gt;MSG ends&lt;br /&gt;&lt;br /&gt;.const&lt;br /&gt;NULL equ &lt;span class="cpp-literal"&gt;0&lt;/span&gt;&lt;br /&gt;CS_VREDRAW equ &lt;span class="cpp-literal"&gt;1&lt;/span&gt;&lt;br /&gt;CS_HREDRAW equ &lt;span class="cpp-literal"&gt;2&lt;/span&gt;&lt;br /&gt;COLOR_WINDOW equ &lt;span class="cpp-literal"&gt;5&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;; WS_OVERLAPPEDWINDOW = (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | &lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;; WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX) &lt;/span&gt;&lt;br /&gt;WS_OVERLAPPEDWINDOW equ 0CF0000h&lt;br /&gt;CW_USEDEFAULT equ 80000000h&lt;br /&gt;SW_SHOW equ &lt;span class="cpp-literal"&gt;5&lt;/span&gt;&lt;br /&gt;WM_DESTROY equ &lt;span class="cpp-literal"&gt;2&lt;/span&gt;&lt;br /&gt;WM_COMMAND equ 111h&lt;br /&gt;IDC_MENU equ &lt;span class="cpp-literal"&gt;109&lt;/span&gt;&lt;br /&gt;IDM_ABOUT equ &lt;span class="cpp-literal"&gt;104&lt;/span&gt;&lt;br /&gt;IDM_EXIT equ &lt;span class="cpp-literal"&gt;105&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;.data&lt;br /&gt;szWindowClass db 'FirstApp', &lt;span class="cpp-literal"&gt;0&lt;/span&gt;&lt;br /&gt;szTitle db 'My First x64 Windows', &lt;span class="cpp-literal"&gt;0&lt;/span&gt;&lt;br /&gt;szHelpTitle db 'Help', &lt;span class="cpp-literal"&gt;0&lt;/span&gt;&lt;br /&gt;szHelpText db 'This will be a big help...', &lt;span class="cpp-literal"&gt;0&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;.data?&lt;br /&gt;hInstance qword ?&lt;br /&gt;hWnd qword ?&lt;br /&gt;wndclass WNDCLASSEX &lt;&lt;span class="cpp-comment"&gt;;&gt;&lt;/span&gt;&lt;br /&gt;wmsg MSG &lt;&lt;span class="cpp-comment"&gt;;&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;.code&lt;br /&gt;&lt;br /&gt;WndProc: &lt;span class="cpp-comment"&gt;; proc hWnd : qword, uMsg : dword, wParam : qword, lParam : qword&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; [rsp+&lt;span class="cpp-literal"&gt;8&lt;/span&gt;], rcx        &lt;span class="cpp-comment"&gt;; hWnd (save parameters as locals)&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; [rsp+10h], edx      &lt;span class="cpp-comment"&gt;; Msg&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; [rsp+18h], r8       &lt;span class="cpp-comment"&gt;; wParam&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; [rsp+20h], r9       &lt;span class="cpp-comment"&gt;; lParam&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;sub&lt;/span&gt; rsp, 38h&lt;br /&gt;&lt;span class="cpp-keyword"&gt;cmp&lt;/span&gt; edx, WM_DESTROY&lt;br /&gt;&lt;span class="cpp-keyword"&gt;jnz&lt;/span&gt; @next1&lt;br /&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;xor&lt;/span&gt; &lt;span class="cpp-keyword"&gt;ecx&lt;/span&gt;, &lt;span class="cpp-keyword"&gt;ecx&lt;/span&gt;          &lt;span class="cpp-comment"&gt;; exit code&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;call&lt;/span&gt; PostQuitMessage&lt;br /&gt;&lt;span class="cpp-keyword"&gt;xor&lt;/span&gt; rax, rax&lt;br /&gt;&lt;span class="cpp-keyword"&gt;ret&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;@next1:&lt;br /&gt;&lt;span class="cpp-keyword"&gt;cmp&lt;/span&gt; edx, WM_COMMAND&lt;br /&gt;&lt;span class="cpp-keyword"&gt;jnz&lt;/span&gt; @default&lt;br /&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; rbx, rsp&lt;br /&gt;&lt;span class="cpp-keyword"&gt;add&lt;/span&gt; rbx, 38h&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; r10, [rbx+18h]     &lt;span class="cpp-comment"&gt;; wParam&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;cmp&lt;/span&gt; r10w, IDM_ABOUT&lt;br /&gt;jz @about&lt;br /&gt;&lt;span class="cpp-keyword"&gt;cmp&lt;/span&gt; r10w, IDM_EXIT&lt;br /&gt;jz @exit&lt;br /&gt;&lt;span class="cpp-keyword"&gt;jmp&lt;/span&gt; @default&lt;br /&gt;&lt;br /&gt;@about:&lt;br /&gt;&lt;span class="cpp-keyword"&gt;xor&lt;/span&gt; r9d, r9d&lt;br /&gt;&lt;span class="cpp-keyword"&gt;lea&lt;/span&gt; r8, szHelpTitle&lt;br /&gt;&lt;span class="cpp-keyword"&gt;lea&lt;/span&gt; rdx, szHelpText&lt;br /&gt;&lt;span class="cpp-keyword"&gt;xor&lt;/span&gt; &lt;span class="cpp-keyword"&gt;ecx&lt;/span&gt;, &lt;span class="cpp-keyword"&gt;ecx&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;call&lt;/span&gt; MessageBoxA&lt;br /&gt;&lt;span class="cpp-keyword"&gt;jmp&lt;/span&gt; @default&lt;br /&gt;&lt;br /&gt;@exit:&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; rbx, rsp&lt;br /&gt;&lt;span class="cpp-keyword"&gt;add&lt;/span&gt; rbx, 38h&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; rcx, [rbx+8h]       &lt;span class="cpp-comment"&gt;; hWnd&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;call&lt;/span&gt; DestroyWindow&lt;br /&gt;&lt;br /&gt;@default:&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; rbx, rsp&lt;br /&gt;&lt;span class="cpp-keyword"&gt;add&lt;/span&gt; rbx, 38h&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; r9, [rbx+20h]       &lt;span class="cpp-comment"&gt;; lParam&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; r8, [rbx+18h]       &lt;span class="cpp-comment"&gt;; wParam&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; edx, [rbx+10h]      &lt;span class="cpp-comment"&gt;; Msg&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; rcx, [rbx+&lt;span class="cpp-literal"&gt;8&lt;/span&gt;]        &lt;span class="cpp-comment"&gt;; hWnd&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;call&lt;/span&gt; DefWindowProcA&lt;br /&gt;&lt;span class="cpp-keyword"&gt;add&lt;/span&gt; rsp, 38h&lt;br /&gt;&lt;span class="cpp-keyword"&gt;ret&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;MyRegisterClass:  &lt;span class="cpp-comment"&gt;; proc hInst : qword&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;sub&lt;/span&gt; rsp, 28h&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; wndclass.cbSize, sizeof WNDCLASSEX&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; &lt;span class="cpp-keyword"&gt;eax&lt;/span&gt;, CS_VREDRAW&lt;br /&gt;&lt;span class="cpp-keyword"&gt;or&lt;/span&gt; &lt;span class="cpp-keyword"&gt;eax&lt;/span&gt;, CS_HREDRAW&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; wndclass.style, &lt;span class="cpp-keyword"&gt;eax&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;lea&lt;/span&gt; rax, WndProc&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; wndclass.lpfnWndProc, rax&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; wndclass.cbClsExtra, &lt;span class="cpp-literal"&gt;0&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; wndclass.cbWndExtra, &lt;span class="cpp-literal"&gt;0&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; wndclass.hInstance, rcx&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; wndclass.hIcon, NULL&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; wndclass.hCursor, NULL&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; wndclass.hbrBackground, COLOR_WINDOW&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; wndclass.lpszMenuName, IDC_MENU&lt;br /&gt;&lt;span class="cpp-keyword"&gt;lea&lt;/span&gt; rax, szWindowClass&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; wndclass.lpszClassName, rax&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; wndclass.hIconSm, NULL&lt;br /&gt;&lt;span class="cpp-keyword"&gt;lea&lt;/span&gt; rcx, wndclass&lt;br /&gt;&lt;span class="cpp-keyword"&gt;call&lt;/span&gt; RegisterClassExA&lt;br /&gt;&lt;span class="cpp-keyword"&gt;add&lt;/span&gt; rsp, 28h&lt;br /&gt;&lt;span class="cpp-keyword"&gt;ret&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;InitInstance: &lt;span class="cpp-comment"&gt;; proc hInst : qword&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;sub&lt;/span&gt; rsp, 78h       &lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; rax, CW_USEDEFAULT&lt;br /&gt;&lt;span class="cpp-keyword"&gt;xor&lt;/span&gt; rbx, rbx&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; [rsp+58h], rbx            &lt;span class="cpp-comment"&gt;; lpParam&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; [rsp+50h], rcx            &lt;span class="cpp-comment"&gt;; hInstance&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; [rsp+48h], rbx            &lt;span class="cpp-comment"&gt;; hMenu = NULL&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; [rsp+40h], rbx            &lt;span class="cpp-comment"&gt;; hWndParent = NULL&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; [rsp+38h], rbx            &lt;span class="cpp-comment"&gt;; Height&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; [rsp+30h], rax            &lt;span class="cpp-comment"&gt;; Width&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; [rsp+28h], rbx            &lt;span class="cpp-comment"&gt;; Y&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; [rsp+20h], rax            &lt;span class="cpp-comment"&gt;; X&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; r9d, WS_OVERLAPPEDWINDOW  &lt;span class="cpp-comment"&gt;; dwStyle&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;lea&lt;/span&gt; r8, szTitle               &lt;span class="cpp-comment"&gt;; lpWindowName&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;lea&lt;/span&gt; rdx, szWindowClass        &lt;span class="cpp-comment"&gt;; lpClassName&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;xor&lt;/span&gt; &lt;span class="cpp-keyword"&gt;ecx&lt;/span&gt;, &lt;span class="cpp-keyword"&gt;ecx&lt;/span&gt;                  &lt;span class="cpp-comment"&gt;; dwExStyle&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;call&lt;/span&gt; CreateWindowExA&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; hWnd, rax&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; edx, SW_SHOW&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; rcx, hWnd&lt;br /&gt;&lt;span class="cpp-keyword"&gt;call&lt;/span&gt; ShowWindow&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; rax, hWnd                 &lt;span class="cpp-comment"&gt;; set return value&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;add&lt;/span&gt; rsp,78h&lt;br /&gt;&lt;span class="cpp-keyword"&gt;ret&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Main proc&lt;br /&gt;&lt;span class="cpp-keyword"&gt;sub&lt;/span&gt; rsp, 28h&lt;br /&gt;&lt;span class="cpp-keyword"&gt;xor&lt;/span&gt; rcx, rcx   &lt;br /&gt;&lt;span class="cpp-keyword"&gt;call&lt;/span&gt; GetModuleHandleA&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; hInstance, rax&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; rcx, rax&lt;br /&gt;&lt;span class="cpp-keyword"&gt;call&lt;/span&gt; MyRegisterClass&lt;br /&gt;&lt;span class="cpp-keyword"&gt;test&lt;/span&gt; rax, rax&lt;br /&gt;jz @close              &lt;span class="cpp-comment"&gt;; if the RegisterClassEx fails, exit &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;mov&lt;/span&gt; rcx, hInstance&lt;br /&gt;&lt;span class="cpp-keyword"&gt;call&lt;/span&gt; InitInstance&lt;br /&gt;&lt;span class="cpp-keyword"&gt;test&lt;/span&gt; rax, rax&lt;br /&gt;jz @close              &lt;span class="cpp-comment"&gt;; if the InitInstance fails, exit &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;@handlemsgs:             &lt;span class="cpp-comment"&gt;; message processing routine&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;xor&lt;/span&gt; r9d, r9d         &lt;br /&gt;&lt;span class="cpp-keyword"&gt;xor&lt;/span&gt; r8d, r8d&lt;br /&gt;&lt;span class="cpp-keyword"&gt;xor&lt;/span&gt; edx, edx&lt;br /&gt;&lt;span class="cpp-keyword"&gt;lea&lt;/span&gt; rcx, wmsg&lt;br /&gt;&lt;span class="cpp-keyword"&gt;call&lt;/span&gt; GetMessageA&lt;br /&gt;&lt;span class="cpp-keyword"&gt;test&lt;/span&gt; &lt;span class="cpp-keyword"&gt;eax&lt;/span&gt;, &lt;span class="cpp-keyword"&gt;eax&lt;/span&gt;&lt;br /&gt;jz @close&lt;br /&gt;&lt;span class="cpp-keyword"&gt;lea&lt;/span&gt; rcx, wmsg&lt;br /&gt;&lt;span class="cpp-keyword"&gt;call&lt;/span&gt; TranslateMessage&lt;br /&gt;&lt;span class="cpp-keyword"&gt;lea&lt;/span&gt; rcx, wmsg&lt;br /&gt;&lt;span class="cpp-keyword"&gt;call&lt;/span&gt; DispatchMessageA&lt;br /&gt;&lt;span class="cpp-keyword"&gt;jmp&lt;/span&gt; @handlemsgs&lt;br /&gt;&lt;br /&gt;@close:&lt;br /&gt;&lt;span class="cpp-keyword"&gt;xor&lt;/span&gt; &lt;span class="cpp-keyword"&gt;ecx&lt;/span&gt;, &lt;span class="cpp-keyword"&gt;ecx&lt;/span&gt;  &lt;br /&gt;&lt;span class="cpp-keyword"&gt;call&lt;/span&gt; ExitProcess&lt;br /&gt;Main endp&lt;br /&gt;&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt; &lt;p nd="32"&gt;As you can see, I tried to stay as low level as I could. The reason why I avoided for other functions other than the main the proc macro is that the ml64 puts a prologue end an epilogue, which I didn't want, by itself. Avoiding the macro made it possible to define my own stack frame without any intermission by the compiler. The first thing to notice scrolling this code is the structure:&lt;/p&gt;&lt;pre nd="33" lang="asm"&gt;MSG struct    &lt;br /&gt;hwnd              dq      ?&lt;br /&gt;message           dd      ?&lt;br /&gt;padding1          dd      ?      &lt;span class="cpp-comment"&gt;; padding&lt;/span&gt;&lt;br /&gt;wParam            dq      ?&lt;br /&gt;lParam            dq      ?&lt;br /&gt;time              dd      ?&lt;br /&gt;pt                POINT   &lt;&lt;span class="cpp-comment"&gt;;&gt;&lt;/span&gt;&lt;br /&gt;padding2          dd      ?      &lt;span class="cpp-comment"&gt;; padding&lt;/span&gt;&lt;br /&gt;MSG ends&lt;br /&gt;&lt;/pre&gt; &lt;p nd="34"&gt;It requires two paddings which the x86 declaration of the same structure didn't. The reason, in a few words, is that qword members should be aligned to qword boundaries (this for the first padding). The additional padding at the end of the structure follows the rule that: every structure should be aligned to its largest member. So, being its largest member a qword, the structure should be aligned to an 8-byte boundary. &lt;/p&gt; &lt;p nd="35"&gt;To compile this sample, the command line is:&lt;/p&gt;&lt;pre nd="36" lang="text"&gt;ml64 c:\myapp\test.asm /link /subsystem:windows&lt;br /&gt;  /defaultlib:C:\WinDDK\6000\lib\wnet\amd64\kernel32.lib&lt;br /&gt;  /defaultlib:C:\WinDDK\6000\lib\wnet\amd64\user32.lib&lt;br /&gt;  /entry:Main c:\myapp\test.res&lt;/pre&gt; &lt;p nd="37"&gt;test.res is a file I took from a VC++ wizard project, I was too lazy to make on by myself. Anyway, making a resource file is very easy with the VC++, but no one forbids you to use the notepad, it just takes more time. To compile the resource file all you need to do is to use the command line: "rc test.rc".&lt;/p&gt; &lt;p nd="38"&gt;I think the rest of the code is pretty easy to understand. I didn't cover everything with this paragraph, but now you should have quite a good insight into x64 assembly. Let's move on.&lt;/p&gt; &lt;h3&gt;&lt;a name="C/C++_Programming"&gt;C/C++ Programming&lt;/a&gt;&lt;/h3&gt; &lt;p nd="39"&gt;Writing x64 compatible code in C/C++ is very easy. All what it takes is to follow some basic rules. The most common mistake that make that makes 99% of the old 32bit sources uncompatible is wrong casting. For Instance:&lt;/p&gt;&lt;pre nd="40"&gt;ptr1 = (DWORD) (sizoef (x) + ptr2);  &lt;span class="cpp-comment"&gt;// &lt;-- WRONG!&lt;/span&gt;&lt;/pre&gt; &lt;p nd="41"&gt;This line of code assumes that pointers are 32bit long, but on x64 pointers are 64bit long and the line of code above basically truncates the pointer making it invalid. So, always cast like this:&lt;/p&gt;&lt;pre nd="42"&gt;ptr1 = (ULONG_PTR) (sizoef (x) + ptr2);  &lt;-- RIGHT!&lt;/pre&gt; &lt;p&gt;It doesn't matter if you use ULONG_PTR, LONG_PTR, DWORD_PTR or whatever. The important thing is that you use one of these defines (or directly by pointer type: (void *)).&lt;/p&gt; &lt;p&gt;Keep in mind that all handles and handle derivates are qwords. HANDLE, HKEY, HICON, HBITMAP, HINSTANCE, HMODULE, HWND etc. etc. These are all 64bit long, even though they're not all the same handle (HINSTANCE, for example, is just a pointer, not a real handle). Even WPARAM and LPARAM are now 64bit long. There's no rule to follow, just don't assume these types are 32 or 64bit long: write code that is compatible with both conditions:&lt;/p&gt;&lt;pre&gt;HWND *hWndArray = (HWND *) malloc(&lt;span class="cpp-keyword"&gt;sizeof&lt;/span&gt; (DWORD) * n);  &lt;-- WRONG!&lt;/pre&gt; &lt;p&gt;Instead write:&lt;/p&gt;&lt;pre&gt;HWND *hWndArray = (HWND *) malloc(&lt;span class="cpp-keyword"&gt;sizeof&lt;/span&gt; (HWND) * n);  &lt;-- RIGHT!&lt;/pre&gt; &lt;p&gt;As you can see this isn't a rule, just good sense.&lt;/p&gt; &lt;p&gt;The defines to use for writing architecture-dependent code are:&lt;/p&gt; &lt;table border="0" bordercolor="#000000" cellpadding="3" width="41%"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;_M_IX86 &lt;/code&gt;&lt;/td&gt; &lt;td&gt;x86 code only.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;_M_AMD64&lt;/code&gt;&lt;/td&gt; &lt;td&gt;x64 code only.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;_M_IA64&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Itanium code only.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;_WIN32&lt;/code&gt;&lt;/td&gt; &lt;td&gt;32bit code (x86, maybe ARM for WINCE).&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;_WIN64&lt;/code&gt;&lt;/td&gt; &lt;td&gt;64bit code (x64, Itanium).&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;if you want to write, for example, a piece of code for x86 only, you could write:&lt;/p&gt;&lt;pre lang="c++"&gt;&lt;span class="cpp-preprocessor"&gt;#ifdef _M_IX86&lt;/span&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;// x86 only code&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-preprocessor"&gt;#endif&lt;/span&gt;&lt;/pre&gt; &lt;p&gt;Now that you know all the rules, you just have to compile your project for x64. Keep in mind that every project in VC++ (nowadays) starts with a x86 configuration: it's your job to add a project configuration to the project, but don't worry it's very easy. All you have to do is open the configuration manager (Build -&gt; Configuration Manager) and then under "Active solution platform" click New, just like this:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.codeproject.com/vista/vista_x64/configmanager.jpg" border="0" height="378" width="600" /&gt;&lt;/p&gt; &lt;p&gt;A dialog box will pop up where you can choose the new platform which for to create a new project configuration. There's nothing more to do, except to build.&lt;/p&gt; &lt;h3&gt;&lt;a name="Inline_Assembly"&gt;Inline Assembly&lt;/a&gt;&lt;/h3&gt; &lt;p&gt;Bad news! Microsoft completely removed the support for inline assembly in C/C++, both for user and kernel mode. If you try to compile a code sample like this on x64/Itanium: &lt;/p&gt;&lt;pre lang="c++"&gt;&lt;span class="cpp-preprocessor"&gt;#include "stdafx.h"&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-preprocessor"&gt;#include &lt;windows.h&gt;&lt;/windows.h&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;int&lt;/span&gt; _tmain(&lt;span class="cpp-keyword"&gt;int&lt;/span&gt; argc, _TCHAR* argv[])&lt;br /&gt;{&lt;br /&gt;  __asm &lt;span class="cpp-keyword"&gt;int&lt;/span&gt; &lt;span class="cpp-literal"&gt;3&lt;/span&gt;;&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;return&lt;/span&gt; &lt;span class="cpp-literal"&gt;0&lt;/span&gt;;&lt;br /&gt;}&lt;/pre&gt; &lt;p&gt;It will give you more than just one error. Being the __asm keyword no longer supported, the __naked declspec was removed as well (since it doesn't make sense without inline assembly).&lt;/p&gt; &lt;p&gt;Now, prepare for the good news. Before you start thinking about using external asm files or stuff like that, you should know that the VC++ offers some very powerful assembly intrinsics. The header to include to use these intrinsics is "intrin.h". Let's take for a code sample the intrinsics _ReturnAddress() and _AddressOfReturnAddress(). The first one gives us the return address of the current function and the second one the address of the return address itself. Let's analyze this little code sample that I took from the MSDN:&lt;/p&gt;&lt;pre lang="c++"&gt;&lt;span class="cpp-keyword"&gt;int&lt;/span&gt; _tmain(&lt;span class="cpp-keyword"&gt;int&lt;/span&gt; argc, _TCHAR* argv[])&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;void&lt;/span&gt;* pvAddressOfReturnAddress = _AddressOfReturnAddress();&lt;br /&gt;  printf_s(&lt;span class="cpp-string"&gt;"%p\n"&lt;/span&gt;, pvAddressOfReturnAddress);&lt;br /&gt;  printf_s(&lt;span class="cpp-string"&gt;"%p\n"&lt;/span&gt;, *((&lt;span class="cpp-keyword"&gt;void&lt;/span&gt;**) pvAddressOfReturnAddress));&lt;br /&gt;  printf_s(&lt;span class="cpp-string"&gt;"%p\n"&lt;/span&gt;, _ReturnAddress());&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;return&lt;/span&gt; &lt;span class="cpp-literal"&gt;0&lt;/span&gt;;&lt;br /&gt;}&lt;/pre&gt; &lt;p&gt;The second and the third printf_s will show the same output, since both display the return address of the current function. These intrinsics are very powerful, and nothing can stop us from doing some of the old tricks we did with inline assembly. For instance, having the address of the return address could give me the possibility of changing it and making the function return somewhere else. Let's try that:&lt;/p&gt;&lt;pre lang="c++"&gt;ULONG_PTR OldAddress = &lt;span class="cpp-literal"&gt;0&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;void&lt;/span&gt; f1()&lt;br /&gt;{&lt;br /&gt;  printf_s(&lt;span class="cpp-string"&gt;"Hello there!\n"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;  ULONG_PTR *pAddressOfReturnAddress = (ULONG_PTR *)&lt;br /&gt;      _AddressOfReturnAddress();&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;if&lt;/span&gt; (OldAddress == &lt;span class="cpp-literal"&gt;0&lt;/span&gt;)&lt;br /&gt;  {&lt;br /&gt;      OldAddress = *pAddressOfReturnAddress;&lt;br /&gt;      *pAddressOfReturnAddress =  (ULONG_PTR) &amp;f1;&lt;br /&gt;  }&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;else&lt;/span&gt;&lt;br /&gt;  {&lt;br /&gt;      *pAddressOfReturnAddress = OldAddress;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt; &lt;p&gt;The output of this function is:&lt;/p&gt;&lt;pre lang="text"&gt;&lt;b&gt;Hello there!&lt;br /&gt;Hello there!&lt;/b&gt;&lt;/pre&gt; &lt;p&gt;That's because, as you can see from the code, I changed the return address of the current function making it execute again. I put a condition to make it execute again just once, otherwise it would have brought to an endless loop. An important thing to know is that this sample works in Release mode only if you disable code optimization, otherwise the VC++ will remove the line of code which sets the new return address. I'm sure there are ways to trick the VC++ not to do this, but the problem is that if the function is called just by one caller like this one, the VC++ will put the code of the function directly in the caller one, so setting a new return address under these conditions is a bit risky. Disabling optimization is, I believe, the safest way to act.&lt;/p&gt; &lt;p&gt;Enough of this trivia. Here's a list of the intrinsics for x64 taken from the MSDN (many of them are supported on x86 as well):&lt;/p&gt; &lt;table bordercolordark="#000000" bordercolorlight="#000000" border="0" bordercolor="#000000" cellpadding="3" width="100%"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_AddressOfReturnAddress&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Provides the address of the memory location that holds the return address of the current function. This address may not be used to access other memory locations (for example, the function's arguments).&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__addgsbyte, __addgsword, __addgsdword, __addgsqword&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Add a value to a memory location specified by an offset relative to the beginning of the &lt;b&gt;GS&lt;/b&gt; segment.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__assume&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Passes a hint to the optimizer. &lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_BitScanForward, _BitScanForward64&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Search the mask data from least significant bit (LSB) to the most significant bit (MSB) for a set bit (1).&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_BitScanReverse, _BitScanReverse64&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Search the mask data from most significant bit (MSB) to least significant bit (LSB) for a set bit (1).&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_bittest, _bittest64 &lt;/code&gt;&lt;/td&gt; &lt;td&gt;Generates the &lt;b&gt;bt&lt;/b&gt; instruction, which examines the bit in position b of address a, and returns the value of that bit.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_bittestandcomplement, _bittestandcomplement64 &lt;/code&gt;&lt;/td&gt; &lt;td&gt;Generate the &lt;b&gt;btc&lt;/b&gt; instruction, which examines bit b of the address a, returns its current value, and sets the bit to its complement.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_bittestandreset, _bittestandreset64 &lt;/code&gt;&lt;/td&gt; &lt;td&gt;Generate the &lt;b&gt;btr&lt;/b&gt; instruction, which examines bit b of the address a, returns its current value, and resets the bit to 0.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_bittestandset, _bittestandset64&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Generate the &lt;b&gt;bts&lt;/b&gt; instruction, which examines bit b of the address a, returns its current value, and sets the bit to 1.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__debugbreak&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Causes a breakpoint in your code, where the user will be prompted to run the debugger.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_disable &lt;/code&gt;&lt;/td&gt; &lt;td&gt;Disables interrupts.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__emul, __emulu&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Performs multiplications that overflow what a 32-bit integer can hold.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_enable&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Enables interrupts.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__faststorefence&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Guarantees that every preceding store is globally visible before any subsequent store.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__getcallerseflags&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Returns the EFLAGS value from the caller's context.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__inbyte&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Generates the &lt;b&gt;in&lt;/b&gt; instruction, returning one byte read from the port specified by Port.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__inbytestring&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Reads data from the specified port using the &lt;b&gt;rep insb&lt;/b&gt; instruction.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__incgsbyte, __incgsword, __incgsdword, __incgsqword&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Add one to the value at a memory location specified by an offset relative to the beginning of the &lt;b&gt;GS&lt;/b&gt; segment.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__indword&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Reads one double word of data from the specified port using the &lt;b&gt;in&lt;/b&gt; instruction.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__indwordstring&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Reads data from the specified port using the &lt;b&gt;rep insd&lt;/b&gt; instruction.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__int2c&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Generates the &lt;b&gt;int 2c&lt;/b&gt; instruction, which triggers the &lt;b&gt;2c&lt;/b&gt; interrupt.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_InterlockedAnd, _InterlockedAnd64&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Used to perform an atomic AND operation on a variable shared by multiple threads.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_interlockedbittestandreset, _interlockedbittestandreset64&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Generate the &lt;b&gt;lock_btr&lt;/b&gt; instruction, which examines bit b of the address a and returns its current value.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_interlockedbittestandset, _interlockedbittestandset64 &lt;/code&gt;&lt;/td&gt; &lt;td&gt;Generate the &lt;b&gt;lock_bts&lt;/b&gt; instruction, which examines bit b of the address a and returns its current value.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_InterlockedCompareExchange, _InterlockedCompareExchange64, _InterlockedCompare64Exchange128, _InterlockedCompare64Exchange128_acq, _InterlockedCompare64Exchange128_rel &lt;/code&gt;&lt;/td&gt; &lt;td&gt;Provides compiler intrinsic support for the Win32 Platform SDK InterlockedCompareExchange function.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_InterlockedCompareExchangePointer&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Perform an atomic exchange operation, which copies the address passed in as the second argument to the first and returns the original address of the first.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_InterlockedDecrement, _InterlockedDecrement64&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Provides compiler intrinsic support for the Win32 Platform SDK InterlockedDecrement function.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_InterlockedExchange, _InterlockedExchange64&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Provide compiler intrinsic support for the Win32 Platform SDK InterlockedExchange function.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_InterlockedExchangeAdd, _InterlockedExchangeAdd64&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Provide compiler intrinsic support for the Win32 Platform SDK _InterlockedExchangeAdd Intrinsic Functions function.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_InterlockedExchangePointer&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Perform an atomic exchange operation, which copies the address passed in as the second argument to the first and returns the original address of the first.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_InterlockedIncrement, _InterlockedIncrement64&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Provide compiler intrinsic support for the Win32 Platform SDK InterlockedIncrement function.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_InterlockedOr, _InterlockedOr64&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Perform an atomic operation (in this case, the &lt;b&gt;OR&lt;/b&gt; operation) on a variable shared by multiple threads.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_InterlockedXor, _InterlockedXor64&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Used to perform an atomic operation (in this case, the exclusive or &lt;b&gt;XOR&lt;/b&gt; operation) on a variable shared by multiple threads.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__invlpg &lt;/code&gt;&lt;/td&gt; &lt;td&gt;Generates the x86 &lt;b&gt;invlpg&lt;/b&gt; instruction, which invalidates the translation lookaside buffer (TLB) for the page associated with memory pointed to by Address.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__inword&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Reads data from the specified port using the &lt;b&gt;in&lt;/b&gt; instruction.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__inwordstring&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Reads data from the specified port using the &lt;b&gt;rep insw&lt;/b&gt; instruction.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__ll_lshift &lt;/code&gt;&lt;/td&gt; &lt;td&gt;Shifts a 64-bit value specified by the first parameter to the left by a number of bits specified by the second parameter.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__ll_rshift &lt;/code&gt;&lt;/td&gt; &lt;td&gt;Shifts a 64-bit value specified by the first parameter to the right by a number of bits specified by the second parameter.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__load128, __load128_acq &lt;/code&gt;&lt;/td&gt; &lt;td&gt;Loads a 128-bit value atomically.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_mm_cvtsd_si64x&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Generates the x64 extended form of the Convert Scalar Double-Precision Floating-Point Value to 64-Bit Integer (&lt;b&gt;cvtsd2si&lt;/b&gt;) instruction, which takes the double in the first element of value and converts it to a 64-bit integer.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_mm_cvtsi128_si64x &lt;/code&gt;&lt;/td&gt; &lt;td&gt;Generates the x64 extended form of the &lt;b&gt;movd&lt;/b&gt; instruction, which extracts the low 64-bit integer from an &lt;b&gt;__m128i&lt;/b&gt; structure.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_mm_cvtsi64x_sd &lt;/code&gt;&lt;/td&gt; &lt;td&gt;Generates the Convert Double Word Integer to Scalar Double-Precision Floating-Point Value (&lt;b&gt;cvtsi2sd&lt;/b&gt;) instruction.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_mm_cvtsi64x_si128 &lt;/code&gt;&lt;/td&gt; &lt;td&gt;Generates the x64 extended form of the &lt;b&gt;movd&lt;/b&gt; instruction, which copies a 64-bit value to a &lt;b&gt;__m128i&lt;/b&gt; structure, which represents an XMM register.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_mm_cvtsi64x_ss &lt;/code&gt;&lt;/td&gt; &lt;td&gt;Generates the x64 extended version of the Convert 64-Bit Integer to Scalar Single-Precision Floating-Point Value (&lt;b&gt;cvtsi2ss&lt;/b&gt;) instruction.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_mm_cvtss_si64x&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Generates the x64 extended version of the Convert Scalar Single Precision Floating Point Number to 64-bit Integer (&lt;b&gt;cvtss2si&lt;/b&gt;) instruction.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_mm_cvttsd_si64x&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Generates the x64 extended version of the Convert with Truncation Scalar Double-Precision Floating-Point Value to 64-Bit Integer (&lt;b&gt;cvttsd2si&lt;/b&gt;) instruction, which takes the first double in the input structure of packed doubles, converts it to a 64-bit integer, and returns the result. &lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_mm_cvttss_si64x&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Emits the x64 extended version of the Convert with Truncation Single-Precision Floating-Point Number to 64-Bit Integer (&lt;b&gt;cvttss2si&lt;/b&gt;) instruction.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_mm_set_epi64x&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Returns the &lt;b&gt;__m128i&lt;/b&gt; structure with its two 64-bit integer values initialized to the values of the two 64-bit integers passed in.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_mm_set1_epi64x&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Provides a way to initialize the two 64-bit elements of the &lt;b&gt;__m128i&lt;/b&gt; structure with two identical integers.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_mm_setl_epi64 &lt;/code&gt;&lt;/td&gt; &lt;td&gt;Returns the lower 64 bits of source argument in the lower 64 bits of the result.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_mm_stream_si64x&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Writes the data in Source to a memory location specified by Dest, without polluting the caches.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__movsb &lt;/code&gt;&lt;/td&gt; &lt;td&gt;Generates a Move String (&lt;b&gt;rep movsb&lt;/b&gt;) instruction.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__movsd &lt;/code&gt;&lt;/td&gt; &lt;td&gt;Generates a Move String (&lt;b&gt;rep movsd&lt;/b&gt;) instruction.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__movsq&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Generates a repeated Move String (&lt;b&gt;rep movsq&lt;/b&gt;) instruction.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__movsw&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Generates a Move String (&lt;b&gt;rep movsw&lt;/b&gt;) instruction.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__mul128&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Multiplies two 64-bit integers passed in as the first two arguments and puts the high 64 bits of the product in the 64-bit integer pointed to by HighProduct and returns the low 64 bits of the product.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__mulh &lt;/code&gt;&lt;/td&gt; &lt;td&gt;Returns the high 64 bits of the product of two 64-bit signed integers.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__outbyte&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Generates the &lt;b&gt;out&lt;/b&gt; instruction, which sends 1 byte specified by Data out the I/O port specified by Port.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__outbytestring&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Generates the &lt;b&gt;rep outsb&lt;/b&gt; instruction,which sends the first Count bytes of data pointed to by Buffer to the port specified by Port.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__outdword&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Generates the &lt;b&gt;out&lt;/b&gt; instruction to send a doubleword Data out the port Port.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__outdwordstring&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Generates the &lt;b&gt;rep outsd &lt;/b&gt;instruction, which sends Count doublewords starting at Buffer out the I/O port specified by Port.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__rdtsc&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Generates the &lt;b&gt;rdtsc&lt;/b&gt; instruction, which returns the processor time stamp. The processor time stamp records the number of clock cycles since the last reset.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_ReadBarrier&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Forces memory reads to complete.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__readcr0, __readcr2, __readcr3, __readcr4, __readcr8 &lt;/code&gt;&lt;/td&gt; &lt;td&gt;Read the control registers. These intrinsics are only available in kernel mode.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__readfsbyte, __readfsdword, __readfsqword, __readfsword&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Read memory from a location specified by an offset relative to the beginning of the FS segment. These intrinsics are only available in kernel mode.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__readgsbyte, __readgsdword, __readgsqword, __readgsword &lt;/code&gt;&lt;/td&gt; &lt;td&gt;Read memory from a location specified by an offset relative to the beginning of the GS segment. These intrinsics are only available in kernel mode.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__readmsr&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Generates the &lt;b&gt;rdmsr&lt;/b&gt; instruction, which reads the model-specific register specified by register and returns its value. This function may only be used in kernel mode.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__readpmc&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Generates the &lt;b&gt;rdpmc&lt;/b&gt; instruction, which reads the performance monitoring counter specified by counter.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_ReadWriteBarrier&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Effectively blocks an optimization of reads and writes to global memory.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_ReturnAddress&lt;/code&gt;&lt;/td&gt; &lt;td&gt;The &lt;b&gt;_ReturnAddress&lt;/b&gt; intrinsic provides the address of the instruction in the calling function that will be executed after control returns to the caller.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__shiftleft128&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Shifts a 128-bit quantity, represented as two 64-bit quantities LowPart and HighPart, to the left by a number of bits specified by Shift and returns the high 64 bits of the result.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__shiftright128&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Shifts a 128-bit quantity, represented as two 64-bit quantities LowPart and HighPart, to the right by a number of bits specified by Shift and returns the low 64 bits of the result.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__store128, __store128_rel&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Stores a 128-bit value atomically.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__stosb &lt;/code&gt;&lt;/td&gt; &lt;td&gt;Generates a store string instruction (&lt;b&gt;rep stosb&lt;/b&gt;).&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__stosd&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Generates a store string instruction (&lt;b&gt;rep stosd&lt;/b&gt;).&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__stosq&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Generates a store string instruction (&lt;b&gt;rep stosq&lt;/b&gt;).&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__stosw&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Generates a store string instruction (&lt;b&gt;rep stosw&lt;/b&gt;).&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__ull_rshift&lt;/code&gt;&lt;/td&gt; &lt;td&gt;on x64, shifts a 64-bit value specified by the first parameter to the right by a number of bits specified by the second parameter.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_umul128&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Multiplies two 64-bit unsigned integers passed in as the first two arguments and puts the high 64 bits of the product in the 64-bit unsigned integer pointed to by HighProduct and returns the low 64 bits of the product.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__umulh &lt;/code&gt;&lt;/td&gt; &lt;td&gt;Return the high 64 bits of the product of two 64-bit unsigned integers.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__wbinvd&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Generates the Write Back and Invalidate Cache (&lt;b&gt;wbinvd&lt;/b&gt;) instruction.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;_WriteBarrier&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Forces memory writes to complete and be correct according to program logic at the point of the call.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__writecr0, __writecr3, __writecr4, __writecr8&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Write the control registers. These intrinsics are only available in kernel mode.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__writefsbyte, __writefsdword, __writefsqword, __writefsword &lt;/code&gt;&lt;/td&gt; &lt;td&gt;Write memory to a location specified by an offset relative to the beginning of the FS segment. These intrinsics are only available in kernel mode.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__writegsbyte, __writegsdword, __writegsqword, __writegsword &lt;/code&gt;&lt;/td&gt; &lt;td&gt;Write memory to a location specified by an offset relative to the beginning of the GS segment. These intrinsics are only available in kernel mode.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="289"&gt;&lt;code&gt;__writemsr&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Generates the Write to Model Specific Register (&lt;b&gt;wrmsr&lt;/b&gt;) instruction. This function may only be used in kernel mode.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;There are also some 3D intrinsics (called 3DNow) which will be useful for game/3D coders. I left those intrinsics out of the list since they were too many and you'd need to include another header file to use them: "mm3dnow.h".&lt;/p&gt; &lt;p&gt;If these intrinsics are not enough, you might need to use an external asm file. On the other hand, if you're really lazy and you just need something on the fly, there's a quick way to embed assembly code in your C/C++ files. &lt;/p&gt;&lt;pre lang="c++"&gt;&lt;span class="cpp-preprocessor"&gt;#include "stdafx.h"&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-preprocessor"&gt;#include &lt;windows.h&gt;&lt;/windows.h&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;unsigned&lt;/span&gt; &lt;span class="cpp-keyword"&gt;char&lt;/span&gt; BitSwapAsm[&lt;span class="cpp-literal"&gt;7&lt;/span&gt;] =&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cpp-literal"&gt;0x48&lt;/span&gt;, &lt;span class="cpp-literal"&gt;0x8B&lt;/span&gt;, &lt;span class="cpp-literal"&gt;0xC1&lt;/span&gt;,        &lt;span class="cpp-comment"&gt;// mov rax, rcx&lt;/span&gt;&lt;br /&gt;  &lt;span class="cpp-literal"&gt;0x48&lt;/span&gt;, &lt;span class="cpp-literal"&gt;0x0F&lt;/span&gt;, &lt;span class="cpp-literal"&gt;0xC8&lt;/span&gt;,        &lt;span class="cpp-comment"&gt;// bswap rax&lt;/span&gt;&lt;br /&gt;  &lt;span class="cpp-literal"&gt;0xC3&lt;/span&gt;            &lt;span class="cpp-comment"&gt;// retn&lt;/span&gt;&lt;br /&gt;};&lt;br /&gt;__int64 (*BitSwap)(__int64 Value) =  (__int64 (*)(__int64))&lt;br /&gt;                                                   (ULONG_PTR) BitSwapAsm;&lt;br /&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;int&lt;/span&gt; _tmain(&lt;span class="cpp-keyword"&gt;int&lt;/span&gt; argc, _TCHAR* argv[])&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;// I have to change the page protection, otherwise the code would crash&lt;/span&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;  DWORD dwOldProtect;&lt;br /&gt;  VirtualProtect(BitSwap, &lt;span class="cpp-keyword"&gt;sizeof&lt;/span&gt; (BitSwapAsm), PAGE_EXECUTE_READWRITE,&lt;br /&gt;                 &amp;dwOldProtect);&lt;br /&gt;&lt;br /&gt;  printf_s(&lt;span class="cpp-string"&gt;"%p\n"&lt;/span&gt;, BitSwap(&lt;span class="cpp-literal"&gt;0xDDCCBBAA&lt;/span&gt;));&lt;br /&gt;  getchar();&lt;br /&gt;}&lt;/pre&gt; &lt;p&gt;This code relies on function pointers and I had to change the page protection flags in order to make it execute. It's really a dumb method, but in some case it could be time saving. &lt;/p&gt; &lt;h3&gt;&lt;a name="Windows_On_Windows"&gt;Windows On Windows&lt;/a&gt;&lt;/h3&gt; &lt;p&gt;Of course, compatibility for 32bit applications has to be provided on x64 (and Itanium as well) and this is what WOW64 (Windows on Windows 64) is all about. When we look at the modules loaded by a 32bit application with a 32bit version of the &lt;a href="http://www.ntcore.com/exsuite.php"&gt;Task Explorer&lt;/a&gt; we see this:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.codeproject.com/vista/vista_x64/modules32.jpg" border="0" height="337" width="600" /&gt;&lt;/p&gt; &lt;p&gt;Seems pretty regular, except, of course, for the system files path, which in our case is syswow64 instead of the old common System32. It's easy to understand why it is this way: the System32 folder is now reserved for the 64bit environment and the 32bit files had to be placed somewhere else. But look what happens when I open the same process with an x64 version of the Task Explorer:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.codeproject.com/vista/vista_x64/modules64.jpg" border="0" height="73" width="600" /&gt;&lt;/p&gt; &lt;p&gt;Suddenly, all the 32bit modules are gone and what remains are the WOW64 emulation modules. Here's the description the MSDN gives us of these modules:&lt;/p&gt; &lt;table bgcolor="#e1e1f2" border="0" cellpadding="3" width="100%"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;The WOW64 emulator runs in user mode, provides an interface between the 32-bit version of Ntdll.dll and the kernel of the processor, and it intercepts kernel calls. The emulator consists of the following DLLs:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Wow64.dll provides the core emulation infrastructure and the thunks for the Ntoskrnl.exe entry-point functions.  &lt;/li&gt;&lt;li&gt;Wow64Win.dll provides thunks for the Win32k.sys entry-point functions.  &lt;/li&gt;&lt;li&gt;Wow64Cpu.dll provides x86 instruction emulation on Itanium processors. It executes mode-switch instructions on the processor. This DLL is not necessary for x64 processors because they execute x86-32 instructions at full clock speed. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Along with the 64-bit version of Ntdll.dll, these are the only 64-bit binaries that can be loaded into a 32-bit process.At startup, Wow64.dll loads the x86 version of Ntdll.dll and runs its initialization code, which loads all necessary 32-bit DLLs. Almost all 32-bit DLLs are unmodified copies of 32-bit Windows binaries. However, some of these DLLs are written to behave differently on WOW64 than they do on 32-bit Windows [...].&lt;/p&gt; &lt;p&gt;Instead of using the x86 system-service call sequence, 32-bit binaries that make system calls are rebuilt to use a custom calling sequence. This new sequence is inexpensive for WOW64 to intercept because it remains entirely in user mode. When the new calling sequence is detected, the WOW64 CPU transitions back to native 64-bit mode and calls into Wow64.dll. Thunking is done in user mode to reduce the impact on the 64-bit kernel, and to reduce the risk of a bug in the thunk that causes a kernel-mode crash, data corruption, or a security hole. The thunks extract arguments from the 32-bit stack, extend them to 64 bits, then make the native system call.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;32bit applications have a maximal 2GB space (4GB if explicitly required) and the rest of the space is handled by the system. This doesn't change much of course, since on x86 user mode applications had 2GB of virtual memory space out of 4GB (the other 2GB were reserved for kernel mode). On x64 these two other GB can now be accessed by 32bit applications. In order to achieve this, the &lt;code&gt;IMAGE_FILE_LARGE_ADDRESS_AWARE &lt;/code&gt;flag has to be set in the File Header's Characteristics field. You can do this programmatically or manually with a normal PE editor like the &lt;a href="http://www.ntcore.com/exsuite.php"&gt;CFF Explorer&lt;/a&gt;, just like this:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.codeproject.com/vista/vista_x64/largeaddress.jpg" border="0" height="506" width="518" /&gt;&lt;/p&gt; &lt;p&gt;I've seen this done by 3D-games players in order to increase performances. Of course, it's only useful for very heavy memory consuming applications. &lt;/p&gt; &lt;p&gt;A very useful function to determine whether a process is running under WOW64 or not is:&lt;/p&gt;&lt;pre lang="c++"&gt;BOOL IsWow64Process(&lt;br /&gt;HANDLE hProcess,   &lt;span class="cpp-comment"&gt;// [in] Handle to a process. &lt;/span&gt;&lt;br /&gt;PBOOL Wow64Process &lt;span class="cpp-comment"&gt;// [out] Pointer to a value that is set to TRUE if the &lt;/span&gt;&lt;br /&gt;                   &lt;span class="cpp-comment"&gt;// process is running under WOW64. Otherwise, the value &lt;/span&gt;&lt;br /&gt;                   &lt;span class="cpp-comment"&gt;// is set to FALSE. &lt;/span&gt;&lt;br /&gt;);&lt;/pre&gt; &lt;p&gt;The work done by Wow64Cpu.dll on x64 is zero, because x64 supports x86 natively. I was first tempted to look how the calling sequence works in order to make one myself and provide a way to use x86 components from x64 in the same address space, but, on second thought, even if it could be implemented, it wouldn't work on Itanium. And this brings us to one of the next paragraphs, because under normal conditions a 32bit application cannot load a 64bit dll and a 64bit application cannot load a 32bit dll. So, interprocess communication becomes an important aspect on 64bit systems. Anyway, before that, I have to talk about file system and registry redirection, since they are strictly related to WOW64, but deserve an extra paragraph for their importance. &lt;/p&gt; &lt;h3&gt;&lt;a name="File_System_And_Registry_Redirection"&gt;File System And Registry Redirection&lt;/a&gt;&lt;/h3&gt; &lt;p&gt;Since the System32 path is reserved to 64bit files, any time a 32bit application tries to access this directory it is redirected to SysWow64 one. However, there are some subdirectories of System32 that are shared between 32bit and 64bit applications and so no redirection is needed. These subdirectories are:&lt;/p&gt; &lt;ul&gt;&lt;li&gt;%windir%\system32\catroot  &lt;/li&gt;&lt;li&gt;%windir%\system32\catroot2  &lt;/li&gt;&lt;li&gt;%windir%\system32\drivers\etc  &lt;/li&gt;&lt;li&gt;%windir%\system32\logfiles  &lt;/li&gt;&lt;li&gt;%windir%\system32\spool &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Also, there are some functions related to the WOW64 file system redirection:&lt;/p&gt; &lt;table border="0" bordercolor="#000000" cellpadding="3" width="100%"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="237"&gt;&lt;code&gt;GetSystemWow64Directory&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Retrieves the path of the system directory used by WOW64. This directory is not present on 32-bit Windows.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="237"&gt;&lt;code&gt;Wow64DisableWow64FsRedirection&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Disables file system redirection for the calling thread. File system redirection is enabled by default.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="237"&gt;&lt;code&gt;Wow64EnableWow64FsRedirection&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Enables or disables file system redirection for the calling thread. This function may not work reliably when there are nested calls. Therefore, this function has been replaced by the Wow64DisableWow64FsRedirection and Wow64RevertWow64FsRedirection functions.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="237"&gt;&lt;code&gt;Wow64RevertWow64FsRedirection&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Restores file system redirection for the calling thread.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;I think it's easy to understand how to use these functions. However, I add a little code sample (you can find almost the same one on the MSDN):&lt;/p&gt;&lt;div class="smallText" id="premain19" style="width: 100%;"&gt;&lt;img preid="19" src="http://www.codeproject.com/images/minus.gif" id="preimg19" height="9" width="9" /&gt;&lt;span preid="19" style="margin-bottom: 0pt;" id="precollapse19"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre19" lang="c++"&gt;&lt;span class="cpp-keyword"&gt;int&lt;/span&gt; _tmain(&lt;span class="cpp-keyword"&gt;int&lt;/span&gt; argc, _TCHAR* argv[])&lt;br /&gt;{&lt;br /&gt;  BOOL bIsWOW64Enabled;&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;if&lt;/span&gt; (IsWow64Process(GetCurrentProcess(), &amp;bIsWOW64Enabled))&lt;br /&gt;  {&lt;br /&gt;      &lt;span class="cpp-keyword"&gt;if&lt;/span&gt; (bIsWOW64Enabled == TRUE) &lt;span class="cpp-comment"&gt;// we run under WOW64&lt;/span&gt;&lt;br /&gt;      {&lt;br /&gt;          PVOID pOldValue;&lt;br /&gt;          DWORD FileSize;&lt;br /&gt;&lt;br /&gt;          HANDLE hFile = CreateFile(_T(&lt;span class="cpp-string"&gt;"c:\\windows\\system32\\notepad.exe"&lt;/span&gt;),&lt;br /&gt;              GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, &lt;span class="cpp-literal"&gt;0&lt;/span&gt;, NULL);&lt;br /&gt;&lt;br /&gt;          FileSize = GetFileSize(hFile, NULL);&lt;br /&gt;&lt;br /&gt;          CloseHandle(hFile);&lt;br /&gt;&lt;br /&gt;          _tprintf(_T(&lt;span class="cpp-string"&gt;"File Size: %d Bytes\n"&lt;/span&gt;), FileSize);&lt;br /&gt;&lt;br /&gt;          Wow64DisableWow64FsRedirection(&amp;pOldValue); &lt;span class="cpp-comment"&gt;// disable redirection&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;          hFile = CreateFile(_T(&lt;span class="cpp-string"&gt;"c:\\windows\\system32\\notepad.exe"&lt;/span&gt;),&lt;br /&gt;                             GENERIC_READ, FILE_SHARE_READ, NULL,&lt;br /&gt;                             OPEN_EXISTING, &lt;span class="cpp-literal"&gt;0&lt;/span&gt;, NULL);&lt;br /&gt;&lt;br /&gt;          FileSize = GetFileSize(hFile, NULL);&lt;br /&gt;&lt;br /&gt;          CloseHandle(hFile);&lt;br /&gt;&lt;br /&gt;          _tprintf(_T(&lt;span class="cpp-string"&gt;"File Size: %d Bytes\n"&lt;/span&gt;), FileSize);&lt;br /&gt;&lt;br /&gt;          Wow64RevertWow64FsRedirection(pOldValue);  &lt;span class="cpp-comment"&gt;// restore redirection&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;          getchar();&lt;br /&gt;      }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;return&lt;/span&gt; &lt;span class="cpp-literal"&gt;0&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt; &lt;p&gt;The output of this program is:&lt;/p&gt;&lt;pre lang="text"&gt;&lt;b&gt;File Size: 151040 Bytes&lt;br /&gt;File Size: 169472 Bytes&lt;/b&gt;&lt;/pre&gt; &lt;p&gt;The file size changes because one time the program opens the 32bit notepad and one time the 64bit one. Of course, remember when you're using these functions, always use them along with GetProcAddress, otherwise your code won't work on older systems which don't provide them.&lt;/p&gt; &lt;p&gt;Let's move on to the registry. As for the file system the registry is being redirected as well, or better some keys of it. These keys are:&lt;/p&gt; &lt;ul&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\Software  &lt;/li&gt;&lt;li&gt;HKEY_USERS\*\Software\Classes  &lt;/li&gt;&lt;li&gt;HKEY_USERS\*_Classes &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;You can find every one of these keys duplicated for 32bit applications in their WOW node: any of these keys has a subkey called Wow6432Node, which contains a duplicate of the parent key. For instance:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.codeproject.com/vista/vista_x64/wownode.jpg" border="0" height="306" width="241" /&gt;&lt;/p&gt; &lt;p&gt;Some of these WOW64 redirected keys have subkeys which are reflected. Reflection in this case means that when I change a reflected key in the 32bit node the change is being &lt;i&gt;reflected&lt;/i&gt; on the 64bit key as well and viceversa. This is necessary, because some keys need to remain in synch. This is quite different from just sharing the keys between 64bit and 32bit mode, because the reflection can be filtered and also disabled. These are the reflected keys:&lt;/p&gt; &lt;ul&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\Software\Classes  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\Software\Microsoft\COM3  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\Software\Microsoft\EventSystem  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\Software\Microsoft\Ole  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\Software\Microsoft\Rpc  &lt;/li&gt;&lt;li&gt;HKEY_USERS\*\Software\Classes  &lt;/li&gt;&lt;li&gt;HKEY_USERS\*_Classes &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The functions to handle reflection are:&lt;/p&gt; &lt;table border="0" bordercolor="#000000" cellpadding="3" width="100%"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegQueryReflectionKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Determines whether reflection has been disabled or enabled for the specified key.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegDisableReflectionKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Disables registry reflection for the specified key. Disabling reflection for a key does not affect reflection of any subkeys.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegEnableReflectionKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Restores registry reflection for the specified disabled key. Restoring reflection for a key does not affect reflection of any subkeys.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;They work just like the WOW64 file system functions, so I don't think a code sample is necessary. There are also some shared keys between 64bit and 32bit applications:&lt;/p&gt; &lt;ul&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Classes\HCP  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Calais\Current  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Calais\Readers  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Services  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\CTF\SystemShared  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\CTF\TIP  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DFS  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Driver Signing  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\EnterpriseCertificates  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSMQ  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Non-Driver Signing  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\RAS  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Software\Microsoft\Shared Tools\MSInfo  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SystemCertificates  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\TermServLicensing  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Transaction Server  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontDpi  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontMapper  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontSubstitutes  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Ports  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Control Panel\Cursors\Schemes  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\OC Manager  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Telephony\Locations  &lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Policies &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;As said, these keys are shared, so any change made to them will affect both 32bit and 64bit applications, and there's no way to avoid this like for reflected keys.&lt;/p&gt; &lt;p&gt;But what if a 32bit applications wants to access the 64bit registry or viceversa? Don't worry! As I discovered when I was dealing with the same problem, Microsoft provides a very simple way to do the job. The flags KEY_WOW64_64KEY and KEY_WOW64_32KEY can be used with these functions: RegCreateKeyEx, RegDeleteKeyEx and RegOpenKeyEx.&lt;/p&gt; &lt;table border="0" bordercolor="#000000" cellpadding="3" width="100%"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="152"&gt;&lt;code&gt;KEY_WOW64_64KEY &lt;/code&gt;&lt;/td&gt; &lt;td&gt;Access a 64-bit key from either a 32-bit or 64-bit application.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="152"&gt;&lt;code&gt;KEY_WOW64_32KEY &lt;/code&gt;&lt;/td&gt; &lt;td&gt;Access a 32-bit key from either a 32-bit or 64-bit application.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;What I needed to do was to access the subkeys of a 64bit key from a 32bit application, which translated in code is just:&lt;/p&gt;&lt;pre lang="c++"&gt;RegOpenKeyEx(HKEY_LOCAL_MACHINE, MyKey, &lt;span class="cpp-literal"&gt;0&lt;/span&gt;, KEY_READ | KEY_WOW64_64KEY, &amp;hKey);&lt;/pre&gt; &lt;p&gt;Easy, isn't it?&lt;/p&gt; &lt;p&gt;All in all, the documentation provided by Microsoft on file system and registry redirection is very good and I just reported what I first found on the MSDN. I don't think these redirections are going to be much of a problem for programmers.&lt;/p&gt; &lt;h3&gt;&lt;a name="Interprocess_Communication_"&gt;Interprocess Communication&lt;/a&gt;&lt;/h3&gt; &lt;p&gt;As mentioned in the Windows On Windows paragraph, interprocess communication becomes an important aspect on x64, since a 64bit application might need to use a 32bit component and viceversa. The MSDN suggests these ways for process to communicate between each other:&lt;/p&gt; &lt;ul&gt;&lt;li&gt;Handles to named objects such as mutexes, semaphores, and file handles can all be shared.  &lt;/li&gt;&lt;li&gt;Handles to windows (HWND) can be shared.  &lt;/li&gt;&lt;li&gt;RPC.  &lt;/li&gt;&lt;li&gt;COM LocalServers.  &lt;/li&gt;&lt;li&gt;Shared memory can be used if the contents of the shared memory are not pointer-dependent.  &lt;/li&gt;&lt;li&gt;The CreateProcess and ShellExecute functions can launch 32-bit and 64-bit processes from either 32-bit or 64-bit processes.  &lt;/li&gt;&lt;li&gt;The CreateRemoteThread function is special-cased for specific functions, allowing 64-bit debuggers to break into 32-bit processes. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Using CreateProcess or ShellExecute means that you could communicate through arguments and output reading. If you need something more sofisticated (and professional), you have no choice but to use RPCs (Remote Procedure Calls) or COM objects. For RPCs you need to learn a bit about the MIDL (Microsoft Interface Definition Language), but eventually every code sample I tried wasn't working on Vista x64, so I gave up on RPCs. I would suggest you to use a COM, writing them in MFC is very easy (comparing to writing them without MFC, I mean). There's a very good series of articles on CodeProject about writing &lt;a href="http://www.codeproject.com/com/com_in_c1.asp"&gt;ActiveXs&lt;/a&gt;. Actually, the guide is about how writing ActiveXs in plain C (I had to reduce the size of my ActiveX, so I couldn't use MFC), but the theory is the same and these articles are well written and could save you from the effort of reading a book. If you have never written COM objects before, you will eventually discover that it can be annoying. &lt;/p&gt; &lt;p&gt;Shared memory is not really an option. If you are looking for a solution between CreateProcess and COM objects, you may use pipes or things like that. Actually, you could implement your own pipes through shared memory and mutexes. This is what I have done in some projects:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.codeproject.com/vista/vista_x64/pipes.jpg" border="0" height="477" width="442" /&gt;&lt;/p&gt; &lt;p&gt;The " *32" next to the process name is the way of the Task Manager to tell us which are 32bit processes. As you can see the Server is a 64bit process and the Client a 32bit one. The two processes communicate with each other without problems. However, don't get too excited, there are some problems and I'll explain later what they are about. For now, let's see a code sample (communication.zip download available at the top of the article)&lt;/p&gt; &lt;p&gt;Here's the Client code:&lt;/p&gt;&lt;div class="smallText" id="premain22" style="width: 100%;"&gt;&lt;img preid="22" src="http://www.codeproject.com/images/minus.gif" id="preimg22" height="9" width="9" /&gt;&lt;span preid="22" style="margin-bottom: 0pt;" id="precollapse22"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre22" lang="c++"&gt;&lt;span class="cpp-preprocessor"&gt;#include &lt;windows.h&gt;&lt;/windows.h&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-preprocessor"&gt;#include &lt;tchar.h&gt;&lt;/tchar.h&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="cpp-preprocessor"&gt;#define BUF_SIZE  256 * sizeof (TCHAR)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;TCHAR MyEvent[] = _T(&lt;span class="cpp-string"&gt;"Global\\SharedMemoryEvent"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;TCHAR szName[]= _T(&lt;span class="cpp-string"&gt;"Global\\MyFileMappingObject"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;int&lt;/span&gt; WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,&lt;br /&gt;                  LPSTR szCmdLine, &lt;span class="cpp-keyword"&gt;int&lt;/span&gt; iCmdShow)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;// Create the event to communicate between server and client&lt;/span&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, MyEvent);&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;// Start server process&lt;/span&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  PROCESS_INFORMATION pi = { &lt;span class="cpp-literal"&gt;0&lt;/span&gt; };&lt;br /&gt;  STARTUPINFO si = { &lt;span class="cpp-literal"&gt;0&lt;/span&gt; };&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;if&lt;/span&gt; (!CreateProcess(_T(&lt;span class="cpp-string"&gt;"Server.exe"&lt;/span&gt;), NULL, NULL, NULL, FALSE, &lt;span class="cpp-literal"&gt;0&lt;/span&gt;, NULL,&lt;br /&gt;                     NULL, &amp;si, &amp;amp;pi))&lt;br /&gt;      &lt;span class="cpp-keyword"&gt;return&lt;/span&gt; &lt;span class="cpp-literal"&gt;1&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;// Wait for the server to complete the job&lt;/span&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  WaitForSingleObject(hEvent, INFINITE);&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;// Access shared memory object&lt;/span&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  HANDLE hMapFile = OpenFileMapping(&lt;br /&gt;      FILE_MAP_ALL_ACCESS,   &lt;span class="cpp-comment"&gt;// read/write access&lt;/span&gt;&lt;br /&gt;      FALSE,                 &lt;span class="cpp-comment"&gt;// do not inherit the name&lt;/span&gt;&lt;br /&gt;      szName);               &lt;span class="cpp-comment"&gt;// name of mapping object &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;if&lt;/span&gt; (hMapFile == NULL) &lt;span class="cpp-keyword"&gt;return&lt;/span&gt; &lt;span class="cpp-literal"&gt;1&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;  LPCTSTR pBuf = (LPTSTR) MapViewOfFile(&lt;br /&gt;      hMapFile,              &lt;span class="cpp-comment"&gt;// handle to map object&lt;/span&gt;&lt;br /&gt;      FILE_MAP_ALL_ACCESS,   &lt;span class="cpp-comment"&gt;// read/write permission&lt;/span&gt;&lt;br /&gt;      &lt;span class="cpp-literal"&gt;0&lt;/span&gt;,                  &lt;br /&gt;      &lt;span class="cpp-literal"&gt;0&lt;/span&gt;,                  &lt;br /&gt;      BUF_SIZE);                 &lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;if&lt;/span&gt; (pBuf == NULL) &lt;span class="cpp-keyword"&gt;return&lt;/span&gt; &lt;span class="cpp-literal"&gt;1&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;// Shows Server Output&lt;/span&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  MessageBox(NULL, pBuf, _T(&lt;span class="cpp-string"&gt;"Server Output"&lt;/span&gt;), MB_OK);&lt;br /&gt;&lt;br /&gt;  UnmapViewOfFile(pBuf);&lt;br /&gt;&lt;br /&gt;  CloseHandle(hMapFile);&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;// Tell the server that the object isn't used any longer&lt;/span&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  SetEvent(hEvent);&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;return&lt;/span&gt; &lt;span class="cpp-literal"&gt;0&lt;/span&gt;;&lt;br /&gt;}&lt;/pre&gt; &lt;p&gt;And here's the Server code:&lt;/p&gt;&lt;div class="smallText" id="premain23" style="width: 100%;"&gt;&lt;img preid="23" src="http://www.codeproject.com/images/minus.gif" id="preimg23" height="9" width="9" /&gt;&lt;span preid="23" style="margin-bottom: 0pt;" id="precollapse23"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre23"&gt;&lt;span class="cpp-preprocessor"&gt;#include &lt;windows.h&gt;&lt;/windows.h&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-preprocessor"&gt;#include &lt;tchar.h&gt;&lt;/tchar.h&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="cpp-preprocessor"&gt;#define BUF_SIZE  256 * sizeof (TCHAR)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;TCHAR MyEvent[] = _T(&lt;span class="cpp-string"&gt;"Global\\SharedMemoryEvent"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;TCHAR szName[] = _T(&lt;span class="cpp-string"&gt;"Global\\MyFileMappingObject"&lt;/span&gt;);&lt;br /&gt;TCHAR szMsg[] = _T(&lt;span class="cpp-string"&gt;"Message from server process"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;int&lt;/span&gt; WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,&lt;br /&gt;                   LPSTR szCmdLine, &lt;span class="cpp-keyword"&gt;int&lt;/span&gt; iCmdShow)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;// Create the memory shared object&lt;/span&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  HANDLE hMapFile;&lt;br /&gt;  LPCTSTR pBuf;&lt;br /&gt;&lt;br /&gt;  hMapFile = CreateFileMapping(&lt;br /&gt;      INVALID_HANDLE_VALUE,    &lt;span class="cpp-comment"&gt;// use paging file&lt;/span&gt;&lt;br /&gt;      NULL,                    &lt;span class="cpp-comment"&gt;// default security &lt;/span&gt;&lt;br /&gt;      PAGE_READWRITE,          &lt;span class="cpp-comment"&gt;// read/write access&lt;/span&gt;&lt;br /&gt;      &lt;span class="cpp-literal"&gt;0&lt;/span&gt;,                       &lt;span class="cpp-comment"&gt;// max. object size &lt;/span&gt;&lt;br /&gt;      BUF_SIZE,                &lt;span class="cpp-comment"&gt;// buffer size  &lt;/span&gt;&lt;br /&gt;      szName);                 &lt;span class="cpp-comment"&gt;// name of mapping object&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;if&lt;/span&gt; (hMapFile == NULL) &lt;span class="cpp-keyword"&gt;return&lt;/span&gt; &lt;span class="cpp-literal"&gt;1&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;  pBuf = (LPTSTR) MapViewOfFile(hMapFile,   &lt;span class="cpp-comment"&gt;// handle to map object&lt;/span&gt;&lt;br /&gt;      FILE_MAP_ALL_ACCESS,             &lt;span class="cpp-comment"&gt;// read/write permission&lt;/span&gt;&lt;br /&gt;      &lt;span class="cpp-literal"&gt;0&lt;/span&gt;,                 &lt;br /&gt;      &lt;span class="cpp-literal"&gt;0&lt;/span&gt;,                 &lt;br /&gt;      BUF_SIZE);         &lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;if&lt;/span&gt; (pBuf == NULL) &lt;span class="cpp-keyword"&gt;return&lt;/span&gt; &lt;span class="cpp-literal"&gt;1&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;  CopyMemory((PVOID) pBuf, szMsg, (_tcslen(szMsg) + &lt;span class="cpp-literal"&gt;1&lt;/span&gt;) * &lt;span class="cpp-keyword"&gt;sizeof&lt;/span&gt; (TCHAR));&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;// Wait for event before closing file object&lt;/span&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  HANDLE hEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, MyEvent);&lt;br /&gt;&lt;br /&gt;  SetEvent(hEvent);&lt;br /&gt;&lt;br /&gt;  WaitForSingleObject(hEvent, INFINITE);&lt;br /&gt;&lt;br /&gt;  UnmapViewOfFile(pBuf);&lt;br /&gt;  CloseHandle(hMapFile);&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;return&lt;/span&gt; &lt;span class="cpp-literal"&gt;0&lt;/span&gt;;&lt;br /&gt;}&lt;/pre&gt; &lt;p&gt;What these applications do is:&lt;/p&gt; &lt;ul&gt;&lt;li&gt; &lt;p&gt;The client creates a communication event.&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;The client starts the server and waits for the communication event to be set.&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;The server creates a shared memory object and fills it with an output.&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;The server sets the communication event in order to tell the client to process the output.&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;The server waits for the client to clear the shared memory.&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;The client processes the server's output.&lt;/p&gt; &lt;/li&gt;&lt;li&gt; &lt;p&gt;The client tells the server that it can now clear the shared memory.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;I believe it's easier to understand the code itself than this list. The problem I mentioned earlier is that in order to share a memory object (or an event) between processes, I have to create it in the "Global\\*" section. What happens with Vista is that only applications with admin privileges can access this section with CreateFileMapping (no problems with mutexes or events, though), and since usually applications run in Vista with user privileges, you have to explicitly tell Vista to run the Client application with admin privileges, which is not very professional. The solution to this problem could be to share the memory through a temporary file or even the registry (for small data). &lt;/p&gt; &lt;h3&gt;&lt;a name="Portable_Executable"&gt;Portable Executable&lt;/a&gt;&lt;/h3&gt; &lt;p&gt;If your software has anything to do with Portable Executables it won't be too hard to move to x64 (if you haven't done it already). Basically, what in PE64 changes is the size of virtual addresses (VAs), which are now 64bit wide. Keep in mind that not all the fields described as virtual addresses really are such, most of the time they're just relative virtual addresses (RVAs), which are, like in the PE32, 32bit wide. What changes, in short, is the Optional Header (which has some 64bit wide fields like the ImageBase), Import Directory thunks (the two thunk arrays. OFTs and FTs, are now 64bit wide, since thunks were built to contain virtual addresses among the other things), the Load Config Directory and the TLS Directory.&lt;/p&gt; &lt;p&gt;Let's take, for instance, the old PE32 Optional Header:&lt;/p&gt;&lt;div class="smallText" id="premain24" style="width: 100%;"&gt;&lt;img preid="24" src="http://www.codeproject.com/images/minus.gif" id="preimg24" height="9" width="9" /&gt;&lt;span preid="24" style="margin-bottom: 0pt;" id="precollapse24"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre24" lang="c++"&gt;&lt;span class="cpp-keyword"&gt;typedef&lt;/span&gt; &lt;span class="cpp-keyword"&gt;struct&lt;/span&gt; _IMAGE_OPTIONAL_HEADER {&lt;br /&gt;  &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;// Standard fields.&lt;/span&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  WORD    Magic;&lt;br /&gt;  BYTE    MajorLinkerVersion;&lt;br /&gt;  BYTE    MinorLinkerVersion;&lt;br /&gt;  DWORD   SizeOfCode;&lt;br /&gt;  DWORD   SizeOfInitializedData;&lt;br /&gt;  DWORD   SizeOfUninitializedData;&lt;br /&gt;  DWORD   AddressOfEntryPoint;&lt;br /&gt;  DWORD   BaseOfCode;&lt;br /&gt;  DWORD   BaseOfData;&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;// NT additional fields.&lt;/span&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  DWORD   ImageBase;&lt;br /&gt;  DWORD   SectionAlignment;&lt;br /&gt;  DWORD   FileAlignment;&lt;br /&gt;  WORD    MajorOperatingSystemVersion;&lt;br /&gt;  WORD    MinorOperatingSystemVersion;&lt;br /&gt;  WORD    MajorImageVersion;&lt;br /&gt;  WORD    MinorImageVersion;&lt;br /&gt;  WORD    MajorSubsystemVersion;&lt;br /&gt;  WORD    MinorSubsystemVersion;&lt;br /&gt;  DWORD   Win32VersionValue;&lt;br /&gt;  DWORD   SizeOfImage;&lt;br /&gt;  DWORD   SizeOfHeaders;&lt;br /&gt;  DWORD   CheckSum;&lt;br /&gt;  WORD    Subsystem;&lt;br /&gt;  WORD    DllCharacteristics;&lt;br /&gt;  DWORD   SizeOfStackReserve;&lt;br /&gt;  DWORD   SizeOfStackCommit;&lt;br /&gt;  DWORD   SizeOfHeapReserve;&lt;br /&gt;  DWORD   SizeOfHeapCommit;&lt;br /&gt;  DWORD   LoaderFlags;&lt;br /&gt;  DWORD   NumberOfRvaAndSizes;&lt;br /&gt;  IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];&lt;br /&gt;} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;&lt;/pre&gt; &lt;p&gt;And the PE64 one:&lt;/p&gt;&lt;div class="smallText" id="premain25" style="width: 100%;"&gt;&lt;img preid="25" src="http://www.codeproject.com/images/minus.gif" id="preimg25" height="9" width="9" /&gt;&lt;span preid="25" style="margin-bottom: 0pt;" id="precollapse25"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre25" lang="c++"&gt;&lt;span class="cpp-keyword"&gt;typedef&lt;/span&gt; &lt;span class="cpp-keyword"&gt;struct&lt;/span&gt; _IMAGE_OPTIONAL_HEADER64 {&lt;br /&gt;  WORD        Magic;&lt;br /&gt;  BYTE        MajorLinkerVersion;&lt;br /&gt;  BYTE        MinorLinkerVersion;&lt;br /&gt;  DWORD       SizeOfCode;&lt;br /&gt;  DWORD       SizeOfInitializedData;&lt;br /&gt;  DWORD       SizeOfUninitializedData;&lt;br /&gt;  DWORD       AddressOfEntryPoint;&lt;br /&gt;  DWORD       BaseOfCode;&lt;br /&gt;  ULONGLONG   ImageBase;&lt;br /&gt;  DWORD       SectionAlignment;&lt;br /&gt;  DWORD       FileAlignment;&lt;br /&gt;  WORD        MajorOperatingSystemVersion;&lt;br /&gt;  WORD        MinorOperatingSystemVersion;&lt;br /&gt;  WORD        MajorImageVersion;&lt;br /&gt;  WORD        MinorImageVersion;&lt;br /&gt;  WORD        MajorSubsystemVersion;&lt;br /&gt;  WORD        MinorSubsystemVersion;&lt;br /&gt;  DWORD       Win32VersionValue;&lt;br /&gt;  DWORD       SizeOfImage;&lt;br /&gt;  DWORD       SizeOfHeaders;&lt;br /&gt;  DWORD       CheckSum;&lt;br /&gt;  WORD        Subsystem;&lt;br /&gt;  WORD        DllCharacteristics;&lt;br /&gt;  ULONGLONG   SizeOfStackReserve;&lt;br /&gt;  ULONGLONG   SizeOfStackCommit;&lt;br /&gt;  ULONGLONG   SizeOfHeapReserve;&lt;br /&gt;  ULONGLONG   SizeOfHeapCommit;&lt;br /&gt;  DWORD       LoaderFlags;&lt;br /&gt;  DWORD       NumberOfRvaAndSizes;&lt;br /&gt;  IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];&lt;br /&gt;} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64;&lt;/pre&gt; &lt;p&gt;Of course, &lt;code&gt;ULONGLONG &lt;/code&gt;are 64bit wide fields. As you can see, the &lt;code&gt;AddressOfEntryPoint &lt;/code&gt;remains, as every RVA, a dword. Conversely, &lt;code&gt;ImageBase&lt;/code&gt;, being a Virtual Address, becomes a qword.&lt;/p&gt; &lt;p&gt;Distinguishing between PE32 and PE64 should be done by checking the Magic field in the Optional Header. This field can be one of these values:&lt;/p&gt;&lt;pre lang="c++"&gt;&lt;span class="cpp-preprocessor"&gt;#define IMAGE_NT_OPTIONAL_HDR32_MAGIC      0x10b&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-preprocessor"&gt;#define IMAGE_NT_OPTIONAL_HDR64_MAGIC      0x20b&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-preprocessor"&gt;#define IMAGE_ROM_OPTIONAL_HDR_MAGIC       0x107&lt;/span&gt;&lt;/pre&gt; &lt;p&gt;It is your choice to either double write every time the code to handle both PE32/64 or write a class to handle them automatically.&lt;/p&gt; &lt;h3&gt;&lt;a name="Exception_Handling"&gt;Exception Handling&lt;/a&gt;&lt;/h3&gt; &lt;p&gt;Remember the old days when you set the SEH in your code? Well, with x64/Itanium they're gone. Exception Handlers are now stored as structured in the PE64 Exception Directory. The basic structure is this:&lt;/p&gt;&lt;pre lang="c++"&gt;&lt;span class="cpp-keyword"&gt;typedef&lt;/span&gt; &lt;span class="cpp-keyword"&gt;struct&lt;/span&gt; _RUNTIME_FUNCTION {&lt;br /&gt;  DWORD BeginAddress;&lt;br /&gt;  DWORD EndAddress;&lt;br /&gt;  DWORD UnwindData;&lt;br /&gt;} RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;&lt;/pre&gt; &lt;p&gt;All three fields are RVAs (otherwise there wouldn't be dwords).&lt;/p&gt; &lt;table id="table1" border="0" bordercolor="#000000" cellpadding="3"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="93"&gt;&lt;code&gt;BeginAddress&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Points to the start address of the involved part of code.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="93"&gt;&lt;code&gt;EndAddress&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Points to the end address of the same part of code.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="93"&gt;&lt;code&gt;UnwindData&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Points to an UNWIND_INFO structure.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;The &lt;code&gt;UNWIND_INFO &lt;/code&gt;structure tells how the portion of code should be handled. Here's the declaration I found on MSDN: &lt;/p&gt;&lt;pre lang="c++"&gt;&lt;span class="cpp-keyword"&gt;typedef&lt;/span&gt; &lt;span class="cpp-keyword"&gt;union&lt;/span&gt; _UNWIND_CODE {&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;struct&lt;/span&gt; {&lt;br /&gt;      UBYTE CodeOffset;&lt;br /&gt;      UBYTE UnwindOp : &lt;span class="cpp-literal"&gt;4&lt;/span&gt;;&lt;br /&gt;      UBYTE OpInfo   : &lt;span class="cpp-literal"&gt;4&lt;/span&gt;;&lt;br /&gt;  };&lt;br /&gt;  USHORT FrameOffset;&lt;br /&gt;} UNWIND_CODE, *PUNWIND_CODE;&lt;br /&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;typedef&lt;/span&gt; &lt;span class="cpp-keyword"&gt;struct&lt;/span&gt; _UNWIND_INFO {&lt;br /&gt;  UBYTE Version       : &lt;span class="cpp-literal"&gt;3&lt;/span&gt;;&lt;br /&gt;  UBYTE Flags         : &lt;span class="cpp-literal"&gt;5&lt;/span&gt;;&lt;br /&gt;  UBYTE SizeOfProlog;&lt;br /&gt;  UBYTE CountOfCodes;&lt;br /&gt;  UBYTE FrameRegister : &lt;span class="cpp-literal"&gt;4&lt;/span&gt;;&lt;br /&gt;  UBYTE FrameOffset   : &lt;span class="cpp-literal"&gt;4&lt;/span&gt;;&lt;br /&gt;  UNWIND_CODE UnwindCode[&lt;span class="cpp-literal"&gt;1&lt;/span&gt;];&lt;br /&gt;&lt;span class="cpp-comment"&gt;/*  UNWIND_CODE MoreUnwindCode[((CountOfCodes + 1) &amp; ~1) - 1];&lt;br /&gt;*   union {&lt;br /&gt;*       OPTIONAL ULONG ExceptionHandler;&lt;br /&gt;*       OPTIONAL ULONG FunctionEntry;&lt;br /&gt;*   };&lt;br /&gt;*   OPTIONAL ULONG ExceptionData[]; */&lt;/span&gt;&lt;br /&gt;} UNWIND_INFO, *PUNWIND_INFO;&lt;br /&gt;&lt;/pre&gt; &lt;p&gt;Here's the description of the &lt;code&gt;UNWIND_INFO &lt;/code&gt;structure members taken directly from the MSDN:&lt;/p&gt; &lt;table id="table2" bgcolor="#e1e1e1" border="0" bordercolor="#000000" cellpadding="3" width="100%"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td valign="top" width="204"&gt;&lt;code&gt;Version&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Version number of the unwind data, currently 1.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="204"&gt;&lt;code&gt;Flags&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Three flags are currently defined:  &lt;p&gt;&lt;code&gt;UNW_FLAG_EHANDLER&lt;/code&gt; The function has an exception handler that should be called when looking for functions that need to examine exceptions. &lt;/p&gt; &lt;p&gt;&lt;code&gt;UNW_FLAG_UHANDLER&lt;/code&gt; The function has a termination handler that should be called when unwinding an exception. &lt;/p&gt; &lt;p&gt;&lt;code&gt;UNW_FLAG_CHAININFO&lt;/code&gt; This unwind info structure is not the primary one for the procedure. Instead, the chained unwind info entry is the contents of a previous RUNTIME_FUNCTION entry. See the following text for an explanation of chained unwind info structures. If this flag is set, then the UNW_FLAG_EHANDLER and &lt;code&gt;UNW_FLAG_UHANDLER&lt;/code&gt; flags must be cleared. Also, the frame register and fixed-stack allocation fields must have the same values as in the primary unwind info. &lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="204"&gt;&lt;code&gt;SizeOfProlog&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Length of the function prolog in bytes.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="204"&gt;&lt;code&gt;CountOfCodes&lt;/code&gt;&lt;/td&gt; &lt;td&gt;This is the number of slots in the unwind codes array. Note that some unwind codes (for example, &lt;code&gt;UWOP_SAVE_NONVOL&lt;/code&gt;) require more than one slot in the array.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="204"&gt;&lt;code&gt;FrameRegister &lt;/code&gt;&lt;/td&gt; &lt;td&gt;If nonzero, then the function uses a frame pointer, and this field is the number of the nonvolatile register used as the frame pointer, using the same encoding for the operation info field of &lt;code&gt;UNWIND_CODE&lt;/code&gt; nodes.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="204"&gt;&lt;code&gt;FrameOffset &lt;/code&gt;&lt;/td&gt; &lt;td&gt;If the frame register field is nonzero, then this is the scaled offset from RSP that is applied to the FP reg when it is established. The actual FP reg is set to RSP + 16 * this number, allowing offsets from 0 to 240. This permits pointing the FP reg into the middle of the local stack allocation for dynamic stack frames, allowing better code density through shorter instructions (more instructions can use the 8-bit signed offset form).&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="204"&gt;&lt;code&gt;UnwindCode&lt;/code&gt;&lt;/td&gt; &lt;td&gt;This is an array of items that explains the effect of the prolog on the nonvolatile registers and RSP. See the section on &lt;code&gt;UNWIND_CODE&lt;/code&gt; for the meanings of individual items. For alignment purposes, this array will always have an even number of entries, with the final entry potentially unused (in which case the array will be one longer than indicated by the count of unwind codes field).&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="204"&gt;&lt;code&gt;ExceptionHandler&lt;/code&gt;&lt;/td&gt; &lt;td&gt;This is an image-relative pointer to either the function's language-specific exception/termination handler (if flag &lt;code&gt;UNW_FLAG_CHAININFO&lt;/code&gt; is clear and one of the flags &lt;code&gt;UNW_FLAG_EHANDLER&lt;/code&gt; or &lt;code&gt;UNW_FLAG_UHANDLER&lt;/code&gt; is set).&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="204"&gt;&lt;code&gt;Language-specific handler data (ExceptionData)&lt;/code&gt;&lt;/td&gt; &lt;td&gt;This is the function's language-specific exception handler data. The format of this data is unspecified and completely determined by the specific exception handler in use.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="204"&gt;&lt;code&gt;Chained Unwind Info (ExceptionData)&lt;/code&gt;&lt;/td&gt; &lt;td&gt;If flag &lt;code&gt;UNW_FLAG_CHAININFO&lt;/code&gt; is set then the &lt;code&gt;UNWIND_INFO&lt;/code&gt; structure ends with three &lt;code&gt;UWORDs&lt;/code&gt;. These &lt;code&gt;UWORDs&lt;/code&gt; represent the &lt;code&gt;RUNTIME_FUNCTION&lt;/code&gt; information for the function of the chained unwind.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;The possible values of the Flags field are:&lt;/p&gt;&lt;pre lang="c++"&gt;&lt;span class="cpp-preprocessor"&gt;#define UNW_FLAG_EHANDLER  0x01&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-preprocessor"&gt;#define UNW_FLAG_UHANDLER  0x02&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-preprocessor"&gt;#define UNW_FLAG_CHAININFO 0x04&lt;/span&gt; &lt;/pre&gt; &lt;p&gt;Let's take for instance this code:&lt;/p&gt;&lt;pre lang="c++"&gt;&lt;span class="cpp-preprocessor"&gt;#include &lt;windows.h&gt;&lt;/windows.h&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-preprocessor"&gt;#include &lt;tchar.h&gt;&lt;/tchar.h&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-preprocessor"&gt;#include &lt;intrin.h&gt;&lt;/intrin.h&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;int&lt;/span&gt; APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,&lt;br /&gt;                LPTSTR lpCmdLine, &lt;span class="cpp-keyword"&gt;int&lt;/span&gt; nCmdShow)&lt;br /&gt;{&lt;br /&gt; __try&lt;br /&gt; {&lt;br /&gt;    __debugbreak();&lt;br /&gt; }&lt;br /&gt; __except (EXCEPTION_EXECUTE_HANDLER)&lt;br /&gt; {&lt;br /&gt;    MessageBox(&lt;span class="cpp-literal"&gt;0&lt;/span&gt;, _T(&lt;span class="cpp-string"&gt;"Hello!"&lt;/span&gt;), _T(&lt;span class="cpp-string"&gt;"SEH"&lt;/span&gt;), &lt;span class="cpp-literal"&gt;0&lt;/span&gt;);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; &lt;span class="cpp-keyword"&gt;return&lt;/span&gt; &lt;span class="cpp-literal"&gt;0&lt;/span&gt;;&lt;br /&gt;}&lt;/pre&gt; &lt;p&gt;The dissassembly would be:&lt;/p&gt;&lt;pre lang="asm"&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401000&lt;/span&gt; wWinMain proc near  &lt;span class="cpp-comment"&gt;; CODE XREF: __tmainCRTStartup+18C p&lt;/span&gt;&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401000&lt;/span&gt;    &lt;span class="cpp-keyword"&gt;sub&lt;/span&gt; rsp, 28h     &lt;span class="cpp-comment"&gt;; BeginAddress &lt;/span&gt;&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401004&lt;/span&gt;    int &lt;span class="cpp-literal"&gt;3&lt;/span&gt;            &lt;span class="cpp-comment"&gt;; Trap to Debugger&lt;/span&gt;&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401005&lt;/span&gt;    &lt;span class="cpp-keyword"&gt;jmp&lt;/span&gt; &lt;span class="cpp-keyword"&gt;short&lt;/span&gt; loc_401021&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401007&lt;/span&gt; &lt;span class="cpp-comment"&gt;; ---------------------------------------------------&lt;/span&gt;&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401007&lt;/span&gt;    &lt;span class="cpp-keyword"&gt;xor&lt;/span&gt; r9d, r9d     &lt;span class="cpp-comment"&gt;; ExceptionHandler&lt;/span&gt;&lt;br /&gt;.text:000000000040100A    &lt;span class="cpp-keyword"&gt;lea&lt;/span&gt; r8, Caption         &lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401011&lt;/span&gt;    &lt;span class="cpp-keyword"&gt;lea&lt;/span&gt; rdx, Text           &lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401018&lt;/span&gt;    &lt;span class="cpp-keyword"&gt;xor&lt;/span&gt; &lt;span class="cpp-keyword"&gt;ecx&lt;/span&gt;, &lt;span class="cpp-keyword"&gt;ecx&lt;/span&gt;            &lt;br /&gt;.text:000000000040101A    &lt;span class="cpp-keyword"&gt;call&lt;/span&gt; cs:__imp_MessageBoxW&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401020&lt;/span&gt;    &lt;span class="cpp-keyword"&gt;nop&lt;/span&gt;&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401021&lt;/span&gt;&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401021&lt;/span&gt; loc_401021:         &lt;span class="cpp-comment"&gt;; CODE XREF: wWinMain+5 j&lt;/span&gt;&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401021&lt;/span&gt;    &lt;span class="cpp-keyword"&gt;xor&lt;/span&gt; &lt;span class="cpp-keyword"&gt;eax&lt;/span&gt;, &lt;span class="cpp-keyword"&gt;eax&lt;/span&gt;&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401023&lt;/span&gt;    &lt;span class="cpp-keyword"&gt;add&lt;/span&gt; rsp, 28h&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401027&lt;/span&gt;    retn&lt;br /&gt;.text:&lt;span class="cpp-literal"&gt;0000000000401027&lt;/span&gt; wWinMain endp       &lt;span class="cpp-comment"&gt;; EndAddress (+ alignment)&lt;/span&gt; &lt;/pre&gt; &lt;p&gt;If you need to generate code dinamically and set for it an exception handler, you can use the function RtlAddFunctionTable, which takes as paramater an array of &lt;code&gt;RUNTIME_FUNCTION &lt;/code&gt;structures. This means, of course, that you'll have to fill one or more &lt;code&gt;UNWIND_INFO &lt;/code&gt;structure/s by yourself. It's certainly a bit more complicated than on x86, but my guess is that a lot of software protections are going to use this method. &lt;/p&gt; &lt;h3&gt;&lt;a name=".NET_Framework"&gt;.NET Framework&lt;/a&gt;&lt;/h3&gt; &lt;p&gt;Both the x86 and x64 .NET frameworks can coexist peacefully on a x64 Windows. In case you install both, there will be two things of everything: two directories in the .NET directory, two directories in the global cache and two main registry keys. Since .NET assemblies don't contain native code, why could it be useful to have both frameworks on the same computer? &lt;/p&gt; &lt;p&gt;.NET assemblies can call native code through the &lt;i&gt;System.Runtime.InteropServices &lt;/i&gt;namespace. Of course, a .NET assembly which runs on the x64 .NET framework is a 64bit process, therefore it can't call x86 components functions. Viceversa, assemblies executed on x86 can't use x64 components. You can explicitly tell the Visual Studio to compile your assembly for a specific platform (x86, x64, Itanium) by just going on Project -&gt; Properties -&gt; Build.&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.codeproject.com/vista/vista_x64/vsnet.jpg" border="0" height="226" width="509" /&gt;&lt;/p&gt; &lt;p&gt;64bit PEs are always built for a specific platform, only PE32 assemblies are allowed to run on every framework (x86 systems wouldn't be able to execute a PE64). Anyway, it's possible to make PE32 assemblies run just on the x86 framework by just setting one flag in the .NET Directory (&lt;code&gt;IMAGE_COR20_DIRECTORY&lt;/code&gt;). The flag is &lt;code&gt;COMIMAGE_FLAGS_32BITREQUIRED&lt;/code&gt;. By setting this flag you'll force to execute the given assembly as a 32bit process even on 64bit platforms.&lt;/p&gt; &lt;p&gt;There are also some differences between the 32bit and 64bit .NET framework. I noticed that the 64bit one is very serious about alignments and integrity cheks in assemblies, and the new 3.0 framework has even more checks.&lt;/p&gt; &lt;h2&gt;&lt;a name="Vista_Section"&gt;Vista Section&lt;/a&gt;&lt;/h2&gt; &lt;h3&gt;&lt;a name="Editions_"&gt;Editions&lt;/a&gt;&lt;/h3&gt; &lt;p&gt;Windows Vista is shipped in various editions, before you install the new system, you should be aware of the features missing in some editions. Here's the official features table given by Microsoft:&lt;/p&gt; &lt;center&gt; &lt;table border="0" bordercolor="#c0c0c0" cellpadding="2"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;&lt;strong&gt;Features&lt;/strong&gt;&lt;/td&gt; &lt;td align="center"&gt;&lt;br /&gt;&lt;strong&gt;Home Basic&lt;br /&gt;&lt;/strong&gt;&lt;/td&gt; &lt;td align="center"&gt;&lt;br /&gt;&lt;strong&gt;Home Premium&lt;br /&gt;&lt;/strong&gt;&lt;/td&gt; &lt;td align="center"&gt;&lt;strong&gt;Business&lt;br /&gt;&lt;/strong&gt;&lt;/td&gt; &lt;td align="center"&gt;&lt;strong&gt;Ultimate&lt;/strong&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td id="feature"&gt;&lt;a href="http://www.microsoft.com/windowsvista/features/foreveryone/security.mspx"&gt;Most secure Windows ever&lt;/a&gt;&lt;br /&gt;with Windows Defender and Windows Firewall&lt;/td&gt; &lt;td id="checkMark" align="center"&gt;&lt;img alt="Home Basic" src="http://www.codeproject.com/vista/vista_x64/check_basic.gif" border="0" /&gt;&lt;/td&gt; &lt;td id="checkMark" align="center"&gt;&lt;img alt="Home Premium" src="http://www.codeproject.com/vista/vista_x64/check_prem.gif" border="0" /&gt;&lt;/td&gt; &lt;td id="checkMark" align="center"&gt;&lt;img alt="Business" src="http://www.codeproject.com/vista/vista_x64/check_busi.gif" border="0" /&gt;&lt;/td&gt; &lt;td id="checkMark" align="center"&gt;&lt;img alt="Ultimate" src="http://www.codeproject.com/vista/vista_x64/check_ult.gif" border="0" /&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td id="feature"&gt;&lt;a href="http://www.microsoft.com/windowsvista/features/foreveryone/searchorg.mspx"&gt;Quickly find what you need&lt;/a&gt;&lt;br /&gt;with Instant Search and Windows Internet&lt;br /&gt;Explorer 7&lt;/td&gt; &lt;td id="checkMark" align="center"&gt;&lt;img alt="Home Basic" src="http://www.codeproject.com/vista/vista_x64/check_basic.gif" border="0" /&gt;&lt;/td&gt; &lt;td id="checkMark" align="center"&gt;&lt;img alt="Home Premium" src="http://www.codeproject.com/vista/vista_x64/check_prem.gif" border="0" /&gt;&lt;/td&gt; &lt;td id="checkMark" align="center"&gt;&lt;img alt="Business" src="http://www.codeproject.com/vista/vista_x64/check_busi.gif" border="0" /&gt;&lt;/td&gt; &lt;td id="checkMark" align="center"&gt;&lt;img alt="Ultimate" src="http://www.codeproject.com/vista/vista_x64/check_ult.gif" border="0" /&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td id="feature"&gt;&lt;a href="http://www.microsoft.com/windowsvista/features/default.mspx"&gt;Elegant Windows Aero desktop experience&lt;/a&gt;&lt;br /&gt;with Windows Flip 3D navigation&lt;/td&gt; &lt;td align="center"&gt;&lt;br /&gt;&lt;/td&gt; &lt;td id="checkMark" align="center"&gt;&lt;img alt="Home Premium" src="http://www.codeproject.com/vista/vista_x64/check_prem.gif" border="0" /&gt;&lt;/td&gt; &lt;td id="checkMark" align="center"&gt;&lt;img alt="Business" src="http://www.codeproject.com/vista/vista_x64/check_busi.gif" border="0" /&gt;&lt;/td&gt; &lt;td id="checkMark" align="center"&gt;&lt;img alt="Ultimate" src="http://www.codeproject.com/vista/vista_x64/check_ult.gif" border="0" /&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td id="feature"&gt;&lt;a href="http://www.microsoft.com/windowsvista/features/forbiz/mobilepc.mspx"&gt;Best choice for laptops&lt;/a&gt;&lt;br /&gt;with enhanced Windows Mobility Center and&lt;br /&gt;Tablet PC support&lt;/td&gt; &lt;td align="center"&gt;&lt;br /&gt;&lt;/td&gt; &lt;td id="checkMark" align="center"&gt;&lt;img alt="Home Premium" src="http://www.codeproject.com/vista/vista_x64/check_prem.gif" border="0" /&gt;&lt;/td&gt; &lt;td id="checkMark" align="center"&gt;&lt;img alt="Business" src="http://www.codeproject.com/vista/vista_x64/check_busi.gif" border="0" /&gt;&lt;/td&gt; &lt;td id="checkMark" align="center"&gt;&lt;img alt="Ultimate" src="http://www.codeproject.com/vista/vista_x64/check_ult.gif" border="0" /&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td id="feature"&gt;&lt;a href="http://www.microsoft.com/windowsvista/features/forbiz/sharing.mspx"&gt;Collaborate and share documents&lt;/a&gt;&lt;br /&gt;with Windows Meeting Space&lt;/td&gt; &lt;td align="center"&gt;&lt;br /&gt;&lt;/td&gt; &lt;td id="checkMark" align="center"&gt;&lt;img alt="Home Premium" src="http://www.codeproject.com/vista/vista_x64/check_prem.gif" border="0" /&gt;&lt;/td&gt; &lt;td id="checkMark" align="center"&gt;&lt;img alt="Business" src="http://www.codeproject.com/vista/vista_x64/check_busi.gif" border="0" /&gt;&lt;/td&gt; &lt;td id="checkMark" align="center"&gt;&lt;img alt="Ultimate" src="http://www.codeproject.com/vista/vista_x64/check_ult.gif" border="0" /&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td id="feature"&gt;&lt;a href="http://www.microsoft.com/windowsvista/features/forhome/mediacenter.mspx"&gt;Experience photos and entertainment&lt;/a&gt;&lt;br /&gt;in your living room with Windows Media Center&lt;/td&gt; &lt;td align="center"&gt;&lt;br /&gt;&lt;/td&gt; &lt;td id="checkMark" align="center"&gt;&lt;img alt="Home Premium" src="http://www.codeproject.com/vista/vista_x64/check_prem.gif" border="0" /&gt;&lt;/td&gt; &lt;td align="center"&gt;&lt;br /&gt;&lt;/td&gt; &lt;td id="checkMark" align="center"&gt;&lt;img alt="Ultimate" src="http://www.codeproject.com/vista/vista_x64/check_ult.gif" border="0" /&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td id="feature"&gt;&lt;a href="http://www.microsoft.com/windowsvista/experiences/magic.mspx"&gt;Enjoy Windows Media Center&lt;/a&gt;&lt;br /&gt;on TVs throughout your home with Xbox 360™ and other devices&lt;/td&gt; &lt;td align="center"&gt;&lt;br /&gt;&lt;/td&gt; &lt;td id="checkMark" align="center"&gt;&lt;img alt="Home Premium" src="http://www.codeproject.com/vista/vista_x64/check_prem.gif" border="0" /&gt;&lt;/td&gt; &lt;td align="center"&gt;&lt;br /&gt;&lt;/td&gt; &lt;td id="checkMark" align="center"&gt;&lt;img alt="Ultimate" src="http://www.codeproject.com/vista/vista_x64/check_ult.gif" border="0" /&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td id="feature"&gt;&lt;a href="http://www.microsoft.com/windowsvista/features/forbiz/diagnostics.mspx"&gt;Help protect against hardware failure&lt;/a&gt;&lt;br /&gt;with advanced business backup features&lt;/td&gt; &lt;td align="center"&gt;&lt;br /&gt;&lt;/td&gt; &lt;td align="center"&gt;&lt;br /&gt;&lt;/td&gt; &lt;td id="checkMark" align="center"&gt;&lt;img alt="Business" src="http://www.codeproject.com/vista/vista_x64/check_busi.gif" border="0" /&gt;&lt;/td&gt; &lt;td id="checkMark" align="center"&gt;&lt;img alt="Ultimate" src="http://www.codeproject.com/vista/vista_x64/check_ult.gif" border="0" /&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td id="feature"&gt;&lt;a href="http://www.microsoft.com/windowsvista/features/foreveryone/networking.mspx"&gt;Business networking and Remote Desktop&lt;/a&gt;&lt;br /&gt;for easier connectivity&lt;/td&gt; &lt;td align="center"&gt;&lt;br /&gt;&lt;/td&gt; &lt;td align="center"&gt;&lt;br /&gt;&lt;/td&gt; &lt;td id="checkMark" align="center"&gt;&lt;img alt="Business" src="http://www.codeproject.com/vista/vista_x64/check_busi.gif" border="0" /&gt;&lt;/td&gt; &lt;td id="checkMark" align="center"&gt;&lt;img alt="Ultimate" src="http://www.codeproject.com/vista/vista_x64/check_ult.gif" border="0" /&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td id="feature"&gt;&lt;a href="http://www.microsoft.com/windowsvista/features/forbiz/protection.mspx"&gt;Better protect your data&lt;/a&gt;&lt;br /&gt;against loss or theft with Windows&lt;br /&gt;BitLocker™ Drive Encryption&lt;/td&gt; &lt;td align="center"&gt;&lt;br /&gt;&lt;/td&gt; &lt;td align="center"&gt;&lt;br /&gt;&lt;/td&gt; &lt;td align="center"&gt;&lt;br /&gt;&lt;/td&gt; &lt;td id="checkMark" align="center"&gt;&lt;img alt="Ultimate" src="http://www.codeproject.com/vista/vista_x64/check_ult.gif" border="0" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/center&gt; &lt;p&gt;But there are other things that the common user might not notice. For instance, the Business and Ultimate edition allow virtualization (using the system as a virtual machine). The End-User License Agreement for the Vista Home Basic and Premium reads:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;4. &lt;b&gt;USE WITH VIRTUALIZATION TECHNOLOGIES.&lt;/b&gt; You may not use the software installed on the licensed device within a virtual (or otherwise emulated) hardware system.&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Apparentely, Microsoft put special checks in the home editions, in order to prevent them from working in emulation. I read that VMWare was quite disappointed by this policy adopted by Microsoft. This controversy might change things, but I think many programmers and companies should know this before buying one or another Vista edition.&lt;/p&gt; &lt;h3&gt;&lt;a name="Microsoft_Visual_Studio"&gt;Microsoft Visual Studio&lt;/a&gt;&lt;/h3&gt; &lt;p&gt;I chose this as the second paragraph of the Windows Vista section, because what every programmer first does when he has a brand new system is to install and set up his compilers. The problem is, since many things change with Vista, the only compatible Visual Studio platform is the 2005 one. Compatibility for Visual Studio 6 and Visual Studio .NET 2003 is no longer provided (although Visual Basic 6 seems to be supported). Not only that, in order to make the VS.NET 2005 work, you'll need to download and install the Service Pack 1 for it. &lt;/p&gt; &lt;p&gt;For a lot of programmers like myself it's not a big deal, since maintaining the code up to date is very important, but who has ever worked with little companies knows that a lot of them have no interest in doing the same, with the result that, for instance, many solutions are still developed for the .NET framework 1.0. Those solutions will, of course, still run on Vista, but there won't be any tool to compile them. I don't think Microsoft is going to solve this issue. Thus, for many companies it will take some time to switch to Vista.&lt;/p&gt; &lt;p&gt;P.S. The setup of Microsoft Visual Studio's Service Pack 1 will take &lt;b&gt;much&lt;/b&gt; time. Don't worry, it's normal.&lt;/p&gt; &lt;h3&gt;&lt;a name="User_Account_Control"&gt;User Account Control&lt;/a&gt;&lt;/h3&gt; &lt;p&gt;What stands in the way of working properly for most applications on Windows Vista is the User Account Control (UAC), also known as Limited User Access (LUA). As we saw in the Interprocess Communication paragraph, admin rights to create shared memory objects are necessary, but Windows Vista runs every process (except system processes) with user rights. Incompatibilities are, most of the times, generated by programmers false assumption that their code will run on admin level. Programs which worked without problems with user rights on Windows NT 4-5.1 won't have any problems running properly on Vista. However, common mistakes (or bad habits) like:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Modifying files in their own Program Files directory.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Writing in the HKEY_LOCAL_MACHINE to store settings. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Are no longer problems, since on Vista there's a thing called virtualization. Basically, every file modified in a system directory, like Program Files, is actually stored in a directory called Virtual Store. My path for this directory is C:\Users\Daniel\AppData\Local\VirtualStore. The Windows Explorer will show you those files in the system directory, but actually they are all in the VirtualStore, which, and it goes without saying, is unique for every user. The files are just stored like this in the Virtual Store:&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;center&gt;&lt;img src="http://www.codeproject.com/vista/vista_x64/fs_virtual.jpg" border="0" height="156" width="600" /&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;The directory hierarchy in the Virtual Store is exactly the same it would be without virtualization. I guess you have already figured out how it works.&lt;br /&gt;&lt;br /&gt;Just like for the File System, there's also a registry virtualization. Everything written in the key &lt;i&gt;HKEY_LOCAL_MACHINE\Software&lt;/i&gt; will actually be stored under &lt;i&gt;HKEY_CLASSES_ROOT\VirtualStore\Software&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;What you should keep in mind is that eveyrthing that might affect other users is no longer possible in a standard execution of your software. This means, apart from the things said above, you won't be able to load drivers, modify certain files (maybe not even read them), modify or read specific registry keys/values, access certain global objects, enumerate or modify the memory of processes which run with higher privileges than you do, etc. And you won't even be able to enumerate or send messages to windows created by those processes. This prevents exploits we have already seen in the past. There's a very good MSDN paper (&lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnlong/html/AccProtVista.asp"&gt;Developer Best Practices and Guidelines for Applications in a Least Privileged Environment&lt;/a&gt;) about the UAC and its conseguences for developers, it's a detailed explanation of everything I tried to say here in short.  &lt;h3&gt;&lt;a name="Compatibility_Verification"&gt;Compatibility Verification&lt;/a&gt;&lt;/h3&gt; &lt;p&gt;There's a tool to verify if your application is compatible with the UAC. This tool is called &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=bd02c19c-1250-433c-8c1b-2619bd93b3a2&amp;DisplayLang=en"&gt;Microsoft Application Verifier&lt;/a&gt; and it can also detect other issues, but right now we're not interested in those ones. Using it is very easy, all you need is to add an application to the list and select what kind of checks the verifier should do. In our case, we'll select the LUA (aka UAC) compatibility check.&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.codeproject.com/vista/vista_x64/appverify.jpg" border="0" height="235" width="600" /&gt;&lt;/p&gt; &lt;p&gt;The next step is running the application you added to the list. When you're done, you save the log and then, as you can read from the screenshot above, you open it with the &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=DF59B474-C0B7-4422-8C70-B0D9D3D2F575&amp;amp;displaylang=en"&gt;Microsoft Standard User Analyzer&lt;/a&gt;. Don't even think about opening it with another application, depending on the size of your software the verifier will generate a gigantic xml log, which would make every other program consume a big part of your ram. For this test I used the &lt;a href="http://ntcore.com/exsuite.php"&gt;Task Explorer&lt;/a&gt; which, of course, tries to adjust its token to SeDebugPrivilege in order to list even system processes. In fact:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.codeproject.com/vista/vista_x64/sua.jpg" border="0" height="133" width="511" /&gt;&lt;/p&gt; &lt;p&gt;Since this application is not running with admin rights, it won't be able to acquire debug privileges. I wouldn't recommend you to use always this tool, since following good design rules should be enough. However, it might be useful.&lt;/p&gt; &lt;h3&gt;&lt;a name="Obtaining_Admin_Rights"&gt;Obtaining Admin Rights&lt;/a&gt;&lt;/h3&gt; &lt;p&gt;Of course, it's still possible to run an application with admin rights. You can either do that manually or through code. To do it manually, you can just right-click on the application an then click "Run as administrator" or check the "Run this program as administrator" box under Properties -&gt; Compatibility. However, programmers cannot expect users to do these operations by themselves, so they'll need another way.&lt;/p&gt; &lt;p&gt;A very easy way is to tell the system the requested execution level through a manifest file. I suppose the reader knows what a manifest file is and how to integrate it in an application. There are plenty of guides about this subject and I don't think it should be re-discussed here. &lt;/p&gt; &lt;p&gt;The schema of such a manifest file should be like this one (this is actually for x86, as you see under processorArchitecture):&lt;/p&gt;&lt;pre lang="xml"&gt;&lt;br /&gt;&lt;assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestversion="1.0"&gt;&lt;br /&gt;&lt;assemblyidentity version="1.0.0.0" processorarchitecture="X86" name="YourAppName" type="win32"&gt;&lt;br /&gt;&lt;br /&gt;&lt;description&gt;Description of your application&lt;/description&gt;&lt;br /&gt;&lt;!-- Identify the application security requirements. --&gt;&lt;br /&gt;&lt;trustinfo xmlns="urn:schemas-microsoft-com:asm.v3"&gt;&lt;br /&gt;  &lt;security&gt;&lt;br /&gt;    &lt;requestedprivileges&gt;&lt;br /&gt;      &lt;requestedexecutionlevel level="requireAdministrator" uiaccess="false"&gt;&lt;br /&gt;    &lt;/requestedexecutionlevel&gt;&lt;br /&gt;  &lt;/requestedprivileges&gt;&lt;br /&gt;&lt;/security&gt;&lt;br /&gt;&lt;/trustinfo&gt;&lt;/assemblyidentity&gt;&lt;/assembly&gt;&lt;/pre&gt; &lt;p&gt;The available values for &lt;b&gt;level&lt;/b&gt; are:&lt;/p&gt; &lt;table id="table4" bgcolor="#e1e1e1" border="0" bordercolor="#000000" cellpadding="3" width="100%"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td valign="top" width="168"&gt;&lt;code&gt;&lt;b&gt;asInvoker&lt;/b&gt;&lt;/code&gt;&lt;/td&gt; &lt;td&gt;The application runs with the same token as the parent process.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="168"&gt;&lt;code&gt;&lt;b&gt;highestAvailable&lt;/b&gt;&lt;/code&gt;&lt;/td&gt; &lt;td&gt;The application runs with the highest privileges the current user can obtain.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="168"&gt;&lt;code&gt;&lt;b&gt;requireAdministrator&lt;/b&gt;&lt;/code&gt;&lt;/td&gt; &lt;td&gt;The application runs only for administrators and requires that the application be launched with the full token of an administrator.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;And for &lt;b&gt;uiAccess&lt;/b&gt;:&lt;/p&gt; &lt;table id="table5" bg border="0" border cellpadding="3" width="100%" style="color:#000000;"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td valign="top"&gt;&lt;code&gt;&lt;b&gt;&lt;span class="cpp-keyword"&gt;false&lt;/span&gt;&lt;/b&gt;&lt;/code&gt;&lt;/td&gt; &lt;td width="928"&gt;The application does not need to drive input to the UI of another window on the desktop. Applications that are not providing accessibility should set this flag to false. Applications that are required to drive input to other windows on the desktop (on-screen keyboard, for example) should set this value to true.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top"&gt;&lt;code&gt;&lt;b&gt;&lt;span class="cpp-keyword"&gt;true&lt;/span&gt;&lt;/b&gt;&lt;/code&gt;&lt;/td&gt; &lt;td width="928"&gt;The application is allowed to bypass UI protection levels to drive input to higher privilege windows on the desktop. This setting should only be used for UI Accessibility applications.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;I wrote a very small application (which just waits for an input key) to demonstrate the use of a manifest file. The download can be found at the top of this article.&lt;/p&gt; &lt;p&gt;There's also a function, &lt;code&gt;CredUIPromptForCredentials&lt;/code&gt;, to request specific credentials from a user and can be used to obtain admin rights, but it's not very comfortable for the user himself.&lt;/p&gt; &lt;h3&gt;&lt;a name="Disable_It"&gt;Disable It&lt;/a&gt;&lt;/h3&gt; &lt;p&gt;If you are annoyed by all these dialogs asking you for permissions, you can disable the UAC. There are two simple ways I'm aware of. The first one described in detail on the &lt;a href="http://blogs.msdn.com/uac/archive/2006/01/22/516066.aspx"&gt;UAC Team Blog&lt;/a&gt; is about going to Control Panel -&gt; Administrative Tools -&gt; Local Security Policy. In the tree on the left click Local Policies and then Security Options. Scroll until you find: "User Account Control: behavior of the elevation prompt for administrators". Change the current value to: "Elevate without prompting". Just like this:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.codeproject.com/vista/vista_x64/locsecpol.jpg" border="0" height="405" width="600" /&gt;&lt;/p&gt; &lt;p&gt;The other method is more drastic. It's about removing completely the UAC and requires a machine's reboot. In Administrative Tools, instead of clicking on Local Security Policy, click on System Configuration. Choose the tab "Tools" in the dialog and scroll until you find "Disable UAC" under "Tool Name". To execute the command, click on Launch.&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.codeproject.com/vista/vista_x64/sysconf.jpg" border="0" height="389" width="585" /&gt;&lt;/p&gt; &lt;p&gt;As you can see from the command line, it simply executes reg.exe to add a key/value. The full command line is:&lt;/p&gt;&lt;pre lang="text"&gt;C:\Windows\System32\cmd.exe /k %windir%\System32\reg.exe&lt;br /&gt;ADD HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System&lt;br /&gt;/v EnableLUA /t REG_DWORD /d 0 /f&lt;/pre&gt; &lt;p&gt;To re-enable the UAC, it sets the EnableLUA dword to 1.&lt;/p&gt; &lt;p&gt;I don't know whether it's a good idea or not to disable the UAC. Sure is that a lot of programmers will be too annoyed to keep it enabled. There's been a lot of criticism about this security system. However, I personally believe it's the only one to guarantee a minimum of security on an account where one has still admin rights. If one needs more security, one shall switch to a normal user account.&lt;/p&gt; &lt;h3&gt;&lt;a name="Address_Space_Layout_Randomization"&gt;Address Space Layout Randomization&lt;/a&gt;&lt;/h3&gt; &lt;p&gt;In short ASLR. There's an interesting &lt;a href="http://blogs.msdn.com/michael_howard/"&gt;weblog&lt;/a&gt; about this new feature on Vista. Randomization, as you know, is useful to prevent buffer overflow exploits and has already been implemented on other operating systems. On Vista randomization is done on various levels:&lt;/p&gt; &lt;ul&gt;&lt;li&gt;Image Base  &lt;/li&gt;&lt;li&gt;Stack  &lt;/li&gt;&lt;li&gt;Heap &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;With the new Service Pack 1 for Visual Studio 2005 the option /dynamicbase has been introduced. This options makes it possible to relocate executables just like dynamic libraries, just by adding a relocation section to the PE header. All executables on Windows Vista have been compiled with this option, making it impossible for a programmer to assume where specific data is placed. Randomization for images has 256 variations. The reason for this are explained by Michael Howard:&lt;/p&gt; &lt;table id="table7" bgcolor="#e1e1e1" border="0" bordercolor="#000000" cellpadding="3" width="100%"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;On a final note, it is true that we don't have as much randomization as PaX and other more aggressive ASLR implementations. For instance, image randomization is only 8 bits (1 of 256 variations). Images have to be 64K aligned, and so on a 32-bit system we could have theoretically randomized images by up to 15 bits (1 of 32, 768 variations), but the incremental security gain is small - if you navigate to a Website and your browser crashes, will you go back to that site another 255 times - and would have come at the expense of fragmenting the entire address space, thereby reducing the contiguous memory available to applications and degrading system performance? We think we hit a nice balance.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;I did some tests and it seems that on x86, unlike on x64, the image base changes only when rebooting. On x64 the imagebase seems changing with every execution. By the way, x64 shouldn't have problems with contiguous memory availability, since the address space is enormously larger than on x86. Unfortunately, I can't do more tests, because, at the moment, I'm running on Vista x86.&lt;/p&gt; &lt;p&gt;On the other hand, the stack should have 16,384 possible variations (14 bits). I wrote, for testing purposes, a little application to calculate stack variations on N executions. I wrote it very quick, so the implementation is also very rudimental. Basically, one executable calls another executable, compiled with the /dynamicbase option, N times and gets from it the stack address of a local variable. It then evaluates if the stack address has already been used or not; if not, it increments the number of variations. To communicate the stack address to the parent, the dynamic-base executable uses a &lt;code&gt;SendMessage &lt;/code&gt;(which is enough, since &lt;code&gt;wparam &lt;/code&gt;and &lt;code&gt;lparam &lt;/code&gt;are the same size of a pointer). This application was compiled for both x86 and x64.&lt;/p&gt; &lt;p&gt;Here's the dynamic-base executable source:&lt;/p&gt;&lt;pre lang="c++"&gt;&lt;span class="cpp-preprocessor"&gt;#include &lt;windows.h&gt;&lt;/windows.h&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-preprocessor"&gt;#include &lt;tchar.h&gt;&lt;/tchar.h&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="cpp-preprocessor"&gt;#define WM_STACKADDRESS        (WM_USER + 100)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;int&lt;/span&gt; APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,&lt;br /&gt;           LPTSTR lpCmdLine, &lt;span class="cpp-keyword"&gt;int&lt;/span&gt; nCmdShow)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;int&lt;/span&gt; x;&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;return&lt;/span&gt; (&lt;span class="cpp-keyword"&gt;int&lt;/span&gt;) SendMessage(FindWindow(NULL, _T(&lt;span class="cpp-string"&gt;"RandTest"&lt;/span&gt;)),&lt;br /&gt;      WM_STACKADDRESS, &lt;span class="cpp-literal"&gt;0&lt;/span&gt;, (LPARAM) &amp;x);&lt;br /&gt;}&lt;/pre&gt;And this is the main executable: &lt;div class="smallText" id="premain35" style="width: 100%;"&gt;&lt;img preid="35" src="http://www.codeproject.com/images/minus.gif" id="preimg35" height="9" width="9" /&gt;&lt;span preid="35" style="margin-bottom: 0pt;" id="precollapse35"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre35" lang="c++"&gt;&lt;span class="cpp-preprocessor"&gt;#include &lt;windows.h&gt;&lt;/windows.h&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-preprocessor"&gt;#include &lt;tchar.h&gt;&lt;/tchar.h&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-preprocessor"&gt;#include "resource.h"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="cpp-preprocessor"&gt;#define WM_STACKADDRESS        (WM_USER + 100)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;ULONG_PTR *pAddresses = NULL;&lt;br /&gt;UINT nAddresses = &lt;span class="cpp-literal"&gt;0&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;// Test Loop thread: not blocking for GUI&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;void&lt;/span&gt; TestLoop(ULONG_PTR p)&lt;br /&gt;{&lt;br /&gt;  UINT nExec = (UINT) p;&lt;br /&gt;&lt;br /&gt;  STARTUPINFO si = { &lt;span class="cpp-literal"&gt;0&lt;/span&gt; };&lt;br /&gt;  PROCESS_INFORMATION pi = { &lt;span class="cpp-literal"&gt;0&lt;/span&gt; };&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;for&lt;/span&gt; (UINT x = &lt;span class="cpp-literal"&gt;0&lt;/span&gt;; x &lt; class="cpp-string"&gt;"DynBaseApp.exe"&lt;/span&gt;), NULL, NULL, NULL, FALSE, &lt;span class="cpp-literal"&gt;0&lt;/span&gt;,&lt;br /&gt;          NULL, NULL, &amp;si, &amp;amp;amp;pi);&lt;br /&gt;&lt;br /&gt;      WaitForSingleObject(pi.hProcess, &lt;span class="cpp-literal"&gt;3000&lt;/span&gt;);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;delete&lt;/span&gt; pAddresses;&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;// We're through with testing, show number of variations&lt;/span&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  TCHAR szMsg[&lt;span class="cpp-literal"&gt;100&lt;/span&gt;];&lt;br /&gt;&lt;br /&gt;  wsprintf(szMsg, _T(&lt;span class="cpp-string"&gt;"The number of variations on %d executions is: %d."&lt;/span&gt;),&lt;br /&gt;      nExec, nAddresses);&lt;br /&gt;&lt;br /&gt;  MessageBox(NULL, szMsg, _T(&lt;span class="cpp-string"&gt;"Test Result"&lt;/span&gt;), MB_ICONINFORMATION);&lt;br /&gt;&lt;br /&gt;  ExitThread(&lt;span class="cpp-literal"&gt;0&lt;/span&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;LRESULT CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;switch&lt;/span&gt; (uMsg)&lt;br /&gt;  {&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;case&lt;/span&gt; WM_CLOSE:&lt;br /&gt;      {&lt;br /&gt;          EndDialog(hDlg, FALSE);&lt;br /&gt;          &lt;span class="cpp-keyword"&gt;break&lt;/span&gt;;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;case&lt;/span&gt; WM_COMMAND:&lt;br /&gt;      {&lt;br /&gt;          &lt;span class="cpp-keyword"&gt;switch&lt;/span&gt; ((WORD) wParam)&lt;br /&gt;          {&lt;br /&gt;&lt;br /&gt;          &lt;span class="cpp-keyword"&gt;case&lt;/span&gt; IDC_TEST:&lt;br /&gt;              {&lt;br /&gt;                  &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;                  &lt;span class="cpp-comment"&gt;// If executions != 0 start the loop&lt;/span&gt;&lt;br /&gt;                  &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;                  TCHAR nStrExec[&lt;span class="cpp-literal"&gt;20&lt;/span&gt;];&lt;br /&gt;&lt;br /&gt;                  GetDlgItemText(hDlg, ED_EXECUTIONS, nStrExec, &lt;span class="cpp-literal"&gt;20&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;                  UINT nExec = _tcstoul(nStrExec, NULL, &lt;span class="cpp-literal"&gt;10&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;                  &lt;span class="cpp-keyword"&gt;if&lt;/span&gt; (nExec == &lt;span class="cpp-literal"&gt;0&lt;/span&gt;) &lt;span class="cpp-keyword"&gt;break&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;                  pAddresses = &lt;span class="cpp-keyword"&gt;new&lt;/span&gt; ULONG_PTR [nExec];&lt;br /&gt;                  nAddresses = &lt;span class="cpp-literal"&gt;0&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;                  CreateThread(NULL, &lt;span class="cpp-literal"&gt;0&lt;/span&gt;, (LPTHREAD_START_ROUTINE) &amp;TestLoop,&lt;br /&gt;                      (LPVOID) (ULONG_PTR) nExec, &lt;span class="cpp-literal"&gt;0&lt;/span&gt;, NULL);&lt;br /&gt;&lt;br /&gt;                  &lt;span class="cpp-keyword"&gt;break&lt;/span&gt;;&lt;br /&gt;              }&lt;br /&gt;          }&lt;br /&gt;&lt;br /&gt;          &lt;span class="cpp-keyword"&gt;break&lt;/span&gt;;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;case&lt;/span&gt; WM_STACKADDRESS:&lt;br /&gt;      {&lt;br /&gt;          &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;          &lt;span class="cpp-comment"&gt;// It's a stack address being sended by DynBaseApp.exe&lt;/span&gt;&lt;br /&gt;          &lt;span class="cpp-comment"&gt;// add it to the list if not already there&lt;/span&gt;&lt;br /&gt;          &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;          ULONG_PTR Addr = (ULONG_PTR) lParam;&lt;br /&gt;&lt;br /&gt;          &lt;span class="cpp-keyword"&gt;for&lt;/span&gt; (UINT x = &lt;span class="cpp-literal"&gt;0&lt;/span&gt;; x &lt; class="cpp-keyword"&gt;if&lt;/span&gt; (Addr == pAddresses[x]) &lt;span class="cpp-keyword"&gt;return&lt;/span&gt; FALSE;&lt;br /&gt;          }&lt;br /&gt;&lt;br /&gt;          pAddresses[nAddresses] = Addr;&lt;br /&gt;          nAddresses++;&lt;br /&gt;&lt;br /&gt;          &lt;span class="cpp-keyword"&gt;break&lt;/span&gt;;&lt;br /&gt;      }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;return&lt;/span&gt; FALSE;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;int&lt;/span&gt; APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,&lt;br /&gt;           LPTSTR lpCmdLine, &lt;span class="cpp-keyword"&gt;int&lt;/span&gt; nCmdShow)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;return&lt;/span&gt; (&lt;span class="cpp-keyword"&gt;int&lt;/span&gt;) DialogBox(hInstance, (LPCTSTR) IDD_RANDTEST, NULL,&lt;br /&gt;                        (DLGPROC) DlgProc);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt; &lt;p&gt;The results were pretty good. On 16,385 execution the minimum I got was 4026 (on x64). With less executions the results were, of course, even better (100/100, 199/200, 296/300).&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.codeproject.com/vista/vista_x64/randtest.jpg" border="0" height="159" width="402" /&gt;&lt;/p&gt; &lt;p&gt;To compile executables with the /dynamicbase option, just add "/dynamicbase" (without brackets) in the linker command line (Project -&gt; Properties -&gt; Linker -&gt; Command Line -&gt; Additional options).&lt;/p&gt; &lt;h3&gt;&lt;a name="Driver_Signing"&gt;Driver Signing&lt;/a&gt;&lt;/h3&gt; &lt;p&gt;The big change with Vista is that drivers require now to be certificated to run (at least on 64bit), and in order to obtain the certification you have to ship an x64 version of your driver. x86-only submission are no longer accepted by WHQL (Windows Hardware Quality Labs). If you have no clue how to sign a driver there's a good doc on &lt;a href="http://www.microsoft.com/whdc/system/platform/64bit/kmsigning.mspx"&gt;MSDN&lt;/a&gt; and, of course, the &lt;a href="http://www.microsoft.com/whdc/winlogo/drvsign/drvsign.mspx"&gt;official page&lt;/a&gt;. Nevertheless, it's still possible to disable driver certification for testing and debugging reasons. Reboot your system and press F8 to get the Advanded Boot Options. Select "Disable Driver Signature Enforcement".&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.codeproject.com/vista/vista_x64/advboot.jpg" border="0" height="349" width="500" /&gt;&lt;/p&gt; &lt;p&gt;However, there's a lot more to be discussed if you're a device driver programmer or want to be one. In that case, I advise you to read the &lt;a href="http://www.osronline.com/"&gt;NT Insider&lt;/a&gt; and for this particular issue this &lt;a href="http://www.osronline.com/article.cfm?article=475"&gt;article&lt;/a&gt;. It describes all the steps that have to be done to set up a Vista machine for driver debugging and testing.&lt;/p&gt; &lt;h3&gt;&lt;a name="Patch_Guard"&gt;Patch Guard&lt;/a&gt;&lt;/h3&gt; &lt;p&gt;This paragraph (and child) shouldn't be for Vista only. However, there's been a lot of talking about Vista's Patch Guard. Patch Guard isn't news, it was first introduced for x64 (it's not available for x86) with Windows XP and 2003. I chose to put this paragraph in the Vista section, because the messing around with this technology brought some changes in Vista. What Patch Guard means is that it's no longer possible to patch kernel data, not even by trusted components. In fact, some companies, like Symantec, protested against this technology and said that Microsoft was using it in order to prevent third-part developed security solutions from working. This is non-sense, of course. Microsoft security products don't patch Vista's kernel either and use instead documented interfaces as everyone else. Basically, Patch Guard checks the integrity of system data, and if it's corrupted it calls KeBugCheckEx causing the system to shut down. Things that trigger this behavior are:&lt;/p&gt; &lt;ul&gt;&lt;li&gt;Modifying system service tables (SDT).  &lt;/li&gt;&lt;li&gt;Modifying the interrupt descriptor table (IDT).  &lt;/li&gt;&lt;li&gt;Modifying the global descriptor table (GDT).  &lt;/li&gt;&lt;li&gt;Using kernel stacks that are not allocated by the kernel.  &lt;/li&gt;&lt;li&gt;Patching any part of the kernel (detected only on AMD64-based systems). &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Patch Guard is disabled only when debugging the system. If your product relies on patching the kernel, you might be able to use an alternative method like suggested in this &lt;a href="http://blogs.msdn.com/windowsvistasecurity/archive/2006/08/11/695993.aspx"&gt;weblog&lt;/a&gt;.&lt;/p&gt; &lt;table id="table6" bgcolor="#e1e1e1" border="1" bordercolor="#000000" cellpadding="3" width="100%"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Clearly, customers demand effective security solutions, and they can be developed without relying on kernel patching techniques. Some of the alternatives to kernel patching are:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Windows Vista includes the "Windows Filtering Platform", which enables software to perform network oriented activities such as packet inspection and other activities necessary to support firewall products.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The file system mini filter model allows software to participate in file system activities, which can be used by Anti-Virus software.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Registry notification hooks, introduced in Windows XP, and recently enhanced in Windows Vista, allow software to participate in registry related activities in the system.&lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;I'll discuss the third alternative in the Registry Filtering paragraph.&lt;/p&gt; &lt;h3&gt;&lt;a name="Attacks"&gt;Attacks&lt;/a&gt;&lt;/h3&gt; &lt;p&gt;Some efforts have been made in this direction, since Patch Guard is a software implementation. &lt;a href="http://www.uninformed.org/?v=3&amp;a=3"&gt;Uninformed&lt;/a&gt; bypassed the Patch Guard protection on Windows XP x64. &lt;a href="http://theinvisiblethings.blogspot.com/"&gt;Joanna Rutkowska &lt;/a&gt;bypassed Vista RC1's Patch Guard by patching (on disk) the pagefile of a driver. This &lt;a href="http://invisiblethings.org/papers/joanna%20rutkowska%20-%20subverting%20vista%20kernel.ppt"&gt;attack&lt;/a&gt; was done in user mode and therefore requires the ability to open a disk through CreateFile with write permissions and then modify data through WriteFile. It seemed that Vista's RC2 solved the issue by preventing the disk to be modified from user mode (even with high privileges). However, I've done some tests and CreateFile still returns a valid handle. The modification of some disk parts, like the boot sector, is still allowed as I could see. Nevertheless, if your utility relies on raw write access to the disk, you might encounter some problems. Fact is, this limitation doesn't even solve the issue, because theoretically the same trick could still be used in kernel mode.&lt;/p&gt; &lt;h3&gt;&lt;a name="Registry_Filtering"&gt;Registry Filtering&lt;/a&gt;&lt;/h3&gt; &lt;p&gt;Since it's no longer possible patching the Service Descriptor Table (SDT) on x64, one might be wondering how Mark Russinovich's Regmon (alias the new &lt;a href="http://www.microsoft.com/technet/sysinternals/processesandthreads/processmonitor.mspx"&gt;Process Monitor&lt;/a&gt;) works on x64. The answer is simple, starting with Windows XP there's no need to hook the SDT anymore. In fact, with Windows XP a new official and documented way has been introduced to filter the registry. This method relies on three functions: CmRegisterCallback (supported on XP and Vista), CmRegisterCallbackEx (supported on Vista only) and CmUnRegisterCallback. CmRegisterCallback/Ex registers a callback function for every registry operation. The callback function looks like this:&lt;/p&gt;&lt;pre lang="c++"&gt;NTSTATUS RegistryCallback(&lt;br /&gt;  IN PVOID  CallbackContext,&lt;br /&gt;  IN PVOID  Argument1,&lt;br /&gt;  IN PVOID  Argument2&lt;br /&gt;  );&lt;/pre&gt; &lt;p&gt;These are the parameters:&lt;/p&gt; &lt;table id="table8" bgcolor="#e1e1e1" border="1" bordercolor="#000000" cellpadding="3" width="100%"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="127"&gt;&lt;b&gt;CallbackContext&lt;/b&gt;&lt;/td&gt; &lt;td&gt;The value that the driver passed as the Context parameter to CmRegisterCallback or CmRegisterCallbackEx when it registered this RegistryCallback routine.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td height="41" width="127"&gt;&lt;b&gt;Argument1&lt;/b&gt;&lt;/td&gt; &lt;td height="41"&gt;A REG_NOTIFY_CLASS-typed value that identifies the type of registry operation that is being performed and whether the RegistryCallback routine is being called before or after the register operation is performed.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="127"&gt;&lt;b&gt;Argument2&lt;/b&gt;&lt;/td&gt; &lt;td&gt;A pointer to a structure that contains information that is specific to the type of registry operation. The structure type depends on the REG_NOTIFY_CLASS-typed value for Argument1, as shown in the following table. For information about which REG_NOTIFY_CLASS-typed values are available for which operating system versions, see REG_NOTIFY_CLASS.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;Argument1 carries the registry operation and Argument2 is a pointer to a structure. Here's the list of operations and their structures:&lt;/p&gt; &lt;center&gt; &lt;table id="table9" border="1" bordercolor="#000000" cellpadding="3" width="61%"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt; &lt;p&gt;&lt;b&gt;Operation&lt;/b&gt;&lt;/p&gt;&lt;/td&gt; &lt;td&gt; &lt;p&gt;&lt;b&gt;Structure&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtDeleteKey &lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_DELETE_KEY_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPreDeleteKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_DELETE_KEY_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPostDeleteKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_POST_OPERATION_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtSetValueKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_SET_VALUE_KEY_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPreSetValueKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_SET_VALUE_KEY_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPostSetValueKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_POST_OPERATION_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtDeleteValueKey &lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_DELETE_VALUE_KEY_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPreDeleteValueKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_DELETE_VALUE_KEY_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPostDeleteValueKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_POST_OPERATION_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPostDeleteValueKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_POST_OPERATION_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtSetInformationKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_SET_INFORMATION_KEY_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPreSetInformationKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_SET_INFORMATION_KEY_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPostSetInformationKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_POST_OPERATION_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtRenameKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_RENAME_KEY_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPreRenameKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_RENAME_KEY_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPostRenameKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_POST_OPERATION_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtEnumerateKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_ENUMERATE_KEY_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPreEnumerateKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_ENUMERATE_KEY_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPostEnumerateKey &lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_POST_OPERATION_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtEnumerateValueKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_ENUMERATE_VALUE_KEY_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPreEnumerateValueKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_ENUMERATE_VALUE_KEY_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPostEnumerateValueKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_POST_OPERATION_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtQueryKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_QUERY_KEY_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPreQueryKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_QUERY_KEY_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPostQueryKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_POST_OPERATION_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtQueryValueKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_QUERY_VALUE_KEY_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPreQueryValueKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_QUERY_VALUE_KEY_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPostQueryValueKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_POST_OPERATION_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtQueryMultipleValueKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_QUERY_MULTIPLE_VALUE_KEY_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPreQueryMultipleValueKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_QUERY_MULTIPLE_VALUE_KEY_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPostQueryMultipleValueKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_POST_OPERATION_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPreCreateKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_PRE_CREATE_KEY_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPreCreateKeyEx&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_CREATE_KEY_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPostCreateKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_POST_CREATE_KEY_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPostCreateKeyEx&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_POST_OPERATION_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPreOpenKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_PRE_OPEN_KEY_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPreOpenKeyEx&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_OPEN_KEY_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPostOpenKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_POST_OPEN_KEY_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPostOpenKeyEx&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_POST_OPERATION_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtKeyHandleClose&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_KEY_HANDLE_CLOSE_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPreKeyHandleClose &lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_KEY_HANDLE_CLOSE_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPostKeyHandleClose&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_POST_OPERATION_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPreFlushKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_FLUSH_KEY_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPostFlushKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_POST_OPERATION_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPreLoadKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_LOAD_KEY_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPostLoadKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_POST_OPERATION_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPreUnLoadKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_UNLOAD_KEY_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPostUnLoadKey&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_POST_OPERATION_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPreQueryKeySecurity&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_QUERY_KEY_SECURITY_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPostQueryKeySecurity&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_POST_OPERATION_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPreSetKeySecurity&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_SET_KEY_SECURITY_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtPostSetKeySecurity&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_POST_OPERATION_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;RegNtCallbackContextCleanup&lt;/code&gt;&lt;/td&gt; &lt;td&gt;&lt;code&gt;REG_CALLBACK_CONTEXT_CLEANUP_INFORMATION&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/center&gt; &lt;p&gt;According to the MSDN, pointers in these structures should be accessed in try/except blocks. The callback can prevent operations from being performed as well (it's a real filter). To do that on XP, it just has to return a value different from &lt;code&gt;STATUS_SUCCESS&lt;/code&gt;. Unfortunately, by doing this, the thread which originally called the registry function will get the same error as well. That's why on Vista a new value is supported: &lt;code&gt;STATUS_CALLBACK_BYPASS&lt;/code&gt;. By returning this value, the registry operation isn't actually performed, but the thread won't get an error value. This is very useful for security solutions.&lt;/p&gt; &lt;p&gt;I wrote a small (very small) registry filter (see download link for MyRegFilter at the top of the article) to show how this new method works. Don't get too excited about it, I wrote it in 20 minutes and it's not that good, but maybe it's helpful for someone.&lt;/p&gt;&lt;div class="smallText" id="premain37" style="width: 100%;"&gt;&lt;img preid="37" src="http://www.codeproject.com/images/minus.gif" id="preimg37" height="9" width="9" /&gt;&lt;span preid="37" style="margin-bottom: 0pt;" id="precollapse37"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre37" lang="c++"&gt;&lt;span class="cpp-preprocessor"&gt;#include &lt;ntddk.h&gt;&lt;/ntddk.h&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;WCHAR DeviceName[] = L&lt;span class="cpp-string"&gt;"\\Device\\MyRegFilter"&lt;/span&gt;;&lt;br /&gt;WCHAR SymLinkName[] = L&lt;span class="cpp-string"&gt;"\\DosDevices\\MyRegFilter"&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;UNICODE_STRING usDeviceName;&lt;br /&gt;UNICODE_STRING usSymbolicLinkName;&lt;br /&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;typedef&lt;/span&gt; &lt;span class="cpp-keyword"&gt;struct&lt;/span&gt; _DEVICE_CONTEXT&lt;br /&gt;{&lt;br /&gt;  PDRIVER_OBJECT  pDriverObject;     &lt;br /&gt;  PDEVICE_OBJECT  pDeviceObject;&lt;br /&gt;&lt;br /&gt;  LARGE_INTEGER RegCookie;&lt;br /&gt;}&lt;br /&gt;DEVICE_CONTEXT, *PDEVICE_CONTEXT, **PPDEVICE_CONTEXT;&lt;br /&gt;&lt;br /&gt;PDEVICE_OBJECT  g_pDeviceObject  = NULL;&lt;br /&gt;PDEVICE_CONTEXT g_pDeviceContext = NULL;&lt;br /&gt;&lt;br /&gt;&lt;span class="cpp-preprocessor"&gt;#define FILE_DEVICE_MYREGFILTER 0x8000&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;NTSTATUS DriverInitialize(PDRIVER_OBJECT  pDriverObject,&lt;br /&gt;                        PUNICODE_STRING pusRegistryPath);&lt;br /&gt;NTSTATUS DriverEntry(PDRIVER_OBJECT  pDriverObject,&lt;br /&gt;                   PUNICODE_STRING pusRegistryPath);&lt;br /&gt;&lt;br /&gt;NTSTATUS RegistryCallback(PVOID CallbackContext, PVOID Argument1,&lt;br /&gt;                        PVOID Argument2);&lt;br /&gt;&lt;br /&gt;&lt;span class="cpp-preprocessor"&gt;#ifdef ALLOC_PRAGMA&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="cpp-preprocessor"&gt;#pragma alloc_text (INIT, DriverInitialize)&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-preprocessor"&gt;#pragma alloc_text (INIT, DriverEntry)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="cpp-preprocessor"&gt;#endif&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;NTSTATUS DeviceDispatcher(PDEVICE_CONTEXT pDeviceContext, PIRP pIrp)&lt;br /&gt;{&lt;br /&gt;  PIO_STACK_LOCATION pisl;&lt;br /&gt;  NTSTATUS ns = STATUS_NOT_IMPLEMENTED;&lt;br /&gt;&lt;br /&gt;  pisl = IoGetCurrentIrpStackLocation(pIrp);&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;switch&lt;/span&gt; (pisl-&gt;MajorFunction)&lt;br /&gt;  {&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;case&lt;/span&gt; IRP_MJ_CREATE:&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;case&lt;/span&gt; IRP_MJ_CLEANUP:&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;case&lt;/span&gt; IRP_MJ_CLOSE:&lt;br /&gt;       &lt;span class="cpp-keyword"&gt;case&lt;/span&gt; IRP_MJ_DEVICE_CONTROL:&lt;br /&gt;      {&lt;br /&gt;          ns = STATUS_SUCCESS;&lt;br /&gt;          &lt;span class="cpp-keyword"&gt;break&lt;/span&gt;;&lt;br /&gt;      }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  pIrp-&gt;IoStatus.Status = ns;&lt;br /&gt;  pIrp-&gt;IoStatus.Information = &lt;span class="cpp-literal"&gt;0&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;  IoCompleteRequest(pIrp, IO_NO_INCREMENT);&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;return&lt;/span&gt; ns;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;NTSTATUS DriverDispatcher(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;return&lt;/span&gt; (pDeviceObject == g_pDeviceObject ?&lt;br /&gt;      DeviceDispatcher(g_pDeviceContext, pIrp)&lt;br /&gt;      : STATUS_INVALID_PARAMETER_1);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;VOID DriverUnload(PDRIVER_OBJECT pDriverObject)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;// Stop filtering the registry&lt;/span&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;// Shouldn't be placed in the unload&lt;/span&gt;&lt;br /&gt;  &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  CmUnRegisterCallback(g_pDeviceContext-&gt;RegCookie);&lt;br /&gt;&lt;br /&gt;  IoDeleteSymbolicLink(&amp;usSymbolicLinkName);&lt;br /&gt;  IoDeleteDevice(pDriverObject-&gt;DeviceObject);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;NTSTATUS DriverInitialize(PDRIVER_OBJECT pDriverObject,&lt;br /&gt;                        PUNICODE_STRING pusRegistryPath)&lt;br /&gt;{&lt;br /&gt;  PDEVICE_OBJECT pDeviceObject = NULL;&lt;br /&gt;  NTSTATUS ns = STATUS_DEVICE_CONFIGURATION_ERROR;&lt;br /&gt;&lt;br /&gt;  RtlInitUnicodeString(&amp;usDeviceName, DeviceName);&lt;br /&gt;  RtlInitUnicodeString(&amp;usSymbolicLinkName, SymLinkName);&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;if&lt;/span&gt; ((ns = IoCreateDevice(pDriverObject, &lt;span class="cpp-keyword"&gt;sizeof&lt;/span&gt; (DEVICE_CONTEXT),&lt;br /&gt;      &amp;usDeviceName, FILE_DEVICE_MYREGFILTER, &lt;span class="cpp-literal"&gt;0&lt;/span&gt;, FALSE,&lt;br /&gt;      &amp;amp;pDeviceObject)) == STATUS_SUCCESS)&lt;br /&gt;  {&lt;br /&gt;      &lt;span class="cpp-keyword"&gt;if&lt;/span&gt; ((ns = IoCreateSymbolicLink(&amp;usSymbolicLinkName,&lt;br /&gt;          &amp;amp;usDeviceName)) == STATUS_SUCCESS)&lt;br /&gt;      {&lt;br /&gt;          g_pDeviceObject  = pDeviceObject;&lt;br /&gt;          g_pDeviceContext = pDeviceObject-&gt;DeviceExtension;&lt;br /&gt;&lt;br /&gt;          g_pDeviceContext-&gt;pDriverObject = pDriverObject;&lt;br /&gt;          g_pDeviceContext-&gt;pDeviceObject = pDeviceObject;&lt;br /&gt;&lt;br /&gt;      }&lt;br /&gt;      &lt;span class="cpp-keyword"&gt;else&lt;/span&gt;&lt;br /&gt;      {&lt;br /&gt;          IoDeleteDevice(pDeviceObject);&lt;br /&gt;      }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;return&lt;/span&gt; ns;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,&lt;br /&gt;                   PUNICODE_STRING pusRegistryPath)&lt;br /&gt;{&lt;br /&gt;  PDRIVER_DISPATCH *ppdd;&lt;br /&gt;  NTSTATUS ns = STATUS_DEVICE_CONFIGURATION_ERROR;&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;if&lt;/span&gt; ((ns = DriverInitialize(pDriverObject, pusRegistryPath))&lt;br /&gt;                                                          == STATUS_SUCCESS)&lt;br /&gt;  {&lt;br /&gt;      ppdd = pDriverObject-&gt;MajorFunction;&lt;br /&gt;&lt;br /&gt;      ppdd[IRP_MJ_CREATE                  ] =&lt;br /&gt;      ppdd[IRP_MJ_CREATE_NAMED_PIPE       ] =&lt;br /&gt;      ppdd[IRP_MJ_CLOSE                   ] =&lt;br /&gt;      ppdd[IRP_MJ_READ                    ] =&lt;br /&gt;      ppdd[IRP_MJ_WRITE                   ] =&lt;br /&gt;      ppdd[IRP_MJ_QUERY_INFORMATION       ] =&lt;br /&gt;      ppdd[IRP_MJ_SET_INFORMATION         ] =&lt;br /&gt;      ppdd[IRP_MJ_QUERY_EA                ] =&lt;br /&gt;      ppdd[IRP_MJ_SET_EA                  ] =&lt;br /&gt;      ppdd[IRP_MJ_FLUSH_BUFFERS           ] =&lt;br /&gt;      ppdd[IRP_MJ_QUERY_VOLUME_INFORMATION] =&lt;br /&gt;      ppdd[IRP_MJ_SET_VOLUME_INFORMATION  ] =&lt;br /&gt;      ppdd[IRP_MJ_DIRECTORY_CONTROL       ] =&lt;br /&gt;      ppdd[IRP_MJ_FILE_SYSTEM_CONTROL     ] =&lt;br /&gt;      ppdd[IRP_MJ_DEVICE_CONTROL          ] =&lt;br /&gt;      ppdd[IRP_MJ_INTERNAL_DEVICE_CONTROL ] =&lt;br /&gt;      ppdd[IRP_MJ_SHUTDOWN                ] =&lt;br /&gt;      ppdd[IRP_MJ_LOCK_CONTROL            ] =&lt;br /&gt;      ppdd[IRP_MJ_CLEANUP                 ] =&lt;br /&gt;      ppdd[IRP_MJ_CREATE_MAILSLOT         ] =&lt;br /&gt;      ppdd[IRP_MJ_QUERY_SECURITY          ] =&lt;br /&gt;      ppdd[IRP_MJ_SET_SECURITY            ] =&lt;br /&gt;      ppdd[IRP_MJ_POWER                   ] =&lt;br /&gt;      ppdd[IRP_MJ_SYSTEM_CONTROL          ] =&lt;br /&gt;      ppdd[IRP_MJ_DEVICE_CHANGE           ] =&lt;br /&gt;      ppdd[IRP_MJ_QUERY_QUOTA             ] =&lt;br /&gt;      ppdd[IRP_MJ_SET_QUOTA               ] =&lt;br /&gt;      ppdd[IRP_MJ_PNP                     ] = DriverDispatcher;&lt;br /&gt;      pDriverObject-&gt;DriverUnload           = DriverUnload;&lt;br /&gt;&lt;br /&gt;      &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;      &lt;span class="cpp-comment"&gt;// Filter the registry&lt;/span&gt;&lt;br /&gt;      &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;      ns = CmRegisterCallback(RegistryCallback, g_pDeviceContext,&lt;br /&gt;                              &amp;g_pDeviceContext-&gt;RegCookie);&lt;br /&gt;&lt;br /&gt;      &lt;span class="cpp-keyword"&gt;if&lt;/span&gt; (!NT_SUCCESS(ns)) IoDeleteDevice(g_pDeviceObject);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;return&lt;/span&gt; ns;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;// Registry Filter Callback&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;NTSTATUS RegistryCallback(PVOID CallbackContext, PVOID Argument1,&lt;br /&gt;                        PVOID Argument2)&lt;br /&gt;{&lt;br /&gt;  PDEVICE_CONTEXT pContext = (PDEVICE_CONTEXT) CallbackContext;&lt;br /&gt;  REG_NOTIFY_CLASS Action  = (REG_NOTIFY_CLASS) Argument1;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;switch&lt;/span&gt; (Action)&lt;br /&gt;  {&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;case&lt;/span&gt; RegNtPreDeleteKey:&lt;br /&gt;      {&lt;br /&gt;          &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;          &lt;span class="cpp-comment"&gt;// Pre DeleteKey&lt;/span&gt;&lt;br /&gt;          &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;          PREG_DELETE_KEY_INFORMATION pInfo&lt;br /&gt;                              = (PREG_DELETE_KEY_INFORMATION) Argument2;&lt;br /&gt;&lt;br /&gt;          DbgPrint(&lt;span class="cpp-string"&gt;"Delete Key\n"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;          &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;          &lt;span class="cpp-comment"&gt;// You can prevent this operation from happening&lt;/span&gt;&lt;br /&gt;          &lt;span class="cpp-comment"&gt;// Without having the thread noticing it&lt;/span&gt;&lt;br /&gt;          &lt;span class="cpp-comment"&gt;// Only on Windows Vista&lt;/span&gt;&lt;br /&gt;          &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;          &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;          &lt;span class="cpp-comment"&gt;// return STATUS_CALLBACK_BYPASS;&lt;/span&gt;&lt;br /&gt;          &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;          &lt;span class="cpp-keyword"&gt;break&lt;/span&gt;;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;case&lt;/span&gt; RegNtPreCreateKeyEx:&lt;br /&gt;      {&lt;br /&gt;          &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;          &lt;span class="cpp-comment"&gt;// Pre CreateKey&lt;/span&gt;&lt;br /&gt;          &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;          PREG_CREATE_KEY_INFORMATION pInfo&lt;br /&gt;                              = (PREG_CREATE_KEY_INFORMATION) Argument2;&lt;br /&gt;&lt;br /&gt;          DbgPrint(&lt;span class="cpp-string"&gt;"Create Key\n"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;          &lt;span class="cpp-keyword"&gt;break&lt;/span&gt;;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;default&lt;/span&gt;:&lt;br /&gt;      {&lt;br /&gt;          &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;          &lt;span class="cpp-comment"&gt;// Return STATUS_SUCCESS&lt;/span&gt;&lt;br /&gt;          &lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;          &lt;span class="cpp-keyword"&gt;break&lt;/span&gt;;&lt;br /&gt;      }&lt;br /&gt;    &lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;span class="cpp-keyword"&gt;return&lt;/span&gt; STATUS_SUCCESS;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt; &lt;p&gt;In this code sample I use DbgPrint to be notified of registry operations. On Vista the output of DbgPrint is disabled by default. If you want to enable it, follow &lt;a href="http://www.osronline.com/article.cfm?id=295"&gt;these&lt;/a&gt; instructions.&lt;/p&gt; &lt;h3&gt;&lt;a name="Power_Management_"&gt;Power Management &lt;/a&gt;&lt;/h3&gt; &lt;p&gt;Power Management was improved in Vista, not only because new things have been introduced, but also because the Power Management for device driver programmers has been made easier. These &lt;a href="http://www.microsoft.com/whdc/system/pnppwr/powermgmt/default.mspx"&gt;WinHec docs&lt;/a&gt; are a very good source to start from. One of the big news is the introduction of the Hybrid Sleep (the default off-mode). In this sleep mode the system image is written on a hybernation file on disk from where the system can be resumed. Drivers are notified of entering the Hybrid Sleep (S4 state) by IRP_MN_SET_POWER (Parameters.Power.State == PowerSystemHybernate). Use the SYSTEM_POWER_STATE_CONTEXT structure (Parameters.Power.SystemPowerStateContext) to determine the state transition process.&lt;/p&gt; &lt;p&gt;Also, it might not be very important, but I happened to read what follows. Silent shutdown cancellations (in user mode) are no longer allowed on Vista. This means that if your application gets a WM_QUERYENDSESSION and doesn't return TRUE (in order to let the system shut down), Vista will show a dialog box informing the user of this behavior.&lt;/p&gt; &lt;h2&gt;&lt;a name=".NET_Framework_3.0"&gt;.NET Framework 3.0&lt;/a&gt;&lt;/h2&gt; &lt;p&gt;The .NET Framework 3.0 is shipped along with Vista. However, it can be &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=10cc340b-f857-4a14-83f5-25634c3bf043&amp;displaylang=en"&gt;installed on XP SP2&lt;/a&gt; as well. To use the new technologies introduced by this new framework with your Visual Studio 2005, you'll need two extensions. One for the &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=F54F5537-CC86-4BF5-AE44-F5A1E805680D&amp;amp;displaylang=enx"&gt;Windows Presentation Foundation (WPF) and Windows Communication Foundation (WCF)&lt;/a&gt;. And one for the &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=5D61409E-1FA3-48CF-8023-E8F38E709BA6&amp;displaylang=en"&gt;Windows Workflow Foundation (WWF)&lt;/a&gt;. I cannot discuss these technologies extensively, of course, but I can try to give an insight to programmers who have never worked with them.&lt;/p&gt; &lt;h3&gt;&lt;a name="Windows_Presentation_Foundation"&gt;Windows Presentation Foundation&lt;/a&gt;&lt;/h3&gt; &lt;p&gt;I'm very enthusiastic about this technology, but it takes a moment or two for old fashioned C/C++ programmers (like myself) to understand how it works. Basically, it's a new way of creating GUIs for desktop applications and web pages. The main difference from the old way, is that these GUIs are created through XAML (eXtensible Application Markup Language), a language based on XML. The advantages of using the WPF are many. You can use 2D/3D, audio, video, animations etc. in seconds. There are no more HWNDs, and all the work is delegated to the GPU. On &lt;a href="http://msdn2.microsoft.com/en-us/netframework/aa663326.aspx"&gt;MSDN TV&lt;/a&gt; there are a few demonstrations of how through the WPF you can design beautiful and advanced GUIs. The WPF offers a very good separation between GUI development and the internal code implementation. Also, a lot of things can be achieved through XAML without having to use C#/VB code (smallWPF.zip download available at the top of the article)&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.codeproject.com/vista/vista_x64/smallwpf.jpg" border="0" height="450" width="465" /&gt;&lt;/p&gt; &lt;p&gt;In this little code sample I bind sliders to values of a listbox in order to change its appearance (position and shadow). What's so stunning is that the listbox can still be used, you can scroll it, select items, etc. I don't want to say that rotating a listbox is useful, but this is just a sample of what can be done. As I said, the slider are bound to values, this means that I didn't use code. Everything this application does is written in XAML. Here's all the code:&lt;/p&gt;&lt;div class="smallText" id="premain38" style="width: 100%;"&gt;&lt;img preid="38" src="http://www.codeproject.com/images/minus.gif" id="preimg38" height="9" width="9" /&gt;&lt;span preid="38" style="margin-bottom: 0pt;" id="precollapse38"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre38" lang="xml"&gt;&lt;window class="SmallWPF.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" x="http://schemas.microsoft.com/winfx/2006/xaml" title="SmallWPF" height="339" width="454" my="clr-namespace:System;assembly=mscorlib"&gt;&lt;br /&gt;&lt;grid&gt;&lt;br /&gt;  &lt;border borderbrush="White" borderthickness="5" horizontalalignment="Center" verticalalignment="Top"&gt;&lt;br /&gt;    &lt;listbox width="200" height="200" name="listBox1"&gt;&lt;br /&gt;      &lt;listboxitem&gt;Hello,&lt;/listboxitem&gt;&lt;br /&gt;      &lt;listboxitem isselected="True"&gt;how are you?&lt;/listboxitem&gt;&lt;br /&gt;      &lt;listboxitem&gt;This&lt;/listboxitem&gt;&lt;br /&gt;      &lt;listboxitem&gt;is&lt;/listboxitem&gt;&lt;br /&gt;      &lt;listboxitem&gt;a&lt;/listboxitem&gt;&lt;br /&gt;      &lt;listboxitem&gt;3D&lt;/listboxitem&gt;&lt;br /&gt;      &lt;listboxitem&gt;ListBox!&lt;/listboxitem&gt;&lt;br /&gt;    &lt;/listbox&gt;&lt;br /&gt;    &lt;border.bitmapeffect&gt;&lt;br /&gt;      &lt;bitmapeffectgroup&gt;&lt;br /&gt;        &lt;dropshadowbitmapeffect color="Black" direction="{Binding ElementName=MySlider4, Path=Value}" shadowdepth="{Binding ElementName=MySlider5, Path=Value}" softness="1" opacity="0.5"&gt;&lt;br /&gt;      &lt;/dropshadowbitmapeffect&gt;&lt;br /&gt;    &lt;/bitmapeffectgroup&gt;&lt;br /&gt;    &lt;border.rendertransform&gt;&lt;br /&gt;      &lt;transformgroup&gt;&lt;br /&gt;        &lt;skewtransform centerx="0" centery="0" anglex="{Binding ElementName=MySlider1, Path=Value}" angley="{Binding ElementName=MySlider2, Path=Value}"&gt;&lt;br /&gt;        &lt;rotatetransform angle="{Binding ElementName=MySlider3, Path=Value}"&gt;&lt;br /&gt;      &lt;/rotatetransform&gt;&lt;br /&gt;    &lt;/skewtransform&gt;&lt;br /&gt;  &lt;/transformgroup&gt;&lt;br /&gt;  &lt;slider height="21" margin="42,0,0,43" name="MySlider1" verticalalignment="Bottom" horizontalalignment="Left" width="104" minimum="0" maximum="50"&gt;&lt;br /&gt;  &lt;slider height="21" margin="184,0,158,43" name="MySlider2" verticalalignment="Bottom" width="104" minimum="0" maximum="50"&gt;&lt;br /&gt;  &lt;slider height="21" margin="0,0,33,43" name="MySlider3" verticalalignment="Bottom" horizontalalignment="Right" width="104" minimum="0" maximum="50"&gt;&lt;br /&gt;  &lt;slider height="21" margin="42,0,0,15" name="MySlider4" verticalalignment="Bottom" width="104" minimum="0" maximum="200" horizontalalignment="Left"&gt;&lt;br /&gt;  &lt;slider height="21" margin="184,0,158,13" name="MySlider5" verticalalignment="Bottom" width="104" minimum="0" maximum="100"&gt;&lt;br /&gt;&lt;/slider&gt;&lt;br /&gt;&lt;/slider&gt;&lt;/slider&gt;&lt;/slider&gt;&lt;/slider&gt;&lt;/border.rendertransform&gt;&lt;/border.bitmapeffect&gt;&lt;/border&gt;&lt;/grid&gt;&lt;/window&gt;&lt;/pre&gt; &lt;p&gt;I used this code to bind a value to a slider:&lt;/p&gt;&lt;pre lang="xml"&gt;AngleX="{Binding ElementName=MySlider1, Path=Value}"&lt;/pre&gt; &lt;p&gt;ElementName is the name of the control to bind and Path is the property of the bound control which should be used to fill the value. In this case, the position of MySlider1 fills the AngleX field. I could also bind a control's behavior to C# code. But, of course, this is not the place to discuss every property of this technology. I just hope that this paragraph got you intrigued enough to make you want to read more about it.&lt;/p&gt; &lt;h3&gt;&lt;a name="Windows_Communication_Foundation"&gt;Windows Communication Foundation&lt;/a&gt;&lt;/h3&gt; &lt;p&gt;The WCF is an interface to design services. The background idea is unified programming model for already existing technologies: COM+ / .NET Enterprise services, MSMQ, .NET Remoting, ASP.NET Web Services, Web Services Enhancements (WSE). Moreover, the ability of intercommunication between these technologies handled by the WCF, without having the programmer to worry about it, through reliable and secure ways. From what I could read, it seems a very good final solution to all the problems we know from the past, since from now on the programmer doesn't have to think about the communication process itself, which is handled by the WCF, meaning he doesn't have to worry about which technology he is communicating with and where from. For more information, this is the official &lt;a href="http://wcf.netfx3.com/"&gt;Windows Communication Foundation&lt;/a&gt; hompage. However, there are even more practical samples on codeproject.&lt;/p&gt; &lt;h3&gt;&lt;a name="Windows_Workflow_Foundation"&gt;Windows Workflow Foundation&lt;/a&gt;&lt;/h3&gt; &lt;p&gt;The WWF is a good way of formalizing workflow-based activities through visual items which are bound to code. Ok, this sounds strange, I'll try again. Basically, if you are a company and have to formalize a process of activities and want the comfort of having a visual model, then the WWF is what you are looking for. I can't talk about this subject extensively because I haven't used this technology extensively myself. However, since many programmers might wonder what this technology is all about, I'll try a simple understanding approach. Here's a workflow graph I made:&lt;/p&gt; &lt;center&gt;&lt;img src="http://www.codeproject.com/vista/vista_x64/smallwwf.jpg" border="0" height="456" width="312" /&gt;&lt;/center&gt; &lt;p&gt;As you can see, the graph is divided in single activities (very few, because I have no imagination). The activities can be bound through declarative rules. This means that if a have a condition that needs to be satisfied, I can declare the condition as a property. There are a many workflow components, each of them has its own properties. For instance, the code-workflow component can define a code function in a C# file, which is executed when it's the component turn of activity. In this little sample, the first activity is to wait for the user's input. After that, a declarative rule is set, which sub-divides the workflow in two separate activity flows.&lt;/p&gt; &lt;p&gt;I hope that, in spite of my terrible workflow model, you got the general purpose of the Windows Workflow Foundation. If you're interested in learning more, check out the &lt;a href="http://wf.netfx3.com/"&gt;official homepage&lt;/a&gt; where you can also find a lot of &lt;a href="http://wf.netfx3.com/files/13/default.aspx"&gt;code samples&lt;/a&gt;. As usual, there's plenty of guides about this subject.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1192972388107063553-1381546018574899912?l=chamildz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chamildz.blogspot.com/feeds/1381546018574899912/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1192972388107063553&amp;postID=1381546018574899912' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1192972388107063553/posts/default/1381546018574899912'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1192972388107063553/posts/default/1381546018574899912'/><link rel='alternate' type='text/html' href='http://chamildz.blogspot.com/2007/02/moving-to-windows-vista-x64-net-30.html' title='Moving to Windows Vista x64 - .NET 3.0'/><author><name>Chamil</name><uri>http://www.blogger.com/profile/00204727013782891667</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1192972388107063553.post-1128843629503523913</id><published>2007-02-02T02:19:00.000-08:00</published><updated>2007-02-02T02:21:46.548-08:00</updated><title type='text'>A Vector Type for C#</title><content type='html'>&lt;span id="intelliTXT"&gt;&lt;ul class="download"&gt;&lt;li&gt;&lt;a href="http://www.codeproject.com/useritems/VectorType/src.zip"&gt;Download source - 6.9 Kb&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;  &lt;h2&gt;Introduction&lt;/h2&gt;  &lt;p&gt;For years I have seen people struggle with vector mathematics. This guide should walk you through the creation of a reusable &lt;code&gt;Vector&lt;/code&gt; type and the mathematics behind it all. The resulting code is not designed to be fast or efficient but is to be as simple and understandable as possible.&lt;/p&gt;  &lt;p&gt;I havel used the Cartesian coordinate system in three-dimensions (i.e. three perpendicular axis of x, y and z) and Euclidian geometry. Don't worry about these terms, they are just the formal names for some of the maths covered at senior school. The vector space is volumetric (cube); note that you can use other vector spaces, such as a cylindrical space where one axis (usually z) relates to the radius of the cylinder.&lt;/p&gt;  &lt;p&gt;You may have guessed that computers are quite slow with this type of math. Matrix mathematics is more efficient but much harder to understand. You will need a basic grasp of trigonometry and algebra to understand this guide.&lt;/p&gt;  &lt;p&gt;Unless stated otherwise I assume that the vector is positional, originating at point (0,0,0). Alternatives to positional vectors are: unit vectors, which can be interpreted as either having no magnitude or an infinite magnitude; and vector pairs where the origin of the vector is another vector, magnitude being a distance from the origin vector.&lt;/p&gt;  &lt;p&gt;Please note that this guide is extremely verbose and goes into far too much detail for a normal C# programmer. Please do not be offended if any part of this seems patronising. I have written the guide for a wide audience.&lt;/p&gt;  &lt;p&gt;A quick glossary:&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;Operator, this is the symbol used to define an operation such as plus (&lt;code&gt;+&lt;/code&gt;) in (a+b) &lt;/li&gt;&lt;li&gt;Operand, these are the variables used in an operation such as (a) and (b) in (a+b). The left-hand-side (LHS) operand is (a) where as the right-hand-side (RHS) operand is (b). &lt;/li&gt;&lt;/ul&gt;  &lt;p&gt;All of the equations in this guide assume A (or v1) and B (or v2) can be broken down into:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image001.gif" height="80" width="59" /&gt; &lt;img src="http://www.codeproject.com/useritems/VectorType/image002.gif" height="82" width="62" /&gt;&lt;/p&gt;  &lt;h2&gt;Using the code&lt;/h2&gt;  &lt;p&gt;To begin with let us define how the vector information will be stored. I don't often create structs when coding but for our &lt;code&gt;Vector&lt;/code&gt; this is perfect. If you are reading this article you probably already know that a vector represents values along a number of axes. For this tutorial we will be developing a three-dimensional type so... thee variables and three axis.&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;struct&lt;/span&gt; Vector&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;private&lt;/span&gt; &lt;span class="cs-keyword"&gt;double&lt;/span&gt; x, y, z;&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;What orientation are the axes in? Well, for the type we are building it doesn't matter but I always assume:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/axisOrient.gif" height="244" width="305" /&gt;&lt;/p&gt;  &lt;p&gt;You may have noticed that Z is negative as you look down the axis. This is a common convention in graphics libraries such as OpenGL. Again, these axis have no affect on our code.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;A quick diversion&lt;/strong&gt;: Why a struct instead of a class?&lt;br /&gt;&lt;br /&gt;The differences between struct and class:&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;A struct is a value type created on the stack instead of the heap, thus reducing garbage collection overheads. &lt;/li&gt;&lt;li&gt;They are passed by value not by reference. &lt;/li&gt;&lt;li&gt;They are created and disposed of quickly and efficiently. &lt;/li&gt;&lt;li&gt;You cannot derive other types from them (i.e. non-inheritable). &lt;/li&gt;&lt;li&gt;They are only appropriate for types with a small number of members (variables). Microsoft recommends a struct should be less than 16 bytes. &lt;/li&gt;&lt;li&gt;You do not need the new keyword to instantiate a struct. &lt;/li&gt;&lt;/ul&gt;  &lt;p&gt;Basically, it looks like, acts like, and is a primitive type. Although, there is no reason why the vector type could not be created as a class.&lt;br /&gt;A more in-depth article on structs has been written by S. Senthil Kumar at &lt;a href="http://www.codeproject.com/csharp/structs_in_csharp.asp"&gt;http://www.codeproject.com/csharp/structs_in_csharp.asp&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Accessing the variables&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Did you notice that the variables were private?&lt;br /&gt;&lt;br /&gt;While I have chosen to build a struct, I habitually hide my variables and create public accessor and mutator properties. This is not strictly good practice for structs, but I have created them in case I feel the need to convert to a class at a later date (this is good practice for classes).&lt;br /&gt;&lt;br /&gt;In addition to the properties, an array style interface has also been provided. This lets the user call the &lt;code&gt;Vector&lt;/code&gt; with &lt;code&gt;myVector[x]&lt;/code&gt;, &lt;code&gt;myVector[y]&lt;/code&gt;, &lt;code&gt;myVector[z]&lt;/code&gt;. Additionally, the user can get or set all of the components as an array using the &lt;code&gt;Array&lt;/code&gt; property, i.e. &lt;code&gt;myVector.Array = {x,y,z}&lt;/code&gt;.&lt;/p&gt;  &lt;div class="smallText" id="premain1" style="width: 100%;"&gt;&lt;img preid="1" src="http://www.codeproject.com/images/minus.gif" id="preimg1" height="9" width="9" /&gt;&lt;span preid="1" style="margin-bottom: 0pt;" id="precollapse1"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre1" lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;double&lt;/span&gt; X&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;get&lt;/span&gt;{&lt;span class="cs-keyword"&gt;return&lt;/span&gt; x;}&lt;br /&gt;  &lt;span class="cs-keyword"&gt;set&lt;/span&gt;{x = value;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;double&lt;/span&gt; Y&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;get&lt;/span&gt;{&lt;span class="cs-keyword"&gt;return&lt;/span&gt; y;}&lt;br /&gt;  &lt;span class="cs-keyword"&gt;set&lt;/span&gt;{y = value;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;double&lt;/span&gt; Z&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;get&lt;/span&gt;{&lt;span class="cs-keyword"&gt;return&lt;/span&gt; z;}&lt;br /&gt;  &lt;span class="cs-keyword"&gt;set&lt;/span&gt;{z = value;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;double&lt;/span&gt;[] Array&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;get&lt;/span&gt;{&lt;span class="cs-keyword"&gt;return&lt;/span&gt; &lt;span class="cs-keyword"&gt;new&lt;/span&gt; &lt;span class="cs-keyword"&gt;double&lt;/span&gt;[] {x,y,z};}&lt;br /&gt;  &lt;span class="cs-keyword"&gt;set&lt;/span&gt;&lt;br /&gt;  {&lt;br /&gt;     &lt;span class="cs-keyword"&gt;if&lt;/span&gt;(value.Length == &lt;span class="cs-literal"&gt;3&lt;/span&gt;)&lt;br /&gt;     {&lt;br /&gt;        x = value[&lt;span class="cs-literal"&gt;0&lt;/span&gt;];&lt;br /&gt;        y = value[&lt;span class="cs-literal"&gt;1&lt;/span&gt;];&lt;br /&gt;        z = value[&lt;span class="cs-literal"&gt;2&lt;/span&gt;];&lt;br /&gt;     }&lt;br /&gt;     &lt;span class="cs-keyword"&gt;else&lt;/span&gt;&lt;br /&gt;     {&lt;br /&gt;        &lt;span class="cs-keyword"&gt;throw&lt;/span&gt; &lt;span class="cs-keyword"&gt;new&lt;/span&gt; ArgumentException(THREE_COMPONENTS);&lt;br /&gt;     }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;double&lt;/span&gt; &lt;span class="cs-keyword"&gt;this&lt;/span&gt;[ &lt;span class="cs-keyword"&gt;int&lt;/span&gt; index ]&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;get&lt;/span&gt;&lt;br /&gt;  {&lt;br /&gt;     &lt;span class="cs-keyword"&gt;switch&lt;/span&gt; (index)&lt;br /&gt;     {&lt;br /&gt;        &lt;span class="cs-keyword"&gt;case&lt;/span&gt; &lt;span class="cs-literal"&gt;0&lt;/span&gt;: {&lt;span class="cs-keyword"&gt;return&lt;/span&gt; X; }&lt;br /&gt;        &lt;span class="cs-keyword"&gt;case&lt;/span&gt; &lt;span class="cs-literal"&gt;1&lt;/span&gt;: {&lt;span class="cs-keyword"&gt;return&lt;/span&gt; Y; }&lt;br /&gt;        &lt;span class="cs-keyword"&gt;case&lt;/span&gt; &lt;span class="cs-literal"&gt;2&lt;/span&gt;: {&lt;span class="cs-keyword"&gt;return&lt;/span&gt; Z; }&lt;br /&gt;        &lt;span class="cs-keyword"&gt;default&lt;/span&gt;: &lt;span class="cs-keyword"&gt;throw&lt;/span&gt; &lt;span class="cs-keyword"&gt;new&lt;/span&gt; ArgumentException(THREE_COMPONENTS, &lt;span class="cpp-string"&gt;"index");&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;  set&lt;br /&gt;  {&lt;br /&gt;      switch (index)&lt;br /&gt;      {&lt;br /&gt;         case 0: {X = value; break;}&lt;br /&gt;         case 1: {Y = value; break;}&lt;br /&gt;         case 2: {Z = value; break;}&lt;br /&gt;         default: throw new ArgumentException(THREE_COMPONENTS, "index");&lt;br /&gt;     }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;private const string THREE_COMPONENTS = "Array must contain exactly three components, (x,y,z)"&lt;/span&gt;;&lt;/pre&gt;  &lt;p&gt;To construct the type using typical class syntax the following constructir methods have been provided:&lt;/p&gt;  &lt;div class="smallText" id="premain2" style="width: 100%;"&gt;&lt;img preid="2" src="http://www.codeproject.com/images/minus.gif" id="preimg2" height="9" width="9" /&gt;&lt;span preid="2" style="margin-bottom: 0pt;" id="precollapse2"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre2" lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; Vector(&lt;span class="cs-keyword"&gt;double&lt;/span&gt; x, &lt;span class="cs-keyword"&gt;double&lt;/span&gt; y, &lt;span class="cs-keyword"&gt;double&lt;/span&gt; z)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;this&lt;/span&gt;.x = &lt;span class="cs-literal"&gt;0&lt;/span&gt;;&lt;br /&gt;  &lt;span class="cs-keyword"&gt;this&lt;/span&gt;.y = &lt;span class="cs-literal"&gt;0&lt;/span&gt;;&lt;br /&gt;  &lt;span class="cs-keyword"&gt;this&lt;/span&gt;.z = &lt;span class="cs-literal"&gt;0&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;  X = x;&lt;br /&gt;  Y = y;&lt;br /&gt;  Z = z;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; Vector (&lt;span class="cs-keyword"&gt;double&lt;/span&gt;[] xyz)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;this&lt;/span&gt;.x = &lt;span class="cs-literal"&gt;0&lt;/span&gt;;&lt;br /&gt;  &lt;span class="cs-keyword"&gt;this&lt;/span&gt;.y = &lt;span class="cs-literal"&gt;0&lt;/span&gt;;&lt;br /&gt;  &lt;span class="cs-keyword"&gt;this&lt;/span&gt;.z = &lt;span class="cs-literal"&gt;0&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;  Array = xyz;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; Vector(Vector v1)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;this&lt;/span&gt;.x = &lt;span class="cs-literal"&gt;0&lt;/span&gt;;&lt;br /&gt;  &lt;span class="cs-keyword"&gt;this&lt;/span&gt;.y = &lt;span class="cs-literal"&gt;0&lt;/span&gt;;&lt;br /&gt;  &lt;span class="cs-keyword"&gt;this&lt;/span&gt;.z = &lt;span class="cs-literal"&gt;0&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;  X = v1.X;&lt;br /&gt;  Y = v1.Y;&lt;br /&gt;  Z = v1.Z;&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;We now have a framework for storing, accessing and mutating the &lt;code&gt;Vector&lt;/code&gt; and its components (x,y,z). We can now consider mathematical operations applicable to a vector. Let's begin by overloading the basic mathematical operators.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Operator overloading&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Overloading operators allows the programmer to define how a type is used in the code. Take, for example, the plus operator (&lt;code&gt;+&lt;/code&gt;). For numeric types this would suggest addition of two numbers. For strings it represents the concatenation of two strings. Operator overloading is of huge benefit to programmers when describing how a type should interact with the system. In C# the following operators can be overloaded:&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;Addition, concatenation, and reinforcement (&lt;code&gt;+&lt;/code&gt;) &lt;/li&gt;&lt;li&gt;Subtraction and negation (&lt;code&gt;-&lt;/code&gt;) &lt;/li&gt;&lt;li&gt;Logical negation (&lt;code&gt;!&lt;/code&gt;) &lt;/li&gt;&lt;li&gt;Bitwise complement (&lt;code&gt;~&lt;/code&gt;) &lt;/li&gt;&lt;li&gt;Increment (&lt;code&gt;++&lt;/code&gt;) &lt;/li&gt;&lt;li&gt;Decrement (&lt;code&gt;--&lt;/code&gt;) &lt;/li&gt;&lt;li&gt;Boolean Truth (&lt;code&gt;&lt;span class="cpp-keyword"&gt;true&lt;/span&gt;&lt;/code&gt;) &lt;/li&gt;&lt;li&gt;Boolean false (&lt;code&gt;&lt;span class="cpp-keyword"&gt;false&lt;/span&gt;&lt;/code&gt;) &lt;/li&gt;&lt;li&gt;Multiplication (&lt;code&gt;*&lt;/code&gt;) &lt;/li&gt;&lt;li&gt;Division (&lt;code&gt;/&lt;/code&gt;) &lt;/li&gt;&lt;li&gt;Division remainder (&lt;code&gt;%&lt;/code&gt;) &lt;/li&gt;&lt;li&gt;Logical AND (&lt;code&gt;&amp;&lt;/code&gt;) &lt;/li&gt;&lt;li&gt;Logical OR (&lt;code&gt;|&lt;/code&gt;) &lt;/li&gt;&lt;li&gt;Logical Exclusive-OR (&lt;code&gt;^&lt;/code&gt;) &lt;/li&gt;&lt;li&gt;Binary shift left (&lt;code&gt;&lt;&lt;&lt;/code&gt;) &lt;/li&gt;&lt;li&gt;Binary shift right (&lt;code&gt;&gt;&gt;&lt;/code&gt;) &lt;/li&gt;&lt;li&gt;Equality operators, equal and not-equal (&lt;code&gt;==&lt;/code&gt; and &lt;code&gt;!=&lt;/code&gt;) &lt;/li&gt;&lt;li&gt;Difference\comparison operators, less-than and greater-than(&lt;code&gt;&lt;&lt;/code&gt; and &lt;code&gt;&gt;&lt;/code&gt;) &lt;/li&gt;&lt;li&gt;Difference\comparison operators, less-than or equal-to and greater-than or equal-to(&lt;code&gt;&lt;=&lt;/code&gt; and &lt;code&gt;&gt;=&lt;/code&gt;) &lt;/li&gt;&lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Operator overloads for the &lt;code&gt;Vector&lt;/code&gt; type&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Addition&lt;/strong&gt; (v3 = v1 + v2)&lt;/p&gt;  &lt;p&gt;The addition of two vectors is achieved by simply adding the x, y, and z components of one vector to the other (i.e. x+x, y+y, z+z).&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; Vector &lt;span class="cs-keyword"&gt;operator&lt;/span&gt;+(Vector v1, Vector v2)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt;&lt;br /&gt;  (&lt;br /&gt;     &lt;span class="cs-keyword"&gt;new&lt;/span&gt; Vector&lt;br /&gt;     (&lt;br /&gt;        v1.X + v2.X,&lt;br /&gt;        v1.Y + v2.Y,&lt;br /&gt;        v1.Z + v2.Z&lt;br /&gt;     )&lt;br /&gt;  );&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;&lt;strong&gt;Subtraction&lt;/strong&gt; (v3 = v1 - v2)&lt;/p&gt;  &lt;p&gt;Subtraction of two vectors is simply the subtraction of the x, y, and z components of one vector from the other (i.e. x-x, y-y, z-z).&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; Vector &lt;span class="cs-keyword"&gt;operator&lt;/span&gt;-(Vector v1, Vector v2 )&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt;&lt;br /&gt;  (&lt;br /&gt;     &lt;span class="cs-keyword"&gt;new&lt;/span&gt; Vector&lt;br /&gt;     (&lt;br /&gt;         v1.X - v2.X,&lt;br /&gt;         v1.Y - v2.Y,&lt;br /&gt;         v1.Z - v2.Z&lt;br /&gt;     )&lt;br /&gt;  );&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;&lt;strong&gt;Negation&lt;/strong&gt; (v2 = -v1)&lt;/p&gt;  &lt;p&gt;Negation of a vector inverts its direction. This is achieved by simply negating each of the component parts of the vector.&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; Vector &lt;span class="cs-keyword"&gt;operator&lt;/span&gt;-(Vector v1)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt;&lt;br /&gt;  (&lt;br /&gt;     &lt;span class="cs-keyword"&gt;new&lt;/span&gt; Vector&lt;br /&gt;     (&lt;br /&gt;        - v1.X,&lt;br /&gt;        - v1.Y,&lt;br /&gt;        - v1.Z&lt;br /&gt;     )&lt;br /&gt;  );&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;&lt;strong&gt;Reinforcement&lt;/strong&gt; (v2 = +v1)&lt;/p&gt;  &lt;p&gt;Reinforcement of a vector actually does nothing but return the original vector given the rules of addition, (i.e. +-x = -x and ++x = +x).&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; Vector &lt;span class="cs-keyword"&gt;operator&lt;/span&gt;+(Vector v1)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt;&lt;br /&gt;  (&lt;br /&gt;     &lt;span class="cs-keyword"&gt;new&lt;/span&gt; Vector&lt;br /&gt;     (&lt;br /&gt;        + v1.X,&lt;br /&gt;        + v1.Y,&lt;br /&gt;        + v1.Z&lt;br /&gt;     )&lt;br /&gt;  );&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;&lt;strong&gt;Comparison&lt;/strong&gt; (&lt;, &gt;, &lt;=, and &gt;=)&lt;/p&gt;  &lt;p&gt;When comparing two vectors we use magnitude. The magnitude of a vector is its length, irrespective of direction.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Magnitude&lt;/strong&gt;&lt;br /&gt;The length (or magnitude) of a vector can be determined using the formula &lt;img src="http://www.codeproject.com/useritems/VectorType/image003.gif" border="0" height="20" width="130" /&gt;.&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; &lt;span class="cs-keyword"&gt;double&lt;/span&gt; Magnitude(Vector v1)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt;&lt;br /&gt;  (&lt;br /&gt;     Math.Sqrt&lt;br /&gt;     (&lt;br /&gt;        v1.X * v1.X +&lt;br /&gt;        v1.Y * v1.Y +&lt;br /&gt;        v1.Z * v1.Z&lt;br /&gt;     )&lt;br /&gt;   );&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;Where possible I have created static methods to extend the programmer's options when making use of the type. Methods which directly affect or are effected by the instance simply call the static methods.&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;double&lt;/span&gt; Magnitude()&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt; Magnitude(&lt;span class="cs-keyword"&gt;this&lt;/span&gt;);&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;Returning to the comparison operators ...&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Less-than&lt;/strong&gt; (result = v1 &lt;&gt;  &lt;p&gt;Less-than compares two vectors, returning true only if the magnitude of the left-hand-side vector (v1) is less than the magnitude of the other (v2).&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; &lt;span class="cs-keyword"&gt;bool&lt;/span&gt; &lt;span class="cs-keyword"&gt;operator&lt;/span&gt;&lt;(Vector v1, Vector v2)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt; v1.Magnitude() &lt; v2.Magnitude();&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;&lt;strong&gt;Less-than or Equal-to&lt;/strong&gt; (result = v1 &lt;= v2)&lt;/p&gt;  &lt;p&gt;Less-than or equal-to compares two vectors returning true only if the magnitude of the left-hand-side vector (v1) is less than the magnitude of the other (v2) or the two magnitudes are equal.&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; &lt;span class="cs-keyword"&gt;bool&lt;/span&gt; &lt;span class="cs-keyword"&gt;operator&lt;/span&gt;&lt;=(Vector v1, Vector v2)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt; v1.Magnitude() &lt;= v2.Magnitude();&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;&lt;strong&gt;Greater-than&lt;/strong&gt; (result = v1 &gt; v2)&lt;/p&gt;  &lt;p&gt;Greater-than compares two vectors returning true only if the magnitude of the left-hand-side vector (v1) is greater than the magnitude of the other (v2).&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; &lt;span class="cs-keyword"&gt;bool&lt;/span&gt; &lt;span class="cs-keyword"&gt;operator&lt;/span&gt;&gt;(Vector v1, Vector v2)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt; v1.Magnitude() &gt; v2.Magnitude();&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;&lt;strong&gt;Greater-than or Equal-to&lt;/strong&gt; (&lt;code&gt;result = v1 &gt;= v2&lt;/code&gt;)&lt;/p&gt;  &lt;p&gt;Greater-than or equal-to compares two vectors returning true only if the magnitude of the left-hand-side vector (v1) is grearter than the magnitude of the other (v2) or the two magnitudes are equal.&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; &lt;span class="cs-keyword"&gt;bool&lt;/span&gt; &lt;span class="cs-keyword"&gt;operator&lt;/span&gt;&gt;(Vector v1, Vector v2)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt; v1.Magnitude() &gt;= v2.Magnitude();&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;&lt;strong&gt;Equality&lt;/strong&gt; (&lt;code&gt;result = v1 == v2&lt;/code&gt;)&lt;/p&gt;  &lt;p&gt;To check if two vectors are equal we simply check the component pairs. We AND the results so that any pair which is not equal will result in false.&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; &lt;span class="cs-keyword"&gt;bool&lt;/span&gt; &lt;span class="cs-keyword"&gt;operator&lt;/span&gt;==(Vector v1, Vector v2)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt;&lt;br /&gt;  (&lt;br /&gt;     (v1.X == v2.X)&amp;&amp;amp;&lt;br /&gt;     (v1.Y == v2.Y)&amp;&amp;amp;&lt;br /&gt;     (v1.Z == v2.Z)&lt;br /&gt;  );&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;&lt;strong&gt;Inequality&lt;/strong&gt; (&lt;code&gt;result = v1 != v2&lt;/code&gt;)&lt;/p&gt;  &lt;p&gt;If the operator == (equal) is overridden, C# forces us to override != (not-equal). This is simply the inverse of equality.&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; &lt;span class="cs-keyword"&gt;bool&lt;/span&gt; &lt;span class="cs-keyword"&gt;operator&lt;/span&gt;!=(Vector v1, Vector v2)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt; !(v1==v2);&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;&lt;strong&gt;Division&lt;/strong&gt; (&lt;code&gt;v3 = v1 / s2&lt;/code&gt;)&lt;/p&gt;  &lt;p&gt;Division of a vector by a scalar number (e.g. 2) is achieved by dividing each of the component parts by the divisor (s2).&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; Vector &lt;span class="cs-keyword"&gt;operator&lt;/span&gt;/(Vector v1, &lt;span class="cs-keyword"&gt;double&lt;/span&gt; s2)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt;&lt;br /&gt;  (&lt;br /&gt;     &lt;span class="cs-keyword"&gt;new&lt;/span&gt; Vector&lt;br /&gt;     (&lt;br /&gt;        v1.X / s2,&lt;br /&gt;        v1.Y / s2,&lt;br /&gt;        v1.Z / s2&lt;br /&gt;     )&lt;br /&gt;  );&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;&lt;strong&gt;Multiplication&lt;/strong&gt; (dot, cross, and by scalar)&lt;/p&gt;  &lt;p&gt;Multiplication of vectors is tricky. There are three distinct types of vector multiplication:&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;Multiplication by a scalar (v3 = v1 * s2) &lt;/li&gt;&lt;li&gt;Dot product (s3 = v1 . v2) &lt;/li&gt;&lt;li&gt;Cross product (v3 = v1 * v2) &lt;/li&gt;&lt;/ul&gt;  &lt;p&gt;Only multiplication by scalar and division by scalar have been implemented as operator overloads. I have seen operators such as &lt;code&gt;~&lt;/code&gt; overloaded for the dot product to distinguish it from cross product; I believe that this can lead to confusion and have choosen not to provide operators for dot and cross products leaving the user to call the appropriate method instead.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Multiplication by scalar&lt;/strong&gt; is achieved by multiplying each of the component parts by the scalar value.&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; Vector &lt;span class="cs-keyword"&gt;operator&lt;/span&gt;*(Vector v1, &lt;span class="cs-keyword"&gt;double&lt;/span&gt; s2)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt;&lt;br /&gt;  (&lt;br /&gt;     &lt;span class="cs-keyword"&gt;new&lt;/span&gt; Vector&lt;br /&gt;     (&lt;br /&gt;        v1.X * s2,&lt;br /&gt;        v1.Y * s2,&lt;br /&gt;        v1.Z * s2&lt;br /&gt;     )&lt;br /&gt;  );&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;The order of operands in multiplication can, of course, be reversed.&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; Vector &lt;span class="cs-keyword"&gt;operator&lt;/span&gt;*(&lt;span class="cs-keyword"&gt;double&lt;/span&gt; s1, Vector v2)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt; v2 * s1;&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;The &lt;strong&gt;cross product&lt;/strong&gt; of two vectors produces a normal to the plane created by the two vectors given.&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image004.gif" height="232" width="220" /&gt;&lt;/p&gt;  &lt;p&gt;The formulae for this (where v1 = A and v2 = B) is&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image005.gif" height="112" width="339" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image006.gif" border="0" height="20" width="35" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image007.gif" border="0" height="20" width="320" /&gt;&lt;/p&gt;  &lt;p&gt;The equation should always produce a vector as the result.&lt;/p&gt;  &lt;p&gt;The sine of theta is used to account for the direction of the vector. Theta always takes the smallest angle between A and B (i.e. &lt;img src="http://www.codeproject.com/useritems/VectorType/image008.gif" border="0" height="15" width="60" /&gt;).&lt;/p&gt;  &lt;p&gt;The right hand side of the formula is arrived at by expanding and simplifying the left hand side using the rules:&lt;/p&gt;  &lt;p&gt;Sin 0° = 0&lt;/p&gt;  &lt;p&gt;Sin 90° = 1&lt;/p&gt;  &lt;p&gt;In a matrix style notation this looks like:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image009.gif" border="0" height="95" width="180" /&gt;&lt;/p&gt;  &lt;p&gt;You should be aware that this equation is non-commutable. This means that v1 cross-product v2 is NOT the same as v2 cross-product v1.&lt;/p&gt;  &lt;p&gt;The C# code for all of this is:&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; Vector CrossProduct(Vector v1, Vector v2)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt;&lt;br /&gt;  (&lt;br /&gt;     &lt;span class="cs-keyword"&gt;new&lt;/span&gt; Vector&lt;br /&gt;     (&lt;br /&gt;        v1.Y * v2.Z - v1.Z * v2.Y,&lt;br /&gt;        v1.Z * v2.X - v1.X * v2.Z,&lt;br /&gt;        v1.X * v2.Y - v1.Y * v2.X&lt;br /&gt;     )&lt;br /&gt;  );&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;And the instance counterpart of the static method is:&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; Vector CrossProduct(Vector other)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt; CrossProduct(&lt;span class="cs-keyword"&gt;this&lt;/span&gt;, other);&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;Note that this instance method does not affect the instance from which it is called but returns a new &lt;code&gt;Vector&lt;/code&gt; object. I have chosen to implement cross product in this fashion for two reasons; one, to make it conistant with dot product which cannot produce a vector, and two, because cross product is usualy used to generate a normal used somewhere else, the origional vecotor needing to be left intact.&lt;/p&gt;  &lt;p&gt;[Side note] A quick template for manualy calculating the cross product of two vectors is:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image010.gif" height="160" width="172" /&gt;&lt;/p&gt;  &lt;p&gt;The &lt;strong&gt;dot product&lt;/strong&gt; of two vectors is a scalar value defined by the formulae;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image005.gif" height="112" width="339" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image011.gif" border="0" height="20" width="40" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image012.gif" border="0" height="20" width="250" /&gt;&lt;/p&gt;  &lt;p&gt;The equation should always produce a scalar as the result.&lt;/p&gt;  &lt;p&gt;Cosine theta is used to account for the direction of the vector. Theta always takes the smallest angle between A and B (i.e. &lt;img src="http://www.codeproject.com/useritems/VectorType/image008.gif" border="0" height="15" width="80" /&gt;).&lt;/p&gt;  &lt;p&gt;The right hand side of the formula is arrived at by expanding and simplifying the left hand side using the rules:&lt;/p&gt;  &lt;p&gt;Cos 0° =1&lt;/p&gt;  &lt;p&gt;Cos 90° = 0&lt;/p&gt;  &lt;p&gt;The C# code for this is:&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; &lt;span class="cs-keyword"&gt;double&lt;/span&gt; DotProduct(Vector v1, Vector v2)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt;&lt;br /&gt;  (&lt;br /&gt;     v1.X * v2.X +&lt;br /&gt;     v1.Y * v2.Y +&lt;br /&gt;     v1.Z * v2.Z&lt;br /&gt;  );&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;And its counterpart:&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;double&lt;/span&gt; DotProduct(Vector other)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt; DotProduct(&lt;span class="cs-keyword"&gt;this&lt;/span&gt;, other);&lt;br /&gt;}&lt;/pre&gt;  &lt;h2&gt;Extended functionality&lt;/h2&gt;  &lt;p&gt;We now have all the basic functionality required of a &lt;code&gt;Vector&lt;/code&gt; type. To make this type really useful I have provided some additional functionality.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Magnitude&lt;/strong&gt; &lt;em&gt;revisited&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;We have already seen the method to get the magnitude or length of a vector. Here is a method to alter a vector's magnitude.&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; Vector Magnitude(Vector v1, &lt;span class="cs-keyword"&gt;double&lt;/span&gt; newMagnitude)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;if&lt;/span&gt; (newMagnitude &lt; &lt;span class="cs-literal"&gt;0&lt;/span&gt;)&lt;br /&gt;  {&lt;span class="cs-keyword"&gt;throw&lt;/span&gt; &lt;span class="cs-keyword"&gt;new&lt;/span&gt; ArgumentOutOfRangeException(&lt;span class="cpp-string"&gt;"newMagnitude", newMagnitude, NEGATIVE_MAGNITUDE);}&lt;br /&gt;&lt;br /&gt;  if (v1 == new Vector(0, 0, 0))&lt;br /&gt;  {throw new ArgumentException(ORAGIN_VECTOR_MAGNITUDE, "v1");}&lt;br /&gt;&lt;br /&gt;  return&lt;br /&gt;  (&lt;br /&gt;     new Vector&lt;br /&gt;     (&lt;br /&gt;        v1 * (newMagnitude / v1.Magnitude())&lt;br /&gt;     )&lt;br /&gt;  );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void Magnitude(double newMagnitude)&lt;br /&gt;{&lt;br /&gt;  this = Magnitude(this, newMagnitude);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private const string NEGATIVE_MAGNITUDE = "The magnitude of a Vector must be a positive value, (i.e. greater than 0)";&lt;br /&gt;private const string ORAGIN_VECTOR_MAGNITUDE = "Cannot change the magnitude of Vector(0,0,0)"&lt;/span&gt;;&lt;/pre&gt;  &lt;p&gt;&lt;strong&gt;Normalisation and Unit Vector&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;A unit vector is one which has a magnitude of 1. To test if a vector is a unit vector we simply check for 1 against the magnitude method already defined.&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; &lt;span class="cs-keyword"&gt;bool&lt;/span&gt; IsUnitVector(Vector v1)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt; v1.Magnitude() == &lt;span class="cs-literal"&gt;1&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;bool&lt;/span&gt; IsUnitVector()&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt; IsUnitVector(&lt;span class="cs-keyword"&gt;this&lt;/span&gt;);&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;Normalization is the process of converting some vector to a unit vector. The formula for this is:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image013.gif" border="0" height="109" width="156" /&gt;&lt;/p&gt;  &lt;div class="smallText" id="premain24" style="width: 100%;"&gt;&lt;img preid="24" src="http://www.codeproject.com/images/minus.gif" id="preimg24" height="9" width="9" /&gt;&lt;span preid="24" style="margin-bottom: 0pt;" id="precollapse24"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre24" lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; Vector Normalize(Vector v1)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-comment"&gt;// Check for divide by zero errors&lt;/span&gt;&lt;br /&gt;  &lt;span class="cs-keyword"&gt;if&lt;/span&gt; ( v1.Magnitude() == &lt;span class="cs-literal"&gt;0&lt;/span&gt; )&lt;br /&gt;  {&lt;br /&gt;     &lt;span class="cs-keyword"&gt;throw&lt;/span&gt; &lt;span class="cs-keyword"&gt;new&lt;/span&gt; DivideByZeroException( NORMALIZE_0 );&lt;br /&gt;  }&lt;br /&gt;  &lt;span class="cs-keyword"&gt;else&lt;/span&gt;&lt;br /&gt;  {&lt;br /&gt;     &lt;span class="cs-comment"&gt;// find the inverse of the vectors magnitude&lt;/span&gt;&lt;br /&gt;     &lt;span class="cs-keyword"&gt;double&lt;/span&gt; inverse = &lt;span class="cs-literal"&gt;1&lt;/span&gt; / v1.Magnitude();&lt;br /&gt;     &lt;span class="cs-keyword"&gt;return&lt;/span&gt;&lt;br /&gt;     (&lt;br /&gt;        &lt;span class="cs-keyword"&gt;new&lt;/span&gt; Vector&lt;br /&gt;        (&lt;br /&gt;           &lt;span class="cs-comment"&gt;// multiply each component by the inverse of the magnitude&lt;/span&gt;&lt;br /&gt;           v1.X * inverse,&lt;br /&gt;           v1.Y * inverse,&lt;br /&gt;           v1.Z * inverse&lt;br /&gt;        )&lt;br /&gt;     );&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;void&lt;/span&gt; Normalize()&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;this&lt;/span&gt; = Normalize(&lt;span class="cs-keyword"&gt;this&lt;/span&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="cs-keyword"&gt;private&lt;/span&gt; &lt;span class="cs-keyword"&gt;const&lt;/span&gt; &lt;span class="cs-keyword"&gt;string&lt;/span&gt; NORMALIZE_0 = &lt;span class="cpp-string"&gt;"Can not normalize a vector when it's magnitude is zero"&lt;/span&gt;;&lt;/pre&gt; The normalization instance method directly affects the instance.  &lt;p&gt;&lt;strong&gt;Interpolation&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This method takes an interpolated value from between two vectors. This method takes three arguments, a starting point (vector v1), and end point (Vector v2), and a control which is a fraction between 1 and 0. The control determines which point between v1 and v2 is taken. A control of 0 will return v1 and a control of 1 will return v2.&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image014.gif" height="230" width="314" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image015.gif" border="0" height="20" width="150" /&gt;&lt;/p&gt;  &lt;p&gt;or:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image016.gif" border="0" height="20" width="150" /&gt;&lt;/p&gt;  &lt;p&gt;or:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image017.gif" border="0" height="20" width="150" /&gt;&lt;/p&gt;  &lt;p&gt;or:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image018.gif" border="0" height="35" width="160" /&gt;&lt;/p&gt;  &lt;p&gt;where:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image019.gif" border="0" height="15" width="10" /&gt;= Current value&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image020.gif" border="0" height="20" width="15" /&gt; = Initial value (v1)&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image021.gif" border="0" height="20" width="15" /&gt;= Final value (v2)&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image022.gif" border="0" height="15" width="10" /&gt;= Control parameter, where &lt;img src="http://www.codeproject.com/useritems/VectorType/image023.gif" border="0" height="20" width="50" /&gt;, and where, &lt;img src="http://www.codeproject.com/useritems/VectorType/image024.gif" border="0" height="20" width="50" /&gt;, &lt;img src="http://www.codeproject.com/useritems/VectorType/image025.gif" border="0" height="20" width="50" /&gt;&lt;/p&gt;  &lt;div class="smallText" id="premain25" style="width: 100%;"&gt;&lt;img preid="25" src="http://www.codeproject.com/images/minus.gif" id="preimg25" height="9" width="9" /&gt;&lt;span preid="25" style="margin-bottom: 0pt;" id="precollapse25"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre25" lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; Vector Interpolate(Vector v1, Vector v2, &lt;span class="cs-keyword"&gt;double&lt;/span&gt; control)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;if&lt;/span&gt; (control &gt;&lt;span class="cs-literal"&gt;1&lt;/span&gt; || control &lt;&lt;span class="cs-literal"&gt;0&lt;/span&gt;)&lt;br /&gt;  {&lt;br /&gt;     &lt;span class="cs-comment"&gt;// Error message includes information about the actual value of the argument&lt;/span&gt;&lt;br /&gt;     &lt;span class="cs-keyword"&gt;throw&lt;/span&gt; &lt;span class="cs-keyword"&gt;new&lt;/span&gt; ArgumentOutOfRangeException&lt;br /&gt;     (&lt;br /&gt;         &lt;span class="cpp-string"&gt;"control",&lt;br /&gt;         control,&lt;br /&gt;         INTERPOLATION_RANGE + "\n" + ARGUMENT_VALUE + control&lt;br /&gt;     );&lt;br /&gt;  }&lt;br /&gt;  else&lt;br /&gt;  {&lt;br /&gt;     return&lt;br /&gt;     (&lt;br /&gt;        new Vector&lt;br /&gt;        (&lt;br /&gt;            v1.X * (1-control) + v2.X * control,&lt;br /&gt;            v1.Y * (1-control) + v2.Y * control,&lt;br /&gt;            v1.Z * (1-control) + v2.Z * control&lt;br /&gt;         )&lt;br /&gt;     );&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public Vector Interpolate(Vector other, double control)&lt;br /&gt;{&lt;br /&gt;  return Interpolate(this, other, control);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private const string INTERPOLATION_RANGE = "Control parameter must be a value between 0 &amp; 1"&lt;/span&gt;;&lt;/pre&gt;  &lt;p&gt;&lt;strong&gt;Distance&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This method finds the distance between two positional vectors using Pythagoras theorem.&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image026.gif" height="115" width="411" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image027.gif" border="0" height="20" width="400" /&gt;&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; &lt;span class="cs-keyword"&gt;double&lt;/span&gt; Distance(Vector v1, Vector v2)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt;&lt;br /&gt;  (&lt;br /&gt;     Math.Sqrt&lt;br /&gt;     (&lt;br /&gt;         (v1.X - v2.X) * (v1.X - v2.X) +&lt;br /&gt;         (v1.Y - v2.Y) * (v1.Y - v2.Y) +&lt;br /&gt;         (v1.Z - v2.Z) * (v1.Z - v2.Z)&lt;br /&gt;     )&lt;br /&gt;  );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;double&lt;/span&gt; Distance(Vector other)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt; Distance(&lt;span class="cs-keyword"&gt;this&lt;/span&gt;, other);&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;&lt;strong&gt;Absolute&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This method finds the absolute value of a vector by applying the Abs method to each of the component parts. This is not the same as magnitude.&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; Vector Abs(Vector v1)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt;&lt;br /&gt;  (&lt;br /&gt;     &lt;span class="cs-keyword"&gt;new&lt;/span&gt; Vector&lt;br /&gt;     (&lt;br /&gt;        Math.Abs(v1.X),&lt;br /&gt;        Math.Abs(v1.Y),&lt;br /&gt;        Math.Abs(v1.Z)&lt;br /&gt;     )&lt;br /&gt;  );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; Vector Abs()&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt; Abs(&lt;span class="cs-keyword"&gt;this&lt;/span&gt;);&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;&lt;strong&gt;Angle&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This method finds the angle between two vectors using normalization and dot product.&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image028.gif" height="177" width="412" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image029.gif" border="0" height="20" width="200" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image030.gif" border="0" height="40" width="250" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image031.gif" border="0" height="20" width="200" /&gt;&lt;/p&gt;  &lt;p&gt;^ refers to a normalized (unit) vector.&lt;/p&gt;  &lt;p&gt;|| refers to the magnitude of a Vector.&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; &lt;span class="cs-keyword"&gt;double&lt;/span&gt; Angle(Vector v1, Vector v2)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt;&lt;br /&gt;  (&lt;br /&gt;     Math.Acos&lt;br /&gt;     (&lt;br /&gt;        Normalize(v1).DotProduct(Normalize(v2))&lt;br /&gt;     )&lt;br /&gt;  );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;double&lt;/span&gt; Angle(Vector other)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt; Angle(&lt;span class="cs-keyword"&gt;this&lt;/span&gt;, other);&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;&lt;strong&gt;Max and Min&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;These methods compare the magnitude of two vectors and return the vector with the largest or smallest magnitude respectively.&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; Vector Max(Vector v1, Vector v2)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;if&lt;/span&gt; (v1 &gt;= v2){&lt;span class="cs-keyword"&gt;return&lt;/span&gt; v1;}&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt; v2;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; Vector Max(Vector other)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt; Max(&lt;span class="cs-keyword"&gt;this&lt;/span&gt;, other);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; Vector Min(Vector v1, Vector v2)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;if&lt;/span&gt; (v1 &lt;= v2){&lt;span class="cs-keyword"&gt;return&lt;/span&gt; v1;}&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt; v2;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; Vector Min(Vector other)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt; Min(&lt;span class="cs-keyword"&gt;this&lt;/span&gt;, other);&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;&lt;strong&gt;Yaw&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This method rotates a vector around the Y axis by a given number of degrees (Euler rotation around Y).&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image032.gif" height="177" width="412" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image033.gif" height="177" width="412" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image034.gif" border="0" height="40" width="118" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image035.gif" border="0" height="20" width="156" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image036.gif" border="0" height="20" width="250" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image037.gif" border="0" height="40" width="250" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image038.gif" border="0" height="20" width="250" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image039.gif" border="0" height="20" width="30" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image040.gif" border="0" height="40" width="120" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image041.gif" border="0" height="20" width="150" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image042.gif" border="0" height="20" width="200" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image043.gif" border="0" height="40" width="250" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image044.gif" border="0" height="20" width="200" /&gt;&lt;/p&gt;  &lt;p&gt;The hypotenuse (R) cancels out in the equation.&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; Vector Yaw(Vector v1, &lt;span class="cs-keyword"&gt;double&lt;/span&gt; degree)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;double&lt;/span&gt; x = ( v1.Z * Math.Sin(degree) ) + ( v1.X * Math.Cos(degree) );&lt;br /&gt;  &lt;span class="cs-keyword"&gt;double&lt;/span&gt; y = v1.Y;&lt;br /&gt;  &lt;span class="cs-keyword"&gt;double&lt;/span&gt; z = ( v1.Z * Math.Cos(degree) ) - ( v1.X * Math.Sin(degree) );&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt; &lt;span class="cs-keyword"&gt;new&lt;/span&gt; Vector(x, y, z);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;void&lt;/span&gt; Yaw(&lt;span class="cs-keyword"&gt;double&lt;/span&gt; degree)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;this&lt;/span&gt; = Yaw(&lt;span class="cs-keyword"&gt;this&lt;/span&gt;, degree);&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;This method directly affects the instance from which the method was called.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Pitch&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This method rotates a vector around the X axis by a given number of degrees (Euler rotation around X).&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image045.gif" height="177" width="412" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image046.gif" height="177" width="412" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image047.gif" border="0" height="20" width="30" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image048.gif" border="0" height="40" width="122" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image049.gif" border="0" height="20" width="156" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image050.gif" border="0" height="20" width="278" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image051.gif" border="0" height="40" width="266" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image052.gif" border="0" height="20" width="280" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image053.gif" border="0" height="40" width="118" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image054.gif" border="0" height="20" width="154" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image055.gif" border="0" height="20" width="288" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image056.gif" border="0" height="40" width="274" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image057.gif" border="0" height="20" width="277" /&gt;&lt;/p&gt;  &lt;p&gt;The hypotenuse (R) cancels out in the equation.&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; Vector Pitch(Vector v1, &lt;span class="cs-keyword"&gt;double&lt;/span&gt; degree)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;double&lt;/span&gt; x = v1.X;&lt;br /&gt;  &lt;span class="cs-keyword"&gt;double&lt;/span&gt; y = ( v1.Y * Math.Cos(degree) ) - ( v1.Z * Math.Sin(degree) );&lt;br /&gt;  &lt;span class="cs-keyword"&gt;double&lt;/span&gt; z = ( v1.Y * Math.Sin(degree) ) + ( v1.Z * Math.Cos(degree) );&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt; &lt;span class="cs-keyword"&gt;new&lt;/span&gt; Vector(x, y, z);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;void&lt;/span&gt; Pitch(&lt;span class="cs-keyword"&gt;double&lt;/span&gt; degree)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;this&lt;/span&gt; = Pitch(&lt;span class="cs-keyword"&gt;this&lt;/span&gt;, degree);&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;This method directly affects the instance from which the method was called.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Roll&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This method rotates a vector around the Z axis by a given number of degrees (Euler rotation around Z).&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image058.gif" height="177" width="412" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image046.gif" height="177" width="412" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image059.gif" border="0" height="40" width="120" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image060.gif" border="0" height="20" width="156" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image061.gif" border="0" height="20" width="276" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image062.gif" border="0" height="40" width="264" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image063.gif" border="0" height="20" width="280" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image064.gif" border="0" height="40" width="120" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image065.gif" border="0" height="20" width="156" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image066.gif" border="0" height="20" width="290" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image067.gif" border="0" height="40" width="276" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image068.gif" border="0" height="20" width="282" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image069.gif" border="0" height="20" width="30" /&gt;&lt;/p&gt;  &lt;p&gt;The hypotenuse (R) cancels out in the equation.&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; Vector Roll(Vector v1, &lt;span class="cs-keyword"&gt;double&lt;/span&gt; degree)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;double&lt;/span&gt; x = ( v1.X * Math.Cos(degree) ) - ( v1.Y * Math.Sin(degree) );&lt;br /&gt;  &lt;span class="cs-keyword"&gt;double&lt;/span&gt; y = ( v1.X * Math.Sin(degree) ) + ( v1.Y * Math.Cos(degree) );&lt;br /&gt;  &lt;span class="cs-keyword"&gt;double&lt;/span&gt; z = v1.Z;&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt; &lt;span class="cs-keyword"&gt;new&lt;/span&gt; Vector(x, y, z);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;void&lt;/span&gt; Roll(&lt;span class="cs-keyword"&gt;double&lt;/span&gt; degree)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;this&lt;/span&gt; = Roll(&lt;span class="cs-keyword"&gt;this&lt;/span&gt;, degree);&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;This method directly affects the instance from which the method was called.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Back-face&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This method interprets a vector as a face normal and determines whether the normal represents a back facing plane given a line-of-sight vector. A back facing plane will be invisible in a rendered scene and as such can be except from many scene calculations.&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image070.gif" height="192" width="495" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/useritems/VectorType/image071.gif" border="0" height="20" width="350" /&gt;&lt;/p&gt;  &lt;p&gt;If &lt;img src="http://www.codeproject.com/useritems/VectorType/image072.gif" border="0" height="20" width="30" /&gt; then if &lt;img src="http://www.codeproject.com/useritems/VectorType/image073.gif" border="0" height="20" width="200" /&gt;&lt;/p&gt;  &lt;p&gt;If &lt;img src="http://www.codeproject.com/useritems/VectorType/image074.gif" border="0" height="20" width="30" /&gt; then if &lt;img src="http://www.codeproject.com/useritems/VectorType/image075.gif" border="0" height="20" width="200" /&gt;&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; &lt;span class="cs-keyword"&gt;bool&lt;/span&gt; IsBackFace(Vector normal, Vector lineOfSight)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt; normal.DotProduct(lineOfSight) &lt; &lt;span class="cs-literal"&gt;0&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;bool&lt;/span&gt; IsBackFace(Vector lineOfSight)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt; IsBackFace(&lt;span class="cs-keyword"&gt;this&lt;/span&gt;, lineOfSight);&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;&lt;strong&gt;Perpendicular&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This method checks if two vectors are perpendicular (i.e. if one vector is the normal of the other).&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; &lt;span class="cs-keyword"&gt;bool&lt;/span&gt; IsPerpendicular(Vector v1, Vector v2)&lt;br /&gt;{&lt;br /&gt; &lt;span class="cs-keyword"&gt;return&lt;/span&gt; v1.DotProduct(v2) == &lt;span class="cs-literal"&gt;0&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;bool&lt;/span&gt; IsPerpendicular(Vector other)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt; IsPerpendicular(&lt;span class="cs-keyword"&gt;this&lt;/span&gt;, other);&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;&lt;strong&gt;Sum components&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This method simply adds together the vector components (x, y, z).&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; &lt;span class="cs-keyword"&gt;double&lt;/span&gt; SumComponents(Vector v1)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt; (v1.X + v1.Y + v1.Z);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;double&lt;/span&gt; SumComponents()&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt; SumComponents(&lt;span class="cs-keyword"&gt;this&lt;/span&gt;);&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;&lt;strong&gt;To Power&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This method multiplies the vectors components to a given power.&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; Vector Pow(Vector v1, &lt;span class="cs-keyword"&gt;double&lt;/span&gt; power)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt;&lt;br /&gt;  (&lt;br /&gt;     &lt;span class="cs-keyword"&gt;new&lt;/span&gt; Vector&lt;br /&gt;     (&lt;br /&gt;        Math.Pow(v1.X, power),&lt;br /&gt;        Math.Pow(v1.Y, power),&lt;br /&gt;        Math.Pow(v1.Z, power)&lt;br /&gt;     )&lt;br /&gt;  );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;void&lt;/span&gt; Pow(&lt;span class="cs-keyword"&gt;double&lt;/span&gt; power)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;this&lt;/span&gt; = Pow(&lt;span class="cs-keyword"&gt;this&lt;/span&gt;, power);&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;&lt;strong&gt;Square root&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This method applies the square root function to each of the vectors components.&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; Vector Sqrt(Vector v1)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt;&lt;br /&gt;  (&lt;br /&gt;     &lt;span class="cs-keyword"&gt;new&lt;/span&gt; Vector&lt;br /&gt;     (&lt;br /&gt;        Math.Sqrt(v1.X),&lt;br /&gt;        Math.Sqrt(v1.Y),&lt;br /&gt;        Math.Sqrt(v1.Z)&lt;br /&gt;     )&lt;br /&gt;  );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;void&lt;/span&gt; Sqrt()&lt;br /&gt;{&lt;br /&gt;&lt;span class="cs-keyword"&gt;this&lt;/span&gt; = Sqrt(&lt;span class="cs-keyword"&gt;this&lt;/span&gt;);&lt;br /&gt;}&lt;/pre&gt;  &lt;h2&gt;Usability functions&lt;/h2&gt;  &lt;p&gt;For completeness a number of standardised methods have been added complete the type.&lt;/p&gt;  &lt;p&gt;To get a textual description of the type:&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;override&lt;/span&gt; &lt;span class="cs-keyword"&gt;string&lt;/span&gt; ToString()&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;string&lt;/span&gt; output = &lt;span class="cs-keyword"&gt;null&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;  &lt;span class="cs-keyword"&gt;if&lt;/span&gt; (IsUnitVector()){output += UNIT_VECTOR;}&lt;br /&gt;  &lt;span class="cs-keyword"&gt;else&lt;/span&gt; {output += POSITIONAL_VECTOR;}&lt;br /&gt;&lt;br /&gt;  output += &lt;span class="cs-keyword"&gt;string&lt;/span&gt;.Format( &lt;span class="cpp-string"&gt;"( x={0}, y={1}, z={2} )", X, Y, Z );&lt;br /&gt;  output += MAGNITUDE + Magnitude();&lt;br /&gt;&lt;br /&gt;  return output;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private const string UNIT_VECTOR = "Unit vector composing of ";&lt;br /&gt;private const string POSITIONAL_VECTOR = "Positional vector composing of ";&lt;br /&gt;private const string MAGNITUDE = " of magnitude "&lt;/span&gt;;&lt;/pre&gt;  &lt;p&gt;To produce a hashcode for system use (required in order to implement comparator operations (i.e. ==, !=)):&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;override&lt;/span&gt; &lt;span class="cs-keyword"&gt;int&lt;/span&gt; GetHashCode()&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;return&lt;/span&gt;&lt;br /&gt;  (&lt;br /&gt;     (&lt;span class="cs-keyword"&gt;int&lt;/span&gt;)((X + Y + Z) % &lt;span class="cs-clrtype"&gt;Int32&lt;/span&gt;.MaxValue)&lt;br /&gt;  );&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;Check for equality (standardised version of == operatator):&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;override&lt;/span&gt; &lt;span class="cs-keyword"&gt;bool&lt;/span&gt; Equals(&lt;span class="cs-keyword"&gt;object&lt;/span&gt; other)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-comment"&gt;// Check object other is a Vector object&lt;/span&gt;&lt;br /&gt;  &lt;span class="cs-keyword"&gt;if&lt;/span&gt;(other &lt;span class="cs-keyword"&gt;is&lt;/span&gt; Vector)&lt;br /&gt;  {&lt;br /&gt;     &lt;span class="cs-comment"&gt;// Convert object to Vector&lt;/span&gt;&lt;br /&gt;     Vector otherVector = (Vector)other;&lt;br /&gt;     &lt;span class="cs-comment"&gt;// Check for equality&lt;/span&gt;&lt;br /&gt;     &lt;span class="cs-keyword"&gt;return&lt;/span&gt; otherVector == &lt;span class="cs-keyword"&gt;this&lt;/span&gt;;&lt;br /&gt;  }&lt;br /&gt;  &lt;span class="cs-keyword"&gt;else&lt;/span&gt;&lt;br /&gt;  {&lt;br /&gt;     &lt;span class="cs-keyword"&gt;return&lt;/span&gt; &lt;span class="cs-keyword"&gt;false&lt;/span&gt;;&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;Comparison method for two vectors which returns:&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;-1 if the magnitude is less than the others magnitude &lt;/li&gt;&lt;li&gt;0 if the magnitude equals the magnitude of the other &lt;/li&gt;&lt;li&gt;1 if the magnitude is greater than the magnitude of the other &lt;/li&gt;&lt;/ul&gt;  &lt;p&gt;This allows the &lt;code&gt;Vector&lt;/code&gt; type to implement the &lt;code&gt;IComparable&lt;/code&gt; interface.&lt;/p&gt;  &lt;pre lang="cs"&gt;Public &lt;span class="cs-keyword"&gt;int&lt;/span&gt; CompareTo(&lt;span class="cs-keyword"&gt;object&lt;/span&gt; other)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="cs-keyword"&gt;if&lt;/span&gt;(other &lt;span class="cs-keyword"&gt;is&lt;/span&gt; Vector)&lt;br /&gt;  {&lt;br /&gt;     Vector otherVector = (Vector)other;&lt;br /&gt;&lt;br /&gt;     &lt;span class="cs-keyword"&gt;if&lt;/span&gt;( &lt;span class="cs-keyword"&gt;this&lt;/span&gt; &lt; class="cs-keyword"&gt;return&lt;/span&gt; -&lt;span class="cs-literal"&gt;1&lt;/span&gt;; }&lt;br /&gt;     &lt;span class="cs-keyword"&gt;else&lt;/span&gt; &lt;span class="cs-keyword"&gt;if&lt;/span&gt;( &lt;span class="cs-keyword"&gt;this&lt;/span&gt; &gt; otherVector ) { &lt;span class="cs-keyword"&gt;return&lt;/span&gt; &lt;span class="cs-literal"&gt;1&lt;/span&gt;; }&lt;br /&gt;&lt;br /&gt;     &lt;span class="cs-keyword"&gt;return&lt;/span&gt; &lt;span class="cs-literal"&gt;0&lt;/span&gt;;&lt;br /&gt;  }&lt;br /&gt;  &lt;span class="cs-keyword"&gt;else&lt;/span&gt;&lt;br /&gt;  {&lt;br /&gt;     &lt;span class="cs-comment"&gt;// Error condition: other is not a Vector object&lt;/span&gt;&lt;br /&gt;     &lt;span class="cs-keyword"&gt;throw&lt;/span&gt; &lt;span class="cs-keyword"&gt;new&lt;/span&gt; ArgumentException&lt;br /&gt;     (&lt;br /&gt;        &lt;span class="cs-comment"&gt;// Error message includes information about the actual type of the argument&lt;/span&gt;&lt;br /&gt;        NON_VECTOR_COMPARISON + &lt;span class="cpp-string"&gt;"\n" + ARGUMENT_TYPE + other.GetType().ToString(),&lt;br /&gt;        "other"&lt;br /&gt;     );&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private const string NON_VECTOR_COMPARISON = "Cannot compare a Vector to a non-Vector";&lt;br /&gt;private const string ARGUMENT_TYPE = "The argument provided is a type of "&lt;/span&gt;;&lt;/pre&gt;  &lt;p&gt;&lt;strong&gt;Standard Cartesian vectors&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Finaly four standard vector constants are defined:&lt;/p&gt;  &lt;pre lang="cs"&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; &lt;span class="cs-keyword"&gt;readonly&lt;/span&gt; Vector origin = &lt;span class="cs-keyword"&gt;new&lt;/span&gt; Vector(&lt;span class="cs-literal"&gt;0&lt;/span&gt;,&lt;span class="cs-literal"&gt;0&lt;/span&gt;,&lt;span class="cs-literal"&gt;0&lt;/span&gt;);&lt;br /&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; &lt;span class="cs-keyword"&gt;readonly&lt;/span&gt; Vector xAxis = &lt;span class="cs-keyword"&gt;new&lt;/span&gt; Vector(&lt;span class="cs-literal"&gt;1&lt;/span&gt;,&lt;span class="cs-literal"&gt;0&lt;/span&gt;,&lt;span class="cs-literal"&gt;0&lt;/span&gt;);&lt;br /&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; &lt;span class="cs-keyword"&gt;readonly&lt;/span&gt; Vector yAxis = &lt;span class="cs-keyword"&gt;new&lt;/span&gt; Vector(&lt;span class="cs-literal"&gt;0&lt;/span&gt;,&lt;span class="cs-literal"&gt;1&lt;/span&gt;,&lt;span class="cs-literal"&gt;0&lt;/span&gt;);&lt;br /&gt;&lt;span class="cs-keyword"&gt;public&lt;/span&gt; &lt;span class="cs-keyword"&gt;static&lt;/span&gt; &lt;span class="cs-keyword"&gt;readonly&lt;/span&gt; Vector zAxis = &lt;span class="cs-keyword"&gt;new&lt;/span&gt; Vector(&lt;span class="cs-literal"&gt;0&lt;/span&gt;,&lt;span class="cs-literal"&gt;0&lt;/span&gt;,&lt;span class="cs-literal"&gt;1&lt;/span&gt;);&lt;/pre&gt;  &lt;h2&gt;Summary&lt;/h2&gt;  &lt;p&gt;We now have a &lt;code&gt;Vector&lt;/code&gt; type with the following functionality:&lt;/p&gt;  &lt;ul&gt;Constructors  &lt;ul&gt;&lt;li&gt;&lt;code&gt;Vector(&lt;span class="cpp-keyword"&gt;double&lt;/span&gt; x, &lt;span class="cpp-keyword"&gt;double&lt;/span&gt; y, &lt;span class="cpp-keyword"&gt;double&lt;/span&gt; z)&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;Vector(&lt;span class="cpp-keyword"&gt;double&lt;/span&gt;[] xyz)&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;Vector(Vector v1)&lt;/code&gt; &lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;  &lt;ul&gt;Properties  &lt;ul&gt;&lt;li&gt;&lt;code&gt;X&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;Y&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;Z&lt;/code&gt; &lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;  &lt;ul&gt;Operators  &lt;ul&gt;&lt;li&gt;Indexer &lt;/li&gt;&lt;li&gt;&lt;code&gt;+&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;-&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;==&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;!=&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;*&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;/&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;&lt;&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;&gt;&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;&lt;=&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;&gt;=&lt;/code&gt; &lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;  &lt;ul&gt;Static methods  &lt;ul&gt;&lt;li&gt;&lt;code&gt;CrossProduct&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;DotProduct&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;Magnitude&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;Normalize&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;IsUnitVector&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;Interpolate&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;Distance&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;Abs&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;Angle&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;Max&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;Min&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;Yaw&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;Pitch&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;Roll&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;IsBackFace&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;IsPerpendicular&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;SumComponents&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;Sqrt&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;Pow&lt;/code&gt; &lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;  &lt;ul&gt;Instance methods which directly affect the instance variables  &lt;ul&gt;&lt;li&gt;&lt;code&gt;Magnitude&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;Normalize&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;Yaw&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;Pitch&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;Roll&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;Sqrt&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;Pow&lt;/code&gt; &lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;  &lt;ul&gt;Instance methods which return a new object or type  &lt;ul&gt;&lt;li&gt;&lt;code&gt;CrossProduct&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;DotProduct&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;IsUnitVector&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;Interpolate&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;Distance&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;Abs&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;Angle&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;Max&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;Min&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;IsBackFace&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;IsPerpendicular&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;SumComponents&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;CompareTo&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;Equals&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;ToString&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;GetHashCode&lt;/code&gt; &lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1192972388107063553-1128843629503523913?l=chamildz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chamildz.blogspot.com/feeds/1128843629503523913/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1192972388107063553&amp;postID=1128843629503523913' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1192972388107063553/posts/default/1128843629503523913'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1192972388107063553/posts/default/1128843629503523913'/><link rel='alternate' type='text/html' href='http://chamildz.blogspot.com/2007/02/vector-type-for-c.html' title='A Vector Type for C#'/><author><name>Chamil</name><uri>http://www.blogger.com/profile/00204727013782891667</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1192972388107063553.post-4590070258913230407</id><published>2007-02-02T01:52:00.000-08:00</published><updated>2007-02-02T02:05:45.929-08:00</updated><title type='text'>Artificial intelligence network load balancing using Ant Colony Optimisation - C# Algorithms</title><content type='html'>&lt;span name="intelliTxt" id="intelliTXT"&gt;&lt;ul class="download"&gt;&lt;li&gt; &lt;a href="http://www.codeproject.com/useritems/Ant_Colony_Optimisation/ACO.zip"&gt;Download source code - 798 Kb&lt;/a&gt;  &lt;/li&gt;&lt;/ul&gt;   &lt;p&gt;&lt;a href="http://www.codeproject.com/useritems/Ant_Colony_Optimisation/screen.jpg"&gt;&lt;img alt="Sample Image - Ant_Colony_Optimisation.jpg" src="http://www.codeproject.com/useritems/Ant_Colony_Optimisation/Ant_Colony_Optimisation.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;     &lt;h2&gt; Introduction&lt;/h2&gt;  &lt;p nd="1"&gt; Ants first evolved around 120 million years ago, take form in over 11,400 different species and are considered one of the most successful insects due to their highly organised colonies, sometimes consisting of millions of ants. &lt;/p&gt;&lt;p nd="2"&gt;One particular notability of ants is their ability to create "ant streets". Long, bi-directional lanes of single file pathways in which they navigate landscapes in order to reach a destination in optimal time. These ever-changing networks are made possible by the use of pheromones which guide them using a shortest path mechanism. This technique allows an adaptive routing system which is updated should a more optimal path be found or an obstruction placed across an existing pathway. &lt;/p&gt; &lt;p nd="3"&gt;Computer scientists began researching the behaviour of ants in the early 1990's to discover new routing algorithms. The result of these studies is Ant Colony Optimisation (ACO) and in the case of well implemented ACO techniques, optimal performance is comparative to existing top-performing routing algorithms. &lt;/p&gt; &lt;p nd="4"&gt;This article details how ACO can be used to dynamically route traffic efficiently. An efficient routing algorithm will minimise the number of nodes that a call will need to connect to in order to be completed thus; minimising network load and increasing reliability. An implementation of ANTNet based on Marco Dorigo &amp; Thomas stützle has been designed and through this a number of visually aided test were produced to compare the genetic algorithm to a non-generic algorithm. The report will final conclude with a summary of how the algorithm perform and how it could be further optimised. &lt;/p&gt;   &lt;h2&gt;Background &lt;/h2&gt;  &lt;p nd="5"&gt;&lt;strong&gt; &lt;/strong&gt;Electronic communication networks can be categorised as either circuit-switched or packet-switched. Circuit-switched networks rely on a dedicated connection from source to destination which is made once at start-up and remains constant until the tear-down of the connection. An example of a circuit switched network would be British Telecoms telephone network. Packet-switched networks work quite differently however and all data to be transmitted is divided into segments and sent as data-packet. Data-packets can arrive out of order in a packets-switched network with a variety of paths taken through different nodes in order to get to their destination. The internet and office local area networks are both good examples of packet-switched networks. &lt;/p&gt;&lt;p nd="6"&gt;A number of techniques can be employed to optimise the flow of traffic around a network. Such techniques include flow and congestion control where nodes action packet acknowledgements from destination nodes to either ramp-up or decrease packet transmission speed. The area of interest in this report concentrates on the idea of network routing and routing tables. These tables hold information used by a routing algorithm to make a local forwarding decision for the packet on the next node it will visit in order to reach its final destination. &lt;/p&gt; &lt;p nd="7"&gt;One of the issues with network routing (especially in very large networks such as the internet) is adaptability. Not only can traffic be unpredictably high but the structure of a network can change as old nodes are removed and new nodes added. This perhaps makes it almost impossible to find a combination of constant parameters to route a network optimally. &lt;/p&gt; &lt;h5&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;Routing algorithms &lt;/strong&gt;&lt;/h5&gt; &lt;p nd="8"&gt;&lt;strong&gt; &lt;/strong&gt;Packet-switched networks dynamically guide packets to their destination via routing tables stored in a link state and are selected via a link state algorithm. &lt;/p&gt; &lt;p nd="9"&gt;&lt;strong&gt; &lt;/strong&gt;The Link state algorithm works by giving every node in the network a connectivity graph of the network. This graph depicts which nodes are directly connected. Values are stored for connected nodes in map which represent the shortest path to other nodes. One such link state algorithm used in network routing is Dijkstras algorithm. When a path between two nodes is found, its weight is updated in the table. Should a shorter path be found the new optimal weight will be updated to the table replacing the old value. &lt;/p&gt; &lt;p nd="10"&gt;The algorithm allows traffic to be routed around the network whilst connecting to the least number nodes as possible. The system works but doesn't take into account influx of traffic and load balancing. &lt;/p&gt; &lt;h5&gt;&lt;strong&gt;Introducing ANTNet&lt;/strong&gt;&lt;/h5&gt; &lt;p nd="11"&gt;By replacing Dijkstras algorithm with a generic algorithm, paths taken by calls could be scored by how short of a path they took, that way if they were queued on a busy network they would perform badly. Consequently other paths would score relative and be chosen. This would work in real time and allow the routing system to adapt as packets are transmitted ANTNet uses virtual pheromone tables much like when an ant follows a path dropping pheromones to re-enforce it. The quicker the ants move down a path the more throughput of ants thus; a greater concentration of pheromones. In the same way pheromone tables in ANTNet allow fast routes to score a higher chance of being selected whilst the less optimal route scores a low chance of being selected. &lt;/p&gt; &lt;p nd="12"&gt;The idea behind ANTNet is when a call is placed an Ant will traverse across the network using a link-state deterministic algorithm. Every node holds a pheromone table for all other nodes of the network. Each pheromone table holds a list of table entries containing all the connected nodes of the current node. &lt;/p&gt; &lt;h5&gt;&lt;strong&gt;The algorithm &lt;/strong&gt;&lt;/h5&gt; &lt;p nd="13"&gt;To begin with, each possible path has an even likelihood of being chosen. An ant is placed on a network of 4 nodes with the source node of 1 and destination node 2. A chance mechanism is invoked and a path is chosen.&lt;/p&gt; &lt;table align="center" cellpadding="0" cellspacing="0"&gt;   &lt;tbody&gt;&lt;tr&gt;     &lt;td height="274" valign="top" width="325"&gt;&lt;p align="center"&gt;&lt;img src="http://www.codeproject.com/useritems/Ant_Colony_Optimisation/Graph1.png" height="307" width="372" /&gt;&lt;/p&gt;     &lt;p nd="14" align="center"&gt; Figure 3.1 - The network graph &lt;/p&gt;&lt;/td&gt;     &lt;td valign="top" width="325"&gt;                                   &lt;p&gt;&lt;br /&gt;       &lt;br /&gt;      &lt;/p&gt;       &lt;table align="center" border="1" cellpadding="0" cellspacing="0"&gt;         &lt;tbody&gt;&lt;tr&gt;           &lt;td valign="top" width="103"&gt;&lt;p nd="15"&gt; Next Node &lt;/p&gt;&lt;/td&gt;           &lt;td valign="top" width="156"&gt;&lt;p nd="16"&gt; % chance &lt;/p&gt;&lt;/td&gt;         &lt;/tr&gt;         &lt;tr&gt;           &lt;td valign="top" width="103"&gt;&lt;p nd="17"&gt; 2 &lt;/p&gt;&lt;/td&gt;           &lt;td valign="top" width="156"&gt;&lt;p nd="18"&gt; 33.33333% &lt;/p&gt;&lt;/td&gt;         &lt;/tr&gt;         &lt;tr&gt;           &lt;td valign="top" width="103"&gt;&lt;p nd="19"&gt; 3 &lt;/p&gt;&lt;/td&gt;           &lt;td valign="top" width="156"&gt;&lt;p nd="20"&gt; 33.33333% &lt;/p&gt;&lt;/td&gt;         &lt;/tr&gt;         &lt;tr&gt;           &lt;td valign="top" width="103"&gt;&lt;p nd="21"&gt; 4 &lt;/p&gt;&lt;/td&gt;           &lt;td valign="top" width="156"&gt;&lt;p nd="22"&gt; 33.33333% &lt;/p&gt;&lt;/td&gt;         &lt;/tr&gt;       &lt;/tbody&gt;&lt;/table&gt;          &lt;p nd="23" align="center"&gt; Table 3.1 - Pheromone table for node 1 &lt;/p&gt;&lt;/td&gt;   &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;p nd="24"&gt;In this case node 2 has been selected [figure 3.2] and the ant arrives at its source destination. &lt;/p&gt; &lt;p nd="25"&gt; The ant then moves and updates the pheromone tables for the visited nodes with higher (and more mathematically biased) value. This would be calculated for figure 3.2 and table 3.2 in the following way:&lt;/p&gt; &lt;ul&gt;&lt;li nd="26"&gt; Node 2 was the final destination &lt;/li&gt;&lt;li nd="27"&gt; It took 1 hop to get to its destination &lt;/li&gt;&lt;li nd="28"&gt; Divide 1 (hop) by 100 : 100% &lt;/li&gt;&lt;li nd="29"&gt; Add 100 to the probability value of node 2 (currently 33.3333) : 133.3333 &lt;/li&gt;&lt;li nd="30"&gt; Add the values of the other nodes to 133.3333 (133.3333+ 33.3333 + 33.3333) : 200 (approximately) &lt;/li&gt;&lt;li nd="31"&gt; Calculate the ratio : ratio = 100/200 0.5 &lt;/li&gt;&lt;li nd="32"&gt; Set the probability of the node to its current value multiplied by the ratio &lt;/li&gt;&lt;ul&gt;&lt;li nd="33"&gt; Node 2: 133.3333 * ratio (0.5) = 66.6666% &lt;/li&gt;&lt;li nd="34"&gt; Node 3: 33.3333 * ratio (0.5) = 16.6666% &lt;/li&gt;&lt;li nd="35"&gt; Node 4: 33.3333 * ratio (0.5) = 16.6666% &lt;/li&gt;&lt;/ul&gt;&lt;li nd="36"&gt; Node 2 (66.6666%) + Node 3 (16.6666%) + Node 4 (16.6666%) = 99.9999% &lt;/li&gt;&lt;/ul&gt; &lt;p nd="37"&gt; The system isn't 100% accurate as the total will never add up to exactly 100% but it will be close enough to allow accuracy within the level required.&lt;/p&gt; &lt;p nd="38"&gt; The following diagram depicts how the path and pheromone table after the update has taken place.&lt;/p&gt; &lt;table align="center" cellpadding="0" cellspacing="0"&gt;   &lt;tbody&gt;&lt;tr&gt;     &lt;td height="283" valign="top" width="325"&gt;&lt;p align="center"&gt;  &lt;/p&gt;         &lt;p align="center"&gt;&lt;img src="http://www.codeproject.com/useritems/Ant_Colony_Optimisation/Graph2.png" height="307" width="372" /&gt;&lt;/p&gt;     &lt;p nd="39" align="center"&gt; Figure 3.2 &lt;/p&gt;&lt;/td&gt;     &lt;td valign="top" width="325"&gt;                                          &lt;p&gt;&lt;br /&gt;      &lt;/p&gt;       &lt;table align="center" border="1" cellpadding="0" cellspacing="0"&gt;         &lt;tbody&gt;&lt;tr&gt;           &lt;td valign="top" width="103"&gt;&lt;p nd="40"&gt; Next Node &lt;/p&gt;&lt;/td&gt;           &lt;td valign="top" width="156"&gt;&lt;p nd="41"&gt; % chance &lt;/p&gt;&lt;/td&gt;         &lt;/tr&gt;         &lt;tr&gt;           &lt;td valign="top" width="103"&gt;&lt;p nd="42"&gt; 2 &lt;/p&gt;&lt;/td&gt;           &lt;td valign="top" width="156"&gt;&lt;p nd="43"&gt; 66.6666% &lt;/p&gt;&lt;/td&gt;         &lt;/tr&gt;         &lt;tr&gt;           &lt;td valign="top" width="103"&gt;&lt;p nd="44"&gt; 3 &lt;/p&gt;&lt;/td&gt;           &lt;td valign="top" width="156"&gt;&lt;p nd="45"&gt; 16.6666% &lt;/p&gt;&lt;/td&gt;         &lt;/tr&gt;         &lt;tr&gt;           &lt;td valign="top" width="103"&gt;&lt;p nd="46"&gt; 4 &lt;/p&gt;&lt;/td&gt;           &lt;td valign="top" width="156"&gt;&lt;p nd="47"&gt; 16.6666% &lt;/p&gt;&lt;/td&gt;         &lt;/tr&gt;       &lt;/tbody&gt;&lt;/table&gt;         &lt;p nd="48" align="center"&gt; Table 3.2 &lt;/p&gt;&lt;/td&gt;   &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;h5&gt;&lt;strong&gt;The program&lt;/strong&gt;&lt;/h5&gt; &lt;p nd="49"&gt; For the purpose of this program a bi-directional, un-weighted topological network consisting of 30 nodes has been created and closely resembles the British Synchronous Digital Hierarchy (SDH) network. After a basic number of parameters have been set the simulation is run. Firstly all pheromone tables are defaulted to equal weights and then calls are generated and placed on the network. Initially the routes chosen are random. If a call cannot connect to a node it is forced to wait and the wait counter is enumerated to reflect how long (in timer ticks) this was. Once a node has reached its destination node it will work its way backwards altering the local nodes pheromone table as it traverses. The shorter the route taken the greater increase in probability given to its table entry in the pheromone table. This happens repeatedly until the weight of the fastest node is shifted such that slower routes have a very low chance of being chosen.&lt;/p&gt; &lt;p nd="50"&gt;NOTE: in order to compile and run the program you will need to download dotnetcharting from &lt;a href="http://www.dotnetcharting.com/download.aspx"&gt;dotnetcharting.com&lt;/a&gt;&lt;/p&gt; &lt;h5&gt;&lt;strong&gt; Program features &lt;/strong&gt;&lt;/h5&gt;  &lt;ul&gt;&lt;li nd="51"&gt; ANTNet On/Off – Switches the algorithm on and off &lt;/li&gt;&lt;li nd="52"&gt; Simulation Speed – 1 tick p/s – 1,000 tick p/s (or as near speed as the system can run) &lt;/li&gt;&lt;li nd="53"&gt; Total calls to make – Number of completed calls before simulation termination &lt;/li&gt;&lt;li nd="54"&gt; Maximum concurrent calls – number of calls allowed at the same time &lt;/li&gt;&lt;li nd="55"&gt; Node capacity – The number of calls a node can route at once &lt;/li&gt;&lt;li nd="56"&gt; Call duration – The length (in ticks) of a call &lt;/li&gt;&lt;li nd="57"&gt; Reduce I/O – bypasses the network visualisation to increase simulation speed &lt;/li&gt;&lt;li nd="58"&gt; Return on connection – returns the node immediately to source after connection &lt;/li&gt;&lt;li nd="59"&gt; Real-time network load visualisation – view Node ID, capacity and routing state (blue = OFF) &lt;/li&gt;&lt;li nd="60"&gt; Graphing facility with labelling and simulation overlay &lt;/li&gt;&lt;li nd="61"&gt; Render Pheromone Tables to HTML &lt;/li&gt;&lt;/ul&gt; &lt;h5&gt;&lt;strong&gt; Classes &lt;/strong&gt;&lt;/h5&gt; &lt;ul&gt;&lt;li nd="62"&gt;&lt;em&gt; MainForm&lt;/em&gt; – The GUI for the application &lt;/li&gt;&lt;li nd="63"&gt;&lt;em&gt; DrawPanel&lt;/em&gt; – The real-time network visualisation custom control &lt;/li&gt;&lt;li nd="64"&gt;&lt;em&gt; Global&lt;/em&gt; – Contains static variables that are accesses by the application &lt;/li&gt;&lt;li nd="65"&gt;&lt;em&gt; Node&lt;/em&gt; – Represents a Node and holds an array of &lt;em&gt;PheromoneTable&lt;/em&gt; objects for routing &lt;/li&gt;&lt;li nd="66"&gt;&lt;em&gt; Call&lt;/em&gt; – Represents a call on the network and hold a source and destination node &lt;/li&gt;&lt;li nd="67"&gt;&lt;em&gt; Simulation&lt;/em&gt; – Represents a completed simulation and is used for creating graphs &lt;/li&gt;&lt;li nd="68"&gt;&lt;em&gt; PheromoneTable&lt;/em&gt; - A routing table for a Node &lt;/li&gt;&lt;/ul&gt; &lt;p nd="69"&gt;The network contains 30 &lt;em&gt;Nodes&lt;/em&gt; and each &lt;em&gt;Node&lt;/em&gt; contains an array of &lt;em&gt;PheromoneTable&lt;/em&gt; objects, one for every other &lt;em&gt;Node &lt;/em&gt;in the network (29). Every &lt;em&gt;PheromoneTable&lt;/em&gt; contains an array of &lt;em&gt;TableEntries&lt;/em&gt;, one for each &lt;em&gt;Node &lt;/em&gt;connected to the current &lt;em&gt;Node&lt;/em&gt;.&lt;/p&gt; &lt;p nd="70"&gt; The following diagram represents the relationships between classes in the program. &lt;/p&gt; &lt;div align="center"&gt;&lt;img src="http://www.codeproject.com/useritems/Ant_Colony_Optimisation/relationships.png" height="330" width="400" /&gt;&lt;/div&gt;&lt;p nd="71"&gt;   Update the pheromone table&lt;br /&gt; &lt;/p&gt;&lt;div class="smallText" id="premain0" style="width: 100%;"&gt;&lt;span nd="72" preid="0" style="margin-bottom: 0pt;" id="precollapse0"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre nd="73" style="margin-top: 0pt;" id="pre0"&gt;        &lt;span class="cpp-comment"&gt;// returns the next Node of the path&lt;/span&gt;&lt;br /&gt;       public int ProbablePath(ArrayList VisitedNodes)&lt;br /&gt;       {&lt;br /&gt;           &lt;span class="cpp-comment"&gt;// create a random generator&lt;/span&gt;&lt;br /&gt;           Random r = new Random(Global.Seed);&lt;br /&gt;&lt;br /&gt;           double val=0;&lt;br /&gt;           double count = 0;&lt;br /&gt;           double Lastcount = -1;&lt;br /&gt;  &lt;br /&gt;           ArrayList tempTEVector=new ArrayList();&lt;br /&gt;&lt;br /&gt;           &lt;span class="cpp-comment"&gt;// loop through all the connected nodes&lt;/span&gt;&lt;br /&gt;           for(int i=0;i&lt;tableEntry.Length;i++)&lt;br /&gt;           {&lt;br /&gt;               &lt;span class="cpp-comment"&gt;// has the node been visitied?&lt;/span&gt;&lt;br /&gt;               bool v=false;&lt;br /&gt;&lt;br /&gt;               &lt;span class="cpp-comment"&gt;//loop through all the visited nodes&lt;/span&gt;&lt;br /&gt;               for(int j=0;j&lt;VisitedNodes.Count;j++)&lt;br /&gt;               {&lt;br /&gt;                   &lt;span class="cpp-comment"&gt;// if the ID's match then this node has alrady been visited&lt;/span&gt;&lt;br /&gt;                   if(tableEntry[i].NodeID==(int)VisitedNodes[j])&lt;br /&gt;                       v=true;&lt;br /&gt;               }&lt;br /&gt;              &lt;br /&gt;               &lt;span class="cpp-comment"&gt;// If v is false then the node hasnt been visited.. so Add&lt;/span&gt;&lt;br /&gt;               if(!v)&lt;br /&gt;               {&lt;br /&gt;                   &lt;span class="cpp-comment"&gt;// get the node&lt;/span&gt;&lt;br /&gt;                   Node n = Global.Nodes[tableEntry[i].NodeID];&lt;br /&gt;&lt;br /&gt;                   &lt;span class="cpp-comment"&gt;// if the node is accepting connections&lt;/span&gt;&lt;br /&gt;                   if(!n.FullCapacity)&lt;br /&gt;                   {&lt;br /&gt;                       &lt;span class="cpp-comment"&gt;// add the node as a possible candidate&lt;/span&gt;&lt;br /&gt;                       tempTEVector.Add(tableEntry[i]);&lt;br /&gt;                   }&lt;br /&gt;               }&lt;br /&gt;           }&lt;br /&gt;          &lt;br /&gt;           &lt;span class="cpp-comment"&gt;// if all connections have been visited&lt;/span&gt;&lt;br /&gt;           if(tempTEVector.Count==0)&lt;br /&gt;           {&lt;br /&gt;               &lt;span class="cpp-comment"&gt;// loop through all the connected nodes&lt;/span&gt;&lt;br /&gt;               for(int i=0;i&lt;tableEntry.Length;i++)&lt;br /&gt;                   tempTEVector.Add(tableEntry[i]);&lt;br /&gt;           }&lt;br /&gt;&lt;br /&gt;           &lt;span class="cpp-comment"&gt;// get the ceiling amount for probabilities&lt;/span&gt;&lt;br /&gt;           for(int i=0;i&lt;tempTEVector.Count;i++)&lt;br /&gt;               val+= ((TableEntry)tempTEVector[i]).Probablilty;&lt;br /&gt;&lt;br /&gt;           &lt;span class="cpp-comment"&gt;//create randon value&lt;/span&gt;&lt;br /&gt;           val = r.NextDouble()*val;&lt;br /&gt;&lt;br /&gt;           &lt;span class="cpp-comment"&gt;// loop through the temp Table Entryies&lt;/span&gt;&lt;br /&gt;           for(int i=0;i&lt;tempTEVector.Count;i++)&lt;br /&gt;           {&lt;br /&gt;               &lt;span class="cpp-comment"&gt;// increment the count on each loop&lt;/span&gt;&lt;br /&gt;               count += ((TableEntry)tempTEVector[i]).Probablilty;&lt;br /&gt;&lt;br /&gt;               &lt;span class="cpp-comment"&gt;// if the random value falls into delegated range then select that path as the next node&lt;/span&gt;&lt;br /&gt;               if(val&gt;Lastcount &amp;&amp;amp; val &lt; count)&lt;br /&gt;                   return ((TableEntry)tempTEVector[i]).NodeID;&lt;br /&gt;&lt;br /&gt;               &lt;span class="cpp-comment"&gt;// get the value of the last count&lt;/span&gt;&lt;br /&gt;               Lastcount=count;&lt;br /&gt;           }&lt;br /&gt;&lt;br /&gt;           &lt;span class="cpp-comment"&gt;// method should never return here&lt;/span&gt;&lt;br /&gt;           return -1;&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;   Return the next node via the pheromone table&lt;br /&gt; &lt;div class="smallText" id="premain1" style="width: 100%;"&gt;&lt;span nd="75" preid="1" style="margin-bottom: 0pt;" id="precollapse1"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre nd="76" style="margin-top: 0pt;" id="pre1"&gt;        &lt;span class="cpp-comment"&gt;// updates the probabilities of the pheromone table by multiplying the selected &lt;/span&gt;&lt;br /&gt;       &lt;span class="cpp-comment"&gt;// nodes probability by a radio of  newVal&lt;/span&gt;&lt;br /&gt;       public void UpdateProbabilities(double newVal, int EntryTableNodeID)&lt;br /&gt;       {&lt;br /&gt;           TableEntry t;&lt;br /&gt;           double total=0;&lt;br /&gt;&lt;br /&gt;           &lt;span class="cpp-comment"&gt;// loop through all the table entries&lt;/span&gt;&lt;br /&gt;           &lt;span class="cpp-comment"&gt;// get the total enumeration of probabilities and add the new value.&lt;/span&gt;&lt;br /&gt;           &lt;span class="cpp-comment"&gt;// Since this total will be more than 100 a ratio multiplication is&lt;/span&gt;&lt;br /&gt;           &lt;span class="cpp-comment"&gt;// applied. Although these values will not equate to exactly 100% floating&lt;/span&gt;&lt;br /&gt;           &lt;span class="cpp-comment"&gt;// point calculations will be accurate enough at least 99.99999% which is satisfactory&lt;/span&gt;&lt;br /&gt;           for(int j=0;j&lt;tableEntry.Length;j++)&lt;br /&gt;           {&lt;br /&gt;               t = tableEntry[j];&lt;br /&gt;&lt;br /&gt;               &lt;span class="cpp-comment"&gt;// enumerate the total probablility&lt;/span&gt;&lt;br /&gt;               total += t.Probablilty;&lt;br /&gt;              &lt;br /&gt;               &lt;span class="cpp-comment"&gt;// if the table entry matches the id of the chosen node path&lt;/span&gt;&lt;br /&gt;               if(EntryTableNodeID==t.NodeID)&lt;br /&gt;               {&lt;br /&gt;                   &lt;span class="cpp-comment"&gt;// add the new value to the total&lt;/span&gt;&lt;br /&gt;                   total += newVal;&lt;br /&gt;                   t = tableEntry[j];&lt;br /&gt;                   &lt;span class="cpp-comment"&gt;// add the new value the current value of the selected path&lt;/span&gt;&lt;br /&gt;                   t.Probablilty += newVal;&lt;br /&gt;               }&lt;br /&gt;           }&lt;br /&gt;&lt;br /&gt;           &lt;span class="cpp-comment"&gt;// calculate the ratio for the multiplcation&lt;/span&gt;&lt;br /&gt;           double ratio = 100/total;&lt;br /&gt;&lt;br /&gt;           &lt;span class="cpp-comment"&gt;// loop through each table entry and multiple the current probability&lt;/span&gt;&lt;br /&gt;           &lt;span class="cpp-comment"&gt;// by the new ratio&lt;/span&gt;&lt;br /&gt;           for(int j=0;j&lt;tableEntry.Length;j++)&lt;br /&gt;           {&lt;br /&gt;               tableEntry[j].Probablilty *= ratio;&lt;br /&gt;           }&lt;br /&gt;&lt;br /&gt;           &lt;span class="cpp-comment"&gt;// this will enumerate all the values to 99.99999%&lt;/span&gt;&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       &lt;span class="cpp-comment"&gt;// Constructor takes a node to represent and a list of all connected nodes off the&lt;/span&gt;&lt;br /&gt;       &lt;span class="cpp-comment"&gt;// calling node&lt;/span&gt;&lt;br /&gt;       public PheromoneTable(Node n, int[] conns)&lt;br /&gt;       {&lt;br /&gt;           this.NodeID = n.ID;&lt;br /&gt;      &lt;br /&gt;           &lt;span class="cpp-comment"&gt;// create a tableEntry array the same length as the number of connections&lt;/span&gt;&lt;br /&gt;           this.tableEntry = new TableEntry[conns.Length];&lt;br /&gt;&lt;br /&gt;           &lt;span class="cpp-comment"&gt;// create a new tableEntry for each connection&lt;/span&gt;&lt;br /&gt;           for(int i=0;i&lt;conns.Length;i++)&lt;br /&gt;               tableEntry[i] = new TableEntry(conns[i]);&lt;br /&gt;&lt;br /&gt;           &lt;span class="cpp-comment"&gt;// set default equal values&lt;/span&gt;&lt;br /&gt;           for(int i=0;i&lt;conns.Length;i++)&lt;br /&gt;               tableEntry[i].Probablilty = (100 / (double)conns.Length);&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;    &lt;h2&gt;&lt;strong&gt; Simulation results&lt;/strong&gt;&lt;/h2&gt; &lt;p nd="77"&gt; The following tests will illustrated how the ANTNET algorithm effects the routing of traffic. These tests will show effectiveness of the algorithm against the system running without ANTNET. Since it is possible to switch nodes on and off, a number of test comparisons will be done to show how ANTNET can improve the routing of a network when paths are no longer valid and new routes have to be chosen.&lt;/p&gt; &lt;p nd="78"&gt; These tests have been run with the following parameters&lt;/p&gt; &lt;ul&gt;&lt;li nd="79"&gt; ANTNet On &lt;/li&gt;&lt;li nd="80"&gt; Simulation Speed –1,000 tick p/s &lt;/li&gt;&lt;li nd="81"&gt; Total calls to make – 5000 &lt;/li&gt;&lt;li nd="82"&gt; Maximum concurrent calls – 60 &lt;/li&gt;&lt;li nd="83"&gt; Node capacity – 35 &lt;/li&gt;&lt;li nd="84"&gt; Call duration – 170 The length (in ticks) of a call &lt;/li&gt;&lt;li nd="85"&gt; Reduce I/O – bypasses the network visualisation to increase simulation speed &lt;/li&gt;&lt;li nd="86"&gt; Return on connection – returns the node immediately to source after connection &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;strong&gt;5.1 ANTNet VS non- ANTNet&lt;/strong&gt;&lt;/p&gt; &lt;p nd="87"&gt; The first test contains two simulations.&lt;/p&gt; &lt;ul&gt;&lt;li nd="88"&gt; Simulation 1 ( &lt;strong&gt; Orange&lt;/strong&gt; ) – ANTNet algorithm OFF &lt;/li&gt;&lt;li nd="89"&gt; Simulation 2 (&lt;strong&gt; Blue&lt;/strong&gt;) – ANTNet ON &lt;/li&gt;&lt;/ul&gt; &lt;p nd="90"&gt; From this simulation it is clear that even by the first 500 calls completed, ANTNet has reduced the average number of hops by approximately 1.5 nodes. This is made more apparent by the end of the simulation where the best paths are made more biased as a choice and are re-enforced as the optimal route, resulting in ANTnet improving network performance by almost 3.5 hops &lt;/p&gt;  &lt;p align="center"&gt;&lt;img src="http://www.codeproject.com/useritems/Ant_Colony_Optimisation/test1.jpg" height="311" width="479" /&gt;&lt;/p&gt; &lt;p nd="91" align="center"&gt; Figure 5.1 – Non-adaptive algorithm (&lt;strong&gt; orange&lt;/strong&gt;) VS ANTNet algorithm (&lt;strong&gt; blue&lt;/strong&gt;)&lt;/p&gt; &lt;p nd="92"&gt; To view the algorithm from a different perspective the following graph depicts the system running with the ANTNet algorithm off and then activated on the 2,000 th call. This can be identified by a label and follows with a decline of average hops by almost 2. &lt;/p&gt; &lt;p align="center"&gt;&lt;img src="http://www.codeproject.com/useritems/Ant_Colony_Optimisation/test2.jpg" height="295" width="508" /&gt;&lt;/p&gt; &lt;p nd="93" align="center"&gt; Figure 5.2 – ANTNet activated after the 2000th call&lt;/p&gt; &lt;p&gt;&lt;strong&gt; 5.2 &lt;/strong&gt;&lt;strong&gt; Loop&lt;/strong&gt;&lt;strong&gt; elimination &lt;/strong&gt;&lt;/p&gt; &lt;p nd="94"&gt;&lt;strong&gt;  &lt;/strong&gt;Before an Ant returns back to its source node, an optimisation technique of loop elimination can be invoked. The problem with loops is that they can receive several times the amount of pheromone than they should, leading to the problem of self re-enforcing loops. &lt;/p&gt;  &lt;p align="center"&gt;&lt;img src="http://www.codeproject.com/useritems/Ant_Colony_Optimisation/test3.jpg" height="296" width="504" /&gt;&lt;/p&gt; &lt;p nd="95" align="center"&gt; Figure 5.3 – Loop removal (&lt;strong&gt; Blue&lt;/strong&gt;) VS non-loop removal ( &lt;strong&gt; Orange&lt;/strong&gt; )&lt;/p&gt; &lt;p nd="96"&gt; Figure 5.3 shows two simulations:&lt;/p&gt; &lt;ul&gt;&lt;li nd="97"&gt; Simulation 1 ( &lt;strong&gt; Orange&lt;/strong&gt; ) – Loop elimination OFF &lt;/li&gt;&lt;li nd="98"&gt; Simulation 2 (&lt;strong&gt; Blue&lt;/strong&gt;) – Loop elimination ON &lt;/li&gt;&lt;/ul&gt; &lt;p nd="99"&gt; From this test, loop elimination has reduced the average number of hops by 1 node with a much more stable adaptation. This would mean that when alternative paths must be chosen, the loop elimination algorithm responds much faster that the regular implementation.&lt;/p&gt; &lt;p nd="100"&gt; Note: Both lines show the actual number of nodes traversed and not the number after loop removal. &lt;/p&gt; &lt;p&gt;&lt;strong&gt;5.3 Adaptivity&lt;/strong&gt;&lt;/p&gt; &lt;p nd="101"&gt; It is important to simulate how the network adapts when nodes are removed from the network. Static routing tables may hold the shortest path but they don't necessarily take into account network traffic and nodes that are offline. Three simulations have been run on the program to display how the system adapts compared to a non adaptive algorithm.&lt;/p&gt;  &lt;p align="center"&gt;&lt;img src="http://www.codeproject.com/useritems/Ant_Colony_Optimisation/test4.jpg" height="338" width="502" /&gt;&lt;/p&gt; &lt;p nd="102" align="center"&gt; Figure 5.4 – Adaptive vs non-adaptive algorithm &lt;/p&gt; &lt;p align="center"&gt;  &lt;/p&gt; &lt;p&gt;&lt;strong&gt; Simulation 1 ( orange) &lt;/strong&gt;&lt;/p&gt; &lt;p nd="103"&gt; This is a normal run of the simulator to create optimised Pheromone tables for the next two simulations. &lt;/p&gt; &lt;p&gt;&lt;strong&gt;Simulation 2 ( blue) &lt;/strong&gt;&lt;/p&gt; &lt;p nd="104"&gt; Adaptive algorithm switched OFF. &lt;/p&gt; &lt;p nd="105"&gt; Nodes 14,15 and 17 are switched off as these are the main Northern access hubs into London so traffic needs to be diverted to the west of England . Since the network is non adaptive, the pheromone tables are biased towards nodes that are have been taken offline and subsequently being continuously redirected and taking longer journeys every time. This increase is displayed in figure 6.4 by the blue line. &lt;/p&gt; &lt;p&gt;&lt;strong&gt;Simulation 3 ( green) &lt;/strong&gt;&lt;/p&gt; &lt;p nd="106"&gt; Adaptive algorithm switched ON. &lt;/p&gt; &lt;p nd="107"&gt; Nodes 14,15 and 17 are still switched off but since the network is now set to adaptive, the pheromone tables are readjusted and the system learns alternative routes. This can be seen in figure 6.4 by the green line. &lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1192972388107063553-4590070258913230407?l=chamildz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chamildz.blogspot.com/feeds/4590070258913230407/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1192972388107063553&amp;postID=4590070258913230407' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1192972388107063553/posts/default/4590070258913230407'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1192972388107063553/posts/default/4590070258913230407'/><link rel='alternate' type='text/html' href='http://chamildz.blogspot.com/2007/02/artificial-intelligence-network-load.html' title='Artificial intelligence network load balancing using Ant Colony Optimisation - C# Algorithms'/><author><name>Chamil</name><uri>http://www.blogger.com/profile/00204727013782891667</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1192972388107063553.post-3773645290535610057</id><published>2007-02-02T01:37:00.000-08:00</published><updated>2007-02-02T02:12:26.936-08:00</updated><title type='text'>Linux on the Nokia 770 Internet Tablet</title><content type='html'>&lt;span nd="1" name="intelliTxt" id="intelliTxt"&gt;&lt;p nd="2"&gt;The &lt;a href="http://en.wikipedia.org/wiki/Nokia_770"&gt;Nokia 770&lt;/a&gt; is an internet tablet designed to connect to the internet with 802.11b/g WLAN or through a phone with Bluetooth. It has a nice 800 x 480 screen (64k colors) and quite a few apps on board. The underlying OS is the Debian GNU/Linux derivative, BusyBox. As it stands, the device is not a phone.&lt;/p&gt;&lt;div class="adtag right" style="margin: 8px; width: 336px;"&gt;&lt;!-- dy --&gt; &lt;!-- begin ad tag --&gt; &lt;script language="JavaScript" type="text/javascript"&gt; //&lt;![CDATA[ var ord = (ord != null ? ord : Math.random()*10000000000000000 ); document.write('&lt;script language="JavaScript" src="http://ad.doubleclick.net/adj/ttm.linuxdevcenter/linuxart;sz=336x280;tile=3;ord=' + ord + '?" type="text/javascript"&gt;&lt;\/script&gt;'); //]]&gt; &lt;/script&gt;&lt;script language="JavaScript" src="http://ad.doubleclick.net/adj/ttm.linuxdevcenter/linuxart;sz=336x280;tile=3;ord=22544561699183.73?" type="text/javascript"&gt;&lt;/script&gt;&lt;/div&gt;&lt;p nd="3"&gt;The day after my 770 arrived, I read a review in the &lt;em nd="4"&gt;Washington Post&lt;/em&gt; where the guy really didn't like the unit at all. I like it a lot, so I thought about his reasons. My conclusion is that the reviewer is a Windows guy. As such, he would have been less likely to find the other wonderful stuff that's floating around for the 770. In any case, quite a few people have been working on the 770, which richens the experience considerably.&lt;/p&gt;  &lt;h3&gt;The Machine&lt;/h3&gt;  &lt;p nd="5"&gt;Out of the box, the 770 does quite a few things, including being a music and video player. The official lineup of software includes:&lt;/p&gt;  &lt;blockquote nd="6"&gt;Web Browser, Flash Player version 6, Email Client, Internet Radio, News Reader, Media players, Image viewer, PDF viewer, File Manager, Search, Calculator, World Clock, Notes, Sketch, Games including chess, mahjong, and marbles.&lt;/blockquote&gt;  &lt;p nd="7"&gt;It is pretty nice to sit in your most comfy chair and browse the web with a nice light object that doesn't have to sit in your lap (and fry it as some laptops do). The screen is a good size, although the pleasures might be a bit site-dependant in that if the reading columns are wide you will have to scroll sideways. Actually, that's a gotcha. In the menu under "View," click "Optimized view." This will rearrange the pages to avoid sideways scrolling, even if you increase the font size. The standard font size is small but readable. You can make the fonts larger with a simple button push. The screen is sharp as well, which helps.&lt;/p&gt; &lt;!-- sidebar begins --&gt; &lt;!-- don't move sidebars --&gt; &lt;!-- sidebar ends --&gt;   &lt;p nd="8"&gt;It's worth saying a little about the music player. The 770 is a little bigger than an iPod and quite suitable for taking along a limited playlist. For storage, the unit uses Reduced Size MMC and 1GB models available. If you're one of those people with 30,000 MP3s or Ogg Vorbis songs, you can't take the whole song collection. Since you have to select tunes or playlists on the screen, playlists are the best playing mode. Set the screen lock, chuck it your bag, and it will play to the end of the playlist.&lt;/p&gt;  &lt;h3&gt;Data Entry&lt;/h3&gt;  &lt;p nd="9"&gt;You have a choice of a screen keyboard or handwriting recognition. Some people have commented on the slow speed and inaccuracy of the handwriting recognition, but the speed can be set, and when it's on the fastest setting you really have to zip. I found the accuracy to be mostly okay. If you only use this device to enter URLs in the browser or to write short emails, it doesn't present too much of a problem. If you want to do more, there is a lot of help at hand.&lt;/p&gt;  &lt;p nd="10"&gt;That's enough of the technical stuff. Here's the fun part (see Figure 1).&lt;/p&gt;  &lt;div class="image right" style="width: 350px;"&gt; &lt;img src="http://www.linuxdevcenter.com/linux/2006/07/20/graphics/770_doom.jpg" alt="Doom on the Nokia 770" /&gt; &lt;p style="font-style: italic;" nd="11"&gt;Figure 1. Doom on the Nokia 770.&lt;/p&gt;&lt;/div&gt;  &lt;h3&gt;The Hacks&lt;/h3&gt;  &lt;p nd="12"&gt;Because the 770 has been out for a few months there's plenty of porting activity already. Nokia set up &lt;a href="http://www.maemo.org/"&gt;maemo.org&lt;/a&gt; as the official headquarters. The site has a &lt;a href="http://maemo.org/maemowiki/ApplicationCatalog"&gt;Nokia 770 Application Catalog&lt;/a&gt; that lists what's currently available.&lt;/p&gt;  &lt;p nd="13"&gt;What can you get for your "phone?" Several flavors of XTerm, editors including Vim, Joe, Midnight Commander, some Wi-Fi tools, telnet and FTP clients, and a whole lot more, including ... Doom! This plays pretty well actually and the big wide screen (for a handheld) makes it quite an attractive proposition.&lt;/p&gt;  &lt;p nd="14"&gt;To install new software on the 770, first download the deb package. Then connect the 770 by its USB cable and transfer the files to the RSMMC on the 770. Open the control panel on the 770, choose Install Programs, and away you go.&lt;/p&gt;  &lt;p nd="15"&gt;After you've done that, you may notice that you can't immediately launch apps by typing commands into the console (see Figure 2). This is because the new programs go into the directory &lt;em nd="16"&gt;/var/lib/install/usr/bin&lt;/em&gt;. To fix the problem, make a &lt;em nd="17"&gt;.profile&lt;/em&gt; file and add that path. I use:&lt;/p&gt;  &lt;pre&gt;&lt;code&gt;export LD_LIBRARY_PATH=/var/lib/install/usr/lib:$LD_LIBRARY_PATH&lt;br /&gt;export PATH=/var/lib/install/usr/bin:$PATH&lt;/code&gt;&lt;/pre&gt;  &lt;div class="image left" style="width: 350px;"&gt; &lt;img src="http://www.linuxdevcenter.com/linux/2006/07/20/graphics/770_mc.jpg" alt="Figure 2" /&gt; &lt;p style="font-style: italic;" nd="18"&gt;Figure 2. Browsing the Nokia 770 Filesystem.&lt;/p&gt;&lt;/div&gt;  &lt;p nd="19"&gt;At that point you might find that you can't write the &lt;em nd="20"&gt;.profile&lt;/em&gt; file. This is because you're at &lt;em nd="21"&gt;/&lt;/em&gt; by default. Go to &lt;em nd="22"&gt;/home/user&lt;/em&gt;, create the file, and you'll be fine.&lt;/p&gt;  &lt;p nd="23"&gt;Getting root (necessary for some tools) isn't all that straightforward. Fortunately, there are two possibilities: &lt;a href="https://maemo.org/maemowiki/HowDoiBecomeRoot"&gt;How Do I Become Root on the Nokia 770&lt;/a&gt; and &lt;a href="http://www.karoliinasalminen.com/blog/?page_id=68"&gt;How to obtain root in Nokia 770 - the easy way&lt;/a&gt;&lt;a href="http://www.karoliinasalminen.com/blog/?page_id=68"&gt;.&lt;/a&gt;&lt;/p&gt;  &lt;h4&gt;File Manager&lt;/h4&gt;  &lt;p nd="24"&gt;The File Manager application only shows files in your &lt;em nd="25"&gt;/home/user/MyDocs&lt;/em&gt;, directory, your RS-MMC card and on Bluetooth-paired devices. However, there are several workarounds.&lt;/p&gt;  &lt;p nd="26"&gt;For simple viewing/browsing all files, just open the web browser and set the URL to &lt;em nd="27"&gt;/usr/&lt;/em&gt; or similar. Then navigate around as much as you like.&lt;/p&gt;  &lt;p nd="28"&gt;To unlock the full capabilities of the built-in file manager, create a symbolic link. Open X Terminal Emulator and create a link into &lt;em nd="29"&gt;MyDocs&lt;/em&gt; directory:&lt;/p&gt;  &lt;pre&gt;&lt;code&gt;$ &lt;strong&gt;cd ~/MyDocs&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;ln -s / Root&lt;/strong&gt;&lt;/code&gt;&lt;/pre&gt;  &lt;p nd="31"&gt;&lt;em nd="30"&gt;Root&lt;/em&gt; will then appear in the File manager, in Midnight Commander, or whichever shell you prefer.&lt;/p&gt;  &lt;h4&gt;Change the Logo and Sounds&lt;/h4&gt;  &lt;p nd="32"&gt;The big Nokia logo you see on startup comes from the file &lt;em nd="33"&gt;/usr/share/icons/hicolor/scalable/hildon/qgn_indi_startup_nokia_logo.png&lt;/em&gt;. The Nokia hands live at &lt;em nd="34"&gt;/usr/share/icons/hicolor/scalable/hildon/qgn_indi_nokia_hands.png&lt;/em&gt;. The Nokia tunes are in &lt;em nd="35"&gt;/usr/share/sounds&lt;/em&gt;. Replace the files as you like.&lt;/p&gt;  &lt;p nd="36"&gt;(The file manager and logo hacks came from &lt;a href="http://bonte.co.uk/myBlog/?cat=11"&gt;mobile analysis and development's Nokia 770 page&lt;/a&gt;.)&lt;/p&gt;  &lt;h3&gt;Data Entry&lt;/h3&gt;  &lt;p nd="37"&gt;The stock data entry methods for the 770 are quite adequate for minimal typing, but the first long email will send you looking for alternatives. The first option is a Bluetooth keyboard. Nokia makes one but apparently, any HID Bluetooth keyboard will do (except HP's Bluetooth keyboard, which doesn't work). A driver is available from Maemo.org and it's pretty much as simple as downloading, installing, and activating it from the menu bar at the top of the screen.&lt;/p&gt;  &lt;p nd="38"&gt;Maybe you'd like something a bit bigger or less expensive since the Bluetooth keyboards generally seem to have a fair price premium. A great hack by Thoughtfix enables the USB port so that you can use an ordinary (or maybe a slightly compact) USB keyboard. The problem here is that the USB port on the 770 doesn't supply power and won't act as a host. You can fix the second part with a simple download and a command ( see &lt;a href="http://www.karoliinasalminen.com/blog/?page_id=68"&gt;Karoliina's Nokia 770 dev howto&lt;/a&gt; ) but the other part requires the use of some cables, a battery, a voltage regulator, and a little time putting them together. Thoughtfix has project details in &lt;a href="http://thoughtfix.blogspot.com/2006/01/usb-power-injector-for-usb-host-mode.html"&gt;USB power "injector" for USB host mode&lt;/a&gt;&lt;a href="http://thoughtfix.blogspot.com/2006/01/usb-power-injector-for-usb-host-mode.html"&gt;.&lt;/a&gt;&lt;/p&gt;  &lt;h4&gt;Use Wikipedia&lt;/h4&gt;  &lt;p nd="39"&gt;Bleb.org has a hack on &lt;a href="http://www.bleb.org/software/770/#wikipedia"&gt;using nicer CSS for Wikipedia&lt;/a&gt;. The default skin contains a long left-hand column, however by using a Wikipedia account, you can change the skin to one more suited to a device such as the 770.&lt;/p&gt;  &lt;h3&gt;Hacks of the Near Future&lt;/h3&gt;  &lt;p nd="40"&gt;When the news of the 770 first came out, a lot of people said, "Wi-Fi? How about a VoIP client?" As it happens, Nokia might have had these thoughts at the design stage, since there's an inactivated facility for audio input on the current unit. Very recently, they announced a software upgrade that will include a VoIP client.&lt;/p&gt;  &lt;p nd="41"&gt;In the words of Nokia's Ari Virtanen:&lt;/p&gt;  &lt;blockquote nd="42"&gt;The Internet Tablet OS 2006 edition features pre-installed Google Talk and Jabber compatibility for Instant Messaging as well as Google Talk compatibility for Internet calling. This will give Nokia Internet Tablet users the power to instantly communicate with people, both through instant messaging and Voice over IP.&lt;/blockquote&gt;  &lt;p nd="43"&gt;There will also be a built-in Google search facility and support for SIP-based VoIP solutions, which will allow users to make and receive calls from public telephone networks.&lt;/p&gt;  &lt;p nd="44"&gt;Nokia's &lt;a href="http://europe.nokia.com/nokia/0,1522,,00.html?orig=/770"&gt;Nokia 770 Internet Tablet&lt;/a&gt; page allows you to sign up for notifications of this upgrade. I also recommend subscribing to &lt;a href="http://www.bleb.org/software/770/apps.rss"&gt;Bleb.org's feed of new 770 applications&lt;/a&gt; for more information on ports as they come out.&lt;/p&gt;  &lt;h3&gt;Conclusion&lt;/h3&gt;  &lt;p nd="45"&gt;There's a lot more to come for this great little unit. Nokia shows signs of having a clue in shepherding the 770 on its way both in marketing and the way developers have been encouraged, for example they've made an SDK available and have an open source GUI. If you feel like doing some coding or porting, maemo.org is the place to go. Interestingly too, the Windows-only tools that exist for Symbian now have Linux and Mac OS X ports for this Linux-based unit.&lt;/p&gt;  &lt;p nd="46"&gt;There's plenty more to come here!&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1192972388107063553-3773645290535610057?l=chamildz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chamildz.blogspot.com/feeds/3773645290535610057/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1192972388107063553&amp;postID=3773645290535610057' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1192972388107063553/posts/default/3773645290535610057'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1192972388107063553/posts/default/3773645290535610057'/><link rel='alternate' type='text/html' href='http://chamildz.blogspot.com/2007/02/linux-on-nokia-770-internet-tablet.html' title='Linux on the Nokia 770 Internet Tablet'/><author><name>Chamil</name><uri>http://www.blogger.com/profile/00204727013782891667</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1192972388107063553.post-4135940625907522575</id><published>2007-01-31T02:43:00.000-08:00</published><updated>2007-01-31T02:48:31.287-08:00</updated><title type='text'>Using a vista side bar gadget to consume an image feed</title><content type='html'>&lt;span name="intelliTxt" id="intelliTXT"&gt;&lt;ul class="download"&gt;&lt;li&gt;&lt;a href="http://www.codeproject.com/gadgets/SidebarImageFeed/ImageGallerySidebar.zip"&gt;Download gadget - 86.2 Kb&lt;/a&gt;  &lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codeproject.com/gadgets/SidebarImageFeed/ImageGallerySidebar_src.zip"&gt;Download source code - 88.1 Kb&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;&lt;img alt="Sample image" src="http://www.codeproject.com/gadgets/SidebarImageFeed/Flyout.jpg" height="272" width="600" /&gt;  &lt;h2&gt;Introduction&lt;/h2&gt; &lt;p nd="1"&gt;When I first installed Windows Vista on my Virtual Server I noticed the sidebar and thought, "Ok, that's pretty cool". But when I found out that all you needed was HTML and Javascript to create one I said, "WOW, that's awesome!". My mind filled with the possibilities. One of the first that came to mind when I saw the Feed Headlines gadget in the Gadget Gallery was an image feed. I figured if the gadget could pull an RSS feed, which is essentially XML, from a remote location and refresh the data on an interval then I figured I could pull custom XML and display images located on a remote server as well.&lt;/p&gt; &lt;p nd="2"&gt;The goal of this article will take you through the process of creating a Vista Sidebar Gadget for the first time. I have included just about all the steps you need to go through to create any gadget. Plus, I've tried to provide background on each step and point out the Gotchas that I ran into as I was creating this Sidebar Gadget for this article.&lt;/p&gt; &lt;p nd="3"&gt;As a disclaimer, this article is a bit of a shameless plug for the company I work for because we sell professional sports photos online. But I figured it would be ok, because the point of the article is to show how you can integrate a Sidebar Gadget with your online content. For example, you could take this gadget and adapt it to consume an image feed of the current sale items, or best deals in your online catalog. If the user sees something they like they click the "buy" link and can purchase the item!&lt;/p&gt; &lt;h2&gt;What is a Sidebar Gadget?&lt;/h2&gt; &lt;p nd="4"&gt;The Windows Vista Sidebar is an executable that runs on the desktop of the new Windows Vista OS. It hosts "Gadgets" which are small DHTML applications which have almost all the capabilities of a web page running in Internet &lt;a itxtdid="3146790" target="_blank" href="http://www.codeproject.com/gadgets/SidebarImageFeed.asp#" style="border-bottom: 0.075em solid darkgreen; font-weight: normal; font-size: 100%; text-decoration: underline; color: darkgreen; background-color: transparent; padding-bottom: 1px;" class="iAs"&gt;Explorer&lt;/a&gt;. (I say almost all because this is a new technology and it's my first attempt at using it.)&lt;/p&gt; &lt;p nd="5"&gt;Windows Vista comes with a small sampling of Sidebar Gadgets to give you an idea of what is possible. Some seem pretty useful:&lt;/p&gt; &lt;ul&gt;&lt;li nd="6"&gt;An analog clock  &lt;/li&gt;&lt;li nd="7"&gt;An RSS news reader  &lt;/li&gt;&lt;li nd="8"&gt;A CPU / memory monitor &lt;/li&gt;&lt;/ul&gt; &lt;p nd="9"&gt;"What's so useful about an analog clock" you say? Well, it's ok, but what makes it useful is that the Sidebar is capable of running multiple, independent instances of each gadget. And each instance has it's own settings. So if you work in a different time zone than your clients or compatriots you can run a separate instance of the clock for each time zone! Of course your desktop real-estate is limited, but the sidebar is capable of displaying multiple pages of gadgets, so you can navigate through the ones you have open.&lt;/p&gt; &lt;p nd="10"&gt;A minimal Gadget application consists of the following items:&lt;/p&gt; &lt;ul&gt;&lt;li nd="11"&gt;An XML manifest file named gadget.xml (yes, the name is a requirement)  &lt;/li&gt;&lt;li nd="12"&gt;An HTML file  &lt;/li&gt;&lt;li nd="13"&gt;An "icon" (jpg, gif or png) file &lt;/li&gt;&lt;/ul&gt; &lt;p nd="14"&gt;A Gadget application may also include the following items:&lt;/p&gt; &lt;ul&gt;&lt;li nd="15"&gt;script files (.vbs or .js)  &lt;/li&gt;&lt;li nd="16"&gt;stylesheet files (.css)  &lt;/li&gt;&lt;li nd="17"&gt;a settings HTML file  &lt;/li&gt;&lt;li nd="18"&gt;a "flyout" HTML file  &lt;/li&gt;&lt;li nd="19"&gt;globalization files  &lt;/li&gt;&lt;li nd="20"&gt;ActiveX components &lt;/li&gt;&lt;/ul&gt;&lt;img alt="" src="http://www.codeproject.com/gadgets/SidebarImageFeed/SolutionExplorer.jpg" height="549" width="352" /&gt;  &lt;p nd="21"&gt;Gadgets have two installation directories:&lt;/p&gt; &lt;ul&gt;&lt;li nd="22"&gt;%USER_DATA%\Local\Microsoft\Windows Sidebar\Gadgets - for user gadgets  &lt;/li&gt;&lt;li nd="23"&gt;%SYSTEM_ROOT%\Program Files\Windows Sidebar\Gadgets - for global gadgets &lt;/li&gt;&lt;/ul&gt; &lt;h2&gt;Gadget Development Tools &amp; Resources&lt;/h2&gt; &lt;p nd="24"&gt;What tools do you need to create a Sidebar Gadget? The short answer, "Notepad". Yup, if you are comfortable writing your HTML and Javascript or VBScript in a plain text editor then you can do just that. No compilation is needed. However, if you're planning on something more robust than your first "Hello, World!" gadget I'd recommend an IDE that supports script debugging. Because I do all my HTML in a text editor, I tried to get started with notepad on my first try. But since my &lt;code nd="25"&gt;window.alert()&lt;/code&gt; attempts failed from the get go, I was dead in the water right out of the gate.&lt;/p&gt; &lt;p nd="26"&gt;So I installed my IDE of choice, Visual Studio 2005, &lt;a href="http://microsoftgadgets.com/Sidebar/DevelopmentOverview.aspx#modifying" target="_blank"&gt;configured IE for script debugging&lt;/a&gt; and instantly determined the cause of my first problem and every problem thereafter. If you can do it all in notepad, more power to you. You're more of a man than I. But after my first experience, I don't recommend flying blind.&lt;/p&gt; &lt;p nd="27"&gt;You don't need to be running Windows Vista either, but I don't recommend that either since you can't really test your gadget without it. I don't know about you, but I'm not quite ready to take that plunge. So I installed Vista as a virtual machine on Virtual Server. For this article, I am working with Windows Vista Ultimate Edition, RC2 Build 5744. The final release is out by now (or at least it's available on MSDN) so you can work with a more current version, but everything seemed to be working fine for me so there was no reason to download and install the entire OS all over again.&lt;/p&gt; &lt;div style="background-color: rgb(204, 204, 204);"&gt;&lt;strong style="color: red;"&gt;Gotcha #1&lt;/strong&gt;  &lt;p nd="28"&gt;An important note about updating the installed gadget files. I found that if I'm just updating the .htm file for the Flyout or Settings windows, I can update the file and the next time the window loads it will display the updates. However, if I'm modifying a .js, .css or the main Gadget.htm file, then I have to close all running instances of the Gadget before I can open a new instance and view the changes.&lt;/p&gt;&lt;/div&gt; &lt;p nd="29"&gt;Here are a list of resources I found helpful along the way:&lt;/p&gt; &lt;ul&gt;&lt;li nd="30"&gt;&lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sidebar/sidebar/reference/refs.asp" target="_blank"&gt;Sidebar Gadget Object Model&lt;/a&gt; - for reference  &lt;/li&gt;&lt;li nd="31"&gt;&lt;a href="http://microsoftgadgets.com/build/" target="_blank"&gt;Sidebar Gadget Tutorial - Earth Map&lt;/a&gt; - for a more complex example  &lt;/li&gt;&lt;li nd="32"&gt;&lt;a href="http://www.tutorial-web.com/asp/fso/index.asp" target="_blank"&gt;FileSystemObject online reference&lt;/a&gt; - for reading/writing files  &lt;/li&gt;&lt;li nd="33"&gt;&lt;a href="http://www.w3.org/TR/REC-DOM-Level-1/cover.html" target="_blank"&gt;W3 DOM Object model reference&lt;/a&gt; - for DHTML, XML DOM  &lt;/li&gt;&lt;li nd="34"&gt;&lt;a href="http://www.aeroxp.org/board/index.php?showtopic=7318" target="_blank"&gt;List of known bugs&lt;/a&gt; - for sanity &lt;/li&gt;&lt;/ul&gt; &lt;h2&gt;Globalization&lt;/h2&gt; &lt;p nd="35"&gt;If you want to make your Sidebar Gadget localized the key is to use declared constants for all your text. If you have images with text on them, you'll need to create additional copies of the image in each language you intend to support. Then create a folder with the language code (en-US for english united states, for example). That folder should contain a duplicate folder structure for the resources (js, css and image files) and the localized resources. In the image of my solution explorer above, you'll see I have a folder named "en-US" with a subfolder named js which contains a javascript file named local.js. Local.js contains all my declared constants for error messages and other text. If I wanted to support other languages I would simply duplicate the contents of en-US with values in the language being supported.&lt;/p&gt; &lt;h2&gt;Step 1: The manifest File&lt;/h2&gt; &lt;p nd="36"&gt;The manifest file describes your Sidebar Gadget and contains the settings required by Windows Sidebar to both display it in the Sidebar Gallery and create an instance of it in the Sidebar.&lt;/p&gt;&lt;pre nd="37" lang="XML"&gt;&lt;?xml version="1.0" encoding="utf-8" ?&gt;&lt;br /&gt;&lt;gadget&gt;&lt;br /&gt;   &lt;name&gt;MaxPreps Gallery Viewer&lt;/name&gt;&lt;br /&gt;   &lt;namespace&gt;Developmentalmadness.Vista.Gadgets&lt;/namespace&gt;&lt;br /&gt;   &lt;version&gt;1.0.0.0&lt;/version&gt;&lt;br /&gt;   &lt;author name="Mark J. Miller"&gt;&lt;br /&gt;       &lt;info url="http://developmentalmadness.blogspot.com"&lt;br /&gt;             text="Mark J. Miller's blog"/&gt;&lt;br /&gt;   &lt;/author&gt;&lt;br /&gt;   &lt;copyright&gt;© 2007&lt;/copyright&gt;&lt;br /&gt;   &lt;description&gt;View high school sport's action photos!&lt;/description&gt;&lt;br /&gt;   &lt;icons&gt;&lt;br /&gt;       &lt;icon height="150" width="150"&lt;br /&gt;             src="images/icons/MaxPreps_Blk_130w.gif" /&gt;&lt;br /&gt;   &lt;/icons&gt;&lt;br /&gt;   &lt;hosts&gt;&lt;br /&gt;       &lt;host name="sidebar"&gt;&lt;br /&gt;           &lt;base type="HTML" apiversion="1.0.0" src="gadget.htm"&gt;&lt;br /&gt;           &lt;permissions&gt;Full&lt;/permissions&gt;&lt;br /&gt;           &lt;platform minplatformversion="0.3"&gt;&lt;br /&gt;           &lt;defaultimage src="images/icons/MaxPreps_Blk_130w.gif"&gt;&lt;br /&gt;       &lt;/host&gt;&lt;br /&gt;   &lt;/hosts&gt;&lt;br /&gt;&lt;/gadget&gt;            &lt;br /&gt;&lt;/pre&gt; &lt;p nd="38"&gt;There isn't really any documentation on the gadget.xml file schema, all the tutorials simply display an example of the manifest file. It's up to the reader to just copy &amp; paste, then edit the sample. But I'll try and give you a summary here of what I've found. &lt;/p&gt; &lt;p nd="39"&gt;Except for the &lt;code nd="40"&gt;hosts&lt;/code&gt; &lt;a itxtdid="3146774" target="_blank" href="http://www.codeproject.com/gadgets/SidebarImageFeed.asp#" style="border-bottom: 0.075em solid darkgreen; font-weight: normal; font-size: 100%; text-decoration: underline; color: darkgreen; background-color: transparent; padding-bottom: 1px;" class="iAs"&gt;element&lt;/a&gt; and it's children, most of the schema is used to describe your Sidebar Gadget for the Gadget Gallery. The elements &lt;code nd="41"&gt;name&lt;/code&gt; and &lt;code nd="42"&gt;icons&lt;/code&gt; are used to display an application icon above the name of your Sidebar Gadget in the Gadget Gallery. While &lt;code nd="43"&gt;version&lt;/code&gt;, &lt;code nd="44"&gt;author&lt;/code&gt;, &lt;code nd="45"&gt;info&lt;/code&gt;, &lt;code nd="46"&gt;copyright&lt;/code&gt; and &lt;code nd="47"&gt;description&lt;/code&gt; all are used by the details pane to describe your Sidebar Gadget. The &lt;code nd="48"&gt;info&lt;/code&gt; element has two attributes: &lt;code nd="49"&gt;url&lt;/code&gt; and &lt;code nd="50"&gt;text&lt;/code&gt;. &lt;code nd="51"&gt;url&lt;/code&gt; is exactly what it says it is. The &lt;code nd="52"&gt;text&lt;/code&gt; attribute is optional, but if you want to display something descriptive in place of the url you can use it. The only one I haven't been able to account for is &lt;code&gt;&lt;span class="cpp-keyword"&gt;namespace&lt;/span&gt;&lt;/code&gt;, but by the time I realized it, I figured I had already come up with a namespace and entered it, so I decided to leave it. &lt;/p&gt;&lt;img alt="" src="http://www.codeproject.com/gadgets/SidebarImageFeed/GadgetGallery.jpg" height="490" width="600" /&gt;  &lt;p nd="53"&gt;Because of the lack of documentation, I'm guessing on some of this, but most of what is below the &lt;code nd="54"&gt;hosts&lt;/code&gt; element stays as it is. However, the &lt;code nd="55"&gt;src&lt;/code&gt; attribute of &lt;code nd="56"&gt;base&lt;/code&gt; indicates the main HTML file for your Sidebar Gadget and &lt;code nd="57"&gt;defaultImage&lt;/code&gt; allows you to specify a drag icon used when you drag your Sidebar Gadget from the Gadget Gallery to the Sidebar. This can be a transparent png and the transparency should be preserved as you drag the icon to the Sidebar. However, I am by no means a graphic artist, so I did not attempt to make my own graphic to test this.&lt;/p&gt; &lt;h2&gt;Step 2: The Settings Page&lt;/h2&gt; &lt;p nd="58"&gt;As you create your gadget, it should save you some time if you create your settings page next. The reason I say this is because I did not, and I found that I would have to go back through much of my code that is already in place to accommodate each configuration setting I add. Because I found myself running out of time, I settled for keeping the configuration settings to a single simple option so I could have time to write this article. So unless you are disciplined enough to spec out your entire first project before starting it I recommend building your settings page first. Then as you build the rest of your Sidebar Gadget you can quickly add in settings as you write the application code and you won't have to go back and rewrite sections to accommodate new settings.&lt;/p&gt; &lt;p nd="59"&gt;Each page (gadget, settings, flyout) is independent and does not share variables. So the Sidebar Gadget object model contains an &lt;code nd="60"&gt;System.Gadget.Settings&lt;/code&gt; object which allows you to persist data while your Sidebar Gadget is running. It is very useful for saving state data and communicating between the different pages of your Sidebar Gadget. Your settings page is a means to allow users to make configuration changes to your Gadget and persist those during the current session.&lt;/p&gt;&lt;img alt="" src="http://www.codeproject.com/gadgets/SidebarImageFeed/SettingsControl.jpg" height="72" width="46" /&gt;  &lt;p nd="61"&gt;A settings page is not required, but when you do create one you will see the above icon included below the close button next to your gadget. And when you click on it you'll get something like the image below. As I said before, I am not a graphic designer, so the part I appreciate about the settings page is it's simplicity. Even though you need to include a full HTML page (&lt;code nd="62"&gt;HTML&lt;/code&gt;, &lt;code nd="63"&gt;HEAD&lt;/code&gt; and &lt;code nd="64"&gt;BODY&lt;/code&gt; &lt;a itxtdid="3146775" target="_blank" href="http://www.codeproject.com/gadgets/SidebarImageFeed.asp#" style="border-bottom: 0.075em solid darkgreen; font-weight: normal; font-size: 100%; text-decoration: underline; color: darkgreen; background-color: transparent; padding-bottom: 1px;" class="iAs"&gt;elements&lt;/a&gt;) the only other thing you need is to add a &lt;code nd="65"&gt;STYLE&lt;/code&gt; element to designate the height and width of the body and then drop a couple HTML controls onto the page. Everything around the page, including the "OK" and "Cancel" buttons and their functionality comes pre-built as part of the Sidebar Gadget package. I chose to go one step further and add a &lt;code nd="66"&gt;DIV&lt;/code&gt; tag as a place holder for validation errors on the page.&lt;/p&gt;&lt;img alt="" src="http://www.codeproject.com/gadgets/SidebarImageFeed/SettingsPage.jpg" height="252" width="268" /&gt; &lt;pre nd="67" lang="HTML"&gt;&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;br /&gt;   &lt;head&gt;&lt;br /&gt;       &lt;title&gt; Settings&lt;/title&gt;&lt;br /&gt;       &lt;script type="text/javascript" src="js/settings.js"&gt; &lt;/script&gt;&lt;br /&gt;       &lt;style type="text/css"&gt;&lt;br /&gt;           body{&lt;br /&gt;               width:200px;&lt;br /&gt;               height:200px;&lt;br /&gt;           }&lt;br /&gt;       &lt;/style&gt;&lt;br /&gt;   &lt;/head&gt;&lt;br /&gt;   &lt;body onload="loadSettings();"&gt;&lt;br /&gt;       List size (#):&lt;input type="text" id="maxCount" size="3"&gt;&lt;br /&gt;       &lt;div id="errorMessage"&lt;br /&gt;            style="color:Red;font-size:12pt;font-family:Calibri;"&gt; &lt;/div&gt;&lt;br /&gt;   &lt;/body&gt;&lt;br /&gt;&lt;/html&gt;&lt;/pre&gt; &lt;div style="background-color: rgb(204, 204, 204);"&gt;&lt;strong style="color: red;"&gt;Gotcha #2&lt;/strong&gt;  &lt;p nd="68"&gt;A lesson I learned is that certain small details can cause a lot of headaches. When I created my first HTML page for this project I added a &lt;code nd="69"&gt;SCRIPT&lt;/code&gt; tag to the &lt;code nd="70"&gt;HEAD&lt;/code&gt; element to reference an external &lt;code nd="71"&gt;.js&lt;/code&gt; file. But I couldn't figure out why the Sidebar Gadget wouldn't load. (This was when I decided I needed an IDE with script debugging capability if I wanted to continue with this endeavor). It turns out I could not use the following format for my script tag: &lt;code nd="72"&gt;&lt;script type="&lt;span" nd="73" class="cpp-string"&gt;"text/javascript"&lt;/span&gt; src=&lt;span nd="74" class="cpp-string"&gt;"js/settings.js"&lt;/span&gt; /&gt;&lt;/code&gt;. Unless you have a separate closing tag for your script reference, the Sidebar will not recognize it. So make sure your external &lt;code nd="75"&gt;SCRIPT&lt;/code&gt; tags use this format: &lt;code nd="76"&gt;&lt;script type="&lt;span" nd="77" class="cpp-string"&gt;"text/javascript"&lt;/span&gt; src=&lt;span nd="78" class="cpp-string"&gt;"js/settings.js"&lt;/span&gt;&gt;&lt;/script&gt;&lt;/code&gt;&lt;/p&gt;&lt;/div&gt; &lt;p nd="79"&gt;In order to use the settings page you'll need the following two lines of code which will be called from your main page:&lt;/p&gt;&lt;pre nd="80" lang="jscript"&gt;System.Gadget.settingsUI = &lt;span nd="81" class="cpp-string"&gt;"settings.htm"&lt;/span&gt;;&lt;br /&gt;System.Gadget.onSettingsClosed = settingsUpdated;&lt;br /&gt;&lt;/pre&gt; &lt;p nd="82"&gt;The first line should be called from your &lt;code nd="83"&gt;onload&lt;/code&gt; event to tell the Sidebar you are using a settings page. This will add the settings button next to your gadget. When the user clicks this button, it will load your settings page. The second line indicates a method (in this case &lt;code nd="84"&gt;settingsUpdated&lt;/code&gt;) to be called when the settings page successfully closes. It will allow you to read the new settings and update the behavior or layout of your Sidebar Gadget.&lt;/p&gt;&lt;pre nd="85" lang="jscript"&gt;&lt;span class="cpp-keyword"&gt;function&lt;/span&gt; loadSettings()&lt;br /&gt;{&lt;br /&gt;   &lt;span class="cpp-comment"&gt;//set the close event handler&lt;/span&gt;&lt;br /&gt;   System.Gadget.onSettingsClosing = onClose;&lt;br /&gt;  &lt;br /&gt;   &lt;span class="cpp-comment"&gt;//read the current setting&lt;/span&gt;&lt;br /&gt;   &lt;span class="cpp-keyword"&gt;var&lt;/span&gt; sMaxCount = System.Gadget.Settings.read(SETTING_MAX_GALLERY_COUNT);&lt;br /&gt;  &lt;br /&gt;   &lt;span class="cpp-comment"&gt;//check to see if it has been set&lt;/span&gt;&lt;br /&gt;   &lt;span class="cpp-keyword"&gt;if&lt;/span&gt;(sMaxCount != &lt;span nd="86" class="cpp-string"&gt;""&lt;/span&gt;)&lt;br /&gt;       gMaxCount = parseInt(sMaxCount);&lt;br /&gt;      &lt;br /&gt;   &lt;span class="cpp-comment"&gt;//set the value of the HTML control&lt;/span&gt;&lt;br /&gt;   maxCount.value = gMaxCount;&lt;br /&gt;}           &lt;br /&gt;&lt;/pre&gt; &lt;p nd="87"&gt;When your settings page loads, you'll need to do at least two things: set the &lt;code nd="88"&gt;onSettingsClosing&lt;/code&gt; event handler, and read the current settings values to display them in the controls on the settings UI.&lt;/p&gt; &lt;p nd="89"&gt;The first is straightforward, just create a function with the following signature and pass it to the onSettingsClosing delegate: &lt;code nd="90"&gt;function (parameter1)&lt;/code&gt;. The name of the function and the parameter are up to you but here's what my function looks like:&lt;/p&gt;&lt;pre nd="91" lang="jscript"&gt;&lt;span class="cpp-keyword"&gt;function&lt;/span&gt; onClose(event)&lt;br /&gt;{&lt;br /&gt;   &lt;span class="cpp-keyword"&gt;if&lt;/span&gt;(event.closeAction == event.Action.commit)&lt;br /&gt;   {&lt;br /&gt;       &lt;span class="cpp-comment"&gt;//make sure the value entered was numeric&lt;/span&gt;&lt;br /&gt;       &lt;span class="cpp-keyword"&gt;if&lt;/span&gt;(isNaN(maxCount.value))&lt;br /&gt;       {&lt;br /&gt;           &lt;span class="cpp-comment"&gt;//display error message&lt;/span&gt;&lt;br /&gt;           errorMessage.innerHTML = &lt;span nd="92" class="cpp-string"&gt;"Please enter an integer value."&lt;/span&gt;;&lt;br /&gt;          &lt;br /&gt;           &lt;span class="cpp-comment"&gt;//cancel the 'Ok' action&lt;/span&gt;&lt;br /&gt;           event.cancel = &lt;span class="cpp-keyword"&gt;true&lt;/span&gt;;&lt;br /&gt;          &lt;br /&gt;           &lt;span class="cpp-comment"&gt;//exit function&lt;/span&gt;&lt;br /&gt;           &lt;span class="cpp-keyword"&gt;return&lt;/span&gt;;&lt;br /&gt;       }&lt;br /&gt;      &lt;br /&gt;       &lt;span class="cpp-comment"&gt;//get the integer value&lt;/span&gt;&lt;br /&gt;       gMaxCount = parseInt(maxCount.value);&lt;br /&gt;      &lt;br /&gt;       &lt;span class="cpp-comment"&gt;//save settings&lt;/span&gt;&lt;br /&gt;       System.Gadget.Settings.write(SETTING_MAX_GALLERY_COUNT, gMaxCount);&lt;br /&gt;      &lt;br /&gt;       &lt;span class="cpp-comment"&gt;//indicate success&lt;/span&gt;&lt;br /&gt;       event.cancel = &lt;span class="cpp-keyword"&gt;false&lt;/span&gt;;&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt; &lt;p nd="93"&gt;The parameter passed to your event handler is the event arguments. This is another case where I did not find documentation other than what was in the code samples I came across. If anyone finds documentation, I will gladly include it in my resource links. The &lt;code nd="94"&gt;event.Action&lt;/code&gt; property has two possible values: &lt;code nd="95"&gt;commit&lt;/code&gt; or &lt;code nd="96"&gt;cancel&lt;/code&gt;. They correspond to the "Ok" and "Cancel" buttons on the settings UI.&lt;/p&gt; &lt;p nd="97"&gt;In this case, I check to see if the user clicked the "OK" button (&lt;code nd="98"&gt;Action.commit&lt;/code&gt;) and then validate the data to make sure the value is numeric. If it isn't, I display an error message and set &lt;code nd="99"&gt;event.cancel = &lt;span class="cpp-keyword"&gt;true&lt;/span&gt;&lt;/code&gt; so that the user will be returned to the settings page to either cancel the operation or correct the problem and resave the settings. If everything is valid, I save the settings and set &lt;code nd="100"&gt;event.cancel = &lt;span class="cpp-keyword"&gt;false&lt;/span&gt;&lt;/code&gt; so the settings page will close and the user will be returned to my Sidebar Gadget.&lt;/p&gt; &lt;p nd="101"&gt;When you want to persist your settings you have two methods: &lt;code nd="102"&gt;write(string name, obj value)&lt;/code&gt; and &lt;code nd="103"&gt;writeString(string name, obj value)&lt;/code&gt;. When you use &lt;code nd="104"&gt;write&lt;/code&gt; the Settings object will try and guess the type of your value. If your value is a string, use &lt;code nd="105"&gt;writeString&lt;/code&gt; to eliminate the guesswork when you can.&lt;/p&gt; &lt;p nd="106"&gt;This brings us to the second step I mentioned: reading the current settings. The &lt;code nd="107"&gt;write&lt;/code&gt; and &lt;code nd="108"&gt;writeString&lt;/code&gt; methods each have corresponding read methods: &lt;code nd="109"&gt;read(string name)&lt;/code&gt; and &lt;code nd="110"&gt;readString(string name)&lt;/code&gt;. When you read from the Settings object, make sure and check the value for an empty string (&lt;code&gt;&lt;span nd="111" class="cpp-string"&gt;""&lt;/span&gt;&lt;/code&gt;). If the setting is empty or has not been set, it will return and empty string instead of a null value. When using boolean values, a tip I learned from a tutorial I read was to cast the value to force it as boolean. You can cast it like this:&lt;/p&gt;&lt;pre nd="112" lang="jscript"&gt;&lt;span class="cpp-keyword"&gt;var&lt;/span&gt; valueFromSettings = System.Gadget.Settings.read(&lt;span nd="113" class="cpp-string"&gt;"myValue"&lt;/span&gt;);&lt;br /&gt;&lt;span class="cpp-keyword"&gt;var&lt;/span&gt; myBool = !!valueFromSettings;&lt;/pre&gt; &lt;p nd="114"&gt;Now lest move on to the actual Gadget functionality&lt;/p&gt; &lt;h2&gt;Step 3: The Gadget UI&lt;/h2&gt;&lt;img alt="" src="http://www.codeproject.com/gadgets/SidebarImageFeed/Gadget.jpg" height="201" width="145" /&gt;  &lt;p nd="115"&gt;My goal in creating this gadget was to duplicate the RSS Reader gadget's functionality and pull an XML feed which I would use as a source to build a list of the most recent photo galleries on my site. Something I hadn't mentioned yet, is that because of the architecture of Sidebar Gadgets you can open up any Gadget on your system and view the source code, just like if you were viewing a web page in IE. No, I don't mean you can right-click and select "view source...". But you can navigate to the directory where the gadget is located and view the source files. So when I got started I opened up the RSS Reader and realized they were using the Feed Store built-in to IE. And since I would not be using RSS, Atom or any other standard schema for my XML I had to turn elsewhere.&lt;/p&gt; &lt;p nd="116"&gt;After some playing around with XSLT, I opted to go with AJAX instead because it would make certain features easier to implement. There are some good AJAX tutorials on the site I used when I used AJAX for the first time, so do a search and read a few of them if you're not familiar with the technology yet.&lt;/p&gt; &lt;p nd="117"&gt;The next decision I had to make was how to make the XML feed available to the gadget. So in order to simplify things and allow others to use the source code for this gadget on their local machines, I decided to create two static XML files and put them on my local web server. I have included these two xml files and Feed.xml and Feed2.xml in the source files included with the article. You can place them on your local web server or a remote one it doesn't matter. As I was building this gadget, I had the gadget installed on my Vista virtual machine and my feed files stored in my IIS virtual directory on Windows XP. When I wanted to test the auto update ability, I just swapped the files back and forth to imitate a dynamic process.&lt;/p&gt; &lt;p nd="118"&gt;For brevity sake I haven't included the actual AJAX code here, just the pertinent stuff:&lt;/p&gt; &lt;h3&gt;gadget.js&lt;/h3&gt;&lt;pre nd="119" lang="jscript"&gt;&lt;span class="cpp-comment"&gt;///////////////////////////////////////////////&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//  loadMain()&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//  Summary: called by body onload event from &lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//      gadget.htm. Sets Gadget file references&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//      and loads XML data&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;///////////////////////////////////////////////&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;function&lt;/span&gt; loadMain()&lt;br /&gt;{&lt;br /&gt;   &lt;span class="cpp-comment"&gt;// ... other init code here ....&lt;/span&gt;&lt;br /&gt;          &lt;br /&gt;   &lt;span class="cpp-comment"&gt;//get settings&lt;/span&gt;&lt;br /&gt;   &lt;span class="cpp-keyword"&gt;var&lt;/span&gt; sMaxCount = System.Gadget.Settings.read(SETTING_MAX_GALLERY_COUNT);&lt;br /&gt;   &lt;span class="cpp-keyword"&gt;if&lt;/span&gt;( sMaxCount != &lt;span nd="120" class="cpp-string"&gt;""&lt;/span&gt; )&lt;br /&gt;       gListMax = parseInt(sMaxCount);&lt;br /&gt;      &lt;br /&gt; &lt;span class="cpp-comment"&gt;//set flag to resize the height of the&lt;/span&gt;&lt;br /&gt; &lt;span class="cpp-comment"&gt;//gadget after building list&lt;/span&gt;&lt;br /&gt;   gResizeGadget = &lt;span class="cpp-keyword"&gt;true&lt;/span&gt;;&lt;br /&gt;  &lt;br /&gt;   &lt;span class="cpp-comment"&gt;//retrieve data&lt;/span&gt;&lt;br /&gt;   makeXmlRequest(DATA_RESOURCE_URI, AJAX_TYPE_GALLERIES);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt; &lt;h3&gt;ajax.js&lt;/h3&gt;&lt;div class="smallText" id="premain7" style="width: 100%;"&gt;&lt;img preid="7" src="http://www.codeproject.com/images/minus.gif" id="preimg7" height="9" width="9" /&gt;&lt;span nd="121" preid="7" style="margin-bottom: 0pt;" id="precollapse7"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre nd="122" style="margin-top: 0pt;" id="pre7" lang="jscript"&gt;&lt;span class="cpp-comment"&gt;/////////////////////////////////////////////////////////////////&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//  getXmlContent()&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//  Summary: called by the onreadystatechanged event, if&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//      the request is complete it gets the XML document and &lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//      saves it to disk so that it can be accessed by all&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//      gadget pages. Then it calls printGalleries() to &lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//      update the list of galleries on the gadget.&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//////////////////////////////////////////////////////////////////&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;function&lt;/span&gt; getXmlContent()&lt;br /&gt;{&lt;br /&gt;   &lt;span class="cpp-comment"&gt;//check to see if the request is complete&lt;/span&gt;&lt;br /&gt;   &lt;span class="cpp-keyword"&gt;if&lt;/span&gt;(checkReadyState(gRequest))&lt;br /&gt;   {&lt;br /&gt;       &lt;span class="cpp-comment"&gt;//get XML doc&lt;/span&gt;&lt;br /&gt;       &lt;span class="cpp-keyword"&gt;var&lt;/span&gt; ajaxDoc = gRequest.responseXML;&lt;br /&gt;      &lt;br /&gt;   &lt;span class="cpp-comment"&gt;//store XML in global variable&lt;/span&gt;&lt;br /&gt;     gXmlDoc = ajaxDoc;&lt;br /&gt;     &lt;br /&gt;       &lt;span class="cpp-comment"&gt;//if this is a galleries xml doc refresh the gadget&lt;/span&gt;&lt;br /&gt;       &lt;span class="cpp-keyword"&gt;if&lt;/span&gt;(gAjaxType == AJAX_TYPE_GALLERIES)&lt;br /&gt;           printGalleries();&lt;br /&gt;          &lt;br /&gt;       &lt;span class="cpp-comment"&gt;//set timer to refresh data again in 5 minutes&lt;/span&gt;&lt;br /&gt;       setTimeout(&lt;span nd="123" class="cpp-string"&gt;"refreshData()"&lt;/span&gt;, &lt;span class="cpp-literal"&gt;5&lt;/span&gt; * &lt;span class="cpp-literal"&gt;60000&lt;/span&gt;);&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;/////////////////////////////////////////////////////////&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//  refreshData()&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//  Summary: downloads data resource uri and refreshes &lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//      xml data. If xml data is currently being read&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//      the process is rescheduled for 1 min later&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;/////////////////////////////////////////////////////////&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;function&lt;/span&gt; refreshData()&lt;br /&gt;{&lt;br /&gt;   &lt;span class="cpp-comment"&gt;//make sure the data isn't currently being read&lt;/span&gt;&lt;br /&gt;   &lt;span class="cpp-keyword"&gt;if&lt;/span&gt;(gReadingXml)&lt;br /&gt;   {&lt;br /&gt;       &lt;span class="cpp-comment"&gt;//reschedule data refresh&lt;/span&gt;&lt;br /&gt;       setTimeout(&lt;span nd="124" class="cpp-string"&gt;"refreshData()"&lt;/span&gt;, &lt;span class="cpp-literal"&gt;1&lt;/span&gt; * &lt;span class="cpp-literal"&gt;60000&lt;/span&gt;);&lt;br /&gt;       &lt;span class="cpp-keyword"&gt;return&lt;/span&gt;;&lt;br /&gt;   }&lt;br /&gt;  &lt;br /&gt;   &lt;span class="cpp-comment"&gt;//add 'random' parameter to prevent caching&lt;/span&gt;&lt;br /&gt;   &lt;span class="cpp-keyword"&gt;var&lt;/span&gt; dt = &lt;span class="cpp-keyword"&gt;new&lt;/span&gt; Date();&lt;br /&gt;  &lt;br /&gt;   &lt;span class="cpp-comment"&gt;//resubmit AJAX request&lt;/span&gt;&lt;br /&gt;   makeXmlRequest(DATA_RESOURCE_URI + &lt;span nd="125" class="cpp-string"&gt;"?t="&lt;/span&gt; + dt.getTime(),&lt;br /&gt;                  AJAX_TYPE_GALLERIES);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt; &lt;p nd="126"&gt;To tie the missing stuff together here, &lt;code nd="127"&gt;onLoad&lt;/code&gt; calls &lt;code nd="128"&gt;makeXmlRequest&lt;/code&gt; which calls &lt;code nd="129"&gt;getXmlContent&lt;/code&gt; when it completes. Then &lt;code nd="130"&gt;getXmlContent&lt;/code&gt; stores the XML in a global variable and calls &lt;code nd="131"&gt;printGalleries&lt;/code&gt; which uses the global variable to read the XML and build the list on the gadget UI. I haven't included it here because of it's length and there's nothing in &lt;code nd="132"&gt;printGalleries&lt;/code&gt; which is unique to the Sidebar Gadget API. Then a timer is set to requery the remote server for updates to the feed by calling &lt;code nd="133"&gt;refreshData&lt;/code&gt;.&lt;/p&gt; &lt;h3&gt;Layout&lt;/h3&gt; &lt;p nd="134"&gt;A design aspect that you will be forced to deal with is the limited space you are given for your gadget. The width of the Sidebar is 130 pixels, which is not much space for anything. But certainly in our case there isn't much room for text. Because I'm pretty new to DHTML, my first attempt to deal with this was to count up the maximum number of characters I could fit using the current font, then use the &lt;code nd="135"&gt;substring&lt;/code&gt; method to chop that string and append an ellipsis(...). But I couldn't get it to look as neat as the RSS Feed reader Gadget. So again, I opened up the code to see what they had done. Now those of you who are more experienced with CSS and DHTML may have seen this one coming a mile away, but bear with me here.&lt;/p&gt;&lt;div class="smallText" id="premain8" style="width: 100%;"&gt;&lt;img preid="8" src="http://www.codeproject.com/images/minus.gif" id="preimg8" height="9" width="9" /&gt;&lt;span nd="136" preid="8" style="margin-bottom: 0pt;" id="precollapse8"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre nd="137" style="margin-top: 0pt;" id="pre8" lang="jscript"&gt;&lt;span class="cpp-comment"&gt;//create a row and a cell to display the data&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;var&lt;/span&gt; newRow = table.insertRow(table.rows.length);   &lt;br /&gt;&lt;span class="cpp-keyword"&gt;var&lt;/span&gt; cell = newRow.insertCell(&lt;span class="cpp-literal"&gt;0&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//build the innerHTML string&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;var&lt;/span&gt; html = &lt;span nd="138" class="cpp-string"&gt;"&lt;div id="\"&gt;item&lt;span nd="139" class="cpp-string"&gt;" + i + "&lt;/span&gt;\&lt;span nd="140" class="cpp-string"&gt;" title=\"&lt;/span&gt;&lt;span class="cpp-string"&gt;" + node.getAttribute("&lt;/span&gt;name&lt;span class="cpp-string"&gt;")&lt;br /&gt;html += "&lt;/span&gt;\&lt;span class="cpp-string"&gt;" onClick=\"&lt;/span&gt;loadFlyout('&lt;span class="cpp-string"&gt;" + node.getAttribute("&lt;/span&gt;id&lt;span class="cpp-string"&gt;");&lt;br /&gt;html += "&lt;/span&gt;');&lt;span class="cpp-keyword"&gt;this&lt;/span&gt;.blur();\&lt;span class="cpp-string"&gt;""&lt;/span&gt;;&lt;br /&gt;html += &lt;span class="cpp-string"&gt;" onmouseover=\"&lt;/span&gt;&lt;span class="cpp-keyword"&gt;this&lt;/span&gt;.style.color='Red'\&lt;span class="cpp-string"&gt;""&lt;/span&gt;;&lt;br /&gt;html += &lt;span class="cpp-string"&gt;" onmouseout=\"&lt;/span&gt;&lt;span class="cpp-keyword"&gt;this&lt;/span&gt;.style.color=''\&lt;span class="cpp-string"&gt;""&lt;/span&gt;;&lt;br /&gt;html += &lt;span class="cpp-string"&gt;" style=\"&lt;/span&gt;font-size:13px;margin-bottom:0px;margin-top:0px;\&lt;span class="cpp-string"&gt;"&gt; "&lt;/span&gt;;&lt;br /&gt;html += node.getAttribute(&lt;span class="cpp-string"&gt;"name"&lt;/span&gt;) + &lt;span class="cpp-string"&gt;"&lt;/div&gt; "&lt;/span&gt;;&lt;br /&gt;html += &lt;span class="cpp-string"&gt;"&lt;div id="\"&gt;sport&lt;span class="cpp-string"&gt;" + i + "&lt;/span&gt;\&lt;span class="cpp-string"&gt;" style=\"&lt;/span&gt;color:White;font-size:11px;&lt;span class="cpp-string"&gt;";&lt;br /&gt;html += "&lt;/span&gt; color:#67788a;margin-top:0px;margin-bottom:0px;\&lt;span class="cpp-string"&gt;"&gt; "&lt;/span&gt; ;&lt;br /&gt;html += node.getAttribute(&lt;span class="cpp-string"&gt;"sport"&lt;/span&gt;) + &lt;span class="cpp-string"&gt;"&lt;/div&gt; "&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//set the innerHTML for the table cell&lt;/span&gt;&lt;br /&gt;cell.innerHTML = html;&lt;br /&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//format the title so that long text gets cut of with an ellipsis&lt;/span&gt;&lt;br /&gt;eval(&lt;span class="cpp-string"&gt;"item"&lt;/span&gt; + i).style.textOverflow = &lt;span class="cpp-string"&gt;"ellipsis"&lt;/span&gt;;&lt;br /&gt;eval(&lt;span class="cpp-string"&gt;"item"&lt;/span&gt; + i).style.overflow = &lt;span class="cpp-string"&gt;"hidden"&lt;/span&gt;;&lt;br /&gt;eval(&lt;span class="cpp-string"&gt;"item"&lt;/span&gt; + i).style.whiteSpace = &lt;span class="cpp-string"&gt;"nowrap"&lt;/span&gt;;&lt;br /&gt;eval(&lt;span class="cpp-string"&gt;"item"&lt;/span&gt; + i).style.width = &lt;span class="cpp-literal"&gt;115&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//format the sport so that long text gets cut of with an ellipsis&lt;/span&gt;&lt;br /&gt;eval(&lt;span class="cpp-string"&gt;"sport"&lt;/span&gt; + i).style.textOverflow = &lt;span class="cpp-string"&gt;"ellipsis"&lt;/span&gt;;&lt;br /&gt;eval(&lt;span class="cpp-string"&gt;"sport"&lt;/span&gt; + i).style.overflow = &lt;span class="cpp-string"&gt;"hidden"&lt;/span&gt;;&lt;br /&gt;eval(&lt;span class="cpp-string"&gt;"sport"&lt;/span&gt; + i).style.whiteSpace = &lt;span class="cpp-string"&gt;"nowrap"&lt;/span&gt;;&lt;br /&gt;eval(&lt;span class="cpp-string"&gt;"sport"&lt;/span&gt; + i).style.width = &lt;span class="cpp-literal"&gt;115&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//place a border between items to make it easier to read&lt;/span&gt;&lt;br /&gt;eval(&lt;span class="cpp-string"&gt;"sport"&lt;/span&gt; + i).style.borderBottom = &lt;span class="cpp-string"&gt;"dotted 1px White"&lt;/span&gt;;&lt;/pre&gt; &lt;p&gt;There are two important steps here to point out. First, you must be sure to set the width of the HTML element which will act as the container for your text. In this case I am using a &lt;code&gt;DIV&lt;/code&gt; tag within a &lt;code&gt;TD&lt;/code&gt; element. So I have set the width of the &lt;code&gt;DIV&lt;/code&gt; tag. Then for each of the text elements, I set &lt;code&gt;textOverflow&lt;/code&gt;, &lt;code&gt;overflow&lt;/code&gt; and &lt;code&gt;whiteSpace&lt;/code&gt; style properties. You don't have to set them in any particular order, as you can see above, but they each need to be set to get the effect of the text running off the side of the page.&lt;/p&gt; &lt;p&gt;So now we have a Gadget which reads from a remote XML feed and then displays a list of the items in the feed. For navigation controls, I borrowed the graphics used by the RSS Reader Gadget. They include previous and next buttons, and a counter to display the start and end index of the items currently in the list. Let's move on now to what we can now do with that data.&lt;/p&gt; &lt;h2&gt;Step 4: The Flyout&lt;/h2&gt;&lt;img alt="" src="http://www.codeproject.com/gadgets/SidebarImageFeed/Flyout.jpg" height="269" width="600" /&gt;  &lt;p&gt;The flyout is an optional component of the Sidebar Gadget, but it's great when you need more room to display your application. The only limit to the size of your flyout is that of the user's display resolution. With the graphics capabilities required by Windows Vista in the first place it's probably safe to assume that your users are going to have a minimum of 1024x768 resolution.&lt;/p&gt; &lt;p&gt;To open your flyout only takes two lines of code. You need to specify the HTML file used by the flyout and set the &lt;code&gt;show&lt;/code&gt; property to true. Like this:&lt;/p&gt;&lt;pre lang="js"&gt;System.Gadget.Flyout.file = "flyout.htm";&lt;br /&gt;System.Gadget.Flyout.show = true;&lt;br /&gt;&lt;/pre&gt; &lt;p&gt;Where you place these commands isn't so important as the order they are in, before you display the flyout you must indicate the file to be used. You also have the option of registering a method with either or both of the &lt;code&gt;onShow&lt;/code&gt; and &lt;code&gt;onHide&lt;/code&gt; events. Keep in mind that the Gadget page and the Flyout are independent and cannot communicate directly with one another. This means that the &lt;code&gt;onShow&lt;/code&gt; and &lt;code&gt;onHide&lt;/code&gt; events are used for updating the Gadget UI or trigger some behavior in the main Gadget page based on those events. We'll come back to these events in a minute.&lt;/p&gt; &lt;p&gt;The best way to communicate with the flyout is to use the &lt;code&gt;System.Gadget.Settings&lt;/code&gt; object. In this case we use it to store the id of the gallery that was clicked on the Gadget so the flyout can read from the XML and display the images. Here's where we hit a bit of a snag.&lt;/p&gt; &lt;div style="background-color: rgb(204, 204, 204);"&gt;&lt;strong style="color: red;"&gt;Gotcha #3&lt;/strong&gt;  &lt;p&gt;The XML feed was too large to pass into the settings object. Whenever I tried to write the XML as a string, it was unsuccessful. There were no errors, the program just kept running as if everything was ok. But when the flyout tried to read the XML from &lt;code&gt;System.Gadget.Settings.readString&lt;/code&gt; the result was an empty string. I tried inspecting the settings object from the Gadget as soon as I had written the XML, but still the value wasn't getting stored. I knew I was doing everything correctly because I could read the gallery id value I had passed, just not the XML.&lt;/p&gt; &lt;p&gt;To work around this I decided to write the XML to disk, then I could read it in from the flyout. The next obstacle was that the Sidebar object model has no read and write capability without user interaction. If you want to open or save a file the &lt;code&gt;System.Shell&lt;/code&gt; object and it's children provide methods to ask the user where they want to save a file, or which file to open. And it has the ability to inspect the file system objects and to create and delete folders, but not to open files as text or write to them behind the scenes. However, this problem was easily solved by using the &lt;a href="http://www.tutorial-web.com/asp/fso/index.asp" target="_blank"&gt;&lt;code&gt;Scripting.FileSystemObject&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/div&gt; &lt;h3&gt;ajax.js&lt;/h3&gt;&lt;div class="smallText" id="premain10" style="width: 100%;"&gt;&lt;img preid="10" src="http://www.codeproject.com/images/minus.gif" id="preimg10" height="9" width="9" /&gt;&lt;span preid="10" style="margin-bottom: 0pt;" id="precollapse10"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre10" lang="jscript"&gt;&lt;span class="cpp-comment"&gt;///////////////////////////////////////////////////&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//  saveXmlDoc(xmlDoc)&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//  Parameters: xmlDoc - XmlDocment object to be saved&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//      to local disk&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//  Summary: saves the specified XmlDocment object to&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//      the local disk to make it available to flyout.htm&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;///////////////////////////////////////////////////&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;function&lt;/span&gt; saveXmlDoc(xmlDoc)&lt;br /&gt;{&lt;br /&gt;   &lt;span class="cpp-comment"&gt;//set flag so data won't get overwritten while we're using it&lt;/span&gt;&lt;br /&gt;   gReadingXml = &lt;span class="cpp-keyword"&gt;true&lt;/span&gt;;&lt;br /&gt;  &lt;br /&gt;   &lt;span class="cpp-comment"&gt;//get storage path&lt;/span&gt;&lt;br /&gt;   &lt;span class="cpp-keyword"&gt;var&lt;/span&gt; path = getDataPath();&lt;br /&gt;  &lt;br /&gt;   &lt;span class="cpp-comment"&gt;//create/open text file&lt;/span&gt;&lt;br /&gt;   &lt;span class="cpp-keyword"&gt;var&lt;/span&gt; fso = &lt;span class="cpp-keyword"&gt;new&lt;/span&gt; ActiveXObject(&lt;span class="cpp-string"&gt;"Scripting.FileSystemObject"&lt;/span&gt;);&lt;br /&gt;   &lt;span class="cpp-keyword"&gt;var&lt;/span&gt; output = fso.OpenTextFile(path,&lt;span class="cpp-literal"&gt;2&lt;/span&gt;,&lt;span class="cpp-keyword"&gt;true&lt;/span&gt;);&lt;br /&gt;  &lt;br /&gt;   &lt;span class="cpp-comment"&gt;//write XML data to file&lt;/span&gt;&lt;br /&gt;   output.WriteLine(xmlDoc.xml);&lt;br /&gt;  &lt;br /&gt;   &lt;span class="cpp-comment"&gt;//close file&lt;/span&gt;&lt;br /&gt;   output.Close();&lt;br /&gt;  &lt;br /&gt;   &lt;span class="cpp-comment"&gt;//reset flag&lt;/span&gt;&lt;br /&gt;   gReadingXml = &lt;span class="cpp-keyword"&gt;false&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;/////////////////////////////////////////////////////////&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//  deleteXmlDoc(path)&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//  Parameters: path - path of the XML file to delete&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//  Summary: deletes specified file from local disk.&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;/////////////////////////////////////////////////////////&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;function&lt;/span&gt; deleteXmlDoc(path)&lt;br /&gt;{&lt;br /&gt;   &lt;span class="cpp-keyword"&gt;var&lt;/span&gt; fso = &lt;span class="cpp-keyword"&gt;new&lt;/span&gt; ActiveXObject(&lt;span class="cpp-string"&gt;"Scripting.FileSystemObject"&lt;/span&gt;);&lt;br /&gt;   fso.DeleteFile(path);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt; &lt;p&gt;Now I was able to create save and open functions which used the &lt;code&gt;Scripting.FileSystemObject&lt;/code&gt; to allow the XML to be passed back and forth between the Gadget and the Flyout.&lt;/p&gt; &lt;p&gt;Which brings us to permissions. When writing files the Gadget can write files to the file system, but only within the application path and subdirectories. If you try to manipulate files out side that path you'll get permission denied errors. Fortunatelythe Sidebar Gadget object model has a convenient property to give you access to the application path: &lt;code&gt;System.Gadget.path&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;But because we're writing files to be passed back and forth we've created two problems for ourselves. First, the &lt;code&gt;System.Gadget.Settings&lt;/code&gt; object is instance independent, so if there are multiple instances of your control in the sidebar they don't conflict. But part of that benefit, is that you have no way of knowing how many instances are open or what their settings are. So if I'm writing files back and forth, I need to make sure I'm not conflicting with other instances of my Gadget.&lt;/p&gt; &lt;p&gt;I decided the way around this was to use a file name that would be unique among all instances of my Gadget. And the easiest method available was the javascript &lt;code&gt;Data.getTime&lt;/code&gt; method which returns the number of milliseconds since Jan 1, 1970. Since the probability of a user being able to add multiple instances of my Gadget to the Sidebar is nil this works fine for our needs. Then in order to allow the Flyout to retrieve the file all I need to do is pass the path to the file to &lt;code&gt;System.Gadget.Settings&lt;/code&gt;.  &lt;/p&gt;&lt;h3&gt;Event Sequence&lt;/h3&gt; &lt;p&gt;I want to backtrack for a moment to the Flyout events &lt;code&gt;onShow&lt;/code&gt; and &lt;code&gt;onHide&lt;/code&gt;. My first choice was to use these two events to write and clean up the XML file. The &lt;code&gt;onShow&lt;/code&gt; seemed a good choice because it was the perfect trigger to tell my Gadget when the file was needed. &lt;code&gt;onHide&lt;/code&gt; because I found that the Gadget has no onClose event to allow me to clean up files when I'm done. Because the &lt;code&gt;System.Gadget.Settings&lt;/code&gt; object does not persist data after a Gadget is closed, if I don't delete the files then eventually the files will pile up in the users directory over time. Disk space may be cheap, but it's up to the user to determine how to use that space, not me.&lt;/p&gt; &lt;p&gt;As it turns out, the &lt;code&gt;onHide&lt;/code&gt; event worked fine for my needs. Unfortunately, I found out that &lt;code&gt;onShow&lt;/code&gt; fires &lt;strong&gt;after&lt;/strong&gt; the &lt;code&gt;onLoad&lt;/code&gt; event of the Flyout. So now I needed to figure out how to write the file before the Flyout tried to access it in the &lt;code&gt;onLoad&lt;/code&gt; event. I finally decided to use the &lt;code&gt;onClick&lt;/code&gt; event to first, write the XML file to disk, then open the flyout. This guarantees that the file exists before the Flyout loads.&lt;/p&gt; &lt;h3&gt;gadget.js&lt;/h3&gt;&lt;pre lang="jscript"&gt;&lt;span class="cpp-comment"&gt;///////////////////////////////////////////////&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//  loadFlyout(galleryId)&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//  Parameters: galleryId - (string) the id value&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//      of the selected GALLERY element&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//  Summary: Called from onclick event of gadget.htm.&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//      It stores settings needed by flyout&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//      to display selected gallery and opens&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;//      the flyout&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-comment"&gt;///////////////////////////////////////////////&lt;/span&gt;&lt;br /&gt;&lt;span class="cpp-keyword"&gt;function&lt;/span&gt; loadFlyout(galleryId)&lt;br /&gt;{&lt;br /&gt;   &lt;span class="cpp-comment"&gt;//write the xml to local disk so it can be accessed by flyout.htm&lt;/span&gt;&lt;br /&gt;   storeXml();&lt;br /&gt;  &lt;br /&gt;   &lt;span class="cpp-comment"&gt;//display the flyout&lt;/span&gt;&lt;br /&gt;       System.Gadget.Flyout.show = &lt;span class="cpp-keyword"&gt;true&lt;/span&gt;;&lt;br /&gt;}&lt;/pre&gt; &lt;p&gt;So, as I mentioned before, when the user clicks on the name of a gallery the &lt;code&gt;onClick&lt;/code&gt; event fires and calls &lt;code&gt;loadFlyout&lt;/code&gt; and passes the id of the gallery as an argument. The &lt;code&gt;loadFlyout&lt;/code&gt; function writes the XML stored in a global variable to disk, then opens the Flyout.&lt;/p&gt; &lt;div style="background-color: rgb(204, 204, 204);"&gt;&lt;strong style="color: red;"&gt;Gotcha #4&lt;/strong&gt;  &lt;p&gt;The next issue I ran into was a surprise. I had been using an external CSS file for the general formatting of my page, and I wanted to set the background color of the Flyout. But it remained white. The page could view the CSS file, because I could change the height and width of the body, but other settings had no effect. But when I used inline styles, I had no problem. I searched around for a workaround, but only found other complaints of the problem with no solutions. At this point I abandoned the external CSS and used inline styles.&lt;/p&gt;&lt;/div&gt; &lt;h3&gt;External Links&lt;/h3&gt;&lt;img alt="" src="http://www.codeproject.com/gadgets/SidebarImageFeed/EnlargedThumbnail.jpg" height="272" width="600" /&gt;  &lt;p&gt;The last important feature of note was that I wanted a user to be able to go to my website and purchase a print of the image. I thought, there might be a problem with putting a link to an external resource on my flyout page, but there wasn't. In fact it was easier than I imagined. If you put a link to an external resource, a new IE window will open to the resource in the link - exactly the way I wanted it to happen!&lt;/p&gt; &lt;h2&gt;Step 5: Packaging Your Gadget&lt;/h2&gt; &lt;p&gt;So now, we're finished. Or almost. To deploy our newly completed Sidebar Gadget you have two options. You can simply copy the files to a new folder in the Gadget directory, then rename the folder to include ".gadget" at the end. So if our folder is named "Photogallery", just rename it to "Photogallery.gadget".&lt;/p&gt; &lt;p&gt;The above method may work fine if you are creating your own personal gadget and then just dropping it in the folder locally. But if you have a gadget like ours, and you want to deploy it to other users, this second method is actually easier. Simply create a zip file containing all the files and subfolders (but not the root folder itself), then change the .zip extension to .gadget. And that's it! When a user tries to download or open your compressed .gadget file Windows Vista will automatically install it to their user gadgets folder.&lt;/p&gt; &lt;h2&gt;The Finished Product&lt;/h2&gt; &lt;p&gt;There you have it, the complete package, from start to finish. How to develop a functional Vista Sidebar Gadget. I struggled a bit towards the end with a list of features I would have liked to implement or some changes I would make now that I better understand the process. But they'll have to wait until version 2.0. I'd be happy to hear your ideas for different features that could make this Gadget better. Here's a few that I'd like to add when I get time to work on this again:&lt;/p&gt; &lt;ul&gt;&lt;li&gt;Resize the main Gadget window when the user undocks the Gadget.  &lt;/li&gt;&lt;li&gt;Resize the Flyout window when the user clicks a thumbnail in order to make the enlarged view even bigger.  &lt;/li&gt;&lt;li&gt;Add more user configurable settings like the location of the feed, the size of the flyout, the number of thumbnails to display at a time, as well as color and font settings. &lt;/li&gt;&lt;/ul&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1192972388107063553-4135940625907522575?l=chamildz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chamildz.blogspot.com/feeds/4135940625907522575/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1192972388107063553&amp;postID=4135940625907522575' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1192972388107063553/posts/default/4135940625907522575'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1192972388107063553/posts/default/4135940625907522575'/><link rel='alternate' type='text/html' href='http://chamildz.blogspot.com/2007/01/using-vista-side-bar-gadget-to-consume.html' title='Using a vista side bar gadget to consume an image feed'/><author><name>Chamil</name><uri>http://www.blogger.com/profile/00204727013782891667</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1192972388107063553.post-1533853232601690524</id><published>2007-01-29T02:31:00.000-08:00</published><updated>2007-01-29T02:48:36.281-08:00</updated><title type='text'>Exchange Data Securely Without HTTPS/SSL-C# Web Services</title><content type='html'>&lt;span name="intelliTxt" id="intelliTXT"&gt;&lt;h2 style="color: rgb(0, 0, 0);"&gt;Introduction&lt;/h2&gt; &lt;p nd="1"&gt;In this article, I will show you how to exchange data securely with a Web Service without HTTPS/SSL but without compromising the same protection level of HTTPS/SSL. It will also give you a real life example on the implementation and limitation of the important encryption types as well as Digital Signature that are available in .NET Framework.&lt;/p&gt; &lt;h2 style="color: rgb(0, 0, 0);"&gt;Advantages&lt;/h2&gt; &lt;ol&gt;&lt;li nd="2"&gt;No Installation and configuration is required in IIS or in the Client.  &lt;/li&gt;&lt;li nd="3"&gt;No Deployment issue (Nothing to embed/ship) in the client.  &lt;/li&gt;&lt;li nd="4"&gt;No Additional Library is required.  &lt;/li&gt;&lt;li nd="5"&gt;Less easier to implement comparing alternates. &lt;/li&gt;&lt;/ol&gt; &lt;h2 style="color: rgb(0, 0, 0);"&gt;Requirements&lt;/h2&gt;If you are not familiar with Symmetric, Asymmetric Encryption and Digital Signature. I strongly suggest you read the following articles of cp before you move forward, there are also many reference available in the Web on this topic: &lt;ul&gt;&lt;li&gt;&lt;a href="http://www.codeproject.com/useritems/Crypto.asp"&gt;Cryptography 101 for the .NET Framework&lt;/a&gt;  &lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codeproject.com/dotnet/SimpleEncryption.asp"&gt;.NET Encryption Simplified&lt;/a&gt;  &lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codeproject.com/vb/net/Digital_Signatures.asp"&gt;Implementing Digital Signing in .NET&lt;/a&gt;  &lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codeproject.com/dotnet/xmldsiglic.asp"&gt;Using XML Digital Signatures for Application Licensing&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt; &lt;p nd="7"&gt;I have created the solution in Visual Studio 2005 and .NET 2.0 but it can be easily ported to Visual Studio 2003 and .NET 1.1.&lt;/p&gt; &lt;h2 style="color: rgb(0, 0, 0);"&gt;Background&lt;/h2&gt; &lt;h3 style="color: rgb(0, 0, 0);"&gt;Symmetric VS Asymmetric&lt;/h3&gt; &lt;p nd="8"&gt;I assume that you already know the difference between the Symmetric and Asymmetric encryption. In short, in Symmetric encryption both the parties (the server and client) use the same key to encrypt and decrypt the data. On the other hand, in Asymmetric encryption a pair of key (known as Public/Private Key) is used to encrypt/decrypt. If the data is encrypted with the Private Key the only way to decrypt it is the Public Key and the vice versa. &lt;/p&gt; &lt;h3 style="color: rgb(0, 0, 0);"&gt;Digital Signature&lt;/h3&gt; &lt;p nd="9"&gt;Digital Signature is also a part of the Public/Private Key implementation. The private key is used to sign the data and public key is used to verify that data has not been tampered. However, Digital signature does not retain the secrecy of the data, which means the data always remain plain (Not encrypted).&lt;/p&gt; &lt;h2 style="color: rgb(0, 0, 0);"&gt;Alternate Solutions&lt;/h2&gt; &lt;ol&gt;&lt;li nd="10"&gt;Share Common Secret Key: The easiest way to implement it to share a common secret key before the Client and Service start communicating. &lt;/li&gt;&lt;li nd="11"&gt;&lt;a href="http://msdn.microsoft.com/webservices/webservices/building/wse/default.aspx"&gt;&lt;strong&gt;MS WSE Library&lt;/strong&gt;&lt;/a&gt;: I found it difficult to implement. Maybe it will look easier to you. &lt;/li&gt;&lt;/ol&gt; &lt;h2 style="color: rgb(0, 0, 0);"&gt;The Solution&lt;/h2&gt; &lt;h3 style="color: rgb(0, 0, 0);"&gt;Initial Proof of Concept&lt;/h3&gt; &lt;p nd="12"&gt;After going thorough few details of the above mentioned articles and of course, MSDN I came up with the following message exchange between the client and server, which looks pretty, rock solid to me.&lt;/p&gt; &lt;table style="border: 1px solid rgb(0, 0, 0);" border="0" cellpadding="3" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;th style="color: rgb(255, 255, 255); background-color: rgb(0, 0, 0); text-align: left;"&gt;&lt;br /&gt;&lt;/th&gt; &lt;th nd="13" style="width: 33%; color: rgb(255, 255, 255); background-color: rgb(0, 0, 0); text-align: left;"&gt;The Client&lt;/th&gt; &lt;th nd="14" style="width: 33%; color: rgb(255, 255, 255); background-color: rgb(0, 0, 0); text-align: left;"&gt;The Server&lt;/th&gt; &lt;th nd="15" style="width: 33%; color: rgb(255, 255, 255); background-color: rgb(0, 0, 0); text-align: left;"&gt;The Hacker&lt;/th&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td nd="16" style="border-right: 1px solid rgb(0, 0, 0); border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: right;"&gt;&lt;br /&gt;1.&lt;/td&gt; &lt;td nd="17" style="border-right: 1px solid rgb(0, 0, 0); border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;Client creates random Public/Private Key Pair and sends the Server the Public Part&lt;/td&gt; &lt;td nd="18" style="border-right: 1px solid rgb(0, 0, 0); border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;The Server in turns creates a random Public/Private Key Pair and returns Public Part to Client.&lt;br /&gt; &lt;/td&gt; &lt;td nd="19" style="border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;The Hacker can only view both parties Public key.&lt;br /&gt; &lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td nd="20" style="border-right: 1px solid rgb(0, 0, 0); border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: right;"&gt;&lt;br /&gt;2.&lt;/td&gt; &lt;td nd="21" style="border-right: 1px solid rgb(0, 0, 0); border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;The Client encrypts the target data with received Server Public Key and sends it back to Server.&lt;/td&gt; &lt;td nd="22" style="border-right: 1px solid rgb(0, 0, 0); border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;The Server receives the encrypted data decrypts it with the previously generated Server Private Key.&lt;br /&gt;&lt;br /&gt;Server Process the Data.&lt;br /&gt;&lt;br /&gt;Server encrypts the process result with the previously received Client Public Key and returns back to Client.&lt;br /&gt; &lt;/td&gt; &lt;td nd="23" style="border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;The hacker only has the Server Public key. So it is not possible for the hacker to decrypt the data, as it requires the server private key to decrypt.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Again, the Hacker only has the Client Public key and thus it is not possible for the Hacker to decrypt the process result.&lt;br /&gt; &lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td nd="24" style="border-right: 1px solid rgb(0, 0, 0); border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: right;"&gt;&lt;br /&gt;3.&lt;/td&gt; &lt;td nd="25" style="border-right: 1px solid rgb(0, 0, 0); border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;The Client receives the encrypted process result and decrypts it with the previously generated Client Private Key.&lt;br /&gt; &lt;/td&gt; &lt;td style="border-right: 1px solid rgb(0, 0, 0); border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;  &lt;/td&gt; &lt;td style="border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt; &lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td nd="26" style="border-right: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: right;"&gt;&lt;br /&gt;4.&lt;/td&gt; &lt;td nd="27" style="border-right: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;The Client returns to regular processing&lt;br /&gt; &lt;/td&gt; &lt;td nd="28" style="border-right: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;The Server Goes to sleep.&lt;br /&gt; &lt;/td&gt; &lt;td nd="29" style="vertical-align: top; text-align: left;"&gt;&lt;br /&gt;The Hacker Cries.&lt;br /&gt; &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;h3 style="color: rgb(0, 0, 0);"&gt;.NET Platform&lt;/h3&gt; &lt;p nd="30"&gt;In .NET platform, there are different algorithms available for both Symmetric and Asymmetric. I am not going to explain the details of these algorithms as it is beyond the scope of this article. The characteristics are:&lt;/p&gt; &lt;h4 style="color: rgb(0, 0, 0);"&gt;Symmetric Algorithms&lt;/h4&gt; &lt;ul&gt;&lt;li nd="31"&gt;DES: 64 bit encryption - Good.  &lt;/li&gt;&lt;li nd="32"&gt;RC2: 128 bit encryption - Better.  &lt;/li&gt;&lt;li nd="33"&gt;Rijndael: 256 bit also known as AES and the most secure algorithm – The Best.  &lt;/li&gt;&lt;li nd="34"&gt;TripleDES: 192 bit encryption – Much better. &lt;/li&gt;&lt;/ul&gt; &lt;h4 style="color: rgb(0, 0, 0);"&gt;Asymmetric Algorithms&lt;/h4&gt; &lt;ul&gt;&lt;li nd="35"&gt;DSA: Does not support Encryption/Decryption. Only allows Digital Signature (So skipping from discussing).  &lt;/li&gt;&lt;li nd="36"&gt;RSA: Supports both Encryption/Decryption and Digital Signature. But it cannot encrypt/decrypt data more than 117 byte. If you want to encrypt more than 117 byte, it will throw you a Cryptographic Exception with a message that Key not valid for use in specified state. There are many references available in web, which explains this limitation. &lt;/li&gt;&lt;/ul&gt; &lt;h3 style="color: rgb(0, 0, 0);"&gt;Implementation&lt;/h3&gt; &lt;p nd="37"&gt;As mentioned above the only asymmetric algorithm that supports Encryption/Decryption is RSA, but it has the limitation of data length. Moreover, in Web Service it is regular case that we are exchanging data more than 117 bytes with those bulky xml tags. We can surly use other mechanism such as compression, use other medium such as JSON instead of XML to reduce the data size, but none of these ensures that the data size will be always less  than 117 byte. Here comes the Symmetric Key into the scene. Let me revise the previous proof of concept.&lt;/p&gt; &lt;h3 style="color: rgb(0, 0, 0);"&gt;Revised Solution&lt;/h3&gt; &lt;table style="border: 1px solid rgb(0, 0, 0);" border="0" cellpadding="3" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;th style="color: rgb(255, 255, 255); height: 22px; background-color: rgb(0, 0, 0); text-align: left;"&gt;&lt;br /&gt;&lt;/th&gt; &lt;th nd="38" style="width: 33%; color: rgb(255, 255, 255); height: 22px; background-color: rgb(0, 0, 0); text-align: left;"&gt;The Client&lt;/th&gt; &lt;th nd="39" style="width: 33%; color: rgb(255, 255, 255); height: 22px; background-color: rgb(0, 0, 0); text-align: left;"&gt;The Server&lt;/th&gt; &lt;th nd="40" style="width: 33%; color: rgb(255, 255, 255); height: 22px; background-color: rgb(0, 0, 0); text-align: left;"&gt;The Hacker&lt;/th&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td nd="41" style="border-right: 1px solid rgb(0, 0, 0); border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: right;"&gt;&lt;br /&gt;1.&lt;/td&gt; &lt;td nd="42" style="border-right: 1px solid rgb(0, 0, 0); border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;Client creates random Public/Private Key Pair and sends the Server the Public Part.&lt;br /&gt; &lt;/td&gt; &lt;td nd="43" style="border-right: 1px solid rgb(0, 0, 0); border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;The Server in turns creates a random Public/Private Key Pair and returns Public Part to client.&lt;br /&gt; &lt;/td&gt; &lt;td nd="44" style="border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;The Hacker can only view both parties Public Key.&lt;br /&gt; &lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td nd="45" style="border-right: 1px solid rgb(0, 0, 0); border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: right;"&gt;&lt;br /&gt;2.&lt;/td&gt; &lt;td nd="46" style="border-right: 1px solid rgb(0, 0, 0); border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;Client Creates a random symmetric key, encrypts it with the previously received Server Public Key, and sends it to Server.&lt;br /&gt; &lt;/td&gt; &lt;td nd="47" style="border-right: 1px solid rgb(0, 0, 0); border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;The Server receives the client symmetric key decrypts it with the previously generated Server Private Key.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now the Server Creates a Random Symmetric Key encrypts it with the Client Public Key and returns it back to the Client.&lt;br /&gt; &lt;/td&gt; &lt;td nd="48" style="border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;Same thing happens for the Hacker as in the initial proof of concept. The Hacker cannot decrypt the data, as it requires the Server Private key.&lt;br /&gt;&lt;br /&gt;Again, the Hacker only has the Client Public Key and thus it is not possible for the Hacker to decrypt the Server Symmetric Key.&lt;br /&gt; &lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td nd="49" style="border-right: 1px solid rgb(0, 0, 0); border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: right;"&gt;&lt;br /&gt;3.&lt;/td&gt; &lt;td nd="50" style="border-right: 1px solid rgb(0, 0, 0); border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;Client Receives the encrypted Symmetric Key of Server. It decrypts it with previously generated Client Private Key.&lt;br /&gt;&lt;br /&gt;Client Encrypts the target data with the previously generated Client Symmetric key and sends to Server.&lt;br /&gt; &lt;/td&gt; &lt;td nd="51" style="border-right: 1px solid rgb(0, 0, 0); border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Server Receives the Encrypted data, Server decrypts it with the previously received Client Symmetric key.&lt;br /&gt;&lt;br /&gt;Server Process the Data.&lt;br /&gt;&lt;br /&gt;Server encrypts the process result with the previously generated Server Symmetric Key and returns back to Client.&lt;br /&gt; &lt;/td&gt; &lt;td nd="52" style="border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The Hacker does not have the Client Symmetric Key and so it is not possible to decrypt the data.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Again, the Hacker does not have the Server Symmetric Key and thus it is not possible for the hacker to decrypt the process result.&lt;br /&gt; &lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td nd="53" style="border-right: 1px solid rgb(0, 0, 0); border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: right;"&gt;&lt;br /&gt;4.&lt;/td&gt; &lt;td nd="54" style="border-right: 1px solid rgb(0, 0, 0); border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;The Client receives the encrypted process result and decrypts it with the previously received Server Symmetric Key.&lt;br /&gt; &lt;/td&gt; &lt;td style="border-right: 1px solid rgb(0, 0, 0); border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;&lt;br /&gt; &lt;/td&gt; &lt;td style="border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt; &lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td nd="55" style="border-right: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: right;"&gt;&lt;br /&gt;5.&lt;/td&gt; &lt;td nd="56" style="border-right: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;The Client returns to regular processing.&lt;br /&gt; &lt;/td&gt; &lt;td nd="57" style="border-right: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;Server goes to sleep.&lt;br /&gt; &lt;/td&gt; &lt;td nd="58" style="vertical-align: top; text-align: left;"&gt;&lt;br /&gt;The Dumb Hacker cries and but the intelligent hacker might be thinking, “Hey there is something to hack”.&lt;br /&gt; &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;In this revised version an extra step just been introduced -the step 2, where both the parties exchanging Symmetric key (Lets call it session key from now on) instead of the actual data like in the initial concept. Now you might be thinking does not the RSA length limitation applies when encrypting the session key. The Answer is no, it does not, even we are exchange the most secure Rijndael key(256 bit) , the data length becomes 44 byte (256/8) which we can easily encrypted/decrypted with RSA. The only weakness of the above solution is, if the intelligent hacker can somehow discover the session key of the both parties, but which I assume is very difficult to discover based upon the encrypted data.&lt;br /&gt;&lt;br /&gt;&lt;h3 style="color: rgb(0, 0, 0);"&gt;Where is the Digital Signature?&lt;/h3&gt;You might be thinking this article starts with Digital Signature, but still no flavor of it. Let me tell you, although the digital signature is not required but you can implement it to make the solution more secure and ensure that even the intelligent hacker can revive both the parties session key but there will be no way the hacker can tamper the data. Here is the final solution.&lt;br /&gt;&lt;br /&gt;&lt;h3 style="color: rgb(0, 0, 0);"&gt;The Final Solution&lt;/h3&gt; &lt;table style="border: 1px solid rgb(0, 0, 0);" border="0" cellpadding="3" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;th style="width: 21px; color: rgb(255, 255, 255); background-color: rgb(0, 0, 0); text-align: left;"&gt;&lt;br /&gt;&lt;/th&gt; &lt;th nd="59" style="width: 33%; color: rgb(255, 255, 255); background-color: rgb(0, 0, 0); text-align: left;"&gt;The Client&lt;/th&gt; &lt;th nd="60" style="width: 33%; color: rgb(255, 255, 255); background-color: rgb(0, 0, 0); text-align: left;"&gt;The Server&lt;/th&gt; &lt;th nd="61" style="width: 33%; color: rgb(255, 255, 255); background-color: rgb(0, 0, 0); text-align: left;"&gt;The Hacker&lt;/th&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td nd="62" style="border-right: 1px solid rgb(0, 0, 0); border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; width: 21px; text-align: right;"&gt;&lt;br /&gt;1.&lt;/td&gt; &lt;td nd="63" style="border-right: 1px solid rgb(0, 0, 0); border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;Client creates random Public/Private Key Pair and sends the Server the Public Part.&lt;br /&gt;&lt;/td&gt; &lt;td nd="64" style="border-right: 1px solid rgb(0, 0, 0); border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;The Server in turns creates a random Public/Private Key Pair and returns Public Part to client.&lt;br /&gt;&lt;/td&gt; &lt;td nd="65" style="border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;The Hacker can only view both parties Public Key.&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td nd="66" style="border-right: 1px solid rgb(0, 0, 0); border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; width: 21px; text-align: right;"&gt;&lt;br /&gt;2.&lt;/td&gt; &lt;td nd="67" style="border-right: 1px solid rgb(0, 0, 0); border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;Client Creates a random Session key, encrypts it with the previously received Server Public Key, Digitally &lt;a itxtdid="3211104" target="_blank" href="http://www.codeproject.com/useritems/SecureDataExchange.asp#" style="border-bottom: 0.075em solid darkgreen; font-weight: normal; font-size: 100%; text-decoration: underline; color: darkgreen; background-color: transparent; padding-bottom: 1px;" class="iAs"&gt;Signs&lt;/a&gt; it with the Client Private Key and sends it to Server.&lt;br /&gt;&lt;/td&gt; &lt;td nd="68" style="border-right: 1px solid rgb(0, 0, 0); border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;The Server receives the client session key, Checks it integrity with the Client Public Key, if the Key has not been tampered, it decrypts the Client Session Key with the previously generated Server Private Key.&lt;br /&gt;&lt;br /&gt;Now the Server Creates a Random Session Key encrypts it with the Client Public Key, Digitally Signs it with the Server Private Key and returns it back to the Client.&lt;br /&gt;&lt;/td&gt; &lt;td nd="69" style="border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;Same thing happens for the Hacker as in the previous two solutions. The Hacker cannot decrypt the data, as it requires the Server Private key, moreover the Hacker founds the data is now Digitally Signed.&lt;br /&gt;&lt;br /&gt;Again, the Hacker only has the Client Public Key and thus it is not possible for the Hacker to decrypt the Server Session.&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td nd="70" style="border-right: 1px solid rgb(0, 0, 0); border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; width: 21px; text-align: right;"&gt;&lt;br /&gt;3.&lt;/td&gt; &lt;td nd="71" style="border-right: 1px solid rgb(0, 0, 0); border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;Client Receives the encrypted Session Key of Server. It verifies it with the Server Public Key, if not tampered, it decrypts it with previously generated Client Private Key.&lt;br /&gt;&lt;br /&gt;Client Encrypts the target data with the previously generated Client Session Key, Digitally Signs it and sends to Server.&lt;br /&gt;&lt;/td&gt; &lt;td nd="72" style="border-right: 1px solid rgb(0, 0, 0); border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Server Receives the Encrypted data, Server verifies it with Client Public Key, if not tampered it decrypts the data with the previously received Client Session Key.&lt;br /&gt;&lt;br /&gt;Server Process the Data.&lt;br /&gt;&lt;br /&gt;Server encrypts the process result with the previously generated Server Session Key, Digitally Signs it with the Server Private Key and returns it back to Client&lt;br /&gt;&lt;/td&gt; &lt;td nd="73" style="border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The Hacker does not have the Client Session Key and thus it is not possible to decrypt the data, also founds the data is Digitally Signed.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Again, the Hacker does not have the Server Session Key and so it is not possible for the hacker to decrypt the process result.&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td nd="74" style="border-right: 1px solid rgb(0, 0, 0); border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; width: 21px; text-align: right;"&gt;&lt;br /&gt;4.&lt;br /&gt;&lt;/td&gt; &lt;td nd="75" style="border-right: 1px solid rgb(0, 0, 0); border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;The Client receives the encrypted process result, verifies it with Server Public Key and decrypts it with the previously received Server Session Key.&lt;br /&gt;&lt;/td&gt; &lt;td style="border-right: 1px solid rgb(0, 0, 0); border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;&lt;/td&gt; &lt;td style="border-bottom: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt; &lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td nd="76" style="border-right: 1px solid rgb(0, 0, 0); vertical-align: top; width: 21px; text-align: right;"&gt;&lt;br /&gt;5.&lt;/td&gt; &lt;td nd="77" style="border-right: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;The Client returns to regular processing.&lt;br /&gt;&lt;/td&gt; &lt;td nd="78" style="border-right: 1px solid rgb(0, 0, 0); vertical-align: top; text-align: left;"&gt;&lt;br /&gt;Server goes to sleep.&lt;/td&gt; &lt;td nd="79" style="vertical-align: top; text-align: left;"&gt;&lt;br /&gt;Both the Hacker cries now.&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;In the final solution, the digital signature has been introduced to ensure the data has not been tampered between the communications.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1192972388107063553-1533853232601690524?l=chamildz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chamildz.blogspot.com/feeds/1533853232601690524/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1192972388107063553&amp;postID=1533853232601690524' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1192972388107063553/posts/default/1533853232601690524'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1192972388107063553/posts/default/1533853232601690524'/><link rel='alternate' type='text/html' href='http://chamildz.blogspot.com/2007/01/exchange-data-securely-without-httpsssl.html' title='Exchange Data Securely Without HTTPS/SSL-C# Web Services'/><author><name>Chamil</name><uri>http://www.blogger.com/profile/00204727013782891667</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1192972388107063553.post-1547355922951595537</id><published>2007-01-29T02:24:00.000-08:00</published><updated>2007-01-29T02:30:35.278-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Audit'/><title type='text'>Creating Audit functionality using ASP.NET 2.0</title><content type='html'>&lt;span name="intelliTxt" id="intelliTXT"&gt;&lt;h2 style="font-weight: bold; color: rgb(0, 0, 0);"&gt;Introduction&lt;/h2&gt;  &lt;p nd="1"&gt; This article describes how to create an audit tool that tracks and records the changes of any fields with their old and new values using an ASP.NET web page.  To see the project in action, you can download the code, but you must change your connection properties for the database interaction.&lt;/p&gt;      &lt;h2 style="color: rgb(0, 0, 0);"&gt;Background&lt;/h2&gt; &lt;p nd="2"&gt; When posed with this issue, I found various solutions that range from SQL Server Triggers to more custom solutions that require additional knowledge of web controls.  However, my solution has the following benefits: &lt;/p&gt;&lt;ul&gt;&lt;li nd="3"&gt;Records and tracks only the changes made to the field or fields that are changed.              One solution, for example, used a trigger that would populate the audit changes,             but this included ALL fields that were in the UPDATE SQL statement.  What this             means it that it would populate the Audit table with fields that were also not changed, which filled my audit             table exponentially.  &lt;/li&gt;&lt;li nd="4"&gt;Plays on events already part of the .NET framework.  In this example, I used             a GridView that has two key events that allow us to record and compare data changes.              You can also use this same logic on the DetailsView as well.&lt;/li&gt;&lt;li nd="5"&gt;Uses existing properties that allow audit tracking to work.  One event property             that is part of the GridView control allows us to see the new values via a returned             collection object.&lt;/li&gt;&lt;li nd="6"&gt;Builds a custom and portable data object using generics that you can use for any             situation.  The only modifications you will need to do is change the connection             properties for ADO.NET.&lt;/li&gt;&lt;/ul&gt;  &lt;h2 style="color: rgb(0, 0, 0);"&gt;Using the code&lt;/h2&gt;  &lt;p nd="7"&gt;     The first thing to do is review the &lt;i&gt;CurrentFields.cs&lt;/i&gt; code, which you can import into     the App_Code folder.  This is the class that sets up the column name and column value      of the current field values as they are in the database.       &lt;/p&gt;&lt;pre nd="8" lang="cs"&gt;public string CurrColName&lt;br /&gt;{&lt;br /&gt;   get { return _colName; }&lt;br /&gt;   set { _colName = value; }&lt;br /&gt;}&lt;br /&gt;public string CurrColValue&lt;br /&gt;{&lt;br /&gt;   get { return _colValue; }&lt;br /&gt;   set { _colValue = value; }&lt;br /&gt;}&lt;/pre&gt;     &lt;p nd="9"&gt;         When you instantiate the object at runtime, we can then invoke the &lt;code nd="10"&gt;GetCurrentFields(string         empid)&lt;/code&gt; method that returns for us a generic list full of &lt;code nd="11"&gt;CurrentFields&lt;/code&gt; objects. &lt;/p&gt;  &lt;pre nd="12" lang="cs"&gt;&lt;code&gt;public List&lt;currentfields&gt; GetCurrentFields(string empid) { ...}&lt;/pre&gt;  &lt;p nd="13"&gt;     When using the GridView control, the two events of interest are:&lt;/p&gt;&lt;pre nd="14" lang="cs"&gt;OnRowUpdated=&lt;span nd="15" class="cpp-string"&gt;"GridView1_RowUpdated"&lt;/span&gt;&lt;br /&gt;OnRowEditing=&lt;span nd="16" class="cpp-string"&gt;"GridView1_RowEditing"&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;     &lt;p&gt;         &lt;/p&gt;     &lt;p nd="17"&gt;         Remember, you will have to wire up these GridView events.  This is were the         audit tracking starts.  First, the &lt;code nd="18"&gt;RowEditing&lt;/code&gt; event is fired when the user         clicks the "Edit" command button from the GridView.  This is where you create         the &lt;code nd="19"&gt;CurrentFields&lt;/code&gt; object to copy the column names and values as they currently reside         in the database.  In my example, I pass the &lt;code nd="20"&gt;empid&lt;/code&gt; to get the employee id, which         is unique for each person.&lt;/p&gt;     &lt;pre nd="21" lang="cs"&gt;List&lt;currentfields&gt; currFieldList;  &lt;span nd="22" class="cs-comment"&gt;//define globally in the webpage code&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;protected void GridView1_RowEditing(Object sender,&lt;br /&gt;                                   GridViewEditEventArgs e)&lt;br /&gt;{&lt;br /&gt; &lt;span nd="23" class="cs-comment"&gt;//get empid field to query database&lt;/span&gt;&lt;br /&gt; string strId = GridView1.Rows[e.NewEditIndex].Cells[4].Text;&lt;br /&gt; &lt;span nd="24" class="cs-comment"&gt;//instantiate object&lt;/span&gt;&lt;br /&gt; CurrentFields currFlds = new CurrentFields();          &lt;br /&gt; &lt;span nd="25" class="cs-comment"&gt;//get collection of objects of col names and values&lt;/span&gt;&lt;br /&gt; currFieldList = currFlds.GetCurrentFields(strId); &lt;br /&gt; &lt;span nd="26" class="cs-comment"&gt;//store in Session for RowUpdated event          &lt;/span&gt;&lt;br /&gt; Session[&lt;span nd="27" class="cpp-string"&gt;"CurrData"&lt;/span&gt;] = currFieldList;                        &lt;br /&gt;}&lt;/pre&gt;     &lt;p&gt;     &lt;/p&gt;     &lt;p nd="28"&gt;         Next, the user will make a change to the data from the web form.  Now, we look         at the &lt;code nd="29"&gt;RowUpdated&lt;/code&gt; event of the GridView and use the &lt;code nd="30"&gt;e.NewValues&lt;/code&gt; Dictionary collection         returned in the &lt;code nd="31"&gt;GridViewUpdatedEventArgs&lt;/code&gt; event.  This is where we will compare         the current values with the new values.  &lt;strong&gt;NOTE:&lt;/strong&gt;  We have to do two things         here, first, keep track of what fields we are comparing and also, account for null         values IF your database field allows for it.  The downloaded         code includes the class that inserts the audit table changes.  This         is shown here:&lt;/p&gt;     &lt;div class="smallText" id="premain4" style="width: 100%;"&gt;&lt;span nd="32" preid="4" style="margin-bottom: 0pt;" id="precollapse4"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre nd="33" style="margin-top: 0pt;" id="pre4" lang="cs"&gt;protected void GridView1_RowUpdated(object sender,&lt;br /&gt;                                   GridViewUpdatedEventArgs e)&lt;br /&gt;{&lt;br /&gt; &lt;span nd="34" class="cs-comment"&gt;//case Session obj&lt;/span&gt;&lt;br /&gt; currFieldList = (List&lt;currentfields&gt;)Session[&lt;span nd="35" class="cpp-string"&gt;"CurrData"&lt;/span&gt;];  &lt;br /&gt; foreach (DictionaryEntry myDE in e.NewValues)&lt;br /&gt; {&lt;br /&gt;   int i = 0;&lt;br /&gt;   string key = myDE.Key.ToString();&lt;br /&gt;      &lt;br /&gt;   foreach (CurrentFields currFld in currFieldList)&lt;br /&gt;   {&lt;br /&gt;     if (currFld.CurrColName == key)&lt;br /&gt;     {&lt;br /&gt;       break;   &lt;span nd="36" class="cs-comment"&gt;// got a colname match, break out&lt;/span&gt;&lt;br /&gt;     }&lt;br /&gt;     i++;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   if (myDE.Value != null)&lt;br /&gt;   {&lt;br /&gt;     string newVal = myDE.Value.ToString();&lt;br /&gt;     if (currFieldList[i].CurrColValue != newVal)&lt;br /&gt;     {&lt;br /&gt;       InsertAuditData.insertAuditChanges(&lt;span nd="37" class="cpp-string"&gt;"TestNames"&lt;/span&gt;, &lt;span nd="38" class="cpp-string"&gt;"UPDATE"&lt;/span&gt;, &lt;span nd="39" class="cpp-string"&gt;"Harry"&lt;/span&gt;,&lt;br /&gt;           key, currFieldList[i].CurrColValue, newVal);&lt;br /&gt;       }&lt;br /&gt;        }&lt;br /&gt;   else&lt;br /&gt;   {&lt;br /&gt;     if (currFieldList[i].CurrColValue != &lt;span nd="40" class="cpp-string"&gt;""&lt;/span&gt;)&lt;br /&gt;   {&lt;br /&gt;        InsertAuditData.insertAuditChanges(&lt;span nd="41" class="cpp-string"&gt;"TestNames"&lt;/span&gt;, &lt;span nd="42" class="cpp-string"&gt;"UPDATE"&lt;/span&gt;, &lt;span nd="43" class="cpp-string"&gt;"Harry"&lt;/span&gt;,&lt;br /&gt;           currFieldList[i].CurrColName, currFieldList[i].CurrColValue,&lt;br /&gt;           &lt;span nd="44" class="cpp-string"&gt;""&lt;/span&gt;);&lt;br /&gt;   }&lt;br /&gt;        }&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1192972388107063553-1547355922951595537?l=chamildz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1192972388107063553/posts/default/1547355922951595537'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1192972388107063553/posts/default/1547355922951595537'/><link rel='alternate' type='text/html' href='http://chamildz.blogspot.com/2007/01/creating-audit-functionality-using.html' title='Creating Audit functionality using ASP.NET 2.0'/><author><name>Chamil</name><uri>http://www.blogger.com/profile/00204727013782891667</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-1192972388107063553.post-1579894364348396134</id><published>2007-01-29T02:08:00.000-08:00</published><updated>2007-01-29T02:20:31.876-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='&quot;using&quot; C#'/><title type='text'>The "using" key word in C#</title><content type='html'>&lt;span name="intelliTxt" id="intelliTXT"&gt;&lt;h2&gt;Introduction&lt;/h2&gt; &lt;p nd="1" dir="ltr" style="margin-right: 0px;"&gt;So, I was at work today, and someone asked me what happens when you use the  &lt;/p&gt;&lt;div nd="2" style="display: inline; color: blue;"&gt;using&lt;/div&gt; keyword in C#. Most people will tell you that you that it is something you use that will clean up any unmanaged resources for the specified object, which is not incorrect. But what actually happens at the IL level? How does it "clean up" unmanaged resources? I had my assumptions, but I really didn't know. So, I set out to find out for myself.  &lt;h2 style="color: rgb(0, 0, 0);"&gt;Tests&lt;/h2&gt; &lt;p nd="4"&gt;So, I decided I was going to run through a couple of tests:&lt;/p&gt; &lt;p style="color: rgb(0, 0, 0);" nd="5"&gt;&lt;strong&gt;Test #1&lt;/strong&gt;:&lt;/p&gt; &lt;blockquote nd="8" dir="ltr" style="margin-right: 0px;"&gt; &lt;p nd="6"&gt;I wanted to see what the generated MSIL code looks like when I use the  &lt;/p&gt;&lt;div nd="7" style="display: inline; color: blue;"&gt;using&lt;/div&gt; keyword. So, I wrote some very simple sample code in C#, compiled it, then I decompiled it using ildasm to see the MSIL code. &lt;/blockquote&gt; &lt;p style="color: rgb(0, 0, 0);" dir="ltr"&gt;&lt;strong&gt;Test #2:&lt;/strong&gt;&lt;/p&gt; &lt;blockquote nd="11" dir="ltr" style="margin-right: 0px;"&gt; &lt;p nd="9" dir="ltr"&gt;I wanted to see if I could write code without using the  &lt;/p&gt;&lt;div nd="10" style="display: inline; color: blue;"&gt;using&lt;/div&gt; keyword that would generate the exact same MSIL code. This process was a little more trial and error, but was fairly easy.  &lt;/blockquote&gt; &lt;h2 style="color: rgb(0, 0, 0);" dir="ltr"&gt;Test #1&lt;/h2&gt; &lt;p nd="12" dir="ltr"&gt;Here is my sample code:&lt;/p&gt;&lt;pre dir="ltr"&gt;&lt;p&gt;&lt;span style="font-family: courier new;font-size:100%;" nd="13" &gt;&lt;blockquote&gt;[&lt;a title="System.STAThreadAttribute.STAThreadAttribute();"&gt;&lt;span style="color:#006018;"&gt;STAThread&lt;/span&gt;&lt;/a&gt;]&lt;br /&gt;&lt;span nd="14"  style="color:#1000a0;"&gt;private&lt;/span&gt; &lt;span nd="15"  style="color:#1000a0;"&gt;static&lt;/span&gt; &lt;a title="System.Void"&gt;&lt;span style="color:#006018;"&gt;void&lt;/span&gt;&lt;/a&gt; &lt;b&gt;Main&lt;/b&gt;(&lt;a title="System.String"&gt;&lt;span style="color:#006018;"&gt;string&lt;/span&gt;&lt;/a&gt;[] args)&lt;br /&gt;{&lt;br /&gt;     &lt;span nd="16"  style="color:#1000a0;"&gt;using&lt;/span&gt; (&lt;a title="System.Drawing.Bitmap"&gt;&lt;span style="color:#006018;"&gt;Bitmap&lt;/span&gt;&lt;/a&gt; &lt;b&gt;bitmap1&lt;/b&gt; &lt;span nd="17"  style="color:#1000a0;"&gt;=&lt;/span&gt; &lt;span nd="18"  style="color:#1000a0;"&gt;new&lt;/span&gt; &lt;a title="System.Drawing.Bitmap.Bitmap(int, int);"&gt;&lt;span style="color:#006018;"&gt;Bitmap&lt;/span&gt;&lt;/a&gt;(&lt;span nd="19"  style="color:#800000;"&gt;100&lt;/span&gt;, &lt;span nd="20"  style="color:#800000;"&gt;100&lt;/span&gt;))&lt;br /&gt;     {&lt;br /&gt;           &lt;a title="System.Console"&gt;&lt;span style="color:#006018;"&gt;Console&lt;/span&gt;&lt;/a&gt;.&lt;a title="void System.Console.WriteLine(string, object, object);"&gt;&lt;span style="color:#006018;"&gt;WriteLine&lt;/span&gt;&lt;/a&gt;(&lt;span style="color:#800000;"&gt;&lt;span nd="21" class="cpp-string"&gt;"Width: {0}, Height: {1}"&lt;/span&gt;&lt;/span&gt;, &lt;a title="Bitmap bitmap1 // Local Variable"&gt;&lt;span style="color:#006018;"&gt;bitmap1&lt;/span&gt;&lt;/a&gt;.&lt;a title="int System.Drawing.Image.Width { ... }"&gt;&lt;span style="color:#006018;"&gt;Width&lt;/span&gt;&lt;/a&gt;, &lt;a title="Bitmap bitmap1 // Local Variable"&gt;&lt;span style="color:#006018;"&gt;bitmap1&lt;/span&gt;&lt;/a&gt;.&lt;a title="int System.Drawing.Image.Height { ... }"&gt;&lt;span style="color:#006018;"&gt;Height&lt;/span&gt;&lt;/a&gt;);&lt;br /&gt;     }&lt;br /&gt;     &lt;a title="System.Console"&gt;&lt;span style="color:#006018;"&gt;Console&lt;/span&gt;&lt;/a&gt;.&lt;a title="string System.Console.ReadLine();"&gt;&lt;span style="color:#006018;"&gt;ReadLine&lt;/span&gt;&lt;/a&gt;();&lt;br /&gt;}&lt;/blockquote&gt;&lt;/span&gt;&lt;br /&gt;    &lt;/p&gt;&lt;/pre&gt;  &lt;p nd="22" dir="ltr"&gt;As you can see... nothing special in the code. Create a new &lt;code nd="23"&gt;Bitmap&lt;/code&gt; inside a using statement, write some output to the console, wait for user input, then exit.&lt;/p&gt; &lt;p nd="24" dir="ltr"&gt;So, what does this look like when we build the app, then decompile it into MSIL? Check it out:&lt;/p&gt;&lt;div class="smallText" id="premain1" style="width: 100%;"&gt;&lt;span nd="25" preid="1" style="margin-bottom: 0pt;" id="precollapse1"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre nd="30" style="margin-top: 0pt;" id="pre1" dir="ltr"&gt;&lt;span nd="26"  style="color:#1000a0;"&gt;.method&lt;/span&gt; &lt;span nd="27"  style="color:#1000a0;"&gt;private&lt;/span&gt; &lt;span nd="28"  style="color:#1000a0;"&gt;hidebysig&lt;/span&gt; &lt;span nd="29"  style="color:#1000a0;"&gt;static&lt;/span&gt; &lt;a title="void"&gt;&lt;span style="color:#006018;"&gt;void&lt;/span&gt;&lt;/a&gt; &lt;b&gt;Main&lt;/b&gt;(&lt;a title="string"&gt;&lt;span style="color:#006018;"&gt;string&lt;/span&gt;&lt;/a&gt;[] args)&lt;span style="color:#1000a0;"&gt; &lt;/span&gt;&lt;span nd="31"  style="color:#1000a0;"&gt;cil&lt;/span&gt;&lt;span style="color:#1000a0;"&gt; &lt;/span&gt;&lt;span nd="32"  style="color:#1000a0;"&gt;managed&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;     &lt;span nd="33"  style="color:#1000a0;"&gt;.custom&lt;/span&gt; &lt;span nd="34"  style="color:#1000a0;"&gt;instance&lt;/span&gt; &lt;a title="void"&gt;&lt;span style="color:#006018;"&gt;void&lt;/span&gt;&lt;/a&gt; [&lt;a title="mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"&gt;&lt;span style="color:#006018;"&gt;mscorlib&lt;/span&gt;&lt;/a&gt;]&lt;a title="System.STAThreadAttribute"&gt;&lt;span style="color:#006018;"&gt;System.STAThreadAttribute&lt;/span&gt;&lt;/a&gt;::&lt;a title=".ctor"&gt;&lt;span style="color:#006018;"&gt;.ctor&lt;/span&gt;&lt;/a&gt;()&lt;br /&gt;     &lt;span nd="35"  style="color:#1000a0;"&gt;.entrypoint&lt;/span&gt;&lt;br /&gt;     &lt;span nd="36"  style="color:#1000a0;"&gt;.maxstack&lt;/span&gt; 4&lt;br /&gt;     &lt;span nd="37"  style="color:#1000a0;"&gt;.locals&lt;/span&gt; &lt;span nd="38"  style="color:#1000a0;"&gt;init&lt;/span&gt; (&lt;br /&gt;           [&lt;span nd="39"  style="color:#800000;"&gt;0&lt;/span&gt;] [&lt;a title="System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"&gt;&lt;span style="color:#006018;"&gt;System.Drawing&lt;/span&gt;&lt;/a&gt;]&lt;a title="System.Drawing.Bitmap"&gt;&lt;span style="color:#006018;"&gt;System.Drawing.Bitmap&lt;/span&gt;&lt;/a&gt; &lt;b&gt;bitmap1&lt;/b&gt;)&lt;br /&gt;     L_0000: &lt;a title="ldc.i4.s (0x001f): Pushes the supplied int8 value onto the evaluation stack as an int32, short form."&gt;&lt;span style="color:#006018;"&gt;ldc.i4.s&lt;/span&gt;&lt;/a&gt; &lt;span nd="40"  style="color:#800000;"&gt;100&lt;/span&gt;&lt;br /&gt;     L_0002: &lt;a title="ldc.i4.s (0x001f): Pushes the supplied int8 value onto the evaluation stack as an int32, short form."&gt;&lt;span style="color:#006018;"&gt;ldc.i4.s&lt;/span&gt;&lt;/a&gt; &lt;span nd="41"  style="color:#800000;"&gt;100&lt;/span&gt;&lt;br /&gt;     L_0004: &lt;a title="newobj (0x0073): Creates a new object or a new instance of a value type, pushing an object reference (type O) onto the evaluation stack."&gt;&lt;span style="color:#006018;"&gt;newobj&lt;/span&gt;&lt;/a&gt; &lt;span nd="42"  style="color:#1000a0;"&gt;instance&lt;/span&gt; &lt;a title="void"&gt;&lt;span style="color:#006018;"&gt;void&lt;/span&gt;&lt;/a&gt; [&lt;a title="System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"&gt;&lt;span style="color:#006018;"&gt;System.Drawing&lt;/span&gt;&lt;/a&gt;]&lt;a title="System.Drawing.Bitmap"&gt;&lt;span style="color:#006018;"&gt;System.Drawing.Bitmap&lt;/span&gt;&lt;/a&gt;::&lt;a title=".ctor"&gt;&lt;span style="color:#006018;"&gt;.ctor&lt;/span&gt;&lt;/a&gt;(&lt;a title="int32"&gt;&lt;span style="color:#006018;"&gt;int32&lt;/span&gt;&lt;/a&gt;, &lt;a title="int32"&gt;&lt;span style="color:#006018;"&gt;int32&lt;/span&gt;&lt;/a&gt;)&lt;br /&gt;     L_0009: &lt;a title="stloc.0 (0x000a): Pops the current value from the top of the evaluation stack and stores it in a the local variable list at index 0."&gt;&lt;span style="color:#006018;"&gt;stloc.0&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;     L_000a: &lt;a title="ldstr (0x0072): Pushes a new object reference to a string literal stored in the metadata."&gt;&lt;span style="color:#006018;"&gt;ldstr&lt;/span&gt;&lt;/a&gt; &lt;span style="color:#800000;"&gt;&lt;span nd="43" class="cpp-string"&gt;"Width: {0}, Height: {1}"&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;     L_000f: &lt;a title="ldloc.0 (0x0006): Loads the local variable at index 0 onto the evaluation stack."&gt;&lt;span style="color:#006018;"&gt;ldloc.0&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;     L_0010: &lt;a title="callvirt (0x006f): Calls a late-bound method on an object, pushing the return value onto the evaluation stack."&gt;&lt;span style="color:#006018;"&gt;callvirt&lt;/span&gt;&lt;/a&gt; &lt;span nd="44"  style="color:#1000a0;"&gt;instance&lt;/span&gt; &lt;a title="int32"&gt;&lt;span style="color:#006018;"&gt;int32&lt;/span&gt;&lt;/a&gt; [&lt;a title="System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"&gt;&lt;span style="color:#006018;"&gt;System.Drawing&lt;/span&gt;&lt;/a&gt;]&lt;a title="System.Drawing.Image"&gt;&lt;span style="color:#006018;"&gt;System.Drawing.Image&lt;/span&gt;&lt;/a&gt;::&lt;a title="get_Width"&gt;&lt;span style="color:#006018;"&gt;get_Width&lt;/span&gt;&lt;/a&gt;()&lt;br /&gt;     L_0015: &lt;a title="box (0x008c): Converts a value type to an object reference (type O)."&gt;&lt;span style="color:#006018;"&gt;box&lt;/span&gt;&lt;/a&gt; &lt;a title="int32"&gt;&lt;span style="color:#006018;"&gt;int32&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;     L_001a: &lt;a title="ldloc.0 (0x0006): Loads the local variable at index 0 onto the evaluation stack."&gt;&lt;span style="color:#006018;"&gt;ldloc.0&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;     L_001b: &lt;a title="callvirt (0x006f): Calls a late-bound method on an object, pushing the return value onto the evaluation stack."&gt;&lt;span style="color:#006018;"&gt;callvirt&lt;/span&gt;&lt;/a&gt; &lt;span nd="45"  style="color:#1000a0;"&gt;instance&lt;/span&gt; &lt;a title="int32"&gt;&lt;span style="color:#006018;"&gt;int32&lt;/span&gt;&lt;/a&gt; [&lt;a title="System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"&gt;&lt;span style="color:#006018;"&gt;System.Drawing&lt;/span&gt;&lt;/a&gt;]&lt;a title="System.Drawing.Image"&gt;&lt;span style="color:#006018;"&gt;System.Drawing.Image&lt;/span&gt;&lt;/a&gt;::&lt;a title="get_Height"&gt;&lt;span style="color:#006018;"&gt;get_Height&lt;/span&gt;&lt;/a&gt;()&lt;br /&gt;     L_0020: &lt;a title="box (0x008c): Converts a value type to an object reference (type O)."&gt;&lt;span style="color:#006018;"&gt;box&lt;/span&gt;&lt;/a&gt; &lt;a title="int32"&gt;&lt;span style="color:#006018;"&gt;int32&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;     L_0025: &lt;a title="call (0x0028): Calls the method indicated by the passed method descriptor."&gt;&lt;span style="color:#006018;"&gt;call&lt;/span&gt;&lt;/a&gt; &lt;a title="void"&gt;&lt;span style="color:#006018;"&gt;void&lt;/span&gt;&lt;/a&gt; [&lt;a title="mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"&gt;&lt;span style="color:#006018;"&gt;mscorlib&lt;/span&gt;&lt;/a&gt;]&lt;a title="System.Console"&gt;&lt;span style="color:#006018;"&gt;System.Console&lt;/span&gt;&lt;/a&gt;::&lt;a title="WriteLine"&gt;&lt;span style="color:#006018;"&gt;WriteLine&lt;/span&gt;&lt;/a&gt;(&lt;a title="string"&gt;&lt;span style="color:#006018;"&gt;string&lt;/span&gt;&lt;/a&gt;, &lt;a title="object"&gt;&lt;span style="color:#006018;"&gt;object&lt;/span&gt;&lt;/a&gt;, &lt;a title="object"&gt;&lt;span style="color:#006018;"&gt;object&lt;/span&gt;&lt;/a&gt;)&lt;br /&gt;     L_002a: &lt;a title="leave.s (0x00de): Exits a protected region of code, unconditionally tranferring control to a target instruction (short form)."&gt;&lt;span style="color:#006018;"&gt;leave.s&lt;/span&gt;&lt;/a&gt; L_0036&lt;br /&gt;     L_002c: &lt;a title="ldloc.0 (0x0006): Loads the local variable at index 0 onto the evaluation stack."&gt;&lt;span style="color:#006018;"&gt;ldloc.0&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;     L_002d: &lt;a title="brfalse.s (0x002c): Transfers control to a target instruction if value is false, a null reference, or zero."&gt;&lt;span style="color:#006018;"&gt;brfalse.s&lt;/span&gt;&lt;/a&gt; L_0035&lt;br /&gt;     L_002f: &lt;a title="ldloc.0 (0x0006): Loads the local variable at index 0 onto the evaluation stack."&gt;&lt;span style="color:#006018;"&gt;ldloc.0&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;     L_0030: &lt;a title="callvirt (0x006f): Calls a late-bound method on an object, pushing the return value onto the evaluation stack."&gt;&lt;span style="color:#006018;"&gt;callvirt&lt;/span&gt;&lt;/a&gt; &lt;span nd="46"  style="color:#1000a0;"&gt;instance&lt;/span&gt; &lt;a title="void"&gt;&lt;span style="color:#006018;"&gt;void&lt;/span&gt;&lt;/a&gt; [&lt;a title="mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"&gt;&lt;span style="color:#006018;"&gt;mscorlib&lt;/span&gt;&lt;/a&gt;]&lt;a title="System.IDisposable"&gt;&lt;span style="color:#006018;"&gt;System.IDisposable&lt;/span&gt;&lt;/a&gt;::&lt;a title="Dispose"&gt;&lt;span style="color:#006018;"&gt;Dispose&lt;/span&gt;&lt;/a&gt;()&lt;br /&gt;     L_0035: &lt;a title="endfinally (0x00dc): Transfers control from the fault or finally clause of an exception block back to the Common Language Infrastructure (CLI) exception handler."&gt;&lt;span style="color:#006018;"&gt;endfinally&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;     L_0036: &lt;a title="call (0x0028): Calls the method indicated by the passed method descriptor."&gt;&lt;span style="color:#006018;"&gt;call&lt;/span&gt;&lt;/a&gt; &lt;a title="string"&gt;&lt;span style="color:#006018;"&gt;string&lt;/span&gt;&lt;/a&gt; [&lt;a title="mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"&gt;&lt;span style="color:#006018;"&gt;mscorlib&lt;/span&gt;&lt;/a&gt;]&lt;a title="System.Console"&gt;&lt;span style="color:#006018;"&gt;System.Console&lt;/span&gt;&lt;/a&gt;::&lt;a title="ReadLine"&gt;&lt;span style="color:#006018;"&gt;ReadLine&lt;/span&gt;&lt;/a&gt;()&lt;br /&gt;     L_003b: &lt;a title="pop (0x0026): Removes the value currently on top of the evaluation stack."&gt;&lt;span style="color:#006018;"&gt;pop&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;     L_003c: &lt;a title="ret (0x002a): Returns from the current method, pushing a return value (if present) from the caller's evaluation stack onto the callee's evaluation stack."&gt;&lt;span style="color:#006018;"&gt;ret&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;     &lt;span nd="47"  style="color:#1000a0;"&gt;.try&lt;/span&gt; L_000a &lt;span nd="48"  style="color:#1000a0;"&gt;to&lt;/span&gt; L_002c &lt;span nd="49"  style="color:#1000a0;"&gt;finally&lt;/span&gt; &lt;span nd="50"  style="color:#1000a0;"&gt;handler&lt;/span&gt; L_002c &lt;span nd="51"  style="color:#1000a0;"&gt;to&lt;/span&gt; L_0036&lt;br /&gt;}&lt;br /&gt;       &lt;/pre&gt;  &lt;p style="color: rgb(0, 0, 0);" dir="ltr"&gt;&lt;strong&gt;Test #1 Results:&lt;/strong&gt;&lt;/p&gt; &lt;p nd="52" dir="ltr"&gt;So the results from test #1 are interesting. the  &lt;/p&gt;&lt;div nd="53" style="display: inline; color: blue;"&gt;using&lt;/div&gt; keyword is basically a   &lt;div nd="54" style="display: inline; color: blue;"&gt;try&lt;/div&gt; -  &lt;div nd="55" style="display: inline; color: blue;"&gt;finally&lt;/div&gt; block, without a  &lt;div nd="56" style="display: inline; color: blue;"&gt;catch&lt;/div&gt;, where &lt;code nd="57"&gt;IDisposable.Dispose()&lt;/code&gt; is called in the  &lt;div nd="58" style="display: inline; color: blue;"&gt;finally&lt;/div&gt;. One interesting thing to note is that the &lt;code nd="59"&gt;Bitmap&lt;/code&gt; constructor is called before the  &lt;div nd="60" style="display: inline; color: blue;"&gt;try&lt;/div&gt; block begins. This tells me that if, in the &lt;code nd="61"&gt;Bitmap&lt;/code&gt; constructor, an unmanaged resource is allocated, but not freed, then the constructor throws an exception, the unmanaged resource will not get freed by a call to the IDisposable.Dispose(). This also assumes that the IDisposable is implemented properly.  &lt;p nd="62" dir="ltr"&gt;Therefore the  &lt;/p&gt;&lt;div nd="63" style="display: inline; color: blue;"&gt;using&lt;/div&gt; keyword is &lt;strong&gt;useless&lt;/strong&gt; if the &lt;code nd="64"&gt;IDisposable&lt;/code&gt; is not implemented properly. The constructor should clean up resources if it fails, and the &lt;code nd="65"&gt;Dispose()&lt;/code&gt; method should clean up all unmanaged resources. Chances are good that Microsoft has implemented &lt;code nd="66"&gt;IDisposable&lt;/code&gt; correctly in their classes, so whatch out for this if you are implementing your own &lt;code nd="67"&gt;IDisposable&lt;/code&gt;.   &lt;h2 style="color: rgb(0, 0, 0);" dir="ltr"&gt;Test #2:&lt;/h2&gt; &lt;p nd="68" dir="ltr"&gt;Based on the MSIL code that resulted from &lt;em&gt;Test #1,&lt;/em&gt; I decided to write the same code using  &lt;/p&gt;&lt;div nd="69" style="display: inline; color: blue;"&gt;try&lt;/div&gt; -  &lt;div nd="70" style="display: inline; color: blue;"&gt;finally&lt;/div&gt; blocks. This is what I came up with:  &lt;pre nd="71" dir="ltr"&gt;[&lt;a title="System.STAThreadAttribute.STAThreadAttribute();"&gt;&lt;span style="color:#006018;"&gt;STAThread&lt;/span&gt;&lt;/a&gt;]&lt;br /&gt;&lt;span nd="72"  style="color:#1000a0;"&gt;private&lt;/span&gt; &lt;span nd="73"  style="color:#1000a0;"&gt;static&lt;/span&gt; &lt;a title="System.Void"&gt;&lt;span style="color:#006018;"&gt;void&lt;/span&gt;&lt;/a&gt; &lt;b&gt;Main&lt;/b&gt;(&lt;a title="System.String"&gt;&lt;span style="color:#006018;"&gt;string&lt;/span&gt;&lt;/a&gt;[] args)&lt;br /&gt;{&lt;br /&gt;     &lt;a title="System.Drawing.Bitmap"&gt;&lt;span style="color:#006018;"&gt;Bitmap&lt;/span&gt;&lt;/a&gt; &lt;b&gt;bitmap1&lt;/b&gt; = &lt;span nd="74"  style="color:#1000a0;"&gt;new&lt;/span&gt; &lt;a title="System.Drawing.Bitmap.Bitmap(int, int);"&gt;&lt;span style="color:#006018;"&gt;Bitmap&lt;/span&gt;&lt;/a&gt;(&lt;span nd="75"  style="color:#800000;"&gt;100&lt;/span&gt;, &lt;span nd="76"  style="color:#800000;"&gt;100&lt;/span&gt;);&lt;br /&gt;     &lt;span nd="77"  style="color:#1000a0;"&gt;try&lt;/span&gt;&lt;br /&gt;     {&lt;br /&gt;           &lt;a title="System.Console"&gt;&lt;span style="color:#006018;"&gt;Console&lt;/span&gt;&lt;/a&gt;.&lt;a title="void System.Console.WriteLine(string, object, object);"&gt;&lt;span style="color:#006018;"&gt;WriteLine&lt;/span&gt;&lt;/a&gt;(&lt;span style="color:#800000;"&gt;&lt;span nd="78" class="cpp-string"&gt;"Width: {0}, Height: {1}"&lt;/span&gt;&lt;/span&gt;, &lt;a title="Bitmap bitmap1 // Local Variable"&gt;&lt;span style="color:#006018;"&gt;bitmap1&lt;/span&gt;&lt;/a&gt;.&lt;a title="int System.Drawing.Image.Width { ... }"&gt;&lt;span style="color:#006018;"&gt;Width&lt;/span&gt;&lt;/a&gt;, &lt;a title="Bitmap bitmap1 // Local Variable"&gt;&lt;span style="color:#006018;"&gt;bitmap1&lt;/span&gt;&lt;/a&gt;.&lt;a title="int System.Drawing.Image.Height { ... }"&gt;&lt;span style="color:#006018;"&gt;Height&lt;/span&gt;&lt;/a&gt;);&lt;br /&gt;     }&lt;br /&gt;     &lt;span nd="79"  style="color:#1000a0;"&gt;finally&lt;/span&gt;&lt;br /&gt;     {&lt;br /&gt;           &lt;span nd="80"  style="color:#1000a0;"&gt;if&lt;/span&gt; (&lt;a title="Bitmap bitmap1 // Local Variable"&gt;&lt;span style="color:#006018;"&gt;bitmap1&lt;/span&gt;&lt;/a&gt; != &lt;span nd="81"  style="color:#800000;"&gt;null&lt;/span&gt;)&lt;br /&gt;           {&lt;br /&gt;                 &lt;a title="Bitmap bitmap1 // Local Variable"&gt;&lt;span style="color:#006018;"&gt;bitmap1&lt;/span&gt;&lt;/a&gt;.&lt;a title="void System.Drawing.Image.Dispose();"&gt;&lt;span style="color:#006018;"&gt;Dispose&lt;/span&gt;&lt;/a&gt;();&lt;br /&gt;           }&lt;br /&gt;     }&lt;br /&gt;     &lt;a title="System.Console"&gt;&lt;span style="color:#006018;"&gt;Console&lt;/span&gt;&lt;/a&gt;.&lt;a title="string System.Console.ReadLine();"&gt;&lt;span style="color:#006018;"&gt;ReadLine&lt;/span&gt;&lt;/a&gt;();&lt;br /&gt;}&lt;/pre&gt; &lt;p nd="82" dir="ltr"&gt;And this is what it looked like in MSIL:&lt;/p&gt;&lt;div class="smallText" id="premain3" style="width: 100%;"&gt;&lt;span nd="83" preid="3" style="margin-bottom: 0pt;" id="precollapse3"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre nd="88" style="margin-top: 0pt;" id="pre3" dir="ltr"&gt;&lt;span nd="84"  style="color:#1000a0;"&gt;.method&lt;/span&gt; &lt;span nd="85"  style="color:#1000a0;"&gt;private&lt;/span&gt; &lt;span nd="86"  style="color:#1000a0;"&gt;hidebysig&lt;/span&gt; &lt;span nd="87"  style="color:#1000a0;"&gt;static&lt;/span&gt; &lt;a title="void"&gt;&lt;span style="color:#006018;"&gt;void&lt;/span&gt;&lt;/a&gt; &lt;b&gt;Main&lt;/b&gt;(&lt;a title="string"&gt;&lt;span style="color:#006018;"&gt;string&lt;/span&gt;&lt;/a&gt;[] args)&lt;span style="color:#1000a0;"&gt; &lt;/span&gt;&lt;span nd="89"  style="color:#1000a0;"&gt;cil&lt;/span&gt;&lt;span style="color:#1000a0;"&gt; &lt;/span&gt;&lt;span nd="90"  style="color:#1000a0;"&gt;managed&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;     &lt;span nd="91"  style="color:#1000a0;"&gt;.custom&lt;/span&gt; &lt;span nd="92"  style="color:#1000a0;"&gt;instance&lt;/span&gt; &lt;a title="void"&gt;&lt;span style="color:#006018;"&gt;void&lt;/span&gt;&lt;/a&gt; [&lt;a title="mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"&gt;&lt;span style="color:#006018;"&gt;mscorlib&lt;/span&gt;&lt;/a&gt;]&lt;a title="System.STAThreadAttribute"&gt;&lt;span style="color:#006018;"&gt;System.STAThreadAttribute&lt;/span&gt;&lt;/a&gt;::&lt;a title=".ctor"&gt;&lt;span style="color:#006018;"&gt;.ctor&lt;/span&gt;&lt;/a&gt;()&lt;br /&gt;     &lt;span nd="93"  style="color:#1000a0;"&gt;.entrypoint&lt;/span&gt;&lt;br /&gt;     &lt;span nd="94"  style="color:#1000a0;"&gt;.maxstack&lt;/span&gt; 4&lt;br /&gt;     &lt;span nd="95"  style="color:#1000a0;"&gt;.locals&lt;/span&gt; &lt;span nd="96"  style="color:#1000a0;"&gt;init&lt;/span&gt; (&lt;br /&gt;           [&lt;span nd="97"  style="color:#800000;"&gt;0&lt;/span&gt;] [&lt;a title="System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"&gt;&lt;span style="color:#006018;"&gt;System.Drawing&lt;/span&gt;&lt;/a&gt;]&lt;a title="System.Drawing.Bitmap"&gt;&lt;span style="color:#006018;"&gt;System.Drawing.Bitmap&lt;/span&gt;&lt;/a&gt; &lt;b&gt;bitmap1&lt;/b&gt;)&lt;br /&gt;     L_0000: &lt;a title="ldc.i4.s (0x001f): Pushes the supplied int8 value onto the evaluation stack as an int32, short form."&gt;&lt;span style="color:#006018;"&gt;ldc.i4.s&lt;/span&gt;&lt;/a&gt; &lt;span nd="98"  style="color:#800000;"&gt;100&lt;/span&gt;&lt;br /&gt;     L_0002: &lt;a title="ldc.i4.s (0x001f): Pushes the supplied int8 value onto the evaluation stack as an int32, short form."&gt;&lt;span style="color:#006018;"&gt;ldc.i4.s&lt;/span&gt;&lt;/a&gt; &lt;span nd="99"  style="color:#800000;"&gt;100&lt;/span&gt;&lt;br /&gt;     L_0004: &lt;a title="newobj (0x0073): Creates a new object or a new instance of a value type, pushing an object reference (type O) onto the evaluation stack."&gt;&lt;span style="color:#006018;"&gt;newobj&lt;/span&gt;&lt;/a&gt; &lt;span nd="100"  style="color:#1000a0;"&gt;instance&lt;/span&gt; &lt;a title="void"&gt;&lt;span style="color:#006018;"&gt;void&lt;/span&gt;&lt;/a&gt; [&lt;a title="System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"&gt;&lt;span style="color:#006018;"&gt;System.Drawing&lt;/span&gt;&lt;/a&gt;]&lt;a title="System.Drawing.Bitmap"&gt;&lt;span style="color:#006018;"&gt;System.Drawing.Bitmap&lt;/span&gt;&lt;/a&gt;::&lt;a title=".ctor"&gt;&lt;span style="color:#006018;"&gt;.ctor&lt;/span&gt;&lt;/a&gt;(&lt;a title="int32"&gt;&lt;span style="color:#006018;"&gt;int32&lt;/span&gt;&lt;/a&gt;, &lt;a title="int32"&gt;&lt;span style="color:#006018;"&gt;int32&lt;/span&gt;&lt;/a&gt;)&lt;br /&gt;     L_0009: &lt;a title="stloc.0 (0x000a): Pops the current value from the top of the evaluation stack and stores it in a the local variable list at index 0."&gt;&lt;span style="color:#006018;"&gt;stloc.0&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;     L_000a: &lt;a title="ldstr (0x0072): Pushes a new object reference to a string literal stored in the metadata."&gt;&lt;span style="color:#006018;"&gt;ldstr&lt;/span&gt;&lt;/a&gt; &lt;span style="color:#800000;"&gt;&lt;span nd="101" class="cpp-string"&gt;"Width: {0}, Height: {1}"&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;     L_000f: &lt;a title="ldloc.0 (0x0006): Loads the local variable at index 0 onto the evaluation stack."&gt;&lt;span style="color:#006018;"&gt;ldloc.0&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;     L_0010: &lt;a title="callvirt (0x006f): Calls a late-bound method on an object, pushing the return value onto the evaluation stack."&gt;&lt;span style="color:#006018;"&gt;callvirt&lt;/span&gt;&lt;/a&gt; &lt;span nd="102"  style="color:#1000a0;"&gt;instance&lt;/span&gt; &lt;a title="int32"&gt;&lt;span style="color:#006018;"&gt;int32&lt;/span&gt;&lt;/a&gt; [&lt;a title="System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"&gt;&lt;span style="color:#006018;"&gt;System.Drawing&lt;/span&gt;&lt;/a&gt;]&lt;a title="System.Drawing.Image"&gt;&lt;span style="color:#006018;"&gt;System.Drawing.Image&lt;/span&gt;&lt;/a&gt;::&lt;a title="get_Width"&gt;&lt;span style="color:#006018;"&gt;get_Width&lt;/span&gt;&lt;/a&gt;()&lt;br /&gt;     L_0015: &lt;a title="box (0x008c): Converts a value type to an object reference (type O)."&gt;&lt;span style="color:#006018;"&gt;box&lt;/span&gt;&lt;/a&gt; &lt;a title="int32"&gt;&lt;span style="color:#006018;"&gt;int32&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;     L_001a: &lt;a title="ldloc.0 (0x0006): Loads the local variable at index 0 onto the evaluation stack."&gt;&lt;span style="color:#006018;"&gt;ldloc.0&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;     L_001b: &lt;a title="callvirt (0x006f): Calls a late-bound method on an object, pushing the return value onto the evaluation stack."&gt;&lt;span style="color:#006018;"&gt;callvirt&lt;/span&gt;&lt;/a&gt; &lt;span nd="103"  style="color:#1000a0;"&gt;instance&lt;/span&gt; &lt;a title="int32"&gt;&lt;span style="color:#006018;"&gt;int32&lt;/span&gt;&lt;/a&gt; [&lt;a title="System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"&gt;&lt;span style="color:#006018;"&gt;System.Drawing&lt;/span&gt;&lt;/a&gt;]&lt;a title="System.Drawing.Image"&gt;&lt;span style="color:#006018;"&gt;System.Drawing.Image&lt;/span&gt;&lt;/a&gt;::&lt;a title="get_Height"&gt;&lt;span style="color:#006018;"&gt;get_Height&lt;/span&gt;&lt;/a&gt;()&lt;br /&gt;     L_0020: &lt;a title="box (0x008c): Converts a value type to an object reference (type O)."&gt;&lt;span style="color:#006018;"&gt;box&lt;/span&gt;&lt;/a&gt; &lt;a title="int32"&gt;&lt;span style="color:#006018;"&gt;int32&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;     L_0025: &lt;a title="call (0x0028): Calls the method indicated by the passed method descriptor."&gt;&lt;span style="color:#006018;"&gt;call&lt;/span&gt;&lt;/a&gt; &lt;a title="void"&gt;&lt;span style="color:#006018;"&gt;void&lt;/span&gt;&lt;/a&gt; [&lt;a title="mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"&gt;&lt;span style="color:#006018;"&gt;mscorlib&lt;/span&gt;&lt;/a&gt;]&lt;a title="System.Console"&gt;&lt;span style="color:#006018;"&gt;System.Console&lt;/span&gt;&lt;/a&gt;::&lt;a title="WriteLine"&gt;&lt;span style="color:#006018;"&gt;WriteLine&lt;/span&gt;&lt;/a&gt;(&lt;a title="string"&gt;&lt;span style="color:#006018;"&gt;string&lt;/span&gt;&lt;/a&gt;, &lt;a title="object"&gt;&lt;span style="color:#006018;"&gt;object&lt;/span&gt;&lt;/a&gt;, &lt;a title="object"&gt;&lt;span style="color:#006018;"&gt;object&lt;/span&gt;&lt;/a&gt;)&lt;br /&gt;     L_002a: &lt;a title="leave.s (0x00de): Exits a protected region of code, unconditionally tranferring control to a target instruction (short form)."&gt;&lt;span style="color:#006018;"&gt;leave.s&lt;/span&gt;&lt;/a&gt; L_0036&lt;br /&gt;     L_002c: &lt;a title="ldloc.0 (0x0006): Loads the local variable at index 0 onto the evaluation stack."&gt;&lt;span style="color:#006018;"&gt;ldloc.0&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;     L_002d: &lt;a title="brfalse.s (0x002c): Transfers control to a target instruction if value is false, a null reference, or zero."&gt;&lt;span style="color:#006018;"&gt;brfalse.s&lt;/span&gt;&lt;/a&gt; L_0035&lt;br /&gt;     L_002f: &lt;a title="ldloc.0 (0x0006): Loads the local variable at index 0 onto the evaluation stack."&gt;&lt;span style="color:#006018;"&gt;ldloc.0&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;     L_0030: &lt;a title="callvirt (0x006f): Calls a late-bound method on an object, pushing the return value onto the evaluation stack."&gt;&lt;span style="color:#006018;"&gt;callvirt&lt;/span&gt;&lt;/a&gt; &lt;span style="color:#1000a0;"&gt;instance&lt;/span&gt; &lt;a title="void"&gt;&lt;span style="color:#006018;"&gt;void&lt;/span&gt;&lt;/a&gt; [&lt;a title="System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"&gt;&lt;span style="color:#006018;"&gt;System.Drawing&lt;/span&gt;&lt;/a&gt;]&lt;a title="System.Drawing.Image"&gt;&lt;span style="color:#006018;"&gt;System.Drawing.Image&lt;/span&gt;&lt;/a&gt;::&lt;a title="Dispose"&gt;&lt;span style="color:#006018;"&gt;Dispose&lt;/span&gt;&lt;/a&gt;()&lt;br /&gt;     L_0035: &lt;a title="endfinally (0x00dc): Transfers control from the fault or finally clause of an exception block back to the Common Language Infrastructure (CLI) exception handler."&gt;&lt;span style="color:#006018;"&gt;endfinally&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;     L_0036: &lt;a title="call (0x0028): Calls the method indicated by the passed method descriptor."&gt;&lt;span style="color:#006018;"&gt;call&lt;/span&gt;&lt;/a&gt; &lt;a title="string"&gt;&lt;span style="color:#006018;"&gt;string&lt;/span&gt;&lt;/a&gt; [&lt;a title="mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"&gt;&lt;span style="color:#006018;"&gt;mscorlib&lt;/span&gt;&lt;/a&gt;]&lt;a title="System.Console"&gt;&lt;span style="color:#006018;"&gt;System.Console&lt;/span&gt;&lt;/a&gt;::&lt;a title="ReadLine"&gt;&lt;span style="color:#006018;"&gt;ReadLine&lt;/span&gt;&lt;/a&gt;()&lt;br /&gt;     L_003b: &lt;a title="pop (0x0026): Removes the value currently on top of the evaluation stack."&gt;&lt;span style="color:#006018;"&gt;pop&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;     L_003c: &lt;a title="ret (0x002a): Returns from the current method, pushing a return value (if present) from the caller's evaluation stack onto the callee's evaluation stack."&gt;&lt;span style="color:#006018;"&gt;ret&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;     &lt;span style="color:#1000a0;"&gt;.try&lt;/span&gt; L_000a &lt;span style="color:#1000a0;"&gt;to&lt;/span&gt; L_002c &lt;span style="color:#1000a0;"&gt;finally&lt;/span&gt; &lt;span style="color:#1000a0;"&gt;handler&lt;/span&gt; L_002c &lt;span style="color:#1000a0;"&gt;to&lt;/span&gt; L_0036&lt;br /&gt;}&lt;/pre&gt; &lt;p style="color: rgb(0, 0, 0);" dir="ltr"&gt;&lt;strong&gt;Test #2 Results:&lt;/strong&gt;&lt;/p&gt; &lt;p dir="ltr"&gt;It is almost exactly like the MSIL generated from the  &lt;/p&gt;&lt;div style="display: inline; color: blue;"&gt;using&lt;/div&gt; keyword, except this calls &lt;code&gt;Image.Dispose()&lt;/code&gt; rather than &lt;code&gt;IDisposable.Dispose()&lt;/code&gt; , but the affect is the same.   &lt;p dir="ltr"&gt;Just for fun, I regenerated C# code using &lt;strong&gt;&lt;em&gt;Lutz Roeder's .NET Reflector&lt;/em&gt;&lt;/strong&gt;, which is an invaluable tool, and here is the result:&lt;/p&gt;&lt;pre dir="ltr"&gt;[&lt;a title="System.STAThreadAttribute.STAThreadAttribute();"&gt;&lt;span style="color:#006018;"&gt;STAThread&lt;/span&gt;&lt;/a&gt;]&lt;br /&gt;&lt;span style="color:#1000a0;"&gt;private&lt;/span&gt; &lt;span style="color:#1000a0;"&gt;static&lt;/span&gt; &lt;a title="System.Void"&gt;&lt;span style="color:#006018;"&gt;void&lt;/span&gt;&lt;/a&gt; &lt;b&gt;Main&lt;/b&gt;(&lt;a title="System.String"&gt;&lt;span style="color:#006018;"&gt;string&lt;/span&gt;&lt;/a&gt;[] args)&lt;br /&gt;{&lt;br /&gt;     &lt;span style="color:#1000a0;"&gt;using&lt;/span&gt; (&lt;a title="System.Drawing.Bitmap"&gt;&lt;span style="color:#006018;"&gt;Bitmap&lt;/span&gt;&lt;/a&gt; &lt;b&gt;bitmap1&lt;/b&gt; &lt;span style="color:#1000a0;"&gt;=&lt;/span&gt; &lt;span style="color:#1000a0;"&gt;new&lt;/span&gt; &lt;a title="System.Drawing.Bitmap.Bitmap(int, int);"&gt;&lt;span style="color:#006018;"&gt;Bitmap&lt;/span&gt;&lt;/a&gt;(&lt;span style="color:#800000;"&gt;100&lt;/span&gt;, &lt;span style="color:#800000;"&gt;100&lt;/span&gt;))&lt;br /&gt;     {&lt;br /&gt;           &lt;a title="System.Console"&gt;&lt;span style="color:#006018;"&gt;Console&lt;/span&gt;&lt;/a&gt;.&lt;a title="void System.Console.WriteLine(string, object, object);"&gt;&lt;span style="color:#006018;"&gt;WriteLine&lt;/span&gt;&lt;/a&gt;(&lt;span style="color:#800000;"&gt;&lt;span class="cpp-string"&gt;"Width: {0}, Height: {1}"&lt;/span&gt;&lt;/span&gt;, &lt;a title="Bitmap bitmap1 // Local Variable"&gt;&lt;span style="color:#006018;"&gt;bitmap1&lt;/span&gt;&lt;/a&gt;.&lt;a title="int System.Drawing.Image.Width { ... }"&gt;&lt;span style="color:#006018;"&gt;Width&lt;/span&gt;&lt;/a&gt;, &lt;a title="Bitmap bitmap1 // Local Variable"&gt;&lt;span style="color:#006018;"&gt;bitmap1&lt;/span&gt;&lt;/a&gt;.&lt;a title="int System.Drawing.Image.Height { ... }"&gt;&lt;span style="color:#006018;"&gt;Height&lt;/span&gt;&lt;/a&gt;);&lt;br /&gt;     }&lt;br /&gt;     &lt;a title="System.Console"&gt;&lt;span style="color:#006018;"&gt;Console&lt;/span&gt;&lt;/a&gt;.&lt;a title="string System.Console.ReadLine();"&gt;&lt;span style="color:#006018;"&gt;ReadLine&lt;/span&gt;&lt;/a&gt;();&lt;br /&gt;}&lt;/pre&gt; &lt;p dir="ltr"&gt;This looks exactly like our origional code!!!&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1192972388107063553-1579894364348396134?l=chamildz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chamildz.blogspot.com/feeds/1579894364348396134/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1192972388107063553&amp;postID=1579894364348396134' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1192972388107063553/posts/default/1579894364348396134'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1192972388107063553/posts/default/1579894364348396134'/><link rel='alternate' type='text/html' href='http://chamildz.blogspot.com/2007/01/using-key-word-in-c.html' title='The &quot;using&quot; key word in C#'/><author><name>Chamil</name><uri>http://www.blogger.com/profile/00204727013782891667</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1192972388107063553.post-3643958488654050118</id><published>2006-12-16T09:28:00.000-08:00</published><updated>2007-01-22T03:33:38.605-08:00</updated><title type='text'>Creating a ubuntu package repository in a local machine</title><content type='html'>Install dpkg-dev package&lt;br /&gt;&lt;br /&gt;- Go to the directory (folder) with deb packages&lt;br /&gt;&lt;br /&gt;- Run dpkg-scanpackages, send the output to a file Packages&lt;br /&gt;and compress it&lt;br /&gt;&lt;br /&gt;dpkg-scanpackages . /dev/null &gt; Packages&lt;br /&gt;gzip Packages&lt;br /&gt;&lt;br /&gt;- You can also do the previous step in one command&lt;br /&gt;&lt;br /&gt;dpkg-scanpackages . /dev/null | gzip - &gt; Packages.gz&lt;br /&gt;&lt;br /&gt;- Then add the directory (say /foo/bar/) into /etc/apt/sources.list&lt;br /&gt;&lt;br /&gt;deb file:///foo/bar ./&lt;br /&gt;&lt;br /&gt;- Finally run `apt-get update' to update apt's list of packages.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1192972388107063553-3643958488654050118?l=chamildz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://chamildz.blogspot.com/feeds/3643958488654050118/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1192972388107063553&amp;postID=3643958488654050118' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1192972388107063553/posts/default/3643958488654050118'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1192972388107063553/posts/default/3643958488654050118'/><link rel='alternate' type='text/html' href='http://chamildz.blogspot.com/2006/12/creating-ubuntu-package-repository-in.html' title='Creating a ubuntu package repository in a local machine'/><author><name>Chamil</name><uri>http://www.blogger.com/profile/00204727013782891667</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
