Mittwoch, 30. März 2011

Compiler internals - What happens with try/catch/throw in MSVC

Hello everyone

After i have seen that a lot of people are thinking that try - catch is a concept which is completely analyzed during compile time and therefore wont have big impact at runtime i thought i might shed some light on how the Microsoft compiler (cl.exe) is acting with try, catch and throw.

First off we will have a look on how a throw statement is interpreted by the compiler. Lets have a look at the following code:
int main()
{
 try
 {
  throw 2;
 }
 catch(...)
 {
 }
}

For now we are only interested in the throw 2. When the compiler hits the throw statement it actually has no clue if the exception its now converting is handled by an exception handler (and it doesnt care). The throw statement will be converted into a call to _CxxThrowException (exported by MSVCR100.dll (or any other version)). That function is a built in function in the compiler. You can call it yourself if you like ;). The first parameter of that function is a pointer to the object thrown. Therefore it gets clear, that the code above definitely expands to the following:
int main()
{
 try
 {
  int throwObj = 2;
  throw throwObj;
 }
 catch(...)
 {
 }
}

The second parameter of _CxxThrowException holds a pointer to a _ThrowInfo object. _ThrowInfo is also a built in type of the compiler. Its a struct holding various information about the type of exception that was thrown. It looks like that:
typedef const struct _s__ThrowInfo
{
 unsigned int attributes;
 _PMFN pmfnUnwind;
 int (__cdecl*pForwardCompat)(...);
 _CatchableTypeArray *pCatachableTypeArray;
} _ThrowInfo;

Here the important thing is the _CatchableTypeArray. It holds a set of runtime type informations of the types that are catchable within this throw. In our case thats pretty simple. The only catchable type is typeid(int). Lets say you have a class derived from std::exception called my_exception. If you now throw an object of type my_exception you will have two entries in pCatchableTypeArray. One of them is typeid(my_exception) and the other is typeid(std::exception).

The compiler now fills the _ThrowInfo object as a global variable (and all the other objects needed). In the above case this is done the following way:
_TypeDescriptor tDescInt = typeid(int);

_CatchableType tcatchInt = 
{
 0,
 &tDescInt,
 0,
 0,
 0,
 0,
 NULL,
};

_CatchableTypeArray tcatchArrInt = 
{
 1,
 &tcatchInt,
};

_ThrowInfo tiMain1 = 
{
 0,
 NULL,
 NULL,
 &tcatchArrInt
};

You see that thats pretty a lot of information stored just for the throw 2. So finally Our above code expands to:
_TypeDescriptor tDescInt = typeid(int);

_CatchableType tcatchInt = 
{
 0,
 &tDescInt,
 0,
 0,
 0,
 0,
 NULL,
};

_CatchableTypeArray tcatchArrInt = 
{
 1,
 &tcatchInt,
};

_ThrowInfo tiMain1 = 
{
 0,
 NULL,
 NULL,
 &tcatchArrInt
};

int main()
{
 try
 {
  int throwObj = 2;
  _CxxThrowException(&throwObj, &tiMain1);
 }
 catch(...)
 {
 }
}

Inside _CxxThrowException now the following happens: RaiseException is called. But first the neccessary parameters are created. The exception code for an exception thrown by _CxxThrowException is 0xE06D7363. It also passes 3 parameters to RaiseException. A magic number, the pointer to the object thrown and the pointer to the _ThrowInfo. Resulting in the following pseudo code:
__declspec(noreturn) void __stdcall __CxxThrowException(void* pObj, _ThrowInfo* pInfo)
{
 struct { unsigned int magic; void* object, _ThrowInfo* info } Params;
 Params throwParams = 
 {
  0x19930520,
  pObj,
  pInfo
 }

 RaiseException(0xE06D7363, 1, 3, (const ULONG_PTR*)&throwParams);
}

Now we basically know how throw is handled by the compiler and we also see that in the end what you will notice is something like if you have encountered an access violation as they are also invoked by RaiseException.

Ok, if we now go further and inspect the try and catch there should be a bell ringing like crazy and it should be yelling "Wait!! You say that the throw gets transformed into a call to RaiseException like its for access violations, 0 divides and so on?! But they cannot be catched with try-catch!". And yes, you are right, they cant and thats way try - catch in fact gets transformed to a __try __except but in a special form. In code it would look somehow like that (its not real code, just theory):
unsigned long __stdcall mainHandler1(LPEXCEPTION_POINTERS info)
{
 if(info->ExceptionRecord->ExceptionCode != 0xE06D7363)
  return EXCEPTION_CONTINUE_SEARCH;

 if(WeHaveAHandlerForThisTypeSomeWhere(info->ExceptionRecord))
  return EXCEPTION_EXECUTE_HANDLER;

 return EXCEPTON_CONTINUE_SEARCH;
}

/* The stuff with _ThrowInfo comes here, omitted for readability */

int main()
{
 __try
 {
  int throwObj = 2;
  _CxxThrowException(&throwObj, &tiMain1);
 }
 __except(mainHandler1(GetExceptionInfo())
 {
 }
}

But thats not all! Somewhere we need to store which types of exceptions we can catch using our catch-statement. In fact the catch(int) gets transformed into an own function (actually only a function chunk where the runtime jumps using jmp not a real function called with call) which looks like that (now its really pseudocode because i cannot really translate it to C as it misses some information which would blow up the whole thing)
_s_FuncInfo* info = mainCatchBlockInfo1;
__asm { mov eax, info } // Its used for the following function as argument and passed through eax
goto CxxFrameHandler3;

The _s_FuncInfo is now again a structure that is built in to the compiler. It would make the article to big to explain everything like i did for the _ThrowInfo. In short it holds information for every type that can be caught in the current block. This consists (beneath other stuff) of runtime type information for every type and for each of them also the address of the actual code that is inside the catch-block.

Ok, now what is CxxFrameHandler3 doing? This is pretty simple:
1. It rejects exceptions that dont have 0xE06D7363 as code (which stands for C++ exceptions).
2. It searches through the _s_FuncInfo structure to find a type witch matches with one of the types it gets from the exception objects _CatchableTypeArray.
3. If it gets a match it indicates that there is a handler read
4. If there is not match it instructs the OS to search in the next frame

To finish the catch-part all we now need is the actual handler code. This code also is transformed into a function chunk (not a complete function). It actually is transformed into the chunk that ends a function. In code it would look like that:
// execute handler code
return addressWhereToContinueAfterCatch;

The operating system gets the address where it should jump to when it has set up again the original context and performs that jump. An example:
catch(...)
{
}

MessageBox(0, L"Ello!", L"", MB_OK);

Gets translated into the following assembler code:
.text:00401088 $LN16:
.text:00401088                 mov     eax, offset $LN9
.text:0040108D                 retn
.text:0040108E ; ---------------------------------------------------------------------------
.text:0040108E
.text:0040108E $LN9:                                   ; DATA XREF: _main:$LN16 o
.text:0040108E                 push    0               ; uType
.text:00401090                 push    offset Caption  ; lpCaption
.text:00401095                 push    offset Text     ; "Ello!"
.text:0040109A                 push    0               ; hWnd
.text:0040109C                 call    ds:__imp__MessageBoxW@16 ; MessageBoxW(x,x,x,x)

You see that it returns $LN9 in eax which is the address of the call to MessageBox. And $LN16 is the address of the catch block which is referenced in the _s_FuncInfo somewhere.

All that remains now is the try part. Here its no longer the compiler that can "decide" how to do things because now its the operating system that says how it works.

Inside the Thread Information Block the first field (fs:[0]) holds a pointer to a linked list of exception handlers (in our case its the address of the part where it goes to CxxFrameHandler3). Now what try does is it adds the catch-block to the linked list. After the RaiseException call we arrive in the function KiUserExceptionDispatcher. This function does a lot of work but in the end the important thing is that it loads the current linked list from the TIB using FS:[0] and loops through it to find a handler that says that it could handle the exception and calls its handler. If you want to browse through the currently attached handlers you do the following:
struct LinkedExceptionFrame
{
 LinkedExceptionFrame* pPrevious;
 void* pFunction;
};

LinkedExceptionFrame* pCur = NULL;
__asm
{
 mov eax, fs:[0]
 mov pCur, eax
}
while((DWORD)pCur != 0xFFFFFFFF)
{
 std::cout << pCur->pFunction << std::endl;
 pCur = pCur->pPrevious;
}

Now we have all the basic concepts we need to understand that try/catch/throw is not as trivial as most people think and that most things are actually handled at runtime (though a huge amount of additional data and function overhead is made to catch the correct type of exception). There is way more we could talk about (for example: What if we have parts of our frame protected by try-catch and others not or if we even have more than one try-catch-block and so on. But i think so far the most important things are said!

Some tips if you like to browse through it using a disassembler and a debugger:
Use Release build but disable any kind of code optimization. So you dont have all the register checks at the beginning and the end of function calls but your code is not getting rearranged by the optimizer so you can better compare it to the source. And its a good thing to disable Dynamic Base (ASLR) in the linker options (under Advanced).

So far
Yanick

Sonntag, 27. März 2011

Internet Explorer 9 - Avoid JavaScript in x64

Ahoi

Even though im not using the Internet Explorer since ages now and am pretty sticked to one type of browser i still like to browse announcements of new browser (versions). It was Microsoft to release version 9 some days ago so i decided to test it out and see if there are cool new things available.

While actually the x86 version runs pretty fair ive seen a problem coming up with the x64 version. If you launch a site which makes heavy usage of javascript (and there are plenty) you should be aware that it might get pretty slow. Its parsed and executed in a way that really makes you fall asleep. Of course i first thought that this is an issue caused by my system. So i restarted everything checked windows update and dug through the settings of the IE. Sadly nothing helped to make it faster. After browsing a bit through the wide web ive seen that this is an issue that Microsoft obviously knows. They didnt implement the JIT compiler into the x64 version of the browser. This causes the javascript code made by the programmer being executed without any optimization.

Why does Microsoft release a version of a product which lacks such an important feature? It reminds me a lot of visual studio 2010 which until yet does not have any support for intellisense in CLI/C++ which is one of the most important features of .NET as no one can memorize those zillions of objects... I really hate that manner of "We release half finished products and maybe there will be updates some when..."!

What do you think?
Yanick

RtlCaptureStackBackTrace in managed world - Error, error, error!

Hello everyone

Lately ive created an API for a game which is no longer maintained by its developers which will be loaded using DLL-injection. It allows users to write plug-ins for that game. The DLL containing the Framework consists of pure managed code (C#) and is therefore loaded using the ICLRRuntimeHost::ExecuteInDefaultAppDomain method.

As its hard to debug an executable without having the source code of it ive started to create my own symbol database for functions and global objects. I planed to use that table in my stack trace to see more detailed information if i did something wrong (those who now throw in debuggers may know that the game had anti debugging mechanics implemented (as it was an online game back then) and i was to lazy to bypass them (sadly...)).

Since ages i use the function RtlCaptureStackBackTrace to easily create stack traces in unmanaged world. So i did the same in C# using DllImport. After setting framesToSkip to 0 i was pretty shocked that i only got 1 frame returned by the function which was actually RtlCaptureSBT itself. I tried several things and then used Marshal.GetLastWin32Error() to get more information on what im doing wrong. Interestingly it returned that no error happened (yes, SetLastError=true ;)). So the function said something is wrong and GetLastError said nothing is wrong, oh yeah!

So i launched IDA and stepped through the function in another .NET executable which wasn't injected to the game. On my (in this time) x86 machine what it did was calling RtlWalkFrameChain which then called RtlWalk32BitStack. That function loops through the stack frames and calls for the address of each of them the function RtlpIsPointerInDllRange from ntdll.dll which determines if a given pointer is in the accessible memory of any of the loaded modules. If it returns false RtlWalk32BitStack returns false thus RtlWalkFrameChain returns false which also causes RtlCaptureStackBackTrace to return false. But as none of these functions calls SetLastError it stays 0 also on failure.

Ok, so i started a debug run. First frame worked good and it was added to the list. Second frame was in a managed module which caused RtlpIsPointerInDllRange to return false. Now all aborted.

Well then i dug trough ntdll.dll searching references of the global variable used to indicate accessible ranges and found the function RtlpStkMarkDllRange. This function is only referenced by LdrpLoadOrMapDll which is used by LdrLoadDll (called by LoadLibrary). RtlpStkMarkDllRange is also not exported so other DLLs can not actually call it. So i searched for references to RtlpIsPointerInDLLRange (also not exported) and found that its only used by functions that perform stack walks.

So i got the feeling that somehow they forgot to include the call to RtlpStkMarkDllRange when a fully managed DLL is loaded because actually there is no reason why a .NET executable should be not valid for holding pointers to functions! Even more as StackWalk64 works as intended and returns all frames while RtlCaptureStackBackTrace isnt.

What do you think?
Yanick

Samstag, 26. März 2011

Exception Handling - Inform your users! Part 2

Hello again

In the previous article (Part 1) i explained how you provide some basic information about an unhandled exception to the user and announced that in the next part we will have a look on how to get more detailed information. Now thats exactly what we will do in this article. Ill show two methods to gather more information what happened and why it happened.

Method 1: Do it manually
For this method we will create several helper functions that handle one or more types of exceptions. We start with the following code:
#include <Windows.h>
#include <iostream>

LONG WINAPI UnhandledException(LPEXCEPTION_POINTERS exceptionInfo)
{
 return EXCEPTION_EXECUTE_HANDLER;
}

int main()
{
 SetUnhandledExceptionFilter(UnhandledException);
}

The first function we make will return a name which describes the type of exception that happened. Writing that function is pretty easy if we use macro that helps us:
#define EX_CASE(code) \
 case code:\
  return #code;

LPCSTR GetExceptionName(DWORD code)
{
 switch(code)
 {
 EX_CASE(EXCEPTION_ACCESS_VIOLATION);
 EX_CASE(EXCEPTION_DATATYPE_MISALIGNMENT);
 EX_CASE(EXCEPTION_BREAKPOINT);
 EX_CASE(EXCEPTION_SINGLE_STEP);
 EX_CASE(EXCEPTION_ARRAY_BOUNDS_EXCEEDED);
 EX_CASE(EXCEPTION_FLT_DENORMAL_OPERAND);
 EX_CASE(EXCEPTION_FLT_DIVIDE_BY_ZERO);
 EX_CASE(EXCEPTION_FLT_INEXACT_RESULT);
 EX_CASE(EXCEPTION_FLT_INVALID_OPERATION);
 EX_CASE(EXCEPTION_FLT_OVERFLOW);
 EX_CASE(EXCEPTION_FLT_STACK_CHECK);
 EX_CASE(EXCEPTION_FLT_UNDERFLOW);
 EX_CASE(EXCEPTION_INT_DIVIDE_BY_ZERO);
 EX_CASE(EXCEPTION_INT_OVERFLOW);
 EX_CASE(EXCEPTION_PRIV_INSTRUCTION);
 EX_CASE(EXCEPTION_IN_PAGE_ERROR);
 EX_CASE(EXCEPTION_ILLEGAL_INSTRUCTION);
 EX_CASE(EXCEPTION_NONCONTINUABLE_EXCEPTION);
 EX_CASE(EXCEPTION_STACK_OVERFLOW);
 EX_CASE(EXCEPTION_INVALID_DISPOSITION);
 EX_CASE(EXCEPTION_GUARD_PAGE);
 EX_CASE(EXCEPTION_INVALID_HANDLE);

 case 0xE06D7363:
  return "C++ Exception";
 
 default:
  return "Unknown exception";
 }
}

#undef EX_CASE

The next helper function will take an exception address an return in which module the exception occurred. This is done by looping through the loaded modules and comparing which one is the last with its base address before the exception location. Then we use GetModuleFileName to retrieve the name of the module.
#include <windows.h>
#include <iostream>
#include <psapi.h>

#pragma comment(lib, "psapi.lib")

// Definition of function GetExceptionName....


HMODULE GetExceptionModule(LPVOID address, LPSTR moduleName /* must support MAX_PATH characters */)
{
 HMODULE moduleList[1024];
 DWORD sizeNeeded = 0;
 if(FALSE == EnumProcessModules(GetCurrentProcess(), moduleList, 1024, &sizeNeeded) || sizeNeeded < sizeof(HMODULE))
  return NULL;

 int curModule = -1;
 for(int i = 0; i < (sizeNeeded / sizeof(HMODULE)); ++i)
 {
  if((DWORD)moduleList[i] < (DWORD)address)
  {
   if(curModule == -1)
    curModule = i;
   else
   {
    if((DWORD)moduleList[curModule] < (DWORD)moduleList[i])
     curModule = i;
   }
  }
 }

 if(curModule == -1)
  return NULL;

 if(!GetModuleFileName(moduleList[curModule], moduleName, MAX_PATH))
  return NULL;

 return moduleList[curModule];
}
We can test those two functions now and see what result we get using the following code:
// previous code...

LONG WINAPI UnhandledException(LPEXCEPTION_POINTERS exceptionInfo)
{
 char message[MAX_PATH + 255];
 char module[MAX_PATH];
 char* moduleName = NULL;
 if(GetExceptionModule(exceptionInfo->ExceptionRecord->ExceptionAddress, module))
  moduleName = module;
 else
  moduleName = "Unknown module!";

 sprintf_s(message, 
  "An exception has occured which was not handled!\nCode: %s\nModule: %s", 
  GetExceptionName(exceptionInfo->ExceptionRecord->ExceptionCode),
  moduleName
 );

 MessageBox(0, message, "Error!", MB_OK);
 return EXCEPTION_EXECUTE_HANDLER;
}

int main()
{
 SetUnhandledExceptionFilter(UnhandledException);

 int b = 0;
 int a = 2 / b;
}
The messagebox now should display the name of your executable. The EXCEPTION_RECORD structure inside exceptionInfo contains an array of additional data that can be used to provide more information. Sadly those values are not defined by a standard. Its up to every compiler to do whatever it likes to. There are only 2 codes for which additional information is defined in a standardized way. EXCEPTION_ACCESS_VIOLATION and EXCEPTION_IN_PAGE_ERROR. We will now write a function that handles EXCEPTION_ACCESS_VIOLATION separately and provide a function that handles all the other codes.
void HandleAccessViolation(LPEXCEPTION_POINTERS info)
{
 char message[MAX_PATH + 512];
 char module[MAX_PATH];
 char* moduleName = NULL;
 if(GetExceptionModule(info->ExceptionRecord->ExceptionAddress, module))
  moduleName = module;
 else
  moduleName = "Unknown module!";

 DWORD codeBase = (DWORD)GetModuleHandle(NULL);
 DWORD offset = (DWORD)info->ExceptionRecord->ExceptionAddress - codeBase;

 char* accessType = NULL;
 switch(info->ExceptionRecord->ExceptionInformation[0])
 {
 case 0:
  accessType = "Read";
  break;
 case 1:
  accessType = "Write";
  break;
 case 2:
  accessType = "Execute";
  break;
 default:
  accessType = "Unknown";
  break;
 }

 sprintf_s(message, 
  "An exception has occured which was not handled!\nCode: %s\nModule: %s\n"\
  "The thread %u tried to %s memory at address 0x%08X which is inaccessible!\n"\
  "Offset: 0x%08X\nCodebase: 0x%08X",
  GetExceptionName(info->ExceptionRecord->ExceptionCode),
  moduleName,
  GetCurrentThreadId(),
  accessType,
  info->ExceptionRecord->ExceptionInformation[1],
  offset,
  codeBase
 );

 MessageBox(0, message, "Error!", MB_OK);
}

void HandleCommonException(LPEXCEPTION_POINTERS info)
{
 char message[MAX_PATH + 512];
 char module[MAX_PATH];
 char* moduleName = NULL;
 if(GetExceptionModule(info->ExceptionRecord->ExceptionAddress, module))
  moduleName = module;
 else
  moduleName = "Unknown module!";

 DWORD codeBase = (DWORD)GetModuleHandle(NULL);
 DWORD offset = (DWORD)info->ExceptionRecord->ExceptionAddress - codeBase;

 sprintf_s(message, 
  "An exception has occured which was not handled!\nCode: %s\nModule: %s\n"\
  "Offset: 0x%08X\nCodebase: 0x%08X",
  GetExceptionName(info->ExceptionRecord->ExceptionCode),
  moduleName,
  offset,
  codeBase
 );

 MessageBox(0, message, "Error!", MB_OK);
}

LONG WINAPI UnhandledException(LPEXCEPTION_POINTERS exceptionInfo)
{
 switch(exceptionInfo->ExceptionRecord->ExceptionCode)
 {
 case EXCEPTION_ACCESS_VIOLATION:
  HandleAccessViolation(exceptionInfo);
  break;
 default:
  HandleCommonException(exceptionInfo);
  break;
 }
 return EXCEPTION_EXECUTE_HANDLER;
}
Well, thats it! Now we have handled access violations and also a default handling for other exceptions. Method 2: Let windows do the thing! Windows provides a method to create a dump file from the current execution context. This will include a dump of the memory as well as other information visual studio can use to display all the information necessary. The function is called inside the exception handler. Its very easy so i wont tell much about it. It will create a .dmp file which can be opened with Visual Studio. When you start debugging (using the green arrow) you will get all the information needed. Here is the corresponding code:
#include 
#include 
#include 
#include 

#pragma comment(lib, "dbghelp.lib")

LONG WINAPI UnhandledException(LPEXCEPTION_POINTERS exceptionInfo)
{
 char timeStr[255];
 time_t t = time(NULL);
 tm* tM = localtime(&t);
 strftime(timeStr, 255, "CrashDump_%d_%m_%Y_%H_%M_%S.dmp", tM);
 HANDLE hFile = CreateFile(
  timeStr, 
  GENERIC_WRITE | GENERIC_READ,
  0,
  NULL,
  CREATE_ALWAYS,
  0,
  NULL
 );

 if(hFile != NULL)
 {
  MINIDUMP_EXCEPTION_INFORMATION info = 
  {
   GetCurrentThreadId(),
   exceptionInfo,
   TRUE
  };

  MiniDumpWriteDump(
   GetCurrentProcess(),
   GetCurrentProcessId(),
   hFile,
   MiniDumpWithIndirectlyReferencedMemory,
   &info,
   NULL,
   NULL
  );

  CloseHandle(hFile);
 }

 return EXCEPTION_EXECUTE_HANDLER;
}

int main()
{
 SetUnhandledExceptionFilter(UnhandledException);

 int b = 0;
 int a = 2 / b;
}


Now you have 2 good methods to retreive vital information about errors that happened.

Thanks for reading and bye
Yanick

Exception Handling - Inform your users!

Hello everyone!

This article will show you methods to inform the user that something has happened in the program which caused an exception that was not handled by the program. It will also teach you how to use the values you will get and display some more information the user can then submit to you.

First we should know what happens if an exception is thrown. The operating system now aims to find a handler which tells what to do now. In order to find such a handler the system has a fixed order to search. It will start with the vectored exception handlers (added for example using AddVectoredExceptionHandler). If no handler was found there it will continue and in each frame of the stack it will examine all the frame based exception handlers (try - catch, __try - __except). If no handler suited the exception thrown it will then have a look if a top level exception handler is registered (using SetUnhandledExceptionFilter). If that fails too you will get a window "XY has stopped working" with the commonly known options. There is actually one exception from that behavior: When a debugger is attached. In this case the debugger is automatically installed as the top level exception handler and you cannot change it. Using various settings you can even intercept all of the above mentioned handlers and directly pass every exception to the debugger.

Well, now how could we get informed that an exception happened that was not properly handled? Using AddVectoredExceptionHandler is not a good idea because every exception that happened will be interpreted as if it was not handled. Thats not what we try to achieve. Installing a frame on top of every thread that gets started and handling every type of exception there is possible but to much work. Also threads started by external components maybe dont act like that and exceptions caused by them wont be recognized.

The response is using SetUnhandledExceptionFilter. This function lets us register a function that is called if all other handlers failed. As this is the last resort we can be sure that no one "cared" about that exception and that it will lead to an unwanted program termination if nothing is done now. The usage of that function is very easy. All it wants is a pointer to a function which has a special format. It then returns a pointer to the function that was installed before our call so we could reset it if we dont need to handle the exceptions anymore. So to test that we make a simple program:
#include <Windows.h>

LONG WINAPI UnhandledException(LPEXCEPTION_POINTERS exceptionInfo)
{
 MessageBox(0, "An exception occured which wasnt handled!", "Error!", MB_OK);
 return EXCEPTION_EXECUTE_HANDLER;
}

int main()
{
 SetUnhandledExceptionFilter(UnhandledException);

 char* ptr = NULL;
 *ptr = 'a';
}

The return value of our function indicates what the operating system should do next. Returning EXCEPTION_CONTINUE_HANDLER instructs it to execute the handler for that exception. On the top level this actually means that it will directly call ExitProcess. If you run the above code (please make sure you are not attaching any debugger) you will get the messagebox (unless you are in kernel mode) and the application will terminate.

Now lets experiment with that. First we will look if the function also gets called if we surround the bad code with try - catch(...). First maybe think if you can figure out the response yourself.
#include <Windows.h>

LONG WINAPI UnhandledException(LPEXCEPTION_POINTERS exceptionInfo)
{
 MessageBox(0, "An exception occured which wasnt handled!", "Error!", MB_OK);
 return EXCEPTION_EXECUTE_HANDLER;
}

int main()
{
 SetUnhandledExceptionFilter(UnhandledException);

 try
 {
  char* ptr = NULL;
  *ptr = 'a';
 }
 catch(...)
 {

 }
}

After running the code we know: It gets called! Maybe that is surprising you. If so have a look at the following code:
#include <Windows.h>

LONG WINAPI UnhandledException(LPEXCEPTION_POINTERS exceptionInfo)
{
 MessageBox(0, "An exception occured which wasnt handled!", "Error!", MB_OK);
 return EXCEPTION_EXECUTE_HANDLER;
}

int main()
{
 SetUnhandledExceptionFilter(UnhandledException);

 __try
 {
  char* ptr = NULL;
  *ptr = 'a';
 }
 __except(EXCEPTION_EXECUTE_HANDLER)
 {

 }
}

Wait, now it is not called?! But why? The answer is pretty simple: There are two main types of exceptions. The first type are exceptions that are thrown using the keyword 'throw'. They are called C++-exceptions. These exceptions get caught using the try-catch statement. The other type are exceptions that are thrown by the operating system in response of faults that happened. These are called SEH-exceptions (structed exception handling). To catch such an exception there must be a frame which catches exceptions using __try - __except. We see the EXCEPTION_EXECUTE_HANDLER here again. In this case the executed "handler" is the part in the scope after __except.

As dereferencing the NULL-Pointer and assigning a value to it in user mode is not allowed the operating system indicates a fault and throws a SEH-exception. Those exceptions cannot be handled by try - catch statements. Therefore in the first code the exception is passed to our function. But in the second code the exception is caught and the program can continue so our function is not called.

Well, now our messagebox does not really contain a lot of information. A user which sees that message wont have an idea what to do and if he submits it to you this wont help at all. So providing some more information would be helpful. So we'll use the parameter our exception handler receives to find additional information about the exception which we can show to the user. The most important things one should now are the following two:
What happened?
Where did it happen?

The answer to both questions lies inside the exceptionInfo parameter. And here is how we can access it:
#include <Windows.h>
#include <iostream>

LONG WINAPI UnhandledException(LPEXCEPTION_POINTERS exceptionInfo)
{
 char message[255];
 sprintf_s<255>(message, 
  "An exception occured which wasnt handled!\nCode: 0x%08X\nAddress: 0x%08X", 
  exceptionInfo->ExceptionRecord->ExceptionCode,
  exceptionInfo->ExceptionRecord->ExceptionAddress
 );
 MessageBox(0, message, "Error!", MB_OK);
 return EXCEPTION_EXECUTE_HANDLER;
}

int main()
{
 SetUnhandledExceptionFilter(UnhandledException);

 char* ptr = NULL;
 *ptr = 'a';
}

I think this is pretty self-explaining. Though there is one major problem with the exception address. If our binary uses ASLR (Address Space Layout Randomization) its base address will start at a random address at every launch. Therefore the address is completely useless for us as we dont know where the binary starts. To solve that problem we could print the start and end address for every module loaded into the message box which would allow us to exactly determine in which module at which offset the exception happened or we just print the start of the main module and the offset from there. The second version is less informative because if the exception didnt happen in the main module we again have an offset which is not really useful. But anyway, we will use the second approach as we focus on our executable.

#include <Windows.h>
#include <iostream>

LONG WINAPI UnhandledException(LPEXCEPTION_POINTERS exceptionInfo)
{
 DWORD codeBase = (DWORD)GetModuleHandle(NULL);
 char message[255];
 sprintf_s<255>(message, 
  "An exception occured which wasnt handled!\nCode: 0x%08X\nOffset: 0x%08X\nCodebase: 0x%08X", 
  exceptionInfo->ExceptionRecord->ExceptionCode,
  (DWORD)exceptionInfo->ExceptionRecord->ExceptionAddress - codeBase,
  codeBase
 );
 MessageBox(0, message, "Error!", MB_OK);
 return EXCEPTION_EXECUTE_HANDLER;
}

int main()
{
 SetUnhandledExceptionFilter(UnhandledException);

 char* ptr = NULL;
 *ptr = 'a';
}

Now we have an offset which can be used to determine which instruction caused the exception. If you start google and search for "Exception code 0xC0000005" you will find that this stands for an access violation. Wouldnt it be nice to show EXCEPTION_ACCESS_VIOLATION instead of 0xC0000005? There is a simple way doing that using a little macro that converts the predefined codes into a friendlier form:
#include <Windows.h>
#include <iostream>

#define EXCEPTION_CASE(code) \
 case code: \
  exceptionString = #code; \
  break

LONG WINAPI UnhandledException(LPEXCEPTION_POINTERS exceptionInfo)
{
 const char* exceptionString = NULL;
 switch(exceptionInfo->ExceptionRecord->ExceptionCode)
 {
 EXCEPTION_CASE(EXCEPTION_ACCESS_VIOLATION);
 EXCEPTION_CASE(EXCEPTION_DATATYPE_MISALIGNMENT);
 EXCEPTION_CASE(EXCEPTION_BREAKPOINT);
 EXCEPTION_CASE(EXCEPTION_SINGLE_STEP);
 EXCEPTION_CASE(EXCEPTION_ARRAY_BOUNDS_EXCEEDED);
 EXCEPTION_CASE(EXCEPTION_FLT_DENORMAL_OPERAND);
 // add more cases...

 default:
  exceptionString = "Unknown exception";
  break;
 }

 DWORD codeBase = (DWORD)GetModuleHandle(NULL);
 char message[255];
 sprintf_s<255>(message, 
  "An exception occured which wasnt handled!\nCode: %s (0x%08X)\nOffset: 0x%08X\nCodebase: 0x%08X", 
  exceptionString,
  exceptionInfo->ExceptionRecord->ExceptionCode,
  (DWORD)exceptionInfo->ExceptionRecord->ExceptionAddress - codeBase,
  codeBase
 );
 MessageBox(0, message, "Error!", MB_OK);
 return EXCEPTION_EXECUTE_HANDLER;
}

int main()
{
 SetUnhandledExceptionFilter(UnhandledException);

 char* ptr = NULL;
 *ptr = 'a';
}

Now the user sees a better readable name for the exception code. Have a look at this article on MSDN to get a list with all defined exception codes that commonly occur: Article

Now lets change the main function to the following:
int main()
{
 SetUnhandledExceptionFilter(UnhandledException);

 throw "An error!";
}

Even if you defined all cases from the MSDN-article here you will get "Unknown exception (weird hex-number)". What does that number stand for? Maybe its a pointer to the string we have thrown? And beside that, why do we get such a huge offset? Our executable isn't that big! To answer the second question first: throw will actually be replaced by the compiler to a internal function call to CxxThrowException which then again calls RaiseException. The offset you get is the offset to RaiseException as this is considered the source of the exception and RaiseException lies inside the ntdll.dll which is loaded in high memory regions. See the following extract from IDA Pro:
.text:7DE80000 ; File Name   : C:\Windows\System32\ntdll.dll
.text:7DE80000 ; Format      : Portable executable for 80386 (PE)
.text:7DE80000 ; Imagebase   : 7DE70000

To answer the first question try throwing different things. Throw an integer, throw nothing (just throw;), throw another string, ... . You will notice that the hex-number will always be the same (0xE06D7363). So obviously it has nothing to do with the content thrown. No, it denotes that the thrown exception was a C++ exception (remember, these are exceptions thrown by the programmer using throw). So every time you use throw you will get the code mentioned above. So we can extend our switch with that static code:
#include <Windows.h>
#include <iostream>

#define EXCEPTION_CASE(code) \
 case code: \
  exceptionString = #code; \
  break

LONG WINAPI UnhandledException(LPEXCEPTION_POINTERS exceptionInfo)
{
 const char* exceptionString = NULL;
 switch(exceptionInfo->ExceptionRecord->ExceptionCode)
 {
 EXCEPTION_CASE(EXCEPTION_ACCESS_VIOLATION);
 EXCEPTION_CASE(EXCEPTION_DATATYPE_MISALIGNMENT);
 EXCEPTION_CASE(EXCEPTION_BREAKPOINT);
 EXCEPTION_CASE(EXCEPTION_SINGLE_STEP);
 EXCEPTION_CASE(EXCEPTION_ARRAY_BOUNDS_EXCEEDED);
 EXCEPTION_CASE(EXCEPTION_FLT_DENORMAL_OPERAND);
 // add more cases...

 case 0xE06D7363:
  exceptionString = "C++ exception (using throw)";
  break;

 default:
  exceptionString = "Unknown exception";
  break;
 }

 DWORD codeBase = (DWORD)GetModuleHandle(NULL);
 char message[255];
 sprintf_s<255>(message, 
  "An exception occured which wasnt handled!\nCode: %s (0x%08X)\nOffset: 0x%08X\nCodebase: 0x%08X", 
  exceptionString,
  exceptionInfo->ExceptionRecord->ExceptionCode,
  (DWORD)exceptionInfo->ExceptionRecord->ExceptionAddress - codeBase,
  codeBase
 );
 MessageBox(0, message, "Error!", MB_OK);
 return EXCEPTION_EXECUTE_HANDLER;
}

int main()
{
 SetUnhandledExceptionFilter(UnhandledException);

 throw "An error!";
}

So far those are the most important things you should now about displaying generic information about every type of exception. In upcoming articles we will have a look on how we can give more information which will require us to perform individual actions for each type of exception.

Thanks for reading and happy commenting
Yanick

Using WMI to call method on objects

Hello everyone

As the title states in this article we will have a look on how to call methods on objects we have got in WMI. In the example source code we will stick on printers and call the SetDefaultPrinter method on an instance of a printer.

Functions can be called as static functions or they can be called on an object. For the function mentioned above it may be pretty clear that we need to call it as part of an object (which actually indicates the printer to be the default one).

We will start with a part of the code presented in the last part of the WMI articles (See here). This actually just initializes WMI and connects to the CIMV2 namespace.
#include <Windows.h>
#include <iostream>
#include <WbemCli.h>

#pragma comment(lib, "wbemuuid.lib")

int main()
{
 using std::cout;
 using std::cin;
 using std::endl;

 HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
 if(FAILED(hRes))
 {
  cout << "Unable to launch COM: 0x" << std::hex << hRes << endl;
  return 1;
 }

 if((FAILED(hRes = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0))))
 {
  cout << "Unable to initialize security: 0x" << std::hex << hRes << endl;
  return 1;
 }

 IWbemLocator* pLocator = NULL;
 if(FAILED(hRes = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pLocator))))
 {
  cout << "Unable to create a WbemLocator: " << std::hex << hRes << endl;
  return 1;
 }

 IWbemServices* pService = NULL;
 if(FAILED(hRes = pLocator->ConnectServer(L"root\\CIMV2", NULL, NULL, NULL, WBEM_FLAG_CONNECT_USE_MAX_WAIT, NULL, NULL, &pService)))
 {
  pLocator->Release();
  cout << "Unable to connect to \"CIMV2\": " << std::hex << hRes << endl;
  return 1;
 }
Now what we need to identify our printer is a value that identifies it. I used the Caption but you can also choose other keys. You can find the caption of your printers in the control panel under "Devices and Printers" (also linked when you press Start). This will look somehow like that but with your printers:


The tick in the green circle indicates that the printer is the default printer. In my case its the PDFCreator. Now i want to make the HP Deskjet my default printer. So i rember the name "HP Deskjet F4100 series" which will be the caption used to query it. To query a special object we can use the WHERE claue in the query. That gives this code
IEnumWbemClassObject* pEnumerator = NULL;
 if(FAILED(hRes = pService->ExecQuery(L"WQL", L"SELECT * FROM Win32_Printer WHERE Caption = 'HP Deskjet F4100 Series'", WBEM_FLAG_FORWARD_ONLY, NULL, &pEnumerator)))
 {
  pLocator->Release();
  pService->Release();
  cout << "Unable to retrive the printer: " << std::hex << hRes << endl;
  return 1;
 }
Now we have an enumerator for the printers which are named "HP Deskjet F4100 Series" (case insensitive). Even if there is only one printer matching the criteria you will still get enumerator to enumerate all of them (which is only one...). The next step we could do is actually not necessary for that particular function. When we call GetMethod in a IWbemClassObject we can query information about a method. This includes parameters that are used by the function as input and parameters that are output by the function. The second one (output) is pretty useless if you will call the function because the call actually will also return an IWbemClassObject containing all the output parameters of the function. The input parameter object is actually also not really useful because if you call a function you actually already know what input parameters it expects. Thats why the GetMethod method is actually more for informative purpose if you dont plan to call the function afterwards. In our case its even worse, we dont have any Input or Output parameters so we dont need that at all. So we can start enumerating the objects right on. Every instance of a certain object (in our case Win32_Printer) becomes it unique path. Also objects themselves have paths.

For example a path for the object would be: \\ADMIN-PC\root\CIMV2:Win32_Printer

A path for an instance of that object could be: \\ADMIN-PC\root\CIMV2:Win32_Printer.DeviceID="HP Deskjet F4100 series"

To obtain the path of our instance we can query the __PATH property of the object. So our loop starts like that:
IWbemClassObject* clsObj = NULL;
 int numElems;
 while((hRes = pEnumerator->Next(WBEM_INFINITE, 1, &clsObj, (ULONG*)&numElems)) != WBEM_S_FALSE)
 {
  if(FAILED(hRes))
   break;

  VARIANT vtPath;
  VariantInit(&vtPath);
  if(FAILED(clsObj->Get(L"__Path", 0, &vtPath, NULL, NULL)))
  {
   cout << "Object has no __Path!" << endl;
   clsObj->Release();
   continue;
  }
To call a method we use the IWbemServices interface which exposes a method called ExecMethod. This method first expects the path of the object or instance the function should be called on. If you are calling a static function line Win32_Process.Create you should provide the path to the object and if you are calling a non-static method like SetDefaultPrinter you should give the path to an instance. The second parameter is pretty simple just the name of the function to call. The flags and context parameters are not important now but interesting are the parameters pInParams and ppOutParams. The first expects a pointer to a IWbemClassObject which has properties that holds the input parameters for that function. For example the function Win32_Process.Create has an input parameter called CommandLine. Therefore your IWbemClassObject which will be put as pInParams must define a property with the name CommandLine and its value should be the command line. Our function has no parameters so we can pass NULL. ppOutParams will hold a pointer to a IWbemClassObject after the function has completed. This object has a property for each output parameter and one special property called "ReturnValue". So we can call the function like that:

IWbemClassObject* pResult = NULL;
  if(FAILED(hRes = pService->ExecMethod(vtPath.bstrVal, L"SetDefaultPrinter", 0, NULL, NULL, &pResult, NULL)))
   cout << "Unable to set the default printer: " << std::hex << hRes << endl;

Next we want to extract the returned value if the function has succeeded. As i mentioned above this value is stored in the property "ReturnValue". So we query that property from the returned result object.
else
  {
   VARIANT vtRet;
   VariantInit(&vtRet);
   if(FAILED(hRes = pResult->Get(L"ReturnValue", 0, &vtRet, NULL, 0)))
    cout << "Unable to get return value of call: " << std::hex << hRes << endl;
   else
    cout << "Method returned: " << vtRet.intVal << endl;

   VariantClear(&vtRet);
   pResult->Release();
  }

Thats it! We have called the function and got its return value. All left now is releasing everything we dont need anymore and exit the program.
VariantClear(&vtPath);
  clsObj->Release();
 }

 pEnumerator->Release();
 pService->Release();
 pLocator->Release();
 cin.get();
 return 0;
}

And here is the complete source code again:
#include <Windows.h>
#include <iostream>
#include <WbemCli.h>

#pragma comment(lib, "wbemuuid.lib")

int main()
{
 using std::cout;
 using std::cin;
 using std::endl;

 HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
 if(FAILED(hRes))
 {
  cout << "Unable to launch COM: 0x" << std::hex << hRes << endl;
  return 1;
 }

 if((FAILED(hRes = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0))))
 {
  cout << "Unable to initialize security: 0x" << std::hex << hRes << endl;
  return 1;
 }

 IWbemLocator* pLocator = NULL;
 if(FAILED(hRes = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pLocator))))
 {
  cout << "Unable to create a WbemLocator: " << std::hex << hRes << endl;
  return 1;
 }

 IWbemServices* pService = NULL;
 if(FAILED(hRes = pLocator->ConnectServer(L"root\\CIMV2", NULL, NULL, NULL, WBEM_FLAG_CONNECT_USE_MAX_WAIT, NULL, NULL, &pService)))
 {
  pLocator->Release();
  cout << "Unable to connect to \"CIMV2\": " << std::hex << hRes << endl;
  return 1;
 }

 IEnumWbemClassObject* pEnumerator = NULL;
 if(FAILED(hRes = pService->ExecQuery(L"WQL", L"SELECT * FROM Win32_Printer WHERE Caption = 'HP Deskjet F4100 Series'", WBEM_FLAG_FORWARD_ONLY, NULL, &pEnumerator)))
 {
  pLocator->Release();
  pService->Release();
  cout << "Unable to retrive the printer: " << std::hex << hRes << endl;
  return 1;
 }

 IWbemClassObject* clsObj = NULL;
 int numElems;
 while((hRes = pEnumerator->Next(WBEM_INFINITE, 1, &clsObj, (ULONG*)&numElems)) != WBEM_S_FALSE)
 {
  if(FAILED(hRes))
   break;

  VARIANT vtPath;
  VariantInit(&vtPath);
  if(FAILED(clsObj->Get(L"__Path", 0, &vtPath, NULL, NULL)))
  {
   cout << "Object has no __Path!" << endl;
   clsObj->Release();
   continue;
  }

  IWbemClassObject* pResult = NULL;
  if(FAILED(hRes = pService->ExecMethod(vtPath.bstrVal, L"SetDefaultPrinter", 0, NULL, NULL, &pResult, NULL)))
   cout << "Unable to set the default printer: " << std::hex << hRes << endl;
  else
  {
   VARIANT vtRet;
   VariantInit(&vtRet);
   if(FAILED(hRes = pResult->Get(L"ReturnValue", 0, &vtRet, NULL, 0)))
    cout << "Unable to get return value of call: " << std::hex << hRes << endl;
   else
    cout << "Method returned: " << vtRet.intVal << endl;

   VariantClear(&vtRet);
   pResult->Release();
  }

  VariantClear(&vtPath);
  clsObj->Release();
 }

 pEnumerator->Release();
 pService->Release();
 pLocator->Release();
 return 0;
}

I hope you have learned how methods are called and when you run the above code you will see that your printer is now the default one!


Thanks for reading and bye
Yanick

Freitag, 25. März 2011

WMI in C++ - Query everyting from your OS!

Hi everyone

In this article i will give you some information how you can dig into the deep waters of WMI which is a part of the Windows API that is designed to give feedback to queries about software and hardware specifications of the windows system the calling application is executing on or even on remote machines. This goes from simple things like the version of the installed windows over installed software and running processors up to very detailed stuff like the number of cycles the fan of your cooler (if you have a fan cooling the CPU) made so far.

WMI is designed to act like a huge database system. Such a system contains databases, tables and rows. Thats also what WMI provides us. We can select objects from tables using a SQL like syntax. For example the following would be a legit query in WMI:
SELECT * FROM Win32_Session;

In WMI databases are not called databases but namespaces. On your system there may be various namespaces available. One with very interesting tables is the namespace "CIMV2". It contains tables for nearly everything that acts on your computer! As with any other database you first need to connect to it. This is done using the interface IWbemLocator. This interface (and all subsequent ones) are defined in the header file WbemCli.h. The CLSID for those interfaces are defined in wbemuuid.lib. So this results in our first code snippet:
#include <Windows.h>
#include <iostream>
#include <WbemCli.h>

#pragma comment(lib, "wbemuuid.lib")

int main()
{
 using std::cout;
 using std::cin;
 using std::endl;

 HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
 if(FAILED(hRes))
 {
  cout << "Unable to launch COM: 0x" << std::hex << hRes << endl;
  return 1;
 }

 IWbemLocator* pLocator = NULL;
 if(FAILED(hRes = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pLocator))))
 {
  cout << "Unable to create a WbemLocator: " << std::hex << hRes << endl;
  return 1;
 }


 pLocator->Release();
 return 0;
}

Thats just some COM-stuff, nothing special. The IWbemLocator interface now exposes a method called ConnectServer. This function connects to a namespace. We will be using CIMV2 so thats where we will connect to. As a result of that function we get an interface called IWbemServices. Imagine that like an open connection to the database. As i stated above you can also connect to namespace on a different machine. So the ConnectServer accepts also a username, a password and an authority to connect. As we will just use the current user on the local machine we dont need to supply that and can pass NULL to all of them and we set root as the location where the namespace should be searched. Its important to specify WBEM_FLAG_CONNECT_USE_MAX_WAIT as flag to indicate that the function should abort after MAX_WAIT time has passed. So we can prevent that the function never returns if the remote host for example is not ready.

Here is some more code:
#include <Windows.h>
#include <iostream>
#include <WbemCli.h>

#pragma comment(lib, "wbemuuid.lib")

int main()
{
 using std::cout;
 using std::cin;
 using std::endl;

 HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
 if(FAILED(hRes))
 {
  cout << "Unable to launch COM: 0x" << std::hex << hRes << endl;
  return 1;
 }

 IWbemLocator* pLocator = NULL;
 if(FAILED(hRes = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pLocator))))
 {
  cout << "Unable to create a WbemLocator: " << std::hex << hRes << endl;
  return 1;
 }

 IWbemServices* pService = NULL;
 if(FAILED(hRes = pLocator->ConnectServer(L"root\\CIMV2", NULL, NULL, NULL, WBEM_FLAG_CONNECT_USE_MAX_WAIT, NULL, NULL, &pService)))
 {
  pLocator->Release();
  cout << "Unable to connect to \"CIMV2\": " << std::hex << hRes << endl;
  return 1;
 }

 pService->Release();
 pLocator->Release();
 return 0;
}

Now we are ready to query information from the CIMV2 namespace! This is done using the function ExecQuery from the IWbemService interface. This function will return an enumerator which enumerates all objects that match the query. This enumerator can be speed up if it must not be a bidirectional enumerator. Therefore if you dont need it its good to specify that in ExecQuery. The first parameter of ExecQuery theoretically would allow to specify the type of language that is used in the query but at the moment the only valid value is WQL. So we get the following code.
#include <Windows.h>
#include <iostream>
#include <WbemCli.h>

#pragma comment(lib, "wbemuuid.lib")

int main()
{
 using std::cout;
 using std::cin;
 using std::endl;

 HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
 if(FAILED(hRes))
 {
  cout << "Unable to launch COM: 0x" << std::hex << hRes << endl;
  return 1;
 }

 IWbemLocator* pLocator = NULL;
 if(FAILED(hRes = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pLocator))))
 {
  cout << "Unable to create a WbemLocator: " << std::hex << hRes << endl;
  return 1;
 }

 IWbemServices* pService = NULL;
 if(FAILED(hRes = pLocator->ConnectServer(L"root\\CIMV2", NULL, NULL, NULL, WBEM_FLAG_CONNECT_USE_MAX_WAIT, NULL, NULL, &pService)))
 {
  pLocator->Release();
  cout << "Unable to connect to \"CIMV2\": " << std::hex << hRes << endl;
  return 1;
 }

 IEnumWbemClassObject* pEnumerator = NULL;
 if(FAILED(hRes = pService->ExecQuery(L"WQL", L"SELECT * FROM Win32_DesktopMonitor", WBEM_FLAG_FORWARD_ONLY, NULL, &pEnumerator)))
 {
  pLocator->Release();
  pService->Release();
  cout << "Unable to retrive desktop monitors: " << std::hex << hRes << endl;
  return 1;
 }

 pEnumerator->Release();
 pService->Release();
 pLocator->Release();
 return 0;
}

If you compile that code and run it you will most likely run into problems because it will print Unalbe to retrieve desktop monitors. Thats because all those objects are encapsulated into security levels. At the moment our application has not chosen any security level and is therefore assigned to the lowest. From this layer we cannot access that object! In order to do that we call the function CoInitializeSecurity right after CoInitialiize. Please refer to MSDN for a full description of security levels (until i wrote an article about that). Just believe that for the current operation (and most common ones) the following is fairly enough:
CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0);

Adding that after CoInitialize should remove the error encountered above! That means we are now ready to enumerate through the objects! The enumerator is pretty easy to handle. IEnumWbemClassObjects exposes a method called Next. This method request a chunk of objects from the collection and returns how many objects were extracted. Also here its important to know that these objects could be on another machine. So Next also expects a parameter indicating how long it should wait for the objects to respond. As we are on our own computer i specify INFINITE. That yields the following code:
#include <Windows.h>
#include <iostream>
#include <WbemCli.h>

#pragma comment(lib, "wbemuuid.lib")

int main()
{
 using std::cout;
 using std::cin;
 using std::endl;

 HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
 if(FAILED(hRes))
 {
  cout << "Unable to launch COM: 0x" << std::hex << hRes << endl;
  return 1;
 }

 if((FAILED(hRes = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0))))
 {
  cout << "Unable to initialize security: 0x" << std::hex << hRes << endl;
  return 1;
 }

 IWbemLocator* pLocator = NULL;
 if(FAILED(hRes = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pLocator))))
 {
  cout << "Unable to create a WbemLocator: " << std::hex << hRes << endl;
  return 1;
 }

 IWbemServices* pService = NULL;
 if(FAILED(hRes = pLocator->ConnectServer(L"root\\CIMV2", NULL, NULL, NULL, WBEM_FLAG_CONNECT_USE_MAX_WAIT, NULL, NULL, &pService)))
 {
  pLocator->Release();
  cout << "Unable to connect to \"CIMV2\": " << std::hex << hRes << endl;
  return 1;
 }

 IEnumWbemClassObject* pEnumerator = NULL;
 if(FAILED(hRes = pService->ExecQuery(L"WQL", L"SELECT * FROM Win32_DesktopMonitor", WBEM_FLAG_FORWARD_ONLY, NULL, &pEnumerator)))
 {
  pLocator->Release();
  pService->Release();
  cout << "Unable to retrive desktop monitors: " << std::hex << hRes << endl;
  return 1;
 }

 IWbemClassObject* clsObj = NULL;
 int numElems;
 while((hRes = pEnumerator->Next(WBEM_INFINITE, 1, &clsObj, (ULONG*)&numElems)) != WBEM_S_FALSE)
 {
  if(FAILED(hRes))
   break;

  clsObj->Release();
 }

 pEnumerator->Release();
 pService->Release();
 pLocator->Release();
 return 0;
}

Now finally we have a IWbemClassObject that exposes the properties of the selected object. This is done using the Get function. The usage is pretty simple! We query the Description of the monitor in this example:
#include <Windows.h>
#include <iostream>
#include <WbemCli.h>

#pragma comment(lib, "wbemuuid.lib")

int main()
{
 using std::cout;
 using std::cin;
 using std::endl;

 HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
 if(FAILED(hRes))
 {
  cout << "Unable to launch COM: 0x" << std::hex << hRes << endl;
  return 1;
 }

 if((FAILED(hRes = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0))))
 {
  cout << "Unable to initialize security: 0x" << std::hex << hRes << endl;
  return 1;
 }

 IWbemLocator* pLocator = NULL;
 if(FAILED(hRes = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pLocator))))
 {
  cout << "Unable to create a WbemLocator: " << std::hex << hRes << endl;
  return 1;
 }

 IWbemServices* pService = NULL;
 if(FAILED(hRes = pLocator->ConnectServer(L"root\\CIMV2", NULL, NULL, NULL, WBEM_FLAG_CONNECT_USE_MAX_WAIT, NULL, NULL, &pService)))
 {
  pLocator->Release();
  cout << "Unable to connect to \"CIMV2\": " << std::hex << hRes << endl;
  return 1;
 }

 IEnumWbemClassObject* pEnumerator = NULL;
 if(FAILED(hRes = pService->ExecQuery(L"WQL", L"SELECT * FROM Win32_DesktopMonitor", WBEM_FLAG_FORWARD_ONLY, NULL, &pEnumerator)))
 {
  pLocator->Release();
  pService->Release();
  cout << "Unable to retrive desktop monitors: " << std::hex << hRes << endl;
  return 1;
 }

 IWbemClassObject* clsObj = NULL;
 int numElems;
 while((hRes = pEnumerator->Next(WBEM_INFINITE, 1, &clsObj, (ULONG*)&numElems)) != WBEM_S_FALSE)
 {
  if(FAILED(hRes))
   break;

  VARIANT vRet;
  VariantInit(&vRet);
  if(SUCCEEDED(clsObj->Get(L"Description", 0, &vRet, NULL, NULL)) && vRet.vt == VT_BSTR)
  {
   std::wcout << L"Description: " << vRet.bstrVal << endl;
   VariantClear(&vRet);
  }

  clsObj->Release();
 }

 pEnumerator->Release();
 pService->Release();
 pLocator->Release();
 return 0;
}

Thats it, we now successfully accessed our first objects from WMI!

For a full list of classes available please have a look at the following link:
MSDN

In the next part we will have a look on how to call methods inside those objects!

Thanks for reading and bye bye
Yanick

Dialog Controls explained - Part 1

Hello

In this series of articles i will describe you the usage of several common controls that are used together with windows. Here it actually doesn't matter if you are using a dialog resource and DialogBox to create the window or if you are doing it the manual way using CreateWindow for the main window and all its controls. All you need is just a HWND to that control you are interacting with. Tough in this article for now you can only see the source code that uses a dialog template to create the window. So if you are not using a dialog resource just stick to the part we are actually acting with the controls.

The base part of this project is an empty dialog with no controls on it and the following code that displays it:
#include <Windows.h>
#include "resource.h"

#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

BOOL WINAPI DialogProc(HWND hWindow, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
 switch(uMsg)
 {
 case WM_CLOSE:
  EndDialog(hWindow, 0);
  DestroyWindow(hWindow);
  return TRUE;

 case WM_INITDIALOG:
  return TRUE;
 }

 return FALSE;
}

int main()
{
 DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG1), GetDesktopWindow(), DialogProc);
}

Now lets start adding controls to it!


The common button control

Buttons are represented by the following window class: "Button" (pretty unexpected...)

We can drag & drop button from the toolbox onto our dialog:


The property bar in Visual Studio already gives you a lot of customization options. As every of them is described pretty well inside the property view i think its not really necessary to talk about them. If you are unsure about one just leave a comment!

Well, the most important thing buttons are for is handling clicks. Thus we should know what happens if we click on a button. This is rather simple. The button sends a WM_COMMAND message to its parent window setting wParam and lParam to appropriate values. Its like that:
HIWORD(wParam) = notification code = BN_CLICKED
LOWORD(wParam) = Control ID = IDC_BUTTON1 (for this button in my case)
lParam = Control handle = some value we dont know yet

So to handle a click from a button all you need to do is catching WM_COMMAND in the DialogProc (or WndProc if you are using a regular window) and interpret the values!

Thats an example code that handles the click on our button:
#include <Windows.h>
#include "resource.h"

#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

BOOL WINAPI DialogProc(HWND hWindow, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
 switch(uMsg)
 {
 case WM_CLOSE:
  EndDialog(hWindow, 0);
  DestroyWindow(hWindow);
  return TRUE;

 case WM_INITDIALOG:
  return TRUE;

 case WM_COMMAND:
  {
   if(LOWORD(wParam) == IDC_BUTTON1)
   {
    if(HIWORD(wParam) == BN_CLICKED)
     MessageBox(0, "Button clicked!", "", MB_OK);
   }
  }
  return TRUE;
 }

 return FALSE;
}

int main()
{
 DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG1), GetDesktopWindow(), DialogProc);
}

All we do is catching WM_COMMAND and then we compare if the ID is our button and if the code is BN_CLICKED. Thats pretty easy!

As a side note there are interesting styles for buttons defined in CommCtrl.h! For example the following code:
#include <windows.h>
#include "resource.h"
#include <commctrl.h>

#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

BOOL WINAPI DialogProc(HWND hWindow, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
 switch(uMsg)
 {
 case WM_CLOSE:
  EndDialog(hWindow, 0);
  DestroyWindow(hWindow);
  return TRUE;

 case WM_INITDIALOG:
  {
   HWND hButton = GetDlgItem(hWindow, IDC_BUTTON1);
   // do something if hButton == NULL
   LONG oldStyle = GetWindowLongPtr(hButton, GWL_STYLE);
   oldStyle |= BS_SPLITBUTTON;
   SetWindowLongPtr(hButton, GWL_STYLE, oldStyle);
  }
  return TRUE;

 case WM_COMMAND:
  {
   if(LOWORD(wParam) == IDC_BUTTON1)
   {
    if(HIWORD(wParam) == BN_CLICKED)
     MessageBox(0, "Button clicked!", "", MB_OK);
   }
  }
  return TRUE;
 }

 return FALSE;
}

int main()
{
 DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG1), GetDesktopWindow(), DialogProc);
}

Lets the button look like that:


but be aware: This is only available from Windows Vista on!

Another neat feature of buttons is that they can display images! This is done pretty easy. In the property page you can set the "Bitmap" property to true which will instruct the button to display a bitmap (of course only after we send BM_SETIMAGE). With that in mind the following code can be used to add the image to the button:
#include <windows.h>
#include "resource.h"
#include <commctrl.h>

#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

BOOL WINAPI DialogProc(HWND hWindow, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
 static HBITMAP hButtonBackg = (HBITMAP)LoadImage(0, "image.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
 switch(uMsg)
 {
 case WM_CLOSE:
  EndDialog(hWindow, 0);
  DestroyWindow(hWindow);
  return TRUE;

 case WM_INITDIALOG:
  {
   HWND hButton = GetDlgItem(hWindow, IDC_BUTTON1);
   // do something if hButton == NULL
   SendMessage(hButton, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hButtonBackg);
  }
  return TRUE;

 case WM_COMMAND:
  {
   if(LOWORD(wParam) == IDC_BUTTON1)
   {
    if(HIWORD(wParam) == BN_CLICKED)
     MessageBox(0, "Button clicked!", "", MB_OK);
   }
  }
  return TRUE;
 }

 return FALSE;
}

int main()
{
 DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG1), GetDesktopWindow(), DialogProc);
}

And instead of text now there is an image being displayed (of course only if image.bmp exists in the current folder!). One might expect that setting the bitmap property inside the property page to false will hide the image on the button. But thats not true. That property more says "Only bitmap and no text". If you set Bitmap to false and send BM_SETIMAGE the text and the image will displayed organized on the button!

And a last nice feature of buttons (starting at Windows Vista) is that they can be used to elevate the current user level (pushing the application into administrator mode).

If you have windows vista the following code will put an UAC-Shield on the button (this wont handle putting the application into a higher state! It only displays the shield!)
#include <Windows.h>
#include "resource.h"
#include <commctrl.h>

#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

BOOL WINAPI DialogProc(HWND hWindow, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
 static HBITMAP hButtonBackg = (HBITMAP)LoadImage(0, "image2.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
 switch(uMsg)
 {
 case WM_CLOSE:
  EndDialog(hWindow, 0);
  DestroyWindow(hWindow);
  return TRUE;

 case WM_INITDIALOG:
  {
   HWND hButton = GetDlgItem(hWindow, IDC_BUTTON1);
   // do something if hButton == NULL
   SendMessage(hButton, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hButtonBackg);
   Button_SetElevationRequiredState(hButton, TRUE);
  }
  return TRUE;

 case WM_COMMAND:
  {
   if(LOWORD(wParam) == IDC_BUTTON1)
   {
    if(HIWORD(wParam) == BN_CLICKED)
     MessageBox(0, "Button clicked!", "", MB_OK);
   }
  }
  return TRUE;
 }

 return FALSE;
}

int main()
{
 DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG1), GetDesktopWindow(), DialogProc);
}

Note that the other image we sent isnt displayed anymore!

More to come later...

Thanks for reading and happy commenting!
Yanick

Donnerstag, 24. März 2011

Getting static - Tips with static controls

Aloha

This article covers handling of static controls. Those controls are a bit nasty and need to be tweaked so they work correctly. Also it sometimes is not obvious that a control is a static control which we will see later!

The following code is based on the project created in this article. If you dont remember how interacting with controls works check out this article.

Our final application will load an image when a button is pressed and display it inside a picturebox. You maybe are wondering now where there is a static control involved because neither a button nor a picturebox is really static. But in fact a picturebox is considered a static control. To be clearer a picturebox is nothing more than a simple static control with a style that indicates that this control accepts bitmaps as background.

To start we drag a picturebox control on the dialog and we add a button. I renamed the button to IDB_LOADIMG and left the picturebox as it is. If you save now and open the resource.h you may see that there is only the IDB_LOADIMG and the ID from the picturebox is not present! Why?

Static controls by default are not listed and cannot be accessed. To change that you have to change the ID of every static control you create. This will immediatly add it to the resource.h. Ok, i renamed my picturebox control to IDC_PICBOX. To set the background of a static control you have to send a message to that control. This is done using the function SendMessage. The message to use is STM_SETIMAGE. So the code looks like that:
#include <Windows.h>
#include "resource.h"

#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

BOOL WINAPI DialogProc(HWND hWindow, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
 static HWND hButtonLoad = NULL;
 static HWND hPicBox = NULL;
 static HBITMAP hBmp = (HBITMAP)LoadImage(NULL, "image.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

 switch(uMsg)
 {
 case WM_CLOSE:
  EndDialog(hWindow, 0);
  DestroyWindow(hWindow);
  return TRUE;

 case WM_INITDIALOG:
  {
   hButtonLoad = GetDlgItem(hWindow, IDB_LOADIMG);
   hPicBox = GetDlgItem(hWindow, IDC_PICBOX);
   if(hButtonLoad == NULL || hPicBox == NULL)
   {
    MessageBox(hWindow, "Unable to retrieve controls! Closing....", "Error!", MB_OK);
    EndDialog(hWindow, 0);
    DestroyWindow(hWindow);
    return TRUE;
   }

   break;
  }
  return TRUE;

 case WM_COMMAND:
  {
   if(HIWORD(wParam) != BN_CLICKED) // we are only interested in clicks
    break;

   switch(LOWORD(wParam))
   {
   case IDB_LOADIMG:
    {
     SendMessage(hPicBox, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBmp);
     break;
    }
    break;
   }
  }
  return TRUE;
 }

 return FALSE;
}

int main()
{
 DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG1), GetDesktopWindow(), DialogProc);
}

If you run this you need to make sure that an image called image.bmp is in the folder of the executable. LoadImage is used to load that image as a bitmap. The WPARAM of STM_SETIMAGE indicates which type of background we are sending and the LPARAM is in this case a handle to the bitmap.

When you compile this and run the application and press the button to load the image most likely you will see something like that:


Hey, where is our image?! The answer: Its not displayed at all! Why? Pretty simple: Have a look at the properties page of the picturebox control inside the dialog editor. You can find the column "type" which currently contains "Frame" (unless you have changed it). This tells the system that the control is just a frame. If you send an image to that control Windows will think "Wow, its nice he sends me an image, but actually im just a frame, i dont display images!". So we need to instruct the operating system that our control should accept bitmaps. We change the "Type" to "Bitmap". You may notice that the control now isnt scalable anymore. This is because it will automatically scale to fit the size of the image that gets loaded.

If we compile now and rerun the application after pressing the button the image gets displayed, in my case it looks like that:


Cool, isnt it? :)

Thanks for reading and cya
Yanick

Using a dialog - Using buttons & co.

Hi everyone

This article continues where the first article about dialogs ended. If you didn't read that so far you can do it here.

Important notice for users which do not use the paid version of Visual Studio:
Depending on the free editor you are using you maybe need to convert the source code a bit or move files. For example ResEdit creates a resource.h but you need to move it to your projects folder first
.

In the article linked above we have seen how we can show and destroy a dialog using a resource inside the executable and the function DialogBox. Now we want to let the user interact with controls on the dialog. In this example we will make a dialog that has a two buttons and an edit box where the user can enter text.

First we need to design our dialog. Please have a look at the properties tab in visual studio for the dialog and the children to customize them. Here is how i made mine look:


Now in order to identify controls on a dialog every control becomes its own ID. You can view this ID if you select the control and go to the properties tab. There you'll find the column "ID". It contains the name of the control. For my Flash Window button it looks like that:


This name will be important later. The Request text button has the ID IDB_REQTEXT and the edit control is named IDC_EDIT1. Thats all for the design. Now we can switch back to the code!

As all logic will be performed inside the DialogProc function so long all variables will be static ones inside that function. To retrieve handles (accessors) for the controls windows exposes the function GetDlgItem (which means "get item inside dialog") which searches all controls and looks if it matches the given ID. The usage of GetDlgItem is very simple. The first parameter is the dialog that should be searched and the second parameter is the ID (see above) of the control to search.

This results in the following code:
#include <windows.h>
#include "resource.h"

#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

BOOL WINAPI DialogProc(HWND hWindow, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
 static HWND hButtonFlash = NULL;
 static HWND hButtonReq = NULL;
 static HWND hEdit1 = NULL;

 switch(uMsg)
 {
 case WM_CLOSE:
  EndDialog(hWindow, 0);
  DestroyWindow(hWindow);
  return TRUE;

 case WM_INITDIALOG:
  {
   hButtonFlash = GetDlgItem(hWindow, IDB_FLASH);
   hButtonReq = GetDlgItem(hWindow, IDB_REQTEXT);
   hEdit1 = GetDlgItem(hWindow, IDC_EDIT1);
   if(hButtonFlash == NULL || hButtonReq == NULL || hEdit1 == NULL)
   {
    MessageBox(hWindow, "Unable to retrieve controls! Closing....", "Error!", MB_OK);
    EndDialog(hWindow, 0);
    DestroyWindow(hWindow);
    return TRUE;
   }

   break;
  }
  return TRUE;
 }

 return FALSE;
}

int main()
{
 DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG1), GetDesktopWindow(), DialogProc);
}

We are searching the codes as soon as the dialog is ready which is inside WM_INITDIALOG. We also check if we could get handles to all controls we need and if not we sadly need to terminate the application because they are essential!

Well, now, what happens if the user clicks on the flash button? In fact a message to its owner (which is the dialog) is sent indicating what happened. The ID of that message is WM_COMMAND. For controls of a dialog it has a special layout. The high word of wParam holds the type of command that is sent. The low word of wParam holds the ID of the control that sent the message and lParam holds a handle to that control. Using that we can easily determine if one of our buttons was pressed and also which one as you can see in this code:
#include <Windows.h>
#include "resource.h"

#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

BOOL WINAPI DialogProc(HWND hWindow, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
 static HWND hButtonFlash = NULL;
 static HWND hButtonReq = NULL;
 static HWND hEdit1 = NULL;

 switch(uMsg)
 {
 case WM_CLOSE:
  EndDialog(hWindow, 0);
  DestroyWindow(hWindow);
  return TRUE;

 case WM_INITDIALOG:
  {
   hButtonFlash = GetDlgItem(hWindow, IDB_FLASH);
   hButtonReq = GetDlgItem(hWindow, IDB_REQTEXT);
   hEdit1 = GetDlgItem(hWindow, IDC_EDIT1);
   if(hButtonFlash == NULL || hButtonReq == NULL || hEdit1 == NULL)
   {
    MessageBox(hWindow, "Unable to retrieve controls! Closing....", "Error!", MB_OK);
    EndDialog(hWindow, 0);
    DestroyWindow(hWindow);
    return TRUE;
   }

   break;
  }
  return TRUE;

 case WM_COMMAND:
  {
   if(HIWORD(wParam) != BN_CLICKED) // we are only interested in clicks
    break;

   switch(LOWORD(wParam))
   {
   case IDB_FLASH:
    {
     FlashWindow(hWindow, TRUE);
     break;
    }
    break;
   case IDB_REQTEXT:
    {
     int textLen = GetWindowTextLength(hEdit1);
     if(textLen == 0)
      break;

     // We need to include the terminating 0, GetWindowTextLength does not count it!
     TCHAR* wndText = new TCHAR[textLen + 1];
     GetWindowText(hEdit1, wndText, textLen + 1);
     MessageBox(hWindow, wndText, "Info", MB_OK);
     delete [] wndText;
    }
    break;
   }
  }
  return TRUE;
 }

 return FALSE;
}

int main()
{
 DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG1), GetDesktopWindow(), DialogProc);
}

There is one other important thing to say about WM_COMMAND. The high word of wParam which specifies the notification code is not different for every single type of notification that exists. Its only unique for each type of control. For example BN_CLICKED is defined as 0. There are other types of controls which also have the notification code defined which not really means that they were clicked. So always take the type of control that sent the notification into account, thats very important!

Thanks for reading and cheers
Yanick

Messages - The communication

Hello there

In this article I will show how the message system in windows works. The message system is actually used where communication between different thread is necessary. They are used to inform a thread that either something has happened or that the sender needs to know something only the receiving thread can tell. Windows already implements all necessary to work with messages.

A commonly known place where messages are used are windows. If anything happens with the window the operating system sends a message to the application telling it what happened. For example if you click with the left mouse button on the window the system first sends a message WM_LBUTTONDOW and when you release the button a WM_LBUTTONUP message to the application. Thats how an application gets informed that something happened in its window. There are also dozens of other messages that may be sent from a window.

Of course messages are not restricted to windows! You can also implement your own message system using the message API. There are several functions that can be used to work with messages. These are examples:
PostThreadMessage // Sends a message to a thread without waiting what the thread returns!
GetMessage // Takes a message from the current threads message queue. It will not return until a message could be taken
PeekMessage // Takes a message from the current threads message queue. Returns immediatly and indicates if there was message in the queue.

You can find a full list here

Opening the Window - Creating a dialog!

Hello everyone!

In this article we will focus on how to easily create a basic layout for a window. It is using dialog templates stored as a resource inside an executable or DLL. It is often a lot of work to create a layout for a window just using the
CreateWindow
function is pretty a mess also because you cannot view directly how it will finally look. Having a WYSIWYG editor would be way easier! Interestingly there exists a simple way to code using such an editor. In order to achieve that you need to create the window from a resource which is embedded into the executable. This resource contains text that describes how the window should be led out. And the best thing is: There are free and paid editors for those files. Ill describe both, one with a free and one with a paid editor.

Users with a paid version of Visual Studio 
To add a dialog resource you do the following



This will show up a new dialog window that lets us select which type of resource to add. Obviously we will create a dialog resource!



The simplest is to just use Dialog. It will create a nice window and show it up in a new UI. There you can freely add controls, change properties of the window or the controls added.

When you are finished designing the window you can return to your project and you see that there are 2 new files. One is the resource.h which defines symbolic names for the resources and ProjectName.rc. This is the file which describes how resources are called inside the executable.


Users which have no paid version of Visual Studio 
There are free editors available to create a resource script (.rc) file and edit the contents. I think the best one is ResEdit. Its freely available and pretty easy to handle. When finished you will have a .rc file with a dialog resource included. You can drag that .rc file into your project and compile. It will be included into the executable. Thats it!

From now on everything is the same for the paid and the free version. 

Simply displaying the dialog is a very easy task. Windows offers us a function called DialogBox. This function expects parameters that specify where to find the dialog resource. Then it shows the dialog and returns when the dialog is destroyed. As usual also dialogs send messages to the application telling it that something interesting may have happened. So the code to show our dialog is pretty simple:
#include <Windows.h>
#include "resource.h" // users with ResEdit do not need that because they dont have it

// make sure visual styles are enabled
#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

BOOL WINAPI DialogProc(HWND hWindow, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
 switch(uMsg)
 {
 case WM_CLOSE:
  EndDialog(hWindow, 0);
  DestroyWindow(hWindow);
  return TRUE;
 case WM_INITDIALOG:
  return TRUE;
 }

 return FALSE;
}

int main()
{
 // Users with ResEdit specify "Name of the resource" for the second param
 DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG1), GetDesktopWindow(), DialogProc);
}

The most complex is the DialogProc function. In opposite to regular message handlers it only returns a boolean. This boolean tells the operation system if our application has handled the message or not. The two messages that are important are WM_CLOSE and WM_INITDIALOG. The first message is sent when the user presses the close icon, the latter is sent when the dialog is loaded. In WM_INITDIALOG the return value indicates if the keyboard focus should be set to the control the operating system has chosen or not. This actually the recommended way.

In WM_CLOSE we first end the dialog using EndDialog and then destroy the window using DestroyWindow. The second parameter of EndDialog will be the value that DialogBox will return!

Thats it, we have made a nice window without much code!

Next step: here

Thanks for reading and greetings
Yanick

Enabling Visual Styles - Make it pretty!

Hello there

A lot of people ask me why in C++ the windows they create look that ugly while in C# or other .NET languages they look very nice. To illustrate what i mean look at the following images:
C++:


C#


The reason why this happens lies inside the manifest (or more exactly the application context). A .NET application automatically generates an application context that loads the Version 6 of the Microsoft.Windows.Common-Controls assembly instead of the default one which is Version 5. While Version 5 renders the common controls without any visual styles Version 6 uses the appropriate styles since Windows XP.

To achieve that you need to add a dependency inside the manifest and you need to ship it with your executable. Thats how the source code looks in my example application which is the way i prefer to ship the manifest with my application.
#include <windows.h>
#include "resource.h"

#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

BOOL WINAPI DialogProc(HWND hWindow, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
 switch(uMsg)
 {
 case WM_CLOSE:
  EndDialog(hWindow, 0);
  DestroyWindow(hWindow);
  return TRUE;
 case WM_INITDIALOG:
  return TRUE;
 }

 return FALSE;
}

int main()
{
 DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG1), GetDesktopWindow(), DialogProc);
}

IDD_DIALOG1 is the numerical constant of a dialog resource embedded inside my executable.

Thanks for reading and im looking forward reading your comments!
Yanick

Shipping Manifests

Hello there

In this article we will have a look how to ship a manifest with your application. If you need to know what a manifest is please reference to this article.

There are different ways to deploy a manifest with your application. I will refer on how to achieve it using the Microsoft IDE (either for C# or C++ respectively).
  1. In C++ you can directly modify the default manifest using a #pragma directive or the project settings
  2. In C++ you can directly create a manifest as a resource of your application
  3. In C# you have to possibility to add a manifest as a project object and select it as default one
  4. For every component you can ship the manifest as separate file (not recommended!)
Now lets explain this a bit more:

Modify the default manifest 
To modify the manifest directly inside your code you can use the #pragma comment(linker, "...") directive. This is an example how this would look like:

#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

This adds a dependent assembly to the manifest (reference article linked above if you need to know what a dependent assembly is). The same can also be achieved if you go to your project properties. There in the category linker you find the property page "Manifest file". This looks like the following:



There you can modify the manifest as you like to.

Add a manifest resource
Adding a manifest as a resource is very easy. You can simply create your manifest as you like and add it to the executable with resource type RT_MANIFEST or 24. Its recommended that you choose the name taken in the assemblyIdentity part inside the manifest followed by .manifest as name of the resource. Thats it!


Add a manifest inside C#Adding manifests in C# is even simpler. Right click into your project and choose Add -> New Item. In the dialog scroll down until you find "Application manifest file" and give it a name. It creates the default entries and lists it in the solution explorer. You can now edit the manifest inside the editor. If you want to make your manifest the default one visit the project settings and go to the "Application" tab. There you find a region with "Resources" which contains a drop down list with possible manifest files to use. Thats it!

So adding manifests is a very easy thing to do and its worth it ;)

Thanks for reading and goodbye
Yanick 

Manifests - Lets declare some principles!

Hello again!

In this article I like to spend a few words on a concept introduced with Windows XP: Manifest files. These files are used beside an executable to tell various things about the context the program will run in. I think the most common usage of manifests is to enable visual styles in an application. But if we look closer on that we can see that it actually is not like manifests directly enable the visual styles, no, the manifest actually only tells the operating system that our application depends on a so called 'assembly'. Don't be scared, it has nothing to do with assembler, ill explain later what to understand under assemblies and what dependency means.

So we have learned one important aspect of manifests:
  • They can declare dependencies to assemblies.
Ok, but ask yourself: Did you ever find a manifest in programming world yet? I bet no if you didn't intend to ;). So  is no one using manifests or what is the reason for that? No, id say every executable you start is using a manifest, but where is it? To answer that question you need to know how the operating system actually searches for that manifest.
  1. It searches in the global cache.
  2. It searches for the first resource inside the executable which has the type RT_MANIFEST (24 on my system) 
  3. If nothing is found inside the exe it searches inside the folder if it finds a file named EXENAME.exe.manifest.
Because modifying a manifest without knowledge about it by an end user may result in severe problems running the application the third method isn't chosen often by deployed programs. As modifying resources at least requires the knowledge how to access and compile resources into a file you can be pretty sure that most users of your application wont be able to accidentally destroy the manifest (and if they do its not our problem :D). Thats the reason why you probably have never seen a manifest file - they are inside the executable!

Well, i think its time now to have a view on an example manifest. If you create a new project in Visual Studio a manifest is automatically generated when you build your application. It can be found inside the Debug (or Release) folder of your project (not solution) and is called 'ProjectName.exe.intermediate.manifest'. It has the intermediate inside it because thats the part that gets automatically added but you can modify that inside the project settings and thus its not the final version but only an intermediate one.

I named my Project ManifestExample so the manifest is called ManifestExample.exe.intermediate.manifest and the contents are:
<assembly manifestversion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
  <trustinfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedprivileges>
        <requestedexecutionlevel level="asInvoker" uiaccess="false">
      </requestedexecutionlevel>
    </security>
  </trustinfo>
</assembly> 

First thing we see is that manifests are written using the XML syntax. That makes it pretty straightforward to understand and we can focus on the actual elements. What this manifest does is that it defines some security related properties of the application. To be more clear: It declares which access rights the user has to have this application will run in. That is controlled using the 'level' attribute inside the requestedexecutionlevel tag. There are 3 values valid for the level attribute:
  1. asInvoker -> The application will run with the same privileges as the calling user
  2. highestAvailable -> The application will run with the highest privileges the current user can reach
  3. requireAdministrator -> The application must be run in administrator mode (on Vista and Win7 a window will pop up asking the user to allow the application to run as administrator if thats enabled)
The default value of course is asInvoker as thats pretty neutral.

The uiaccess attribute is a bit more complex. Imagine you are writing an application that simulates a keyboard on the monitor where the user can make input. Now it may be necessary to bypass regular input control mechanics to work properly. To be able to do that the uiaccess attribute must be set to true.

In addition setting uiaccess to true requires some additional security options! The application first has to be signed by Authenticode and second it has to be in protected folder (for example system32 or program files).

Second thing we learned about manifests:
  • Manifests define security aspects of an application.
Now lets have a look at a manifest that does what i ment above: Add a dependency to an executable. In this example we add a dependency to the assembly called "CommonControls". It has to be said that your application be default already has a dependency to CommonControls but it depends on version 5 of CommonControls which contains the old visual themes and we need version 6 which contains the new visual themes since XP!

<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level='asInvoker' uiAccess='false' />
      </requestedPrivileges>
    </security>
  </trustInfo>

  <dependency>
    <dependentAssembly>
      <assemblyIdentity 
        type='win32' 
        name='Microsoft.Windows.Common-Controls'
        version='6.0.0.0' 
        processorArchitecture='*'
        publicKeyToken='6595b64144ccf1df'
        language='*'
      />
    </dependentAssembly>
  </dependency>
</assembly>


The new tags we see are dependency, dependentAssembly, assemblyIndentity. The dependency tag lists a dependency for application the dependentAssembly tag hosts a dependency to an assembly and the assemblyIndentity tag finally specifies the assembly our application is depending from. There we find several possible attributes that identify the assembly. Actually only two of them are required the rest is optional and is used to distinguish it from other assemblies that may have the same attributes.

Explanation:
  • type - Optional - Only valid value is win32
  • name - Required - The name of the assembly
  • version - Required - The version of the assembly to load
  • processorArchitectur - Optional - May be clear. Valid values are (ia64, amd64, x86, msil)
  • publicKeyToken - Optional - The strong name of the assembly
  • language - Optional - The language ID of the assembly
As you can see we request version 6 of the Common-Controls which means controls with new visual styles!

Now its time to talk about how the system finds an assembly. This is actually pretty simple. The system does the same as it does when you launch an application. In the above code it will search a manifest which denotes an assembly witch defines an assemblyIdentity that matches the requested one. In our case it searches the following way:
  1. It searches the Microsoft.Windows.Common-Controls.dll inside global search paths and inside the current executables path. If it finds that dll it searches a manifest resource inside that dll that is called "Microsoft.Windows.Common-Controls.manifest" and compares it.
  2. If that didnt succeed the system searches in the same paths for a file called Microsoft.Windows.Common-Controls.manifest and parses it
  3. If that failed it searches for the folder "Microsoft.Windows.Common-Controls" inside all global search paths and the current executable path and does the same search as above again
To be identified a component (for example a DLL) must have a manifest that defines a global assemblyIdentity. That actually makes it an recognizable assembly inside the system. Here is an example manifest that identifies everything its included into as an assembly of the given name (and does nothing more):


      <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
      <assembly xmlns="urn:schemas-microsoft-com:asm.v1"  manifestVersion="1.0">
        <assemblyIdentity
          type="Win32"
          name="MyNiceAssembly"
          version="1.0.0.0" 
        />
      </assembly>
      

      We learn:
      • Manifests can be used to give any component (DLL, exe, ...) a name with which it can be identified
      Thats it for this article! Feel free to post comments or ask questions. I dont think that everything got clear enough for everyone so im really happy if you tell me your problems or questions!

      Thanks
      Yanick