Thursday, September 27, 2007

MAKEINTRESOURCE macro

Many Win32 API functions use a LPCTSTR parameter as resource name or type.
For example, a trivial one:

HICON LoadIcon(HINSTANCE hInstance, LPCTSTR lpIconName);

And the documentation for the lpIconName states that:

Pointer to a null-terminated string that contains the name of the icon resource to be loaded. Alternatively, this parameter can contain the resource identifier in the low-order word and zero in the high-order word. Use the MAKEINTRESOURCE macro to create this value.

Now, how the LoadIcon code knows to diferentiate between a resource string name and a predefined constant like IDI_ASTERISK which is defined as:

#define IDI_ASTERISK MAKEINTRESOURCE(32516)

We are used to the wizard generated resource IDs in our applications but a resource can have any null terminated string as name and type too. Look to the FindResource function for example.

All resource Win32API functions use the macro IS_INTRESOURCE(id)

BOOL IS_INTRESOURCE(
WORD wInteger
);

#define IS_INTRESOURCE(_r) (((ULONG_PTR)(_r) >> 16) == 0)

If the macro is TRUE then the id "specifies the integer identifier of the name or type of the given resource. Otherwise, those parameters are long pointers to null-terminated strings"

Practically, the memory address of a name or type passed as input, is checked to see if its within the WORD boundary, or else said if the memory address is between 0 and unsigned short (65536), because:

typedef unsigned short WORD;

So, for the win32 API functions, if the pointer value has an 'invalid address' it's clear that it's rather an id (a integer, an unsisgned short in fact) then an actual memory address containing a null terminated string from the application.

Wednesday, September 26, 2007

Navigating to an embedded resource in .NET

This task is very common but since i did not find a clear and simple solution i decided to write it.

I have a simple C# application which has a webbrowser control and i want to use the res:// protocol to navigate to an embedded resource, a html file from the assembly, like this:

webbrowser.Navigate("res://myApp.exe/Help.htm");

since managed resources are not native ones, adding an html file to the project and select "embedded resource" wont help.
if you open the assembly with a resource editor you won;t see the html resource.
hence, the res:// protocol wont work.

so i wrote this simple console application which accepts as parameters the resource file you want to add.

Usage:
AddResourceManaged.exe ExePath ResFile ResName [ResType]

adds a new resource to an exe file
ExePath - path of the exe
ResFile - path of the file to be added as a resource
ResName - name of the resource
ResType - (optional) type of the resource; if omitted, the application will try to use one of the default resource types
based on the ResFile file extension

Example:
AddResourceManaged.exe myManagedApp.exe Help.htm help.htm 23

it is equivalent to:

AddResourceManaged.exe myManagedApp.exe Help.htm help.htm
because the value of MAKEINTRESOURCE(RT_HTML) is 23

Wednesday, July 25, 2007

AIAB (Asynchronous Invocation Application Block)

i'll edit this post from time to time to update it untill it's finished.

Worker Thread and Service Agent execution.
If an exception is thrown from the SA, the exceeption is logged (using the Exception management mechanism). The default exception publisher logs to System Event log.
This is because the worker thread has a try-catch inside the thread proc. And this makes that the while loop inside the thread procedure to continue.
The Worker thread has a serviceAgentRequest memeber variable which is set \ cleared to null on SA creation execution \ SA execution returns.
Worker thred checks for this variable at the loop begin and resubmits the request (it wont look at the requests queue).

So, when an exception is thrown from a SA during execution, the SA will be resubmitted indefinetely until the SAMonitor aborts the worker thread.

Regarding the SAMonitor: Note that in the case of the exeception thrown from SA, the SAMonitor is called to add the worker thread at each resubmission. But SAMonitor checks if it has that worker thread already in its thread table and removes it and adds it again.

So this means that if a SA exception appears you can decide to either rethrow the exception so the request is resubmit or not rethrow it and maybe just return from execution (and the worker thread will mark the request as completed).

Sunday, July 15, 2007

Opening CHM Help files from Network or Internet

Due to a security patch Windows has restricted access to a CHM. More info here: http://support.microsoft.com/kb/896358.

The attached reg script fixes one of the 4 problems described in the KB. It works for most of the CHM files. Here is the file.


Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\HTMLHelp\1.x\ItssRestrictions]
"MaxAllowedZone"=dword:00000004

Monday, July 09, 2007

Win32 HANDLEs

Each time when you use a win32 API which uses a HANDLE remember that the handle Must be valid (not closed).

It is important to understand the concepts of the handle being signaled and being closed.

Signaled state refers to the handle state. It can be signaled or unsignaled. Wait functions for example, like WaitForSingleObject, block current thread until the object gets signaled.

A handle is said to be closed when its reference count reaches zero value. When this happens the handle is closed and doing any waiting on it is error prone.

A handle is a pointer on an object. Wait functions check the state of the object, hence it is a must that the handler (the pointer) is valid. Otherwise, waiting functions wont work properly (while waiting on an invalid handle, you might wait indefinetly).

One example of bogus use is with MFC AfxBeginThread function. Its default behaviour is to auto 'delete' the thread, i.e to close its handle.
Its bad to use the returned handle after the thread is terminated and closed.
That its not a HANDLE. its a wild HANDLE.

This is described excellent in Chapter 12, Threads in the well known book by Jeff Prosise, Programming Windows with MFC, 2nd Edition.

Another missuse, without MFC, might be in an multithreaded application. One threads create a thread and share the handle others thread which use it.

Thursday, June 21, 2007

Monstrous compilation error on any MFC application

Ok, I've just created a simple MFC DLL, hit the compile button and I got this monstrous error:

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\excpt.h(36): error C2144: syntax error : 'int' should be preceded by ';'
c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\excpt.h(36): error C2501: 'x' : missing storage-class or type specifiers

And i was like, "WTF !?".
When I see these kind of errors i instantly get several thoughts but in a 'chain of responsability' pattern way:
'i need to check the code again'
'ummm, lemme search google for the error'
'shit, i need to reinstall the vstudio'
'ok, i think i need 'a' beer'

Ive been lucky enough not to reach the last option in my programming problems ive had so far(though, i dont need programming problems to do that, really).

googling a bit i found somebody adviced for a VisualStudio reinstallation. hmmm. too lazy for doing that (and not necessary). but searchin in the microsoft.com for 'C2144' i got a post with a similar issue and an idea that some of the headears might got mistakenly changed by an accidentaly edit.
i said, Ok, no problem i will do a search on windows explorer to see what was changed today.
i did, and to my horrification i found no change.
luckily, i have another pc with a visual studio installation. i quickly opened windiff over the atlmfc folder. and there it was: 'afxv_w32.h'. a smiley 'x' was lying there.

i wasnt able to find the header simply because it was not changed today. it was changed 2 days ago :|

Wednesday, April 04, 2007

Compile libjpeg instructions

http://www.nevrax.org/tikiwiki/tiki-index.php?page=libJPEG