Archive for the ‘Win32’ Category

Delegators #3 – The ATL Way

Saturday, November 24th, 2007

The Active-Template Library (or ATL) is very useful. I think that if you code in C++ under Windows it’s even a must. It will solve your great many hours of work. Although I have personally found a few bugs in this library, the code is very tight and does the work well. In this post I’m going to focus on the CWindow class, although there are many other classes which do the delegations seamlessly for the user, such as: CAxDialogImpl, CAxWindow, etc. CWindow is the main one and so we will examine it.

I said in an earlier post that ATL uses thunks to call the instance’s window-procedure. A thunk is a mechanism to convert a function invocation between callee and caller. Look it up in Wiki for more info… To be honest, I was somewhat surprised to see that the mighty ATL uses Assembly to implement the thunks. As I was suggesting a few ways myself to avoid Assembly, I don’t see a really good reason to use Assembly here. You can say that the the ways I suggested are less safe, but if a window is choosing to be malicious you can make everything screwed anyway, so I don’t think it’s for this reason they used Assembly. Another reason I can think of is because their way, they don’t have to look-up for the instance’s ‘this’ pointer, they just have it, wheareas you will have to call GetProp or GetWindowLong. But come on… so if you got any idea let me know. I seriously have no problem with Assembly, but as most people thought that delegations must be implemented in Assembly, I showed you that’s not true. The reason it’s really surprised me is that the Assembly code is not portable among processors as you know; and ATL is very popular and used library. So if you take a look at ATL’s thunks code, you will see that they support x86 (obviously), AMD64, MIPS, ARM and more. And I ask, why the heck?when you can avoid it all? Again, for speed? Not sure it’s really worth it. The ATL guys know what they do, I doubt they didn’t know they could have done it without Assembly.

Anyhow, let’s get dirty, it’s all about their _stdcallthunk struct in the file atlstdthunk.h. The struct has a few members, that their layout in memory will be the same as it was in the file, that’s the key here. There is an Init function which constructs the members. These members are the byte code of the thunk itself, that’s why their layout in memory is important, because they are get to ran later by the processor. The Init function gets the ‘this’ pointer and the window procedure pointer. And then it will initialize the members to form the following code:

mov dword ptr [esp+4], this
jmp WndProc

Note that ‘this’ and ‘WndProc’ are member values that their values will be determined in construction-time. They must be known in advance, prior to creation of the thunk. Seeing [esp+4] we know they override the first argument of the instance’s window-procedure which is hWnd. They could have pushed another argument for the ‘this’ pointer, but why should they do it if they can recover the hWnd from the ‘this’ pointer anyway…? And save a stack-access? :)

Since the jmp instruction is relative in its behaviour, that is, the offset to the target address is not absolute but rather relative to the address of the jmp instruction itself, upon initialization the offset is calculated as well, like this:

DWORD((INT_PTR)proc – ((INT_PTR)this+sizeof(_stdcallthunk)));

Note that the ‘this’ here is the address of the thunk itself in memory (already allocated).
Now that we know how the thunk really looks and what it does, let’s see how it’s all get connected, from the global window procedure to the instance’s one. This is some pseudo code I came up with (and does not really reflect the ATL code, I only wanna give you the idea of it):

CWindow::CreateWindow:

WndProcThunk = AllocThunk((DWORD)this.WndProc, (DWORD)this);
m_hWnd = CreateWindow (…);
SetWindowLong(m_hWnd, GWL_WNDPROC, WndProcThunk);

This is not all yet, although in reality it’s a bit more complicated in the way they bind the HWND with its thunk…Now when the window will be sent a message, the stack will contain the HWND, MESSAGE, WPARAM and LPARAM arguments for the original window procedure, but then the thunk will change the HWND to THIS and immediately transfer control to the global window procedure, but this time they got the context of the instance!

CWindow::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 CWindowImplBaseT< TBase, TWinTraits >* pThis = (CWindowImplBaseT< TBase, TWinTraits >*)hWnd;
 pThis->ProcessWindowMessage(pThis->m_hWnd, uMsg, wParam, lParam, lRes, 0);
}

And there we go. Notice the cast from hWnd to the ‘this’ pointer and the call with the context of the instance, at last, mission accomplished ;)

More information can be found here.

 A new problem now arises, I will mention it in the next post in this chain, but in a couple of words, here’s a hint: NX bit.

Delegators #2 – C++ & Win32

Saturday, November 17th, 2007

Last post I was talking about using SetProp/GetProp to link between an HWND and an instance to a class that encapsulates the window widget. There’s another way to do it.

The first time you are taught how to create a window in Win32, they tell you that you have to fill in all fields in the WNDCLASS structure, but they always keep on saying to ignore some of the advanced fields. One of the fields inside that structure is cbWndExtra, this one says to the windows manager how many bytes to allocate after the original windows manager’s structure. So suppose all we need is to save the ‘this’ pointer, it means we will need 4 bytes, in 32bits environment system, of course. So we can set cbWndExtra to 4, and then we have a DWORD we can access to as much as we like with the SetWindowLong/GetWindowLong API.

Something like this would suffice:

WNDCLASS wc;
wc. fields = …
wc.lpszClassName = “myclass”;
wc.cbWndExtra = 4;
RegisterClass(&wc);
HWND hWnd = CreateWindow(“myclass”, …)
SetWindowLong(hWnd, 0, this);
ShowWindow(…);

..

And later on in the window-procedure, you can do this:

LRESULT WINAPI MyWindow::WndProc(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam)
{
 MyWindow* pThis = (MyWindow*)GetWindowLong(hWnd, 0);
 if (pThis != 0) return pThis->WndProc(message, wparam, lparam);
 return DefWindowProc(hWnd, message, wparam, lparam);
}

 And there you go. There are a few problems with this technique though. You can’t handle the WM_CREATE message inside the instance’s WndProc, that’s because before CreateWindow returns, the global WndProc will get called with this message, and you didn’t have the chance to set the ‘this’ pointer…

The second problem is that this technique is good only for windows you create yourself, because you control the WNDCLASS… You can use pre-created window-classes of the system by changing their fields in your application only, I think this will create a copy of the pre-created classes only for your process.

Anyhow, to solve the first problem, I saw implementation that create the instance of the object when they receive the WM_CREATE inside the global WndProc. This is really a matter of design, but this way you can call an initializer of the instance once WM_CREATE was received. I can’t come up with another way at the moment if the instance is already created. Maybe just call the initializer on the first message the window gets? Well it’s a bit cracky.

Delegators #1 – C++ & Win32

Wednesday, November 14th, 2007

In the technical point of view a Delagator is a call-forwarder, as simple as that. But in the designing aspect it is a technique where an object outwardly expresses certain behaviour but in reality delegates responsibility for implementing that behavior… And thanks for Wiki for sparing me the ugly explanation. :)

The reason I came up to want to implement delegators as seamlessly as possible in C++ was because I got to a situation where I wanted to write a pure OOP wrapper for windows objects (CreateWindow). Now let me get into the juicy details before you raise your eyebrows. And even before that – yes, something like ATL but only for windows. So say you have a class that is responsible for creating a window and controling it by handling its messages and stuff. Sounds legitimate, right? It would look something like:

class Window {
public:
Window(const cstring& name) { m_hWnd = CreateWindow(…) }
void Show () { ShowWindow(m_hWnd, SW_SHOW); }
 …
 ..
private:
 HWND m_hWnd;
};

And you get the notion. It looks ok and it is right, but let’s get further and hit the problem. When we create a window we need to pass the name of the window-class, that is some structure that contains more general info about the class itself, like the background color, mouse cursor and other stuff, but the most important one of them is wndproc pointer. The wndproc pointer is a pointer to a callback function that handles the messages of the windows that belong to this window-class. I assume you know how Win32 Windows system works. Now, can you spot the problem already?

Well, since it asks for a pointer to a function, and we want to have an instance of our Window object per window, there is no way to bind between the two. (OK, I lie, but continue reading please). In our case we would like to have the method of our message-handler being called and not a global function. If you’re not sure why, then think that each window has some private members in its instance that tells special things about that window. So we gotta find a way to link between our instance and our “window-procedure” method.

This is a start:

class Window
private:
LRESULT WINAPI WndProc(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam)
{
 switch (message)
 {
  …
  ..
 }
 return DefWindowProc(hWnd, message, wparam, lparam);
}
public:
static LRESULT WINAPI WndProc(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam)
{
 // Delegate to the instance’s window procedure.
 return g_window.WndProc(hWnd, message, wparam, lparam);
}

So now the window-class structure will point to the static function WndProc which when called will delegate its parameters to the internal (private) WndProc that can access the members. It’s almost a good solution. But now we are allowed to have only one window and a global instance that contains it. The good thing is that a static public function can call a private method of the same class, so we can hide the core of it. The bad thing is we still expose an internal function we don’t want to in the first place.

The problem is now to find a way to link between a real window object and our instance. The ID of a window is its HWND (or Handle to Window). So we could hold a list with all HWND’s we created and look it up before delegation and then make the right call to the correct instance. This is too much hassle for nothing. There ought to be a way to store some private data on the window object itself, right? At least I would suspect so. Eventually, after reading some MSDN and searching the net, I found a savior function which is called SetProp (and GetProp ofc). Exmaining their prototypes:
BOOL SetProp(HWND hWnd, LPCTSTR lpString, HANDLE hData);
HANDLE GetProp(HWND hWnd, LPCTSTR lpString);
We actually have a kind of dictionary, we give a string and store a pointer (to anything we’re upto). Afterwards, we can retrieve that pointer by using GetProp. Let’s work it out again:

ctor:
m_hWnd = CreateWindow(…);
SetProp(m_hWnd, “THIS_POINTER”, (HANDLE)this); // Ah ha!

What we did was to link the HWND with the this pointer. The window procedure will look like this now:

static LRESULT WINAPI WndProc(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam)
{
 Window* pThis = (Window*)GetProp(m_hWnd, “THIS_POINTER”); // Some magic?
 if (pThis != NULL) return pThis->WndProc(…); // Forward the call to the correct instance.
 …
 …
 return DefWindowProc(…);
}

 Well, as for the code here, I don’t handle errors, and I use C casts, so sue me :). I merely wanna show you the mechanism. And if you really wanna get dirty, you will have to RemoveProp when you get WM_NCDESTROY, etc…

After I got this code really working, I still was wondering how ATL does this binding. So I took a look at their code… It seems to have a global linked list with all instances of the windows that ATL created. And then when the global window procedure is get called, it looks it up on that list. In reality it is much more complex then my explanation, since they need to synchronize accesses among threads, make sure the window belongs to the same thread, etc… All that for only the first time call of the window-procedure. Then it sets the REAL ‘window-procedure’ method of the instance itself, and there it uses Assembly, muwahaha. That will be covered next time.

BTW – SetWindowLong cannot work since all you can do is changing the window-class fields. Although, maybe there is some undocumented field you can play with to store anything you like. Never know? :)

Say No to Redundant Checks

Wednesday, August 29th, 2007

I had a long argument with a friend about some check that I don’t do in diStorm. He only said that apparently I don’t do that check (if statement to test some value.) But if it was not important enough he wouldn’t have said that in the first place, right? :) And I told him that he is right – I don’t, because it is absolutely not necessary. Soon I will let you judge yourself. Eventually we got nothing with that argument, probably both sides are mad (at least I was pissed off) and the code left the same.

Now let me show you an example where I will ask you if you do an (extra?) test of the result or not. Since I’m a Win32 guy, here we go:

char buf[256];
int length = GetWindowText(HWND, buf, 256);
if (length == 0) return ; // No string for some reason, though I don’t care why.

memcpy(DST, buf, length+1); // Include null termination char.
Well, that’s a useless code, but still good enough for the sake of conversation. So I get the caption of some window and copy it into another destination buffer. Did you notice that I did not check the length before copying to DST?! (And yes, DST is the same size as buf). Oh no!! Am I doomed now? Of course not, it is guaranteed that the length will be less than 256 for sure. Because otherwise the API is broken. Now we can start another flaming about who’s fault it is, but spare me this, please. So if the API is broken, it will be probably a bug, and will break other applications which use it. But that’s not the point. Say the API is fine, why don’t I check the length before I memcpy? Am I doing anything wrong? I will say it shortly: NO. My code is just fine (as long as DST size is at least buf’s size, of course). So his accusations were that I should be a code-monkey-freak and consistent. And then he said something like “And what if in the future the API changes?”, Well, bammer, all other API’s users are now broken as well. If it was for that question, I would have to pad all my code with extra unnecessary IF’s. No thanks. Besides if I won’t trust my API’s what should I trust? They are the basis for every appliaction.

Now in diStorm the case is the almost the same, there is some internal function that you call with lots of parameters, one of them is an output param that receives the size which was written to some buffer you supply as well as a maximum size of that buffer. So I examine the return code and see whether I can use the data in the buffer or not, and then I know that the size of written entries in my buffer cannot exceed the maximum size I supplied. So why the heck should I check that writtenEntriesCount < MaximumEntries? Tell me, please!

The only rational I can see is to make an assertion (and only in debug mode) that everything is correct. But that’s not a must, and not doing that won’t even let you the possibility to say that I am a bad coder. The thing is, that both the internal function and its caller were written by me, and both are internal only (not exported in any way) so as long as one of them (probably the called) guarantees that the written entries don’t exceed the maximum size. Everyone are is happy. If it wasn’t the case, I should have had a crash (buffer overflow, access violation), just something nasty, that will hint of the buggy function. Now we can get into the philosophical issue of whether the callee or caller should make that test, or both. But for me, as I see it, it’s better be put inside the called function since it must work well for the interface it supplies. And I always think ahead and ask myself “…and what if someone will call that function and forgets(/doesn’t know -) to add the extra check?”

Don’t get me wrong assertions are really useful devices, I really suggest you use them. It just happened that diStorm doesn’t have them. Maybe I should add them. And yet, it’s not a must.

NTVDM #1

Sunday, July 15th, 2007

DOS is dead; and that’s a fact. But NTVDM is still a cool and handy useful tool. I guess that most of us are not satisfied with the way it works…usually the sound doesn’t work, which is a good enough cause to try the great opened source projects which simulate DOS. Anyways, a few years a go, a friend of mine wrote some piece of code which writes to 0xb800, remember this one? That’s the text mode buffer starting address. Anyways, I was wondering how come you write to this address and something appears on the screen (of course, there is the attribute and the character), mind you it’s NTVDM we are talking about. But this wasn’t the interesting part – Why sometimes your writes to this buffer works and sometimes simply not. I decided to learn the situation and see why it happens.

So here’s what I did:

mov ax, 0xb800
mov ds, ax
mov ax, 0x0741
mov [bx], ax
ret

Which prints a grey ‘a’ in the top left corner, yeppi. Now if you open cmd and run the .com file of this binary you won’t see anything at all. Which is unexpected because you write to the ‘screen’, after all. Now, my friend only knew that whenever he runs ‘debug’ before his program, which I just showed the important part above, then the letter ‘a’ will be displayed. So I gave it a long thought…. …. After that I tried the following addition to the above code (I put it before the original code):

mov ax, 3
int 0x10

This will only set the current video mode to text mode 80x25x16… And then voila, the writing worked as expected. Then I suspected that the VM monitors for int 0x10 and function #0, set mode. But it had seemed that every function will enable the writes…And I later confirmed that it is true.

So now that I knew how to trigger the magic, I simply searched for ‘cd 10’ (that’s int 0x10) in ‘debug’ and found a few occurrences, which proved my friend’s experience – that after running ‘debug’, writing to 0xb800 would work. Of course, if you ran other programs which used int 0x10, you’re good to go as well.

But that was only one thing of the mystery, I wanted to also understand how the writes really happens. Whether the VM monitors all instructions and checks the final effective address to see if it’s in the buffer range, or maybe the memory is specially mapped with Win32 API. Because after all, the NTVDM screen is a normal console window (not speaking of graphical modes now). Surprisingly, I found out that the solution was even simpler, a timer was issued every short interval, which called among other things to a function that copies the 0xb800 buffer to the real console screen, using some console APIs… And yes, your simulated writes really go to the virtual memory of the same address in the real NTVDM.exe process. Maybe it has a filter or something I assume, but I didn’t look for it, so I really don’t know.

HICON from Memory – Fixed

Friday, June 15th, 2007

It gets worse from where I left it. My solution was good for retrieving the one and only icon image in the .ico file. It fulfilled my needs, so I didn’t have to check it further. But Jaine left a comment where she says my code doesn’t work for her icons. So I created a dummy project and tried my code with an icon file which contains several images and tried to get one of them, and to my surprise it didn’t work. The reason I decided to write about this issue in the first place, was because I thought I had a good solution that might interest other people. Specifically the implementation that I am dependent only on standard API’s, nothing undocumented, etc…

First thing I should do is explain why my code doesn’t work for several images in the same file. So, if you took a look at the article I directed you in the other post, “Icons in Win32”, you’ll notice, and I said that earlier too, that there are two structures of the images of the icon: in-memory and in-file. My assumption was that they are of the same size, but I didn’t notice that the in-memory structure is two bytes lesser than the in-file structure. To be accurate, the in-file structure named ICONDIRECTORY, according to that article, is 0x10 bytes in size. And the in-memory structure named GRPICONDIRENTRY, is 0xe bytes in size. The different is in the last field, which I said was the same in both structures, which is the Id and Offset. The Id is a word sized and the Offset is dword sized (so you can point to the whole file, > 64kb). So what happened was that LookupIconIdFromDirectoryEx scanned the bits we fed it with the sizeof(GRPICONDIRENTRY) and the file we read is using the ICONDIRECTORY structure which is longer. Thus, every loop (if you have more than one image in the .ico file), the offset to read the next structure of the image was -2 behind… and things messed up, of course. Note that icons in resources are stored as in-memory, recall you pass ID using MAKEINTRESOURCE to LoadImage…

I really hoped to find a solution which uses the standard API, but without success. Maybe GDI+ will do the job, but I didn’t try and I don’t wanna use GDI+ in my case…but you should give it a shot, with IStream and other not-pretty stuff. :) Anyways, I couldn’t avoid a hacky solution, this way or another, it seems we will have to rely on that article and hope MS won’t change their icon format (LOL, never know). So this is my really hacky solution:

void FixIconToResource(PBYTE pbuf)
{
unsigned short i, count = *(unsigned short*)&pbuf[4];

for (i = 1; i < count; i++) {

// 6 to skip GRPICONDIRENTRY header. 0x10=in-file size, 0xe=in-mem size.

memcpy(pbuf + 6 + (i * 0xe), pbuf + 6 + (i * 0x10), 0xe);
}
}

It has to be called with the buffer of the icon and before it is passed to LookupIconIdFromDirectoryEx. It assumes the icon is valid and that I can access the structures inside it. What this code actually does is repositioning the ICONDIRECTORY structures to be in their appropriate place as GRPICONDIRENTRY (just copying them 2 bytes backward, overriding the 2 bytes of the offset). This solution seems to work well, but it has two drawbacks, the easy-to-notice one is that I alter the buffer in-place. But I guess that’s not a biggy. The other problem is that while copying the structure, I actually convert it, thus chopping the last 2 bytes of the Offset (of the image inside the file…) and making it a word sized value. So it means that if you have icon files that are bigger than 64kb, this solution won’t work…

The funny thing (or really sad) is the reason my code still worked for the first icon without this fix. The thing is that the Id  (word) and Offset(dword) start on the same offset in both structures. So if you have a dword and you read only a word from it, you will get the low-word. Luckily, we’re on x86 architecture and the little-endian behavior made it working for me, otherwise I would probably end up with Offset of zero…

I thought it’s important to, at least, say a few words about the ‘best’ solution. That will be like what LoadImage actually does deep inside its code… constructing a fake GRPICONDIR (that’s like the icon resource inside a PE) and filling in all fields from the in-file structures to the GRPICONDIRENTRY. But this is not enough, because we still want to support any file-size. So you will pass in the index of the image inside the icon group. Then when you are done converting all images, you will call LookupIconIdFromDirectoryEx which will return the correct Id (which is actually the index to the icon) and what you are left to do is seeking to the in-file structures as an array with that index, and get the offset to the image, passing that to the CreateIcon…

Thanks Jaine, without you it wouldn’t have happened… :P

Plugins’ Headache

Sunday, June 10th, 2007

As I was writing a plugin, or to be more accurate, an extension module for Python in C/Win32; I had mysterious crashings here and there. Using a JIT I saw that the crash is in malloc/free so I looked at the stack and saw where’s the problem at (function scope). So far so good, piece of cake. Isolating the problematic code, yet I still didn’t fully understand why it happens, I ran it on a new clean project in Debug mode and got the cool message that there might be a heap corruption. Not surprising, of course. Now, the thing that made me really angry was that my extension used to work with an older version of MSVS. So thinking of this fact, I immediately took a look at python25.dll and saw that it uses MSVCRT version 7. Also, looking at my recently compiled extension dll, I noticed that my CRT is version 8. Knowing all this: heap does problems and different CRTs, I understood that my code uses one heap and Python’s uses another heap. Which is a big no-no, of course, mixing between different heaps…ouch.

Well, it was time to find a solution to a simple problem – I have to use the same heap. But how? Well, to make a short story shorter, I took a look at the Python’s header files and noticed they have two malloc’s. One was a macro which substitutes with malloc(size), which means use the current compiler’s CRT (that what I had used actually). And the other malloc was their own implementation of memory-allocation (above their own CRT’s malloc). Reading the comments surrounding that function declaration it says something like “platform independent allocations”. So voila, I knew that all I had to do is using these memory functions. At the moment I saw these functions, I blessed Python’s developers for thinking, whether directly or not, about this problem :)

The moral story is that if you integrate your code with another application in the code level make sure you talk the same protocol. It might be a memory heap, in my case, and it might be different implementation to FILE*… Just remember to supply the necessary functions for different compilers. Or if you’re on the SDK users side, use the SDK wisely, before you start hacking your way to a working solution.

Creating HICON Directly from Memory

Friday, June 8th, 2007

[updated] 

 How many times you had to do something trivial and you knew there ought to be a decent solution out there?

That’s another common problem that I smashed my head against the wall and came up with a surprising simple solution. For example you might archive icons in a single file, or you download them from the Internet to a buffer in memory. And then you want to display them. That sounds an easy task ah? But most people will just write the memory block back to a temporary file and only then will use LoadImage to load the icon from the disk. That’s lame and hits performance big time. To spare you with the research I had done to solve it, here’s the code:

HICON createIcon(PBYTE iconData, int iconSize)     

{     

   HICON hIcon = NULL;     

   // Ahhh, this is the magic API.     

   int offset = LookupIconIdFromDirectoryEx(iconData, TRUE, iconSize, iconSize, LR_DEFAULTCOLOR);     

   if (offset != 0) {     

      hIcon = CreateIconFromResourceEx(iconData + offset, 0, TRUE, 0x30000, iconSize, iconSize, LR_DEFAULTCOLOR);     

   }     

   return hIcon;     

}

You should read the documenation about LookupIconIdFromDirectoryEx, it says the call should be wrapped with SEH…for malformed files. Probably you ask yourself why I treat the ID as an offset. But that’s because if you look at the structures of ICON in-file and in-memory you’ll notice that’s the same field. So it fits for our purpose here and gives us the offset to the single icon’s data rather than the whole directory as it is saved in file or resource data.

Of course, you have to call DestroyIcon when you’re done messing with the icon…

 For more information about icons format and Win32 implementation and relevant API,  check this out. It really helped me in understanding how it all works. Funny that it even hints about that LookupIconIdFromDirectoryEx. ;) Too late.

Focusing on the Focus

Thursday, June 7th, 2007

Sometimes you want to create a pop up window that won’t steal the focus. It seems that even a simple ShowWindow(SW_SHOW); instructs the windows manager to set the focus and activate that window. But what if you want a tooltip ? After all, even a tooltip is a window. So no need to invent the wheel again, you can just use SW_SHOWNA which means – hey, show my window but don’t activate it.

If the window is already activated, thus having the focus, specifying SHOWNA won’t help it, because it’s already got the focus. So you are doomed, and have to wait until some other window takes the focus or when your window is destroyed the window manager will automatically giev the focus to the former window. But that won’t be good enough for a tooltip-like window. So you have to be careful with it. Even if you want to reposition the window using SetWindowPos you will have to set the SWP_NOACTIVATE flag, so it won’t get the focus. That’s true also in a case where the window is hidden, which sounds a bit stupid to me (why activate a hidden window?). But who said it’s perfect? and not to mention the dialog manager…pffft.

After seeing myself that many people have this problem, I decided it’s worth a post. :)