Exemple #1
0
int CProcessModule::EnumProcessModules(DWORD process_id)
{
	m_nModCount =0;
/*#ifdef WINNT
	DWORD cbNeeded;

	if(m_hProcess) CloseHandle(m_hProcess);

	m_hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, process_id);

	if (m_hProcess == NULL)
		return -1;
	if(!m_pEnumProcessModules(m_hProcess, m_hMods, sizeof(m_hMods), &cbNeeded))
	{
		char err_msg[256];
		DWORD err=GetLastError();
		GetErrString(err_msg, sizeof(err_msg), err);
		WriteLog("failed to EnumProcessModules, err=%d-%s", err, err_msg);
		CloseHandle(m_hProcess);
		return 0;
	}
	m_nModCount =cbNeeded / sizeof(HMODULE);
#else*/
	HANDLE hSnapShot;
	MODULEENTRY32 ModuleEntry32;
	BOOL Result;
 
	hSnapShot = pCreateToolhelp32Snapshot(TH32CS_SNAPMODULE, process_id);

	if (hSnapShot == (HANDLE)-1)
		return -1;

	ModuleEntry32.dwSize = sizeof(MODULEENTRY32);

	Result = pModule32First(hSnapShot, &ModuleEntry32);

	if (Result != TRUE)
	{
		CloseHandle(hSnapShot);
		return -1;
	}

	do
	{
		strcpy(m_mod_name[m_nModCount], ModuleEntry32.szModule);
		m_hMods[m_nModCount] =ModuleEntry32.hModule;
		m_nModCount++;

	} while (pModule32Next(hSnapShot, &ModuleEntry32) && m_nModCount <MAX_MODULE_COUNT);

	CloseHandle(hSnapShot);
//#endif

	return m_nModCount;
}
Exemple #2
0
int GetAppByWindow(HWND Window, LPSTR processName)
{
	processName[0]=0;
	DWORD pid;
	HANDLE hPr;

	GetWindowThreadProcessId(Window, &pid); // determine the process id of the window handle

	if (pCreateToolhelp32Snapshot && pModule32First && pModule32Next)
	{
		// grab all the modules associated with the process
		hPr = pCreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
		if (hPr != INVALID_HANDLE_VALUE)
		{
			MODULEENTRY32 me;
			HINSTANCE hi = (HINSTANCE)GetWindowLongPtr(Window, GWLP_HINSTANCE);

			me.dwSize = sizeof(me);
			if (pModule32First(hPr, &me))
				do
					if (me.hModule == hi)
					{
						strcpy(processName, me.szModule);
						break;
					}
				while (pModule32Next(hPr, &me));
			CloseHandle(hPr);
		}
	}
	else
		if (pGetModuleBaseName && pEnumProcessModules)
		{
			HMODULE hMod;
			DWORD cbNeeded;
			hPr = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, FALSE, pid);
			if (hPr != NULL)
			{
				if (pEnumProcessModules(hPr, &hMod, sizeof(hMod), &cbNeeded))
				{
					pGetModuleBaseName(hPr, hMod, processName, MAX_PATH);
				}
				CloseHandle(hPr);
			}
		}

	// dbg_printf("appname = %s\n", processName);
	return strlen(processName);
}
Exemple #3
0
static void test_module(DWORD pid, const char* expected[], unsigned num_expected)
{
    HANDLE              hSnapshot;
    PROCESSENTRY32      pe;
    THREADENTRY32       te;
    MODULEENTRY32       me;
    unsigned            found[32];
    unsigned            i;
    int                 num = 0;

    ok(NUM_OF(found) >= num_expected, "Internal: bump found[] size\n");

    hSnapshot = pCreateToolhelp32Snapshot( TH32CS_SNAPMODULE, pid );
    ok(hSnapshot != NULL, "Cannot create snapshot\n");

    for (i = 0; i < num_expected; i++) found[i] = 0;
    me.dwSize = sizeof(me);
    if (pModule32First( hSnapshot, &me ))
    {
        do
        {
            trace("PID=%x base=%p size=%x %s %s\n",
                  me.th32ProcessID, me.modBaseAddr, me.modBaseSize, me.szExePath, me.szModule);
            ok(me.th32ProcessID == pid, "wrong returned process id\n");
            for (i = 0; i < num_expected; i++)
                if (!lstrcmpi(expected[i], me.szModule)) found[i]++;
            num++;
        } while (pModule32Next( hSnapshot, &me ));
    }
    for (i = 0; i < num_expected; i++)
        ok(found[i] == 1, "Module %s is %s\n",
           expected[i], found[i] ? "listed more than once" : "not listed");

    /* check that first really resets the enumeration */
    for (i = 0; i < num_expected; i++) found[i] = 0;
    me.dwSize = sizeof(me);
    if (pModule32First( hSnapshot, &me ))
    {
        do
        {
            trace("PID=%x base=%p size=%x %s %s\n",
                  me.th32ProcessID, me.modBaseAddr, me.modBaseSize, me.szExePath, me.szModule);
            for (i = 0; i < num_expected; i++)
                if (!lstrcmpi(expected[i], me.szModule)) found[i]++;
            num--;
        } while (pModule32Next( hSnapshot, &me ));
    }
    for (i = 0; i < num_expected; i++)
        ok(found[i] == 1, "Module %s is %s\n",
           expected[i], found[i] ? "listed more than once" : "not listed");
    ok(!num, "mismatch in counting\n");

    pe.dwSize = sizeof(pe);
    ok(!pProcess32First( hSnapshot, &pe ), "shouldn't return a process\n");

    te.dwSize = sizeof(te);
    ok(!pThread32First( hSnapshot, &te ), "shouldn't return a thread\n");

    CloseHandle(hSnapshot);
    ok(!pModule32First( hSnapshot, &me ), "shouldn't return a module\n");
}
Exemple #4
0
static LONG WINAPI hb_winExceptionHandler( struct _EXCEPTION_POINTERS * pExceptionInfo )
{
   char errmsg[ 8192 ];
   int errmsglen = sizeof( errmsg ) - 1;

   errmsg[ 0 ] = '\0';

#if defined( HB_OS_WIN_64 ) && defined( HB_CPU_X86_64 )
   {
      char buf[ 32 ];
      PCONTEXT pCtx = pExceptionInfo->ContextRecord;
      const char * szCode;

      /* two most common codes */
      switch( pExceptionInfo->ExceptionRecord->ExceptionCode )
      {
         case EXCEPTION_ACCESS_VIOLATION:
            szCode = " " "ACCESS_VIOLATION";
            break;
         case EXCEPTION_IN_PAGE_ERROR:
            szCode = " " "IN_PAGE_ERROR";
            break;
         default:
            szCode = "";
      }

      hb_snprintf( errmsg, errmsglen,
         "\n\n"
         "    Exception Code:%08X%s\n"
         "    Exception Address:%016" PFLL "X\n"
         "    RAX:%016" PFLL "X  RBX:%016" PFLL "X  RCX:%016" PFLL "X  RDX:%016" PFLL "X\n"
         "    RSI:%016" PFLL "X  RDI:%016" PFLL "X  RBP:%016" PFLL "X\n"
         "    R8 :%016" PFLL "X  R9 :%016" PFLL "X  R10:%016" PFLL "X  R11:%016" PFLL "X\n"
         "    R12:%016" PFLL "X  R13:%016" PFLL "X  R14:%016" PFLL "X  R15:%016" PFLL "X\n"
         "    CS:RIP:%04X:%016" PFLL "X  SS:RSP:%04X:%016" PFLL "X\n"
         "    DS:%04X  ES:%04X  FS:%04X  GS:%04X\n"
         "    Flags:%08X\n",
         ( HB_U32 ) pExceptionInfo->ExceptionRecord->ExceptionCode, szCode,
         ( HB_PTRDIFF ) pExceptionInfo->ExceptionRecord->ExceptionAddress,
         pCtx->Rax, pCtx->Rbx, pCtx->Rcx, pCtx->Rdx,
         pCtx->Rsi, pCtx->Rdi, pCtx->Rbp,
         pCtx->R8 , pCtx->R9 , pCtx->R10, pCtx->R11,
         pCtx->R12, pCtx->R13, pCtx->R14, pCtx->R15,
         ( HB_U32 ) pCtx->SegCs, pCtx->Rip, ( HB_U32 ) pCtx->SegSs, pCtx->Rsp,
         ( HB_U32 ) pCtx->SegDs, ( HB_U32 ) pCtx->SegEs, ( HB_U32 ) pCtx->SegFs, ( HB_U32 ) pCtx->SegGs,
         ( HB_U32 ) pCtx->EFlags );

      if( pExceptionInfo->ExceptionRecord->NumberParameters &&
          pExceptionInfo->ExceptionRecord->NumberParameters < ( DWORD ) EXCEPTION_MAXIMUM_PARAMETERS )
      {
         DWORD arg;

         hb_strncat( errmsg, "    Exception Parameters:", errmsglen );
         for( arg = 0; arg < pExceptionInfo->ExceptionRecord->NumberParameters; ++arg )
         {
            hb_snprintf( buf, sizeof( buf ), " %016" PFLL "X", ( HB_U64 ) pExceptionInfo->ExceptionRecord->ExceptionInformation[ arg ] );
            hb_strncat( errmsg, buf, errmsglen );
         }
         hb_strncat( errmsg, "\n", errmsglen );
      }

      /* TODO: 64-bit stack trace.
               See: - StackWalk64()
                    - https://www.codeproject.com/KB/threads/StackWalker.aspx?fid=202364 */
   }
#elif defined( HB_OS_WIN_64 ) && defined( HB_CPU_IA_64 )
   {
      PCONTEXT pCtx = pExceptionInfo->ContextRecord;

      hb_snprintf( errmsg, errmsglen,
         "\n\n"
         "    Exception Code:%08X\n"
         "    Exception Address:%016" PFLL "X\n"
         "    IS0 :%016" PFLL "X  IS1 :%016" PFLL "X  IS2 :%016" PFLL "X  IS3 :%016" PFLL "X\n"
         "    IT0 :%016" PFLL "X  IT1 :%016" PFLL "X  IT2 :%016" PFLL "X  IT3 :%016" PFLL "X\n"
         "    IT4 :%016" PFLL "X  IT5 :%016" PFLL "X  IT6 :%016" PFLL "X  IT7 :%016" PFLL "X\n"
         "    IT8 :%016" PFLL "X  IT9 :%016" PFLL "X  IT10:%016" PFLL "X  IT11:%016" PFLL "X\n"
         "    IT12:%016" PFLL "X  IT13:%016" PFLL "X  IT14:%016" PFLL "X  IT15:%016" PFLL "X\n"
         "    IT16:%016" PFLL "X  IT17:%016" PFLL "X  IT18:%016" PFLL "X  IT19:%016" PFLL "X\n"
         "    IT20:%016" PFLL "X  IT21:%016" PFLL "X  IT22:%016" PFLL "X\n"
         "    IGp :%016" PFLL "X  IV0 :%016" PFLL "X  ISp :%016" PFLL "X  ITeb:%016" PFLL "X\n"
         "    INat:%016" PFLL "X\n",
         ( HB_U32 ) pExceptionInfo->ExceptionRecord->ExceptionCode,
         pExceptionInfo->ExceptionRecord->ExceptionAddress,
         pCtx->IntS0 , pCtx->IntS1 , pCtx->IntS2 , pCtx->IntS3 ,
         pCtx->IntT0 , pCtx->IntT1 , pCtx->IntT2 , pCtx->IntT3 ,
         pCtx->IntT4 , pCtx->IntT5 , pCtx->IntT6 , pCtx->IntT7 ,
         pCtx->IntT8 , pCtx->IntT9 , pCtx->IntT10, pCtx->IntT11,
         pCtx->IntT12, pCtx->IntT13, pCtx->IntT14, pCtx->IntT15,
         pCtx->IntT16, pCtx->IntT17, pCtx->IntT18, pCtx->IntT19,
         pCtx->IntT20, pCtx->IntT21, pCtx->IntT22,
         pCtx->IntGp , pCtx->IntV0 , pCtx->IntSp , pCtx->IntTeb,
         pCtx->IntNats );
   }
#elif defined( HB_OS_WIN_CE ) && defined( HB_CPU_ARM )
   {
      PCONTEXT pCtx = pExceptionInfo->ContextRecord;

      hb_snprintf( errmsg, errmsglen,
         "\n\n"
         "    Exception Code:%08X\n"
         "    Exception Address:%08X\n"
         "    R0 :%08X  R1 :%08X  R2 :%08X  R3 :%08X\n"
         "    R4 :%08X  R5 :%08X  R6 :%08X  R7 :%08X\n"
         "    R8 :%08X  R9 :%08X  R10:%08X  R11:%08X\n"
         "    R12:%08X\n"
         "    SP :%08X  LR :%08X  PC :%08X\n"
         "    Flags:%08X\n",
         ( HB_U32 ) pExceptionInfo->ExceptionRecord->ExceptionCode,
         ( HB_U32 ) pExceptionInfo->ExceptionRecord->ExceptionAddress,
         ( HB_U32 ) pCtx->R0 , ( HB_U32 ) pCtx->R1 , ( HB_U32 ) pCtx->R2 , ( HB_U32 ) pCtx->R3 ,
         ( HB_U32 ) pCtx->R4 , ( HB_U32 ) pCtx->R5 , ( HB_U32 ) pCtx->R6 , ( HB_U32 ) pCtx->R7 ,
         ( HB_U32 ) pCtx->R8 , ( HB_U32 ) pCtx->R9 , ( HB_U32 ) pCtx->R10, ( HB_U32 ) pCtx->R11,
         ( HB_U32 ) pCtx->R12,
         ( HB_U32 ) pCtx->Sp , ( HB_U32 ) pCtx->Lr , ( HB_U32 ) pCtx->Pc,
         ( HB_U32 ) pCtx->Psr );
   }
#elif defined( HB_OS_WIN_CE ) && defined( HB_CPU_MIPS ) && defined( HB_ARCH_32BIT )
   {
      PCONTEXT pCtx = pExceptionInfo->ContextRecord;

      hb_snprintf( errmsg, errmsglen,
         "\n\n"
         "    Exception Code:%08X\n"
         "    Exception Address:%08X\n"
         "    IZe:%08X  IAt:%08X  ILo:%08X  IHi:%08X\n"
         "    IA0:%08X  IA1:%08X  IA2:%08X  IA3:%08X\n"
         "    IT0:%08X  IT1:%08X  IT2:%08X  IT3:%08X\n"
         "    IT4:%08X  IT5:%08X  IT6:%08X  IT7:%08X\n"
         "    IT8:%08X  IT9:%08X  IV0:%08X  IV1:%08X\n"
         "    IS0:%08X  IS1:%08X  IS2:%08X  IS3:%08X\n"
         "    IS4:%08X  IS5:%08X  IS6:%08X  IS7:%08X\n"
         "    IS8:%08X  IK0:%08X  IK1:%08X\n"
         "    IGp:%08X  ISp:%08X  IRa:%08X\n"
         "    Fsr:%08X  Fir:%08X  Psr:%08X\n",
         ( HB_U32 ) pExceptionInfo->ExceptionRecord->ExceptionCode,
         ( HB_U32 ) pExceptionInfo->ExceptionRecord->ExceptionAddress,
         ( HB_U32 ) pCtx->IntZero, ( HB_U32 ) pCtx->IntAt, ( HB_U32 ) pCtx->IntLo, ( HB_U32 ) pCtx->IntHi,
         ( HB_U32 ) pCtx->IntA0, ( HB_U32 ) pCtx->IntA1, ( HB_U32 ) pCtx->IntA2, ( HB_U32 ) pCtx->IntA3,
         ( HB_U32 ) pCtx->IntT0, ( HB_U32 ) pCtx->IntT1, ( HB_U32 ) pCtx->IntT2, ( HB_U32 ) pCtx->IntT3,
         ( HB_U32 ) pCtx->IntT4, ( HB_U32 ) pCtx->IntT5, ( HB_U32 ) pCtx->IntT6, ( HB_U32 ) pCtx->IntT7,
         ( HB_U32 ) pCtx->IntT8, ( HB_U32 ) pCtx->IntT9, ( HB_U32 ) pCtx->IntV0, ( HB_U32 ) pCtx->IntV1,
         ( HB_U32 ) pCtx->IntS0, ( HB_U32 ) pCtx->IntS1, ( HB_U32 ) pCtx->IntS2, ( HB_U32 ) pCtx->IntS3,
         ( HB_U32 ) pCtx->IntS4, ( HB_U32 ) pCtx->IntS5, ( HB_U32 ) pCtx->IntS6, ( HB_U32 ) pCtx->IntS7,
         ( HB_U32 ) pCtx->IntS8, ( HB_U32 ) pCtx->IntK0, ( HB_U32 ) pCtx->IntK1,
         ( HB_U32 ) pCtx->IntGp, ( HB_U32 ) pCtx->IntSp, ( HB_U32 ) pCtx->IntRa,
         ( HB_U32 ) pCtx->Fsr  , ( HB_U32 ) pCtx->Fir  , ( HB_U32 ) pCtx->Psr );
   }
#elif defined( HB_OS_WIN_CE ) && defined( HB_CPU_MIPS ) && defined( HB_ARCH_64BIT ) /* Such platform doesn't currently exist [2010]. */
   {
      PCONTEXT pCtx = pExceptionInfo->ContextRecord;

      hb_snprintf( errmsg, errmsglen,
         "\n\n"
         "    Exception Code:%08X\n"
         "    Exception Address:%016" PFLL "X\n"
         "    IZe:%016" PFLL "X  IAt:%016" PFLL "X  ILo:%016" PFLL "X  IHi:%016" PFLL "X\n"
         "    IA0:%016" PFLL "X  IA1:%016" PFLL "X  IA2:%016" PFLL "X  IA3:%016" PFLL "X\n"
         "    IT0:%016" PFLL "X  IT1:%016" PFLL "X  IT2:%016" PFLL "X  IT3:%016" PFLL "X\n"
         "    IT4:%016" PFLL "X  IT5:%016" PFLL "X  IT6:%016" PFLL "X  IT7:%016" PFLL "X\n"
         "    IT8:%016" PFLL "X  IT9:%016" PFLL "X  IV0:%016" PFLL "X  IV1:%016" PFLL "X\n"
         "    IS0:%016" PFLL "X  IS1:%016" PFLL "X  IS2:%016" PFLL "X  IS3:%016" PFLL "X\n"
         "    IS4:%016" PFLL "X  IS5:%016" PFLL "X  IS6:%016" PFLL "X  IS7:%016" PFLL "X\n"
         "    IS8:%016" PFLL "X  IK0:%016" PFLL "X  IK1:%016" PFLL "X\n"
         "    IGp:%016" PFLL "X  ISp:%016" PFLL "X  IRa:%016" PFLL "X\n"
         "    Fsr:%016" PFLL "X  Fir:%016" PFLL "X  Psr:%016" PFLL "X\n",
         ( HB_U32 ) pExceptionInfo->ExceptionRecord->ExceptionCode,
         pExceptionInfo->ExceptionRecord->ExceptionAddress,
         pCtx->IntZero, pCtx->IntAt, pCtx->IntLo, pCtx->IntHi,
         pCtx->IntA0, pCtx->IntA1, pCtx->IntA2, pCtx->IntA3,
         pCtx->IntT0, pCtx->IntT1, pCtx->IntT2, pCtx->IntT3,
         pCtx->IntT4, pCtx->IntT5, pCtx->IntT6, pCtx->IntT7,
         pCtx->IntT8, pCtx->IntT9, pCtx->IntV0, pCtx->IntV1,
         pCtx->IntS0, pCtx->IntS1, pCtx->IntS2, pCtx->IntS3,
         pCtx->IntS4, pCtx->IntS5, pCtx->IntS6, pCtx->IntS7,
         pCtx->IntS8, pCtx->IntK0, pCtx->IntK1,
         pCtx->IntGp, pCtx->IntSp, pCtx->IntRa,
         pCtx->Fsr  , pCtx->Fir  , pCtx->Psr );
   }
#elif defined( HB_OS_WIN_CE ) && defined( HB_CPU_SH )
   {
      PCONTEXT pCtx = pExceptionInfo->ContextRecord;

      hb_snprintf( errmsg, errmsglen,
         "\n\n"
         "    Exception Code:%08X\n"
         "    Exception Address:%08X\n"
         "    R0 :%08X  R1 :%08X  R2 :%08X  R3 :%08X\n"
         "    R4 :%08X  R5 :%08X  R6 :%08X  R7 :%08X\n"
         "    R8 :%08X  R9 :%08X  R10:%08X  R11:%08X\n"
         "    R12:%08X  R13:%08X  R14:%08X  R15:%08X\n"
         "    PR :%08X MACH:%08X MACL:%08X  GBR:%08X\n",
         ( HB_U32 ) pExceptionInfo->ExceptionRecord->ExceptionCode,
         ( HB_U32 ) pExceptionInfo->ExceptionRecord->ExceptionAddress,
         ( HB_U32 ) pCtx->R0 , ( HB_U32 ) pCtx->R1 , ( HB_U32 ) pCtx->R2 , ( HB_U32 ) pCtx->R3 ,
         ( HB_U32 ) pCtx->R4 , ( HB_U32 ) pCtx->R5 , ( HB_U32 ) pCtx->R6 , ( HB_U32 ) pCtx->R7 ,
         ( HB_U32 ) pCtx->R8 , ( HB_U32 ) pCtx->R9 , ( HB_U32 ) pCtx->R10, ( HB_U32 ) pCtx->R11,
         ( HB_U32 ) pCtx->R12, ( HB_U32 ) pCtx->R13, ( HB_U32 ) pCtx->R14, ( HB_U32 ) pCtx->R15,
         ( HB_U32 ) pCtx->PR, ( HB_U32 ) pCtx->MACH, ( HB_U32 ) pCtx->MACL, ( HB_U32 ) pCtx->GBR );
   }
#elif defined( HB_CPU_X86 )
   {
      char         buf[ 64 + MAX_PATH ];
      PCONTEXT     pCtx = pExceptionInfo->ContextRecord;
      const char * szCode;

      /* two most common codes */
      switch( pExceptionInfo->ExceptionRecord->ExceptionCode )
      {
         case EXCEPTION_ACCESS_VIOLATION:
            szCode = " " "ACCESS_VIOLATION";
            break;
         case EXCEPTION_IN_PAGE_ERROR:
            szCode = " " "IN_PAGE_ERROR";
            break;
         default:
            szCode = "";
      }

      hb_snprintf( errmsg, errmsglen,
         "\n\n"
         "    Exception Code:%08X%s\n"
         "    Exception Address:%08X\n"
         "    EAX:%08X  EBX:%08X  ECX:%08X  EDX:%08X\n"
         "    ESI:%08X  EDI:%08X  EBP:%08X\n"
         "    CS:EIP:%04X:%08X  SS:ESP:%04X:%08X\n"
         "    DS:%04X  ES:%04X  FS:%04X  GS:%04X\n"
         "    Flags:%08X\n",
         ( HB_U32 ) pExceptionInfo->ExceptionRecord->ExceptionCode, szCode,
         ( HB_U32 ) pExceptionInfo->ExceptionRecord->ExceptionAddress,
         ( HB_U32 ) pCtx->Eax, ( HB_U32 ) pCtx->Ebx, ( HB_U32 ) pCtx->Ecx, ( HB_U32 ) pCtx->Edx,
         ( HB_U32 ) pCtx->Esi, ( HB_U32 ) pCtx->Edi, ( HB_U32 ) pCtx->Ebp,
         ( HB_U32 ) pCtx->SegCs, ( HB_U32 ) pCtx->Eip, ( HB_U32 ) pCtx->SegSs, ( HB_U32 ) pCtx->Esp,
         ( HB_U32 ) pCtx->SegDs, ( HB_U32 ) pCtx->SegEs, ( HB_U32 ) pCtx->SegFs, ( HB_U32 ) pCtx->SegGs,
         ( HB_U32 ) pCtx->EFlags );

      if( pExceptionInfo->ExceptionRecord->NumberParameters &&
          pExceptionInfo->ExceptionRecord->NumberParameters < ( DWORD ) EXCEPTION_MAXIMUM_PARAMETERS )
      {
         DWORD arg;

         hb_strncat( errmsg, "    Exception Parameters:", errmsglen );
         for( arg = 0; arg < pExceptionInfo->ExceptionRecord->NumberParameters; ++arg )
         {
            hb_snprintf( buf, sizeof( buf ), " %08X", ( HB_U32 ) pExceptionInfo->ExceptionRecord->ExceptionInformation[ arg ] );
            hb_strncat( errmsg, buf, errmsglen );
         }
         hb_strncat( errmsg, "\n", errmsglen );
      }

      {
         unsigned char * pc;
         unsigned int *  sc;
         unsigned int *  ebp;
         unsigned int    eip;
         unsigned int    j;
         int             i;

         hb_strncat( errmsg, "    CS:EIP:", errmsglen );
         pc = ( unsigned char * ) pCtx->Eip;
         for( i = 0; i < 16; i++ )
         {
            /* TOFIX: Unsafe funcion. */
            if( IsBadReadPtr( pc, 1 ) )
               break;
            hb_snprintf( buf, sizeof( buf ), " %02X", ( int ) pc[ i ] );
            hb_strncat( errmsg, buf, errmsglen );
         }
         hb_strncat( errmsg, "\n    SS:ESP:", errmsglen );
         sc = ( unsigned int * ) pCtx->Esp;
         for( i = 0; i < 16; i++ )
         {
            /* TOFIX: Unsafe funcion. */
            if( IsBadReadPtr( sc, 4 ) )
               break;
            hb_snprintf( buf, sizeof( buf ), " %08X", sc[ i ] );
            hb_strncat( errmsg, buf, errmsglen );
         }
         hb_strncat( errmsg, "\n\n", errmsglen );
         hb_strncat( errmsg, "    C stack:\n", errmsglen );
         hb_strncat( errmsg, "    EIP:     EBP:       Frame: OldEBP, RetAddr, Params...\n", errmsglen );
         eip = pCtx->Eip;
         ebp = ( unsigned int * ) pCtx->Ebp;
         /* TOFIX: Unsafe funcion. */
         if( ! IsBadWritePtr( ebp, 8 ) )
         {
            for( i = 0; i < 20; i++ )
            {
               /* TOFIX: Unsafe funcion. */
               if( ( unsigned int ) ebp % 4 != 0 || IsBadWritePtr( ebp, 40 ) || ( unsigned int ) ebp >= ebp[ 0 ] )
                  break;
               hb_snprintf( buf, sizeof( buf ), "    %08X %08X  ", ( int ) eip, ( int ) ebp );
               hb_strncat( errmsg, buf, errmsglen );
               for( j = 0; j < 10 && ( unsigned int ) ( ebp + j ) < ebp[ 0 ]; j++ )
               {
                  hb_snprintf( buf, sizeof( buf ), " %08X", ebp[ j ] );
                  hb_strncat( errmsg, buf, errmsglen );
               }
               hb_strncat( errmsg, "\n", errmsglen );
               eip = ebp[ 1 ];
               ebp = ( unsigned int * ) ebp[ 0 ];
            }
            hb_strncat( errmsg, "\n", errmsglen );
         }
      }
   }
#endif

   {
#if defined( HB_OS_WIN_CE )
      HMODULE hToolhelp = GetModuleHandle( TEXT( "toolhelp.dll" ) );
#else
      /* NOTE: Several non-MS sources say that Win9x has these functions
               in tlhelp32.dll. Testing shows though, that in Win95, Win95b
               and Win98 they are in kernel32.dll, and tlhelp32.dll doesn't
               exist. [vszakats] */
      HMODULE hToolhelp = GetModuleHandle( TEXT( "kernel32.dll" ) );
#endif

      if( hToolhelp )
      {
         /* NOTE: Hack to force the ASCII versions of these types. [vszakats] */
         #if ! defined( HB_OS_WIN_CE ) && defined( UNICODE )
            #undef MODULEENTRY32
            #undef LPMODULEENTRY32
         #endif

         typedef HANDLE ( WINAPI * P_CTH32SSH )( DWORD, DWORD ); /* CreateToolhelp32Snapshot() */
         typedef BOOL ( WINAPI * P_M32F )( HANDLE, LPMODULEENTRY32 ); /* Module32First() */
         typedef BOOL ( WINAPI * P_M32N )( HANDLE, LPMODULEENTRY32 ); /* Module32Next() */

         P_CTH32SSH pCreateToolhelp32Snapshot = ( P_CTH32SSH ) HB_WINAPI_GETPROCADDRESS( hToolhelp, "CreateToolhelp32Snapshot" );
         P_M32F     pModule32First            = ( P_M32F     ) HB_WINAPI_GETPROCADDRESS( hToolhelp, "Module32First" );
         P_M32N     pModule32Next             = ( P_M32N     ) HB_WINAPI_GETPROCADDRESS( hToolhelp, "Module32Next" );

         if( pCreateToolhelp32Snapshot &&
             pModule32First &&
             pModule32Next )
         {
            /* Take a snapshot of all modules in the specified process. */
            HANDLE hModuleSnap = pCreateToolhelp32Snapshot( TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, GetCurrentProcessId() );

            if( hModuleSnap != INVALID_HANDLE_VALUE )
            {
               MODULEENTRY32 me32;

               /* Set the size of the structure before using it. */
               me32.dwSize = sizeof( MODULEENTRY32 );

               /* Retrieve information about the first module, and exit if unsuccessful */
               if( pModule32First( hModuleSnap, &me32 ) )
               {
                  hb_strncat( errmsg, "\nModules:\n", errmsglen );

                  /* Now walk the module list of the process, and display information about each module */
                  do
                  {
                     char buf[ 256 ];
#if defined( HB_OS_WIN_64 )
                     /* TOFIX: me32.szExePath seemed trashed in some (standalone) tests. */
                     hb_snprintf( buf, sizeof( buf ), "%016" PFLL "X %016" PFLL "X %s\n", ( HB_PTRDIFF ) me32.modBaseAddr, ( HB_PTRDIFF ) me32.modBaseSize, me32.szExePath );
#else
                     char szBuffer[ MAX_PATH ];
                     #if defined( HB_OS_WIN_CE )
                        hb_wcntombcpy( szBuffer, me32.szExePath, HB_SIZEOFARRAY( szBuffer ) - 1 );
                     #else
                        hb_strncpy( szBuffer, me32.szExePath, HB_SIZEOFARRAY( szBuffer ) - 1 );
                     #endif
                     hb_snprintf( buf, sizeof( buf ), "%08lX %08lX %s\n", ( HB_PTRDIFF ) me32.modBaseAddr, ( HB_PTRDIFF ) me32.modBaseSize, szBuffer );
#endif
                     hb_strncat( errmsg, buf, errmsglen );
                  }
                  while( pModule32Next( hModuleSnap, &me32 ) );
               }

               /* Do not forget to clean up the snapshot object. */
               CloseHandle( hModuleSnap );
            }
         }
      }
   }

   hb_errInternalRaw( 6005, "Exception error:%s", errmsg, NULL );

   return hb_cmdargCheck( "BATCH" ) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH;
}