Category Archives: WinAPI

Postings about WinAPI

TFS: Automatically insert Check-In comments into source-code

TFS is in most cases very wonderfull. But if you have projects, which will also be used “outside” of the TFS environment (for example in an other subsidary without TFS access), then it has one disadvantage:
The comments for every check-in is only stored in the TFS version history.

While this is enough, if you always have access to the TFS. But if you work without TFS, then it would be helpfull if these comments are also included in the source-file (like in the old days, when we were using cvs (a feature called keyword-substitution)

I searched the web for any plugin for TFS which has almost the same features… but could not find any plugin….

So I wrote my own plugin, which at least puts the check-in comments into the source-file.
You just need to install this plugin and activate it in the “Check-In policy”.

Then your source-file will contai the comment, after you checked it in:

/*
 * $log$
 * 
 * Comment: And another test
 *          with a multiline
 *          comment...
 * User: xyz
 * DateTime: 2009-07-23 22:05:24
 * Change: edit
 * 
 * Comment: This is an test
 * User: xyz
 * DateTime: 2009-07-23 21:01:22
 * Change: add, edit
 *
 */

I can also customize (like templates) the position and contents of the comments…

If you are interested in this plugin-in, please let me know…

Just a small addition: Here is a post about “keyword expansion” and TFS; and possible side-effects:
http://blogs.msdn.com/buckh/archive/2007/07/07/keyword-expansion-in-tfs.aspx

EDIT: 2009-08-08:
Today I published my first release of the LogSubstPol on CodePlex.

Custom installer without warning dialog… (TrustedInstaller.exe)

If you start an custom install program which is not digital signed, then Vista and later (at least Win7RC1) warns you, that your installer is not digital signed and “do you really wnt to do that”…

This feature is implemented with an shim (in a separate article I will explain shims later).
In short it works like: if an application is started, it checks the shim-database (in general %SYSTEMROOT%\AppPath\sysmain.sdb) if this application matches specific conditions.

For “Installer detection”, there are several conditons. Here is a list, what is checked (Vista and Win7RC1):

  • Productname contains “*instal*” or “*setup*” or “*update*”
  • Companyname contains “*instal*” or “*setup*” or “*update*”
  • Internalname contains “*instal*” and app is not named “TrustedInstaller.exe”
  • Originalfilename contains “*instal*” and app is not named “TrustedInstaller.exe”
  • Filedescription contains “*instal*” and app is not named “TrustedInstaller.exe”
  • Filename contains “*instal*” and is not named “TrustedInstaller.exe”
  • Exportname contains “setup.exe” or “install.exe” or “stub32” or “stub32.exe” or “signstub.exe”
  • Filename contains “*patch*” or “*setup*” or “*uninst*” or “*update*” or “lhaca*.exe”
  • Filedescription contains “*instal*” or “*setup*” or “*update*” or “*uninst*”
  • Originalfilename contains “*setup*” or “*update*”
  • Originalfilename contains “*setup*” or “*update*”

What is the conclusion: If you want to prevent the message box, just name your installer “TrustedInstaller.exe” 😉

You can simple test this by renaming any EXE to “abcinstaldef.exe” and try to execute it 😉 and the rename it to “TrustedInstaller.exe” 😉

On the other hand: Never name your app anything of the above!

Deployment of VC2008 apps without installing anything

If you create a default CRT/MFC application with VS2008, this application will not run on other computers. You application will complain with
“This application has failed to start because the application configuration is incorrect”.

The problem is that by default VC2008 uses the DLL-version of the CRT/MFC. These DLLs are not pre-installed on any OS.
To overcome this problem, you have tree options:

  1. Statically link to the CRT/MFC
  2. Use vcredist_x86.exe / vcredist_x64.exe to install the DLLs in the system
  3. Deploy the CRT/MFC DLLs with your application (in the same directory)

In the following I will explain the last option. Especially in conjunction with VS2008 service pack 1 (SP1). Because this leads to a little bit more compications in ApppLocal deployment.

In general, it is very easy to deploy your application with the needed CRT/MFC DLLs.
Just copy the contents of the directory

  • C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\redist\x86\Microsoft.VC90.CRT
  • C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\redist\x86\Microsoft.VC90.MFC

into the same directory as your application. Then you should have the following files in your app-folder:

Microsoft.VC90.CRT.manifest
msvcr90.dll
msvcp90.dll
msvcm90.dll
Microsoft.VC90.MFC.manifest
mfc90.dll
mfc90u.dll
mfcm90.dll
mfcm90u.dll

Then your application works on an other computer!

BUT: This does not work, if you installed VS2008-SP1 🙁

The problem with VS2008 SP1 is: It overwrites all files in the “VC\redist” directory with the new version. This is not really bad. The problem is: It has a newer version number inside the manifest files. But if you compile your application with VS2008-SP1 it write the RTM-version into the application manifest! Now the version number in your application manifest does not match the version in the “new” CRT/MFC manifest. Therefore it will refuse to load these DLLs and your application cannot start.

The simplest way to overcome this problem is by changing the “Microsoft.VC90.CRT.manifest” and “Microsoft.VC90.MFC.manifest” files. Replace the version attribute in both Microfot.*.manifest files from “9.0.30729.1” (or whatever version/SP you have) to the version number in your applications-manifest (which is normally “9.0.21022.8” (RTM)).
Old:

version="9.0.30729.1"

New:

version="9.0.21022.8"

Then your application will work on an OS without installing anything.

Alternatively, you can change your applications manifest, so that it uses the new version number. This can easily done by defining

#define _BIND_TO_CURRENT_VCLIBS_VERSION 1

in stdafx.h (at the top) or in your project settings. This will embed the actual CRT/MFC-version into your applications manifest (works starting with VS2008-SP1).
Also, if you use new features from the MFC-feature-pack, you should always define this!

Just a small note: You should be aware, that this “AppLocal” installation is not really “AppLocal”… it is only AppLocal, if the vcredist_*.exe was not installed. If the vcredist_*.exe is installed, then the DLLs from the WinSxS directory will be used. If you want to prevent this, you can do a really AppLocal deployment.

A small addition: If you write .NET-apps (/clr) you still must install the .NET Framework redistributable.

But the goood news is: Starting with VC2010, the manifest (WinSxS) is gone 😉

Breaking changes in VS2010 (Beta)

The (beta9 documentation for VS2010 is online, and therefor also the Breaking changes in VS2010 C/C++:

  • “auto” is now a keyword
  • “static_assert” is now a keyword
  • Lambda support excludes support for unquoted GUID in an IDL (it uses the same […] syntax)
  • Some “.NET-Exceptions” can now only be caught with __try __except
  • /GS checks might decrease performance
  • Project files are automatically converted to the new .vcxproj
  • CRT/MFC/ATL/OpenMP-DLLs no longer use fusion (huray!); it uses plan old dll-hell
  • Support for environmentvariable __MSVCRT_HEAP_SELECT was removed
  • New _ITERATOR_DEBUG_LEVEL macro (replaces _SECURE_SCL and _HAS_ITERATOR_DEBUGGING)
  • hash_map and hash_set are now in the std namespace (previously in stdext)
  • SafeInt is included

C++/CLI quiz: Answer

In one of my last post, I asked the question, how does the callstack look like.
It was is simple unmanaged class with a virtual function. If you had executed the sample program, and set a breakpoint into the “Foo” method, you can see in the callstack-window of VS, the following callstack:
Callstack of (native) virtual function in managed code

As you can see, there are two transitions which we had not expected. One transition to native code, and one transition back to managed code.

And if you put a “printf” statement into the copy-constructor of the V-struct, you will see that the copy-constructor is called tiwce! This can have very strong performance effects…

So what might be the course of this “unnecessary” transitions?

The problem is: We have written an unmanaged virtual function as a managed function (the whole file is compiled with /clr). This means, that all unmanaged virtual functions will have two entry points. One entry point is for the “native” v-table call (thiscall); and the other is for the managed entry (clrcall).

If you call a unmanaged virtual function in a managed world, the compiler does not know which function must be callled. This is only examined at runtime through the v-table. Therefor the compiler needs to call the native function which uses the v-table. Then this “proxy”-function is calling the managed entry point. And because there are two functiions involved, the copy-constructor the the V-struct is called twice.

Conclusion:
Be aware that virtual functions in unmanaged classes which are compiled with /clr might lead to performance decrease.
If you have a big codebase, you should only enable /clr for specific files which implements the “wrapper”.
Be aware that every managed/unmanaged transition has additional execution-costs on your application. So prevent this transitions as much as possible.

C++/CLI quiz: What is the exact callstack?

I have a small quiz:
Here is a small code, compiled with “/clr” (this is important).
Can you tell me, what is the exact callstack inside the method “Foo”?
(And how can you prove this)

struct V
{
  V() {}
  V(const V &v) 
  {
    this->i = v.i;
  }
  int i;
};

class C
{
public:
  void CallFoo()
  {
    V v;
    Foo(v);
  }
  virtual void Foo(V v)
  {
    // TODO: What is the callstack!?
  }
};

int main()
{
  C c;
  c.CallFoo();
}

Any hints can be posted as comments.
By the way: VS208 does not show you the exact callstack, but it gives you a hint, that there is something that you do not see 😉

WebService in native Code (WS-*)

After the support for the SOAP-Toolkit was retired, there was no library from Microsoft, to write or consume Web-Services in native code. The suggested solution was to move to the .NET-SOAP classes. Of course, this is not always a solution, for big native code-bases.

It seems that MS has reflected this situation and also has found, that it is a “must have” to have a native WS-* library.

Starting with Windows 7 and Windoes Server 2008 R2, the OSwill have build-in support for native Web-Services.

The APIis called WWS-API (Windows Web Service API). To get an overview and also some examples, you can take a look at the code.msdn-Site.

Also, if you have an existing application and want to move to WWSAPI, you can join a virtual lab, to get help in implementing your web-service (either consuming or exposing).

EDIT:
Nikola added an comment, that WWSAPI will be also available on XP-SP2 and later! These are really great news!
You can already download the beta-bits, see:
Release of WWSAPI beta for Windows XP, Vista, Server 2003 and Server 2008

IE8 smashes Visual Studio 2005 / 2008 Class-Wizard

It seems that the new IE8 has some conflicts with Visual Studio 2008 (incl. SP1). After you installed IE8, you are not able to use the call-wizard for MFC projects anymore. It always gives you an error that there is a bug on the page:
Visual Studio 2008 bug after installing IE8

Currently there is a workaround, until a “real” fix is present:

  • Open regedit
  • Under HKEY_CURRENT_USER \ Software \ Microsoft \ Windows \ CurrentVersion \ Internet Settings \ Zones
    create a new key called 1000 (if it isn’t already there)
  • Under 1000, create a DWORD entry with:
    • Name = 1207
    • Type = REG_DWORD
    • Data = 0x000000

Visual Studio 2008 hotfix for IE8

You can also download the zipped reg-file.

Just for completeness: There is a connect entry since 9 days…

Addition: The problem also occurs with VS2005 (and maybe earlier versions 😉 )

More infos is available from the VC-Teamblog.

Change of Win-API semantics via application manifest!

Starting with Windows 7, the application manifest is becoming more and more important.

In Windows Vista, you need a manifest to bypass the application virtualization. In Window 7, you need a specific application compatibility-manifest to get correct API function behaviour 😉
For example, a race condition in GetOverlappedResult is only solved, if you explicit specify in your manifest, that you want a correct behaviour of this function.
Also a bug in CreateFileEx is only solved if you specify this in your manifest.

Of course, this is in general not a bad idea. But the manifest only allows to enable all new features or nothing. There is no way to exlicit enable only one of the bugfixes.

Here is just a small document of the “Windows 7 – Application Manifests – Compatibility”.

Windows Communication Protocols

Microsoft is publishing many of their “closed” protocols on the internet.
The starting site is: Microsoft Protocol Programs and Open Specifications.

Here is just a small list of available protocol downloads:

Building vcproj-Files with msbuild

If you want to batch-build VC++ projects you can either use devenv or msbuild.
msbuild has many option in which you can change and log the build process.

Here is just a example of a simple .proj-template for starting of batch-builds with msbuild:

 
   
     
     
     
   
   
     
     
   
   
     
     
   
   
     
     
   

You need just to save this file with the extension .proj” and call “msbuild” from the same directory. It will then do a “Rebuild” (see “DefaultTargets”).
Or you can do a “Clean” with “msbuild /t:Clean”.
You can also log to a file with “msbuild /v:d /fileLogger”.
Also, if you do not need a specific build-order of your projects, you can just include every vcproj-File in your subfolders by changing

   
     
     
     
   

to

   
     
   

Also, msbuild returns 0 if the build was sucessfull, otherwise “1”. So you can determine the result of the build in your batch-files.

So you can see: msbuild is very powerfull…

All-in-One Code Framework

If you need examples of some of the current Microsoft technologies, you have many technologies and programming languages available. For each of these technologies/languages you need to find a fitting example.

On CodePlex there is now an example-collection for most of the available technologies (COM, ActiveX-Control, ActiveX-Host, ADO, ADO.NET, Outlook-Customizing, DLL, DLL-delay-loaded, LIB, P/Invoke, CLR-hosting / named-pipes, mailslots, shared-memory, remoting) and programming languages (C/C++ (native / MFC / ATL) / C# / VB.NET):

Check out: All-In-One Code Framework

Windows 7 Beta UAC “improvements”

In the Windows 7 Beta 1, there is a new “feature” in UAC (User Account Control). This new feature seems to help reduce UAC-Dialogs in specific situations, by selecting one of the follwing settings:

  • Always notify on every system change (seems to be the Vista-Style
  • Notify me only when programs try to make changes to my computer.
  • Notify me only when programs try to make changes to my computer, without using the Secure Desktop.
  • Never notify.

This sound really great!
But after looking at this, I thought: How the hell did they implement this? Will there be a list of APIs which are “safe-to-call” in one of the settings?

But after reading this answer from an MS guy in the kernel newsgroup, I could not laugh anymore…
This solution only accepts changed from MS applications!
This solution is one of the the worsts solution and might lead to some work for lawyers… but I hope that this is only a beta feature and will either be removed or opened for other (signed) apps.

I will wait and see…

VS2008 Service Pack 1 is available!

Today, the first service pack for Visual Studio 2008 has shipped:
http://www.microsoft.com/downloads/details.aspx?FamilyID=27673c47-b3b5-4c67-bd99-84e525b5ce61&displaylang=en

But it seems that the installer is not very user-friendly:

If you previously installed a Visual Studio 2008 Hotfix, you must run the Hotfix Cleanup Utility before installing Visual Studio 2008 SP1. For more information, see Visual Studio 2008 Hotfix Cleanup Utility for Installing Visual Studio 2008 SP1.

Also, the KB article with the list of all fixes is not yet updated:
http://support.microsoft.com/kb/945140/en-us

Hopefully this SP will fix many bugs 😉

Main disadvantage of (really) AppLocal deployment

In my last post I described how to (really) deploy CRT/MFC DLLs into the same directory as the application (xcopy deployment).

“Really” means, that it will never load any DLLs installed in the WinSxS directory. This is archived by removing the “publicKeyToken” from the manifest. If you leave the “publicKeyToken” inside the manifest, then it will force loading of (possibly) installed WinSxS versions (and updates/redirections).

The option of really AppLocal installations are not explaind on any Microsoft side (or at least I could not find it). Only the “normal” (semi) AppLocal installation is (a little bit) explaind, for example here:
Visual C++ Libraries DLL Deployment.

One of the main reasons for this is the new focus from Mircosoft to Security.

The main disadvantage of really AppLocal installations is, that Microsoft is not able to update or patch your installation (or better the CRT/MFC components of your installation). And this sees to be anathema to Microsoft.
The same is also true for static linked applications.

So I fear, that Microsoft will

  • remove or deprecate static linking in the next version of VS
  • remove the possibility to really AppLocal installations in the next OS /MFC/CRT DLLs

Hopefully, this will not come true…

Howto: Deploy VC2008 apps without installing vcredist_x86.exe

There are several reasons for xcopy deployment of an application (also known as application local). One main reason is that you are independent of what the target computer has installed.
Also your application always uses the “correct” (or better: tested) version of DLLs, regardless of what MS installed or updated (see: .NET2 SP1 update breaks old apps!?).

The easiest way to overcome the problem is to link static against the CRT/MFC. But in some scenarios this is not an option and not possible.

But to be independent from OS updates or from vcredist_x86.exe installations of other apps, you need to do the following steps:

  • Remove the auto-generation of manifests (from all DLLs) and change the manifest generation form your EXE to an external manifest; you can do this by choosing: Project|Properties|Configuration Properties|Manifest Tool|Input and Output|Embed Manifest: No
  • Recompile your application and modify the external manifest as follows:
  • Copy your application and the external manifest to your deployment directory
  • Open the manifest-file (appname.exe.manifest) and remove the “publicKeyToken” from all MFC/CRT/ATL/OpenMP entries. Please leave the publicKeyToken to the “Microsoft.Windows.Common-Controls” entry.
  • Copy all neccessary directories under %ProgramFiles%\Microsoft Visual Studio 9.0\VC\redist\x86 to your deployment directory
  • In all sub-directories (Microsoft.VC90.CRT, optional: Microsoft.VC90.MFC, Microsoft.VC90.ATL, Microsoft.VC90.OPENMP, Microsoft.VC90.MFCLOC) open the manifest-file and also remove the publicKeyToken
  • Also lookup the version info from these manifest files and correct the version-info of the corresponding entries in your application manifest file
  • Save all manifests and let your program run; it should now run on all supported OS without installing anything…

After doing all these manifest stuff you can also embed the manifest into your application (EXE). And of course: The same can be done with x64 and IA64 apps.

I have made an example of the default MFC app (4.6 MB) for reference.

The (simple) manifests for the new MFC feature pack and the application looks like:

Application.exe.manifest



  
    
      
        
      
    
  
  
    
      
    
  
  
    
      
    
  
  
    
      
    
  

Microsoft.VC90.CRT.manifest



    
    
     
     
    

Microsoft.VC90.MFC.manifest



    
    
     
     
     
    

Instead of putting the “Microsoft.VC90.MFC” and “Microsoft.VC90.CRT” directories into the application folder, you can also just put the files from these folders into the application directory. The main advantage is, that your app will also work on W2k-SP4.

Here is also my older post for VS2005.

Available hotfixes for VC2005-SP1 / VC2008 RTM / VC2008-SP1

There are already several hotfixes available for VC2005 SP1 and VC2008 RTM. Here is a short overview:

Updated: 2008-11-06
Updated: 2009-03-09
Updated: 2009-03-13
Updated: 2009-03-18
Updated: 2009-05-08
Updated: 2009-05-13
Updated: 2009-05-23
Updated: 2009-10-06