Tuesday, 9 August 2011

How to get Windows taskbar position


Handle of the taskbar window (named Shell_TrayWnd) must be provided to SHAppBarMessage function which returns its coordinates. FindWindow returns window handle.



Usage:

How to add tray icon to MFC application


GUI application usually has its main window which can be minimized to tray and/or taskbar. When minimized to tray, application is not visible on the desktop but has its icon in the notification area of the taskbar (usually called tray). Through that icon user can access application, see its status and notifications.

Following code shows some basic usage of the tray icon in some MFC dialog:



References and useful links:

NOTIFYICONDATA Structure
Shell_NotifyIcon Function

Friday, 5 August 2011

Some WinDbg commands for memory dump analysis

!analyze - displays information about the current exception (e.g. type, error code, place where it occurred, call stack)
   -v = show verbose output

.ecxr - switches debugger context to the one of the current exception (must be executed before other call stack commands!)

.frame - shows current frame (function) - specifies which local context (scope) will be used to interpret local variables, or displays the current local context.

.frame N - changes current frame to frame N (N is in hexadecimal format!). Frame with number 0 is the one where exception occurred and which is on the top of the stack.

Example:
.frame 0 - switches scope to function which is on the top of the stack
.frame 1- switches scope to function which called function from frame 0

k - displays stack trace for last set context.

kN - displays call stack for last N frames

kP - displays all frames (entire function call chain) from the call stack, with values of function parameters

!for_each_frame - instructs debugger to execute for each frame in the stack of the current thread

dv - Display Value. Displays the values of function parameters and values of local variables
   /t - show type information
   /v - show address

Example:
To show information about parameters and local variables of the last frame (function) in the stack use:
dv /t /v

To show entire function call chain with parameters and local variables we can use: 
!for_each_frame dv /t /v

dt - Display Type. Displays information (value, members, their values...) about variable or type
   /b - display embedded structures recursively

Example:
If myVar is some local variable from the last frame we can examine its members and their values with:
dt -b myVar

To (recursively) display the contents (members, their types and offsets) of some data type (e.g. CMyClass) use:
dt /b CMyClass

To display the state of some variable of type CMyClass which is at the address 0x00a7ab64 (address could have been obtained with dv) we can use:
dt -b CMyClass 0x00a7ab64


If CMyClass has a member of type T and its offset is for example +0x1f90, we can inspect T object with:
dt -b T 0x00a7ab64+0x1f90

db  
- display raw memory (128 bytes) starting from

If some local variable is pointer, we can examine memory it points to by using operator poi() which   returns value of pointer variable:

db poi(pData)
(db pData would output memory starting with address pData, not the one it points to!)

~
- displays brief list of all threads

~*
- displays brief list of threads, including Priority and Priority Class information

.cls - clear screen


References and useful links:

Debugger Reference(MSDN)
Common WinDbg Commands
WinDbg the easy way
Adventures In A 32-bit Minidump

Wednesday, 3 August 2011

The order of elements in STL map


Have you ever been surprised by the order of elements when traversing the map? We insert elements with random keys but elements appear sorted by their keys when we traverse that map:



Output:

Map elements:

m["Austria"] = "Vienna"
m["Belgium"] = "Brussels"
m["Czech Republic"] = "Prague"

Maybe you expected that countries would be listed in the order of insertion, starting with Belgium but no, that wasn't the case. Let's unveil that magic which made our map sorted.

STL map is associative container so it provides an ability for fast retrieval of data based on keys. Fast lookup is provided by the container's implementation. Maps are usually implemented as binary search trees (ordered, sorted binary trees) where position of the new element depends on its key. Elements remain sorted after insertion; they are NOT stored in the order of insertion like those in vector! Insertion order is lost.

When a new element is being added to a map, its key is compared with keys of existing elements in the map. For each key type there must be some function (let's call it is_less) that accepts two objects of that type, compares them and returns true if left one has lower value than the right one. Hey, we used map but we never mentioned is_less in the code! Why? That's because std::map uses its default comparison function, or more precisely, functor.

Map constructor has four parameters of which last two are optional:



Traits argument is (according to this MSDN article) "The type that provides a function object that can compare two element values as sort keys to determine their relative order in the map. This argument is optional and the binary predicate less is the default value".

std::less is default functor used for keys comparison so, in our case, it was std::less⟨std::string⟩ that helped that wizzard to order elements during insertion.

There is NO way of preserving the order of insertion. The only thing we can do is to provide some custom comparison function/functor which will redefine the meaning of the 'is less' relation. It's a bit of cheating but this way we can insert our countries in reverse order. All we need is a functor 'is_less' which returns true when string1 is actually greater than string2:



With the map which uses this custom comparison function the output is:

Map elements:

m["Czech Republic"] = "Prague"
m["Belgium"] = "Brussels"
m["Austria"] = "Vienna"

Tuesday, 2 August 2011

How to programmatically set access rights on a file (Windows)

Object access control is part of Windows security. Each securable object has its name, type (file, directory, process, event, semaphore, mutex, timer, registry key,...) and security descriptor which contains information about its:
  • owner
  • group
  • ACLs (Access Control Lists) - one instance of each type of ACLs:
    • DACL (Discretionary Access Control List) - specifies the access particular users or groups can have to the object
    • SACL (System Access Control List) - controls the logging of attempts to access the object
ACL is a set of Access Control Entries (ACEs). ACE contains set of structures that specify access rights for  trustee where trustee (user or group) is identified by its Security IDentifier (SID).

If we want to change access right for particular user on some object we need to:
  1. identify object for which we want to set permission (by its name and type)
  2. get object's current DACL (use GetNamedSecurityInfo)
  3. identify user (by its name or SID); identify rights
  4. create new ACE, stating user and its rights (instantiate EXPLICIT_ACCESS structure)
  5. merge new ACE to existing DACL in order to get a new DACL (use SetEntriesInAcl)
  6. attach new DACL to the object (use SetNamedSecurityInfo)
MSDN article "Modifying the ACLs of an Object in C++" shows implementation of these steps within function  AddAceToObjectsSecurityDescriptor. For example, if we want to set read and execute rights for IUSR user on some file which path is in pszPath, we can call this function with following paramethers:

DWORD dwRes = AddAceToObjectsSecurityDescriptor(
pszPath,
SE_FILE_OBJECT,
"IUSR",
TRUSTEE_IS_NAME,
STANDARD_RIGHTS_READ | STANDARD_RIGHTS_EXECUTE,
GRANT_ACCESS,
NO_INHERITANCE);

Monday, 1 August 2011

Removing selected map elements whilst iterating through it

Couple of days ago I wrote about how to remove elements from vector while iterating through it and today I will focus on the same task but performed on STL map data structure.

Let's say we have a dictionary which keys are names of countries and values are names of their capitals. There was an error when capitals were typed so all their names begin with small letters. We want to correct this mistake and make those names to start in capital letters. On the top of this, for some reason, we want to remove those countries which capitals start with a letter 'B'.

Someone might write something like this:



When execution tries to move iterator to the next position after one element has been erased Debugger brings up Debug Assertion window:

MapIteratorNotIncrementable

In aforementioned article we learned that vector::erase invalidates iterators that point at or after element being deleted. Now we know what could have caused this assertion to fail - invalidated iterator. Documentation says that map::erase invalidates only iterator that points to the element being deleted. That was exactly what happened in our case - iterator became invalid after map::erase so it could not have been increased so to point to the next element.

The trick here is to increase iterator BEFORE calling erase:



Output:

Initial map elements:

m["Austria"] = "vienna"
m["Belgium"] = "brussels"
m["Czech Republic"] = "prague"
m["Denmark"] = "copenhagen"
m["Estonia"] = "tallinn"
m["Finland"] = "helsinki"
m["Greece"] = "athens"
m["Hungary"] = "budapest"
m["Iceland"] = "reykjavik"
m["Latvia"] = "riga"
m["Malta"] = "valletta"
m["United Kingdom"] = "london"

Map elements after deletions:

m["Austria"] = "vienna"
m["Czech Republic"] = "prague"
m["Denmark"] = "copenhagen"
m["Estonia"] = "tallinn"
m["Finland"] = "helsinki"
m["Greece"] = "athens"
m["Iceland"] = "reykjavik"
m["Latvia"] = "riga"
m["Malta"] = "valletta"
m["United Kingdom"] = "london"

Nice! No scary assertion dialogs, capitals with 'B' are removed...err...Why do names of capital cities still start with small letters??? We get object for a given dictionary key and we do CHANGE it, right? Do we? Which object is actually changed? In the example above strCapital is string object, initialized with string returned by dereferencing iterator...but strCapital object is totally independent from the object IN the dictionary! It is a COPY! We do change that local variable but that is just wasted effort as we don't change object in the dictionary! We need to access ORIGINAL object and we can do it either by using pointer to it or its reference. This is C++ program and natural choice is to use reference:



Output is now as expected:

Initial map elements:

m["Austria"] = "vienna"
m["Belgium"] = "brussels"
m["Czech Republic"] = "prague"
m["Denmark"] = "copenhagen"
m["Estonia"] = "tallinn"
m["Finland"] = "helsinki"
m["Greece"] = "athens"
m["Hungary"] = "budapest"
m["Iceland"] = "reykjavik"
m["Latvia"] = "riga"
m["Malta"] = "valletta"
m["United Kingdom"] = "london"

Map elements after deletions:

m["Austria"] = "Vienna"
m["Czech Republic"] = "Prague"
m["Denmark"] = "Copenhagen"
m["Estonia"] = "Tallinn"
m["Finland"] = "Helsinki"
m["Greece"] = "Athens"
m["Iceland"] = "Reykjavik"
m["Latvia"] = "Riga"
m["Malta"] = "Valletta"
m["United Kingdom"] = "London"

How to set file permissions in NSIS script

Use AccessControl plugin.
Download package, unpack it and place AccessControl.dll into "..\NSIS\Plugins".

The following code snippet from nsi script creates directory and sets Read, Execute and List folder contents rights for IUSR user on it. Additionally, it makes all objects within it to inherit its permissions.

!define TEST_DIR "C:\inetpub\wwwroot\Test"
...
Section "Create web directory" sec1
   CreateDirectory ${TEST_DIR }
   AccessControl::GrantOnFile ${TEST_DIR } "IUSR" "ListDirectory + GenericRead + GenericExecute"
   AccessControl::EnableFileInheritance ${TEST_DIR }
SectionEnd