Archive for the ‘Win32’ Category

LoadLibrary() can’t load a DLL, and have no clue why?

How do you link or load a DLL file?
My approach is to link a stub *.lib file to a host project. This approach supports best of dynamic load and static load. In other words, each DLL files can be maintained independently, while it is very easy to figure out what functions are not found properly and what functions are in conflict, etc.

However, if you really want to write a host program which can support plug-ins such that each plug-ins can be dropped in a given folder and the host program recognize the plug-in on the fly and starts to provide functionality defined in the plug-ins, you will want more dynamic approach.

Yes. MFC/Win32 provides such approach. With LoadLibrary(), anywhere in your source codes, DLL files can be loaded. Then you can define some common interface/parent class for pluggable architecture.
Neat, isn’t it?
However, there is one problem with LoadLibrary(). It can be difficult to troubleshoot. For example, if your DLL file can’t be loaded, you will check if the search path is correct, if the DLL file is really there, and so on. However, what if all those which affect visibility of the DLL are satisfied but the LoadLibrary() still fails?

Let’s take a look at such codes here.

// JongAm
// Let's try loading "Mediabase.dll". Why the hell WBMediabase started failing in finding the dll?

// Enable the line below to see what is wrong with LoadLibrary()
//SetErrorMode( 0 );

HMODULE dynamicLibrary_Handle = LoadLibrary( _T("MediaBase.dll") );

if( dynamicLibrary_Handle )
{
	AfxMessageBox( _T("Successful in finding Mediabase.dll") );
	TRACE( "Successful\n" );
}
else
{
	int lastError = GetLastError();

	CString message;
	message.Format( _T("Failed in finding Mediabase.dll (%d)"), lastError );
	AfxMessageBox( message );

	TRACE( "Can't find the mediabase.dll\n" );
}

Nothing special, right? However, it failed on me. Why? Later I found out that MediaBase.dll also required other DLL files, and those DLL files also require other DLLs. They are all loaded using LoadLibrary() functions. So, they were not detected with Dependency Walker. Hmmmm….
So, whenever you write LoadLibrary(), it is better to provide some feedback message when it fails loading DLL files like “Failed in loading Blah Blah.dll”.

However, what if you already have a few 3rd parth DLL files which you can’t control?
In such case, there is a really handy diagnosis function. It is the SetErrorMode(). If 0 is passed as its parameter, it will display a message box which tells what is wrong, like “X.dll is missing”.
So, for example, when you load a A.dll using LoadLibrary() but the A.dll also load A-1.dll and the A-1.dll loads A-2.dll and the A-2.dll is missing, the SetErrorMode(0) will make a message box which says “A-2.dll is missing” displayed.

Here are a few screenshots.

When a DLL file required by the designated Mediabase.dll is missing

When the designated DLL file, Mediabase.dll, itself can't be found.

When all DLL file dependency are resolved

Wow.. quite helpful, isn’t it?

Why MFC is bad

Well, MFC has lots of weird aspects. Basically MFC is a framework. What is a framework? Framework is a wrapper of API to make the API easier to use.
However, when MFC is compared to ToolBox which was most popular during similar period of time, MFC is not as easy to use as ToolBox. ToolBox is, however, API not framework.

Here I would like to show one example why MFC is bad and why its design is bad. Let’s think about CListCtrl. It is a list control or table control if you think of it in the context of Mac OS X. What do you want to do with it?
Let’s summarize some of them.

  • Populate ClistCtrl
  • Retrieve row item or column data
  • Change properties like text color, background color, font and so on for row items.
  • Customizing the UI
  • and so on

First, to manipulate the data or to populate the CListCtrl, this class itself doesn’t provide consistency. Why am I talking about consistency? Let’s take a look at CStatic or CEdit. On Windows, you can set a control variable for them or data variable for them. A control variable is like :

CEdit *editBox

, while data variable is like :

CString editBoxString

To manipulate the value itself, data variable is easier. However to control the widget itself, you should use the control value.
With Cocoa, you don’t need to have this separate mechanism. In Windows point of view, it is like to declare CEdit variable and the CEdit class provides all the methods to manipulate the data value. Or with Cocoa binding, things can be done much more easily.

It does not mean that it is impossible to manipulate data with the control variable. With some widget, or control, it is not easy or is not possible at all.

Here, with CListCtrl, there is no “data” variable unlike that of CEdit or CStatic. So, you should manipulate the data with the CListCtrl itself. So, there is no consistency.

Second, it is very difficult to retrieve row item or data.
GetItem() is for that, but if you look up MSDN document for it, it is not clear how to retrieve an item you want.
Here is explanation on what it does.

Retrieves some or all of a list view item’s attributes.

The LVITEM structure specifies or receives the attributes of a list view item.

However, it doesn’t say about how to do so.

There is something which is even worse.
Let’s take a look at the LVITEM parameter.
What is lParam? What does it supposed to contain? There is no explanation about it in MSDN document.

Let’s assume that you want to customize the CListCtrl. You want to set a bold font for a specific row item or column. Does CListCtrl provide such method? No. Also, there is no each way to retrieve ith item on a CListCtrl. Among them, one easy thing is to set a text color or a background color of a item. Well.. how to to so? There is no explanation about it.
Well.. you can implement a message handler for WM_CUSTOMDRAW message. However the MFC document for CListCtrl doesn’t even contain link for the message. You should look up Win32 document. Isn’t it strange? Framework is a wrapper for API to make API easy to use. However, For MFC, if you want to do some common thing like this, the API, or Win32, should be revealed.

Third. Let’s think about a situation in which you want to set a bold font for some items. There seems to be no way to do so.
Creating a CListCtrl Class with Item Style Features (CListCtrlStyled Class) from CodeGuru introduces a customized CListCtrl clas to do that.

Let’s take a look at some source codes from the class.

void CListCtrlStyled::SetItemStyle(int nItem,int nSubItem,DWORD Style,bool redraw)
{
	// We must retrieve the Style info structure of this item
	//
	LVITEM pItem;
	InitLVITEM(nItem,0,&pItem);

	LS_item * lpLS_item = NULL;
	lpLS_item = (LS_item*) pItem.lParam;

	if(nSubItem > 0)
		lpLS_item = lpLS_item->subitems[ nSubItem - 1];

	// no we can update the style
	//
	lpLS_item->StyleFlag = Style;

	DWORD mask = LIS_BOLD | LIS_ITALIC | LIS_UNDERLINE| LIS_STROKE ;
	lpLS_item->in_use = (Style & mask) > 0;

	// if any font exist for this item then delete it
	//
	this->Free_LS_font(lpLS_item);

	// Redraw it
	if(redraw)	CListCtrl::Update(nItem);
}

void CListCtrlStyled::InitLVITEM(int nItem,int nSubItem,LVITEM * pItem)
{ /*
  typedef struct _LV_ITEM {
    UINT   mask;         // see below
    int    iItem;        // see below
    int    iSubItem;     // see below
    UINT   state;        // see below
    UINT   stateMask;    // see below
    LPSTR  pszText;      // see below
    int    cchTextMax;   // see below
    int    iImage;       // see below
    LPARAM lParam;       // 32-bit value to associate with item
   } LV_ITEM;
  */
	pItem->mask = LVIF_PARAM;
	pItem->iItem = nItem;
	pItem->iSubItem = nSubItem;
	pItem->state = NULL;
	pItem->stateMask = NULL;
	pItem->pszText = NULL;
	pItem->cchTextMax = NULL;
	pItem->iImage = NULL;
	pItem->lParam = NULL;
	CListCtrl::GetItem(pItem);
}

In InitLVITEM() method, it calls GetItem(). What it does is to retrieve lParam value in LVITEM. Then in SetItemStyle(), it calls :

	LS_item * lpLS_item = NULL;
	lpLS_item = (LS_item*) pItem.lParam;

	if(nSubItem > 0)
		lpLS_item = lpLS_item->subitems[ nSubItem - 1];

Hmm.. lpLS_item is once set to lParam. And it is set to lParam’s subitems[].
Then based on the value, it tries modify the variable to set a font face.
To do this, you should know that what the lParam means and the data structure lParam contains. Also, you need to know howdata structure its subitems[] looks like.

But where is explanation on them is? I can’t find anything on MSDN.

There are a lot of things in MFC like this.
Classes are not prepared to handle things easily, and its MFC documentation doesn’t have any link or explanation.

I don’t understand why MS doesn’t provide good documentation about its classes. The bad design of MFC can be understood if we consider when it was designed. However, if MFC designer at MS still want to keep the MFC for native environment, they should do something about it.

Visual C++ 2008 resource editing and control variable annoyance

Hmmm.. It was strange that VC++ 2008 add variables wizard didn’t let a “value” variable of a radio button. With VC++ 6, it was possible as far as I remember.

So, I searched to find out what changed since VC++ 6.

What I found are :

However, the most official document is :
Grouping Radio Buttons on a Dialog Box

People are confused by the different way of setting variable for a radio button to they way you do with its previous version, and MS didn’t seem to present “What is changed and How is changed” document.

So, the way it manipulate resources was changed. No, problem. However again MS’s approach shows problems.

  1. In the resource editor, there is no way to group radio boxes visually
  2. Because only one radio buttons is to be turned on exclusively in its group, there should be a visual way to make a series of radio buttons grouped. However, a group is defined by setting the order of radio buttons in series and only the first radio button is flagged as “Group”.

  3. Setting only the first radio button as “Grouped” is not reasonable.
  4. Basically there are multiple radio buttons in a group. Then all should be “grouped”. But MS want you to set only the 1st radio button as “grouped”. Then all the following radio buttons are grouped. It doesn’t feel natural.

  5. Setting the variable to the first radio button
  6. So, a variable for a group should be declared for the group. But a variable for the 1st button is declared and treated like that it is the representative button for the group.

All of them don’t look natural and reasonable.

I think this is why people get confused and couldn’t get a clue on how to make set a variable for radio buttons.

TerminateThread() and its consequence (Windows)

Usually when it is required to quit a thread from outside of its thread function, you declare a variable like shouldQuit, and it checks if the shouldQuit is set inside of the thread function. From outside of the thread function, you set the shouldQuit to tell the thread to quit.

However, if a function in a DLL is called inside of the thread function, and somehow it stucks in the DLL function, the thread function even can’t check whether the shouldQuit is set or not. Eventually, the DLL function may return, but in that case, it is abnormal. Then.. what can you do?
You don’t want to wait until it returns.

Then you are tempted to use TerminateThread() function.
However, MSDN warns its use. Let’s quick test what can happen.

// The one and only application object
CWinApp theApp;

using namespace std;

CEvent g_threadTerminatedEvent;
bool g_shouldStop;

UINT __cdecl myThreadFunc( LPVOID pParam );
void SetThreadName( DWORD dwThreadID, char* threadName);

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	int nRetCode = 0;

	// initialize MFC and print and error on failure
	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
	{
		// TODO: change error code to suit your needs
		_tprintf(_T("Fatal Error: MFC initialization failed\n"));
		nRetCode = 1;
	}
	else
	{
		// TODO: code your application's behavior here.
		g_shouldStop = false;

		CWinThread *pThread = AfxBeginThread( myThreadFunc, NULL );
		HANDLE handleForThread = pThread->m_hThread;
		DWORD threadID = pThread->m_nThreadID;

		SetThreadName( threadID, "My Thread!");

		BOOL isSuccessful;
		DWORD exitCode, error;
		isSuccessful = GetExitCodeThread( handleForThread, &exitCode );
		if( !isSuccessful )
		{
			error = GetLastError();
		}

		DWORD result;
		Sleep( 10000 );
		
		//g_shouldStop = true;
		//result = WaitForSingleObject( g_threadTerminatedEvent, INFINITE );
		//switch( result )
		//{
		//case WAIT_OBJECT_0 :
		//	_tprintf(_T("Thread quits.\n" ));
		//	break;

		//case WAIT_ABANDONED :
		//case WAIT_TIMEOUT :
		//default :
		//	break;
		//}

		// Force quit
		isSuccessful = TerminateThread( handleForThread, exitCode );
		if( !isSuccessful )
		{
			error = GetLastError();
		}

		Sleep(5000);
		_tprintf(_T("Hmm.. is finished?\n") );
	}

	return nRetCode;
}

UINT __cdecl myThreadFunc( LPVOID pParam )
{
	int i = 0;
	while( !g_shouldStop )
	{
		_tprintf(_T("[%3d] Thread is running.\n"), (i++)%1000  );
	}

	_tprintf(_T("Bye bye...\n" ));

	g_threadTerminatedEvent.SetEvent();

	return TRUE;
}

#define MS_VC_EXCEPTION 0x406D1388

#pragma pack(push,8)
typedef struct tagTHREADNAME_INFO
{
   DWORD dwType; // Must be 0x1000.
   LPCSTR szName; // Pointer to name (in user addr space).
   DWORD dwThreadID; // Thread ID (-1=caller thread).
   DWORD dwFlags; // Reserved for future use, must be zero.
} THREADNAME_INFO;
#pragma pack(pop)

void SetThreadName( DWORD dwThreadID, char* threadName)
{
   Sleep(10);
   THREADNAME_INFO info;
   info.dwType = 0x1000;
   info.szName = threadName;
   info.dwThreadID = dwThreadID;
   info.dwFlags = 0;

   __try
   {
      RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info );
   }
   __except(EXCEPTION_EXECUTE_HANDLER)
   {
   }
}

Then when the TerminateThread() is called, the myThreadFunc thread is terminated. However, its main function is finished and the program itself is stucked.
Take a look at this.
force_quit

If you go ahead by hitting F5, you will have this problem.
error

I think it is better not to use TerminateThread() as MSDN suggests.
However, what if you should use it, but knows that this problem happens in advance?
Does anyone know how to solve this problem?

How to prepare a target windows machine for debugging : Windows Side by Side Assemblies

With the Visual C++ 2005, MS introduced very weird entities to relieve the DLL hell. It is called Windows Side by Side Assemblies of Windows SxS.

However, it gives you another headache. It is like to bring foxes to expel tigers. It is very annoying to set-up target machine for debugging. If you have only one target machine, there is no such headache. But while you are at work, you would have many target machines at your software quality assurance team.

However, the MSDN doesn’t provide short and easy explanation how to setup debug version of their SxS. Many articles at the MSDN contains just vague explanation or something that does not really matter.

Especially, the last one is the most important article. However, it doesn’t really explain what is supposed to do clearly.

Instead, I would like to show how to prepare target machines for debugging.

Here is the step.

  1. Copy debug SxS to target machine’s directory where your program to be debugged is copied to.

That’s it!

Then what files/directories to copy?
which_folder_to_copy

Copy those to where your program to be debugged is.
preparing-sxs-fordebugging

Debugging a release build with the Visual C++ 2005

Sometimes debug build doesn’t crash but release build crashes. This usually happens when memory area which is not valid is accessed. Debug build usually has some fence around allocated memory area.

However, recently I suffered somewhat different case. In this case, you need to debug a release build.
Yeah.. It is quite easy. Just enable debug information for a release build. However, in my recent case, doing so didn’t reveal symbols or display correct values for variables.
At first, I thought a stack is corrupted. However, I found out that optimization option did affect the symptom.

So, disabling optimization was the solution to check content of variables.
coptimization

The cause of the crash was due to #pragma pack.
In one of its header file, #pragma pack (push, 1) is used, and at the end of the file #pragma pack(pop, 1).
It should have been #pragma pack(pop) to reverting.

So, in a influenced class implementation file, it used correct alignment, while in other source file which included a troubled header file, the alignment of this class is not interpreted as it should have been.
So, it caused a vtable evasion in a source file which includes the troubled header file. Therefore, it crashed when it called one of the method of the influenced class.

It is strange that this didn’t cause problem with a debug build. There is not explanation on the MSDN site whether this is disabled in debug build or not.

opening a process with SE_DEBUG_NAME privilege

To open a process successfully, the opener should be allowed in the DACL ( discretionary access control list ). So, I also tried adding an ACE, Access Control Entries, to the DACL. At least all who tried seem to think that way after reading MSDN documents. Yeah..

Then, this kind of code will be written.

HANDLE hProcess, hCommandEventLocal, hAllocationEventLocal;

BOOL isOK;
HANDLE hToken;

///////////////////////////////////////////////
// Setting SE_DEBUG_NAME
// First, get an access token for the process
hProcess = OpenProcess( PROCESS_QUERY_INFORMATION, FALSE, processId ); // 1
if( hProcess == NULL )
{
	PrintError(”Failing in getting a process handle with PROCESS_QUERY_INFORMATION at %d (Error Code : %d)”,
				__LINE__, GetLastError());
	return E_FAIL;
}

// Second, get the access token for the process
isOK = OpenProcessToken( hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ); // 2
if( !isOK )
{
	PrintError(”Failing in getting a token handle at %d (Error Code : %d)”,
				__LINE__, GetLastError());
	return E_FAIL;
}

SetPrivilege( hToken, SE_DEBUG_NAME, TRUE );

CloseHandle( hToken );
CloseHandle( hProcess );

//////////////////////////////////////////////////////////////////////

hProcess = OpenProcess( PROCESS_DUP_HANDLE, FALSE, processId ); // 3

The code looks reasonable, doesn’t it?
While writing this code, I found one thing weird.
To open a process with PROCESS_DUP_HANDLE, you need a SeDebugPrivilege. To set SeDebugPrivilege, i.e SE_DEBUG_NAME, you need a token. To get a token, you need an open handle to the process. Oh.. circular dependency!!!!!
So, I tried opening a process with PROCESS_QUERY_INFORMATION.
However this fails at 2. Why? I don’t know there is no explanation on MSDN documents.

Huge barrier!!!!

However, I found a post from MSDN community forum. He also tried codes shown above, but found out the correct way to achieve the goal.
How?

HANDLE hProcess, hCommandEventLocal, hAllocationEventLocal;

BOOL isOK;
HANDLE hToken;
HANDLE hCurrentProcess;
hCurrentProcess = GetCurrentProcess(); // 1
isOK = OpenProcessToken( hCurrentProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken );
if( !isOK )
{
    return E_FAIL;
}

SetPrivilege( hToken, SE_DEBUG_NAME, TRUE );

//////////////////////////////////////////////////////////////////////

hProcess = OpenProcess( PROCESS_DUP_HANDLE, FALSE, processId );

Differences are to open current process instead of the target process, and set the token of the current process to have the SeDebugPrivilege. The the token of the current process have all the privilege to open other processes the way it wants.

Weird!!!! Isn’t it? It is totally different approach than the direction set by the MSDN documents.
Yeah…. MSDN documents.. as usual.

But if you think more, you can figure out why it works.
Probably default DACL can have an ACE like “allow any process with SeDebugPrivilege to open any process anyway it wants.”.
Then it is reasonable.
Why doesn’t MSDN document have this kind of explanation?
Um………………..

P.S. There is a related post at bits and bytes blog.

%d bloggers like this: