Exemplo n.º 1
0
UINT	WINAPI
GetPaletteEntries(HPALETTE hPalette,
	UINT uPaletteIndex, UINT uNumPaletteEntries,
	LPPALETTEENTRY lpPaletteEntries)
{
	LPPALETTE lpPalette;
	LPLOGPALETTE lpLogPalette;
	UINT u;

	APISTR((LF_APICALL, 
	   "GetPaletteEntries(HPALETTE=%x,UINT=%x,UINT=%x,PALETTENTRY *%x)\n",
		hPalette, uPaletteIndex, uNumPaletteEntries,
		lpPaletteEntries));

	ASSERT_PALETTE(lpPalette, hPalette, 0);

	if (!(lpLogPalette = lpPalette->lpLogPalette))
	{
		UNLOCK_PALETTE(hPalette);
		SetLastErrorEx(1, 0);
		APISTR((LF_APIRET, "SetPaletteEntries: returns UINT 0\n"));
		return (0);
	}

	if (!lpPaletteEntries)
	{
		uNumPaletteEntries = lpLogPalette->palNumEntries;
		UNLOCK_PALETTE(hPalette);
		APISTR((LF_APIRET, "SetPaletteEntries: returns UINT %x\n",
			uNumPaletteEntries));
		return (uNumPaletteEntries);
	}

	if (uPaletteIndex >= lpLogPalette->palNumEntries)
	{
		UNLOCK_PALETTE(hPalette);
		SetLastErrorEx(1, 0);
		APISTR((LF_APIRET, "SetPaletteEntries: returns UINT 0\n"));
		return (0);
	}

	uNumPaletteEntries = min(uNumPaletteEntries,
		lpLogPalette->palNumEntries - uPaletteIndex);

	for (u = 0; u < uNumPaletteEntries; u++)
	{
		lpPaletteEntries[u]
			= lpLogPalette->palPalEntry[uPaletteIndex + u];
	}

	UNLOCK_PALETTE(hPalette);

	APISTR((LF_APIRET, "SetPaletteEntries: returns UINT %x\n",
		uNumPaletteEntries));
	return (uNumPaletteEntries);

}
Exemplo n.º 2
0
HPALETTE	WINAPI
CreatePalette(const LOGPALETTE *lpLogPalette)
{
	HPALETTE hPalette;
	LPPALETTE lpPalette;
	UINT u;

	APISTR((LF_APICALL, "CreatePalette(LOGPALETTE *%p)\n",
		lpLogPalette));

	if (!lpLogPalette)
	{
		SetLastErrorEx(1, 0);
		APISTR((LF_APIRET, "CreatePalette: returns HPALETTE 0\n"));
		return ((HPALETTE) 0);
	}

	if (!(lpPalette = CREATEHPALETTE(hPalette)))
	{
		SetLastErrorEx(1, 0);
		APISTR((LF_APIRET, "CreatePalette: returns HPALETTE 0\n"));
		return ((HPALETTE) 0);
	}

	if (!(lpPalette->lpLogPalette = (LPLOGPALETTE)
		WinMalloc(sizeof(LOGPALETTE)
		+ lpLogPalette->palNumEntries * sizeof(PALETTEENTRY))))
	{
#ifdef LATER
		/* DELETE uninitialized HPALETTE here */
#endif
		SetLastErrorEx(1, 0);
		APISTR((LF_APIRET, "CreatePalette: returns HPALETTE 0\n"));
		return ((HPALETTE) 0);
	}

	lpPalette->lpLogPalette->palVersion = lpLogPalette->palVersion;
	lpPalette->lpLogPalette->palNumEntries = lpLogPalette->palNumEntries;
	for (u = 0; u < lpLogPalette->palNumEntries; u++)
	{
		lpPalette->lpLogPalette->palPalEntry[u]
			= lpLogPalette->palPalEntry[u];
	}

	lpPalette->fIsRealized = FALSE;

	UNLOCK_PALETTE(hPalette);

	APISTR((LF_APIRET, "CreatePalette: returns HPALETTE %x\n",hPalette));
	return (hPalette);

}
Exemplo n.º 3
0
BOOL EnableBuddyButton( HWND hwndEdit, HWND hwndButton, UINT uStyle )
{
	//
	//	Quick check to amke sure our parameters are good
	if( uStyle == BBS_LEFT || uStyle == BBS_RIGHT )
	{
		if( IsWindow( hwndEdit ) && IsWindow( hwndButton ) )
		{
			//
			//	Subclass the edit control so we can catch some handy messages
			FARPROC lpfnWndProc = reinterpret_cast<FARPROC>( SetWindowLong( hwndEdit, GWL_WNDPROC, (LONG) SubClassedProc ) );
			ASSERT( lpfnWndProc != NULL );
			VERIFY( ::SetProp( hwndEdit, g_szOldProc, reinterpret_cast<HANDLE>( lpfnWndProc ) ) );

			//
			//	Create our data object. We later give this to our subclassed edit control so we can 
			CData *pData = new CData;
			pData->m_uStyle = uStyle;

			CRect rcButton;
			::GetWindowRect( hwndButton, rcButton );

			pData->m_uButtonWidth = rcButton.Width();
			pData->m_hwndButton = hwndButton;

			VERIFY( ::SetProp( hwndEdit, g_szData, reinterpret_cast<HANDLE>( pData ) ) );

			//
			//	Doing this forces our edit window to pay attention to our change in it's client size
			SetWindowPos( hwndEdit, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED );

			return TRUE;
		}
		else
		{
			//
			//	Set the last error to be something meaningful
			SetLastErrorEx( ERROR_INVALID_WINDOW_HANDLE, SLE_ERROR );
		}
	}
	else
	{
		//
		//	Set the last error to be something meaningful
		SetLastErrorEx( ERROR_INVALID_DATA, SLE_ERROR );
	}
	return FALSE;
}
Exemplo n.º 4
0
UINT	WINAPI
GetNearestPaletteIndex(HPALETTE hPalette, COLORREF crColor)
{
	LPPALETTE lpPalette;
	LPLOGPALETTE lpLogPalette;
	UINT u, uNearestPaletteIndex;
	long delta0, r0, g0, b0, delta, r, g, b;

	APISTR((LF_APICALL, 
		"GetNearestPaletteIndex(HPALETTE=%x,COLORREF=%x)\n",
		hPalette, crColor));

	ASSERT_PALETTE(lpPalette, hPalette, CLR_INVALID);

	if (!(lpLogPalette = lpPalette->lpLogPalette))
	{
		UNLOCK_PALETTE(hPalette);
		SetLastErrorEx(1, 0);
		APISTR((LF_APIRET, "GetNearestPaletteIndex: returns UINT %x\n",
			CLR_INVALID));
		return (CLR_INVALID);
	}

	r0 = GetRValue(crColor);
	g0 = GetGValue(crColor);
	b0 = GetBValue(crColor);
	delta0 = 0x030000L;
	uNearestPaletteIndex = CLR_INVALID;
		
	for (u = 0; u < lpLogPalette->palNumEntries; u++)
	{
		if ((lpLogPalette->palPalEntry[u].peRed == r0)
		 && (lpLogPalette->palPalEntry[u].peGreen == g0)
		 && (lpLogPalette->palPalEntry[u].peBlue == b0))
		{
			uNearestPaletteIndex = u;
			break;
		}
		r = lpLogPalette->palPalEntry[u].peRed;
		g = lpLogPalette->palPalEntry[u].peGreen;
		b = lpLogPalette->palPalEntry[u].peBlue;
		delta = (r-r0)*(r-r0) + (g-g0)*(g-g0) + (b-b0)*(b-b0);
		if (delta < delta0)
		{
			uNearestPaletteIndex = u;
			delta0 = delta;
		}
	}

	UNLOCK_PALETTE(hPalette);

	APISTR((LF_APIRET, "GetNearestPaletteIndex: returns UINT %x\n",
		uNearestPaletteIndex));
	return (uNearestPaletteIndex);

}
Exemplo n.º 5
0
BOOL AddBuddy(HWND hwndTarget, HWND hwndBuddy, UINT uStyle)
{
	if(uStyle == BDS_LEFT || uStyle == BDS_RIGHT || uStyle == BDS_TOP || uStyle == BDS_BOTTOM)
	{
		if(::IsWindow(hwndTarget) && ::IsWindow(hwndBuddy))
		{
			FARPROC lpfnWndProc = reinterpret_cast<FARPROC>(SetWindowLong(hwndTarget, GWL_WNDPROC, (long)SubClassedProc));
			ASSERT(lpfnWndProc != NULL);
			VERIFY(::SetProp(hwndTarget, g_szOldProc, reinterpret_cast<HANDLE>(lpfnWndProc)));
			
			CData *pData = new CData;
			pData->m_uStyle = uStyle;

			CRect rcBuddy;
			::GetWindowRect(hwndBuddy, rcBuddy);

			pData->m_uBuddyWidth = rcBuddy.Width();
			pData->m_uBuddyHeight = rcBuddy.Height();
			pData->m_hwndBuddy = hwndBuddy;
			pData->m_bVisible = -1;

			VERIFY(::SetProp(hwndTarget, g_szData, reinterpret_cast<HANDLE>(pData)));

			::SetWindowPos(hwndTarget, NULL, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED);
			
			return TRUE;
		}
		else
		{
			SetLastErrorEx(ERROR_INVALID_WINDOW_HANDLE, SLE_ERROR);
		}
	}
	else
	{
		SetLastErrorEx(ERROR_INVALID_DATA, SLE_ERROR);
	}

	return FALSE;
}
DWORD __stdcall NTGetModuleBaseName ( HANDLE  hProcess   ,
                                      HMODULE hModule    ,
                                      LPTSTR  lpBaseName ,
                                      DWORD   nSize       )
{
    // Initialize PSAPI.DLL, if needed.
    if ( FALSE == InitPSAPI ( ) )
    {
        ASSERT ( FALSE ) ;
        SetLastErrorEx ( ERROR_DLL_INIT_FAILED , SLE_ERROR ) ;
        return ( FALSE ) ;
    }
    return ( g_pGetModuleBaseName ( hProcess    ,
                                    hModule     ,
                                    lpBaseName  ,
                                    nSize        ) ) ;
}
DWORD __stdcall NTGetModuleFileNameEx ( DWORD     /*dwPID*/    ,
                                        HANDLE    hProcess     ,
                                        HMODULE   hModule      ,
                                        LPTSTR    szFilename   ,
                                        DWORD     nSize         )
{
    // Initialize PSAPI.DLL, if needed.
    if ( FALSE == InitPSAPI ( ) )
    {
        ASSERT ( !"InitPSAPI failed" ) ;
        SetLastErrorEx ( ERROR_DLL_INIT_FAILED , SLE_ERROR ) ;
        return ( FALSE ) ;
    }
    return ( g_pGetModuleFileNameEx ( hProcess   ,
                                      hModule    ,
                                      szFilename ,
                                      nSize       ) ) ;
}
Exemplo n.º 8
0
UINT	WINAPI
GetSystemPaletteEntries(HDC hDC,
	UINT uPaletteIndex, UINT uNumPaletteEntries, 
	LPPALETTEENTRY lpPaletteEntries)
{
	LPDC lpDC;
	HPALETTE hSystemPalette;
	LPPALETTE lpSystemPalette;
	UINT uNumSystemPaletteEntries;

	APISTR((LF_API, 
	"GetSystemPaletteEntries(HDC=%x,UINT=%x,UINT=%x,PALETTEENTRY *%x)\n",
		hDC, uPaletteIndex, uNumPaletteEntries, lpPaletteEntries));

	ASSERT_DC(lpDC, hDC, 0);

#ifdef TWIN_PALETTE
	if (!(hSystemPalette = (HPALETTE)
		DC_OUTPUT(LSD_GETSYSTEMPALETTE, lpDC, 0, 0))
	 || !(lpSystemPalette = LOCK_PALETTE(hSystemPalette)))
	{
		UNLOCK_DC(hDC);
		SetLastErrorEx(1, 0);
		APISTR((LF_APIRET, "SetPaletteEntries: returns UINT 0\n"));
		return (0);
	}

	uNumSystemPaletteEntries = GetPaletteEntries(hSystemPalette,
		uPaletteIndex, uNumPaletteEntries, lpPaletteEntries);
#endif

	UNLOCK_PALETTE(hSystemPalette);
	UNLOCK_DC(hDC);

	APISTR((LF_APIRET, "SetPaletteEntries: returns UINT %x\n",
		uNumSystemPaletteEntries));
	return (uNumSystemPaletteEntries);

}
Exemplo n.º 9
0
BOOL	WINAPI
ResizePalette(HPALETTE hPalette, UINT uPaletteSize)
{
	LPPALETTE lpPalette;
	LPLOGPALETTE lpLogPalette;
	UINT u;

	APISTR((LF_APICALL, "ResizePalette(HPALETTE=%x,UINT=%x)\n",
		hPalette, uPaletteSize));

	ASSERT_PALETTE(lpPalette, hPalette, FALSE);

	if (!(lpLogPalette = (LPLOGPALETTE) WinRealloc(lpPalette->lpLogPalette,
		sizeof(LOGPALETTE) + uPaletteSize * sizeof(PALETTEENTRY))))
	{
		UNLOCK_PALETTE(hPalette);
		SetLastErrorEx(1, 0);
		APISTR((LF_APIRET, "ResizePalette: returns BOOL 0\n"));
		return (FALSE);
	}

	for (u = lpLogPalette->palNumEntries; u < uPaletteSize; u++)
	{
		lpLogPalette->palPalEntry[u].peRed = 0;
		lpLogPalette->palPalEntry[u].peGreen = 0;
		lpLogPalette->palPalEntry[u].peBlue = 0;
		lpLogPalette->palPalEntry[u].peFlags = 0;
	}
	lpLogPalette->palNumEntries = uPaletteSize;
	lpPalette->lpLogPalette = lpLogPalette;

	UNLOCK_PALETTE(hPalette);

	APISTR((LF_APIRET, "ResizePalette: returns BOOL 1\n"));
	return (TRUE);

}
Exemplo n.º 10
0
// The documentation for this function is in BugslayerUtil.h.
BOOL  __stdcall
                           GetLoadedModules ( DWORD     dwPID        ,
                                              UINT      uiCount      ,
                                              HMODULE * paModArray   ,
                                              LPDWORD   pdwRealCount   )
{
    // Do the debug checking.
    ASSERT ( NULL != pdwRealCount ) ;
    ASSERT ( FALSE == IsBadWritePtr ( pdwRealCount , sizeof ( UINT ) ));
#ifdef _DEBUG
    if ( 0 != uiCount )
    {
        ASSERT ( NULL != paModArray ) ;
        ASSERT ( FALSE == IsBadWritePtr ( paModArray                   ,
                                          uiCount *
                                                sizeof ( HMODULE )   ));
    }
#endif

    // Do the parameter checking for real.  Note that I only check the
    // memory in paModArray if uiCount is > 0.  The user can pass zero
    // in uiCount if they are just interested in the total to be
    // returned so they could dynamically allocate a buffer.
    if ( ( TRUE == IsBadWritePtr ( pdwRealCount , sizeof(UINT) ) )    ||
         ( ( uiCount > 0 ) &&
           ( TRUE == IsBadWritePtr ( paModArray ,
                                     uiCount * sizeof(HMODULE) ) ) )   )
    {
        SetLastErrorEx ( ERROR_INVALID_PARAMETER , SLE_ERROR ) ;
        return ( FALSE ) ;
    }

    // Figure out which OS we are on.
    OSVERSIONINFO stOSVI ;

    FillMemory ( &stOSVI ,sizeof ( OSVERSIONINFO ), NULL  ) ;
    stOSVI.dwOSVersionInfoSize = sizeof ( OSVERSIONINFO ) ;

    BOOL bRet = GetVersionEx ( &stOSVI ) ;
    ASSERT ( TRUE == bRet ) ;
    if ( FALSE == bRet )
    {
        TRACE0 ( "GetVersionEx failed!\n" ) ;
        return ( FALSE ) ;
    }

    // Check the version and call the appropriate thing.
    if ( ( VER_PLATFORM_WIN32_NT == stOSVI.dwPlatformId ) &&
         ( 4 == stOSVI.dwMajorVersion                   )    )
    {
        // This is NT 4 so call its specific version in PSAPI.DLL
        return ( NT4GetLoadedModules ( dwPID        ,
                                       uiCount      ,
                                       paModArray   ,
                                       pdwRealCount  ) );
    }
    else
    {
        // Win9x and Win2K go through tool help.
        return ( TLHELPGetLoadedModules ( dwPID         ,
                                          uiCount       ,
                                          paModArray    ,
                                          pdwRealCount   ) ) ;
    }
}
BOOL BUGSUTIL_DLLINTERFACE __stdcall
        HookImportedFunctionsByName ( HMODULE         hModule     ,
                                      LPCSTR          szImportMod ,
                                      UINT            uiCount     ,
                                      LPHOOKFUNCDESCA paHookArray ,
                                      PROC *          paOrigFuncs ,
                                      LPDWORD         pdwHooked    )
{
    // Double check the parameters.
    ASSERT ( NULL != szImportMod ) ;
    ASSERT ( 0 != uiCount ) ;
    ASSERT ( FALSE == IsBadReadPtr ( paHookArray ,
                                     sizeof (HOOKFUNCDESC) * uiCount ));
#ifdef _DEBUG
    if ( NULL != paOrigFuncs )
    {
        ASSERT ( FALSE == IsBadWritePtr ( paOrigFuncs ,
                                          sizeof ( PROC ) * uiCount ) );
    }
    if ( NULL != pdwHooked )
    {
        ASSERT ( FALSE == IsBadWritePtr ( pdwHooked , sizeof ( UINT )));
    }

    // Check each function name in the hook array.
    {
        for ( UINT i = 0 ; i < uiCount ; i++ )
        {
            ASSERT ( NULL != paHookArray[ i ].szFunc  ) ;
            ASSERT ( '\0' != *paHookArray[ i ].szFunc ) ;
            // If the proc is not NULL, then it is checked.
            if ( NULL != paHookArray[ i ].pProc )
            {
                ASSERT ( FALSE == IsBadCodePtr ( paHookArray[i].pProc));
            }
        }
    }
#endif
    // Do the parameter validation for real.
    if ( ( 0    == uiCount      )                                 ||
         ( NULL == szImportMod  )                                 ||
         ( TRUE == IsBadReadPtr ( paHookArray ,
                                  sizeof (HOOKFUNCDESC) * uiCount ) ) )
    {
        SetLastErrorEx ( ERROR_INVALID_PARAMETER , SLE_ERROR ) ;
        return ( FALSE ) ;
    }
    if ( ( NULL != paOrigFuncs )                                &&
         ( TRUE == IsBadWritePtr ( paOrigFuncs ,
                                   sizeof ( PROC ) * uiCount ) )  )
    {
        SetLastErrorEx ( ERROR_INVALID_PARAMETER , SLE_ERROR ) ;
        return ( FALSE ) ;
    }
    if ( ( NULL != pdwHooked )                                    &&
         ( TRUE == IsBadWritePtr ( pdwHooked , sizeof ( UINT ) ) )  )
    {
        SetLastErrorEx ( ERROR_INVALID_PARAMETER , SLE_ERROR ) ;
        return ( FALSE ) ;
    }

    // Is this a system DLL, which Windows95 will not let you patch
    //  since it is above the 2GB line?
    if ( ( FALSE == IsNT ( ) ) && ( (DWORD)hModule >= 0x80000000 ) )
    {
        SetLastErrorEx ( ERROR_INVALID_HANDLE , SLE_ERROR ) ;
        return ( FALSE ) ;
    }


    // TODO TODO
    //  Should each item in the hook array be checked in release builds?

    if ( NULL != paOrigFuncs )
    {
        // Set all the values in paOrigFuncs to NULL.
        memset ( paOrigFuncs , NULL , sizeof ( PROC ) * uiCount ) ;
    }
    if ( NULL != pdwHooked )
    {
        // Set the number of functions hooked to zero.
        *pdwHooked = 0 ;
    }

    // Get the specific import descriptor.
    PIMAGE_IMPORT_DESCRIPTOR pImportDesc =
                     GetNamedImportDescriptor ( hModule , szImportMod );
    if ( NULL == pImportDesc )
    {
        // The requested module was not imported.  This is not an error.
        return ( TRUE ) ;
    }

    // Get the original thunk information for this DLL.  I cannot use
    //  the thunk information stored in the pImportDesc->FirstThunk
    //  because the that is the array that the loader has already
    //  bashed to fix up all the imports.  This pointer gives us acess
    //  to the function names.
    PIMAGE_THUNK_DATA pOrigThunk =
                        MakePtr ( PIMAGE_THUNK_DATA       ,
                                  hModule                 ,
                                  pImportDesc->OriginalFirstThunk  ) ;
    // Get the array pointed to by the pImportDesc->FirstThunk.  This is
    //  where I will do the actual bash.
    PIMAGE_THUNK_DATA pRealThunk = MakePtr ( PIMAGE_THUNK_DATA       ,
                                             hModule                 ,
                                             pImportDesc->FirstThunk  );

    // Loop through and look for the one that matches the name.
    while ( NULL != pOrigThunk->u1.Function )
    {
        // Only look at those that are imported by name, not ordinal.
        if (  IMAGE_ORDINAL_FLAG !=
                        ( pOrigThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG ))
        {
            // Look get the name of this imported function.
            PIMAGE_IMPORT_BY_NAME pByName ;

            pByName = MakePtr ( PIMAGE_IMPORT_BY_NAME    ,
                                hModule                  ,
                                pOrigThunk->u1.AddressOfData  ) ;

            // If the name starts with NULL, then just skip out now.
            if ( '\0' == pByName->Name[ 0 ] )
            {
                continue ;
            }

            // Determines if we do the hook.
            BOOL bDoHook = FALSE ;

            // TODO TODO
            //  Might want to consider bsearch here.

            // See if the particular function name is in the import
            //  list.  It might be good to consider requiring the
            //  paHookArray to be in sorted order so bsearch could be
            //  used so the lookup will be faster.  However, the size of
            //  uiCount coming into this function should be rather
            //  small but it is called for each function imported by
            //  szImportMod.
            for ( UINT i = 0 ; i < uiCount ; i++ )
            {
                if ( ( paHookArray[i].szFunc[0] ==
                                                pByName->Name[0] ) &&
                     ( 0 == _strcmpi ( paHookArray[i].szFunc ,
                                      (char*)pByName->Name   )   )    )
                {
                    // If the proc is NULL, kick out, otherwise go
                    //  ahead and hook it.
                    if ( NULL != paHookArray[ i ].pProc )
                    {
                        bDoHook = TRUE ;
                    }
                    break ;
                }
            }

            if ( TRUE == bDoHook )
            {
                // I found it.  Now I need to change the protection to
                //  writable before I do the blast.  Note that I am now
                //  blasting into the real thunk area!
                MEMORY_BASIC_INFORMATION mbi_thunk ;

                VirtualQuery ( pRealThunk                          ,
                               &mbi_thunk                          ,
                               sizeof ( MEMORY_BASIC_INFORMATION )  ) ;

                VERIFY ( VirtualProtect ( mbi_thunk.BaseAddress ,
                                          mbi_thunk.RegionSize  ,
                                          PAGE_READWRITE        ,
                                          &mbi_thunk.Protect     ) ) ;

                // Save the original address if requested.
                if ( NULL != paOrigFuncs )
                {
                    paOrigFuncs[i] = (PROC)pRealThunk->u1.Function ;
                }
                // Do the actual hook.
                pRealThunk->u1.Function = (DWORD)paHookArray[i].pProc ;

                DWORD dwOldProtect ;

                // Change the protection back to what it was before I
                //  blasted.
                VERIFY ( VirtualProtect ( mbi_thunk.BaseAddress ,
                                          mbi_thunk.RegionSize  ,
                                          mbi_thunk.Protect     ,
                                          &dwOldProtect          ) ) ;

                if ( NULL != pdwHooked )
                {
                    // Increment the total number hooked.
                    *pdwHooked += 1 ;
                }
            }
        }
        // Increment both tables.
        pOrigThunk++ ;
        pRealThunk++ ;
    }

    // All OK, JumpMaster!
    SetLastError ( ERROR_SUCCESS ) ;
    return ( TRUE ) ;
}
/*----------------------------------------------------------------------
FUNCTION        :   GetNamedImportDescriptor
DISCUSSION      :
    Gets the import descriptor for the requested module.  If the module
is not imported in hModule, NULL is returned.
    This is a potential useful function in the future.
PARAMETERS      :
    hModule      - The module to hook in.
    szImportMod  - The module name to get the import descriptor for.
RETURNS         :
    NULL  - The module was not imported or hModule is invalid.
    !NULL - The import descriptor.
----------------------------------------------------------------------*/
PIMAGE_IMPORT_DESCRIPTOR
                     GetNamedImportDescriptor ( HMODULE hModule     ,
                                                LPCSTR  szImportMod  )
{
    // Always check parameters.
    ASSERT ( NULL != szImportMod ) ;
    ASSERT ( NULL != hModule     ) ;
    if ( ( NULL == szImportMod ) || ( NULL == hModule ) )
    {
        SetLastErrorEx ( ERROR_INVALID_PARAMETER , SLE_ERROR ) ;
        return ( NULL ) ;
    }

    PIMAGE_DOS_HEADER pDOSHeader = (PIMAGE_DOS_HEADER)hModule ;

    // Is this the MZ header?
    if ( ( TRUE == IsBadReadPtr ( pDOSHeader                  ,
                                 sizeof ( IMAGE_DOS_HEADER )  ) ) ||
         ( IMAGE_DOS_SIGNATURE != pDOSHeader->e_magic           )   )
    {
        ASSERT ( FALSE ) ;
        SetLastErrorEx ( ERROR_INVALID_PARAMETER , SLE_ERROR ) ;
        return ( NULL ) ;
    }

    // Get the PE header.
    PIMAGE_NT_HEADERS pNTHeader = MakePtr ( PIMAGE_NT_HEADERS       ,
                                            pDOSHeader              ,
                                            pDOSHeader->e_lfanew     ) ;

    // Is this a real PE image?
    if ( ( TRUE == IsBadReadPtr ( pNTHeader ,
                                  sizeof ( IMAGE_NT_HEADERS ) ) ) ||
         ( IMAGE_NT_SIGNATURE != pNTHeader->Signature           )   )
    {
        ASSERT ( FALSE ) ;
        SetLastErrorEx ( ERROR_INVALID_PARAMETER , SLE_ERROR ) ;
        return ( NULL ) ;
    }

    // If there is no imports section, leave now.
    if ( 0 == pNTHeader->OptionalHeader.
                         DataDirectory[ IMAGE_DIRECTORY_ENTRY_IMPORT ].
                                                      VirtualAddress   )
    {
        return ( NULL ) ;
    }

    // Get the pointer to the imports section.
    PIMAGE_IMPORT_DESCRIPTOR pImportDesc
     = MakePtr ( PIMAGE_IMPORT_DESCRIPTOR ,
                 pDOSHeader               ,
                 pNTHeader->OptionalHeader.
                         DataDirectory[ IMAGE_DIRECTORY_ENTRY_IMPORT ].
                                                      VirtualAddress ) ;

    // Loop through the import module descriptors looking for the
    //  module whose name matches szImportMod.
    while ( NULL != pImportDesc->Name )
    {
        PSTR szCurrMod = MakePtr ( PSTR              ,
                                   pDOSHeader        ,
                                   pImportDesc->Name  ) ;
        if ( 0 == _stricmp ( szCurrMod , szImportMod ) )
        {
            // Found it.
            break ;
        }
        // Look at the next one.
        pImportDesc++ ;
    }

    // If the name is NULL, then the module is not imported.
    if ( NULL == pImportDesc->Name )
    {
        return ( NULL ) ;
    }

    // All OK, Jumpmaster!
    return ( pImportDesc ) ;

}
/*----------------------------------------------------------------------
FUNCTION        :   NT4GetLoadedModules
DISCUSSION      :
    The NT4 specific version of GetLoadedModules.  This function assumes
that GetLoadedModules does the work to validate the parameters.
PARAMETERS      :
    dwPID        - The process ID to look into.
    uiCount      - The number of slots in the paModArray buffer.  If
                   this value is 0, then the return value will be TRUE
                   and pdwRealCount will hold the number of items
                   needed.
    paModArray   - The array to place the HMODULES into.  If this buffer
                   is too small to hold the result and uiCount is not
                   zero, then FALSE is returned, but pdwRealCount will
                   be the real number of items needed.
    pdwRealCount - The count of items needed in paModArray, if uiCount
                   is zero, or the real number of items in paModArray.
RETURNS         :
    FALSE - There was a problem, check GetLastError.
    TRUE  - The function succeeded.  See the parameter discussion for
            the output parameters.
----------------------------------------------------------------------*/
BOOL NT4GetLoadedModules ( DWORD     dwPID        ,
                           UINT      uiCount      ,
                           HMODULE * paModArray   ,
                           LPDWORD   pdwRealCount   )
{

    // Initialize PSAPI.DLL, if needed.
    if ( FALSE == InitPSAPI ( ) )
    {
        ASSERT ( FALSE ) ;
        SetLastErrorEx ( ERROR_DLL_INIT_FAILED , SLE_ERROR ) ;
        return ( FALSE ) ;
    }

    // Convert the process ID into a process handle.
    HANDLE hProc = OpenProcess ( PROCESS_QUERY_INFORMATION |
                                    PROCESS_VM_READ         ,
                                 FALSE                      ,
                                 dwPID                       ) ;
    ASSERT ( NULL != hProc ) ;
    if ( NULL == hProc )
    {
        TRACE1 ( "Unable to OpenProcess on %08X\n" , dwPID ) ;
        return ( FALSE ) ;
    }

    // Now get the modules for the specified process.
    ASSERT ( NULL != g_pEnumProcessModules ) ;
    // Because of possible DLL unload order differences, make sure that
    //  PSAPI.DLL is still loaded in case this function is called during
    //  shutdown.
    ASSERT ( FALSE == IsBadCodePtr ( (FARPROC)g_pEnumProcessModules ) );
    if ( TRUE == IsBadCodePtr ( (FARPROC)g_pEnumProcessModules ) )
    {
        TRACE0 ( "PSAPI.DLL has been unloaded on us!\n" ) ;

        // Close the process handle used.
        VERIFY ( CloseHandle ( hProc ) ) ;

        SetLastErrorEx ( ERROR_INVALID_DLL , SLE_ERROR ) ;

        return ( FALSE ) ;
    }

    DWORD dwTotal = 0 ;
    BOOL bRet = g_pEnumProcessModules ( hProc                        ,
                                        paModArray                   ,
                                        uiCount * sizeof ( HMODULE ) ,
                                        &dwTotal                      );

    // Close the process handle used.
    VERIFY ( CloseHandle ( hProc ) ) ;

    // Convert the count from bytes to HMODULE values.
    *pdwRealCount = dwTotal / sizeof ( HMODULE ) ;

    // If bRet was FALSE, and the user was not just asking for the
    //  total, there was a problem.
    if ( ( ( FALSE == bRet ) && ( uiCount > 0 ) ) || ( 0 == dwTotal ) )
    {
        ASSERT ( FALSE ) ;
        TRACE0 ( "EnumProcessModules failed!\n" ) ;
        return ( FALSE ) ;
    }

    // If the total returned in pdwRealCount is larger than the value in
    //  uiCount, then return an error.  If uiCount is zero, then it is
    //  not an error.
    if ( ( *pdwRealCount > uiCount ) && ( uiCount > 0 ) )
    {
        ASSERT ( FALSE ) ;
        TRACE0 ( "Buffer is too small in NT4GetLoadedModules!\n" ) ;
        SetLastErrorEx ( ERROR_INSUFFICIENT_BUFFER , SLE_ERROR ) ;
        return ( FALSE ) ;
    }

    // All OK, Jumpmaster!
    SetLastError ( ERROR_SUCCESS ) ;
    return ( TRUE ) ;
}
Exemplo n.º 14
0
BOOL	WINAPI
AnimatePalette(HPALETTE hPalette,
	UINT uPaletteIndex, UINT uNumPaletteEntries,
	const PALETTEENTRY *lpPaletteEntries)
{
	LPPALETTE lpPalette;
	LPLOGPALETTE lpLogPalette;
	UINT u, uAnimatePaletteIndex;
	BYTE r, g;
	BOOL bSuccess = TRUE;

	APISTR((LF_APICALL, 
	"AnimatePalette(HPALETTE=%x,UINT=%x,UINT=%x,PALETTEENTRY *%p)\n",
		hPalette, uPaletteIndex, uNumPaletteEntries,
		lpPaletteEntries));

	/* (UNDOCUMENTED) null palette handle ==> animate system palette */
	if (!hPalette)
	{
		for (u = uAnimatePaletteIndex = 0; u < uNumPaletteEntries;
		     u++, uAnimatePaletteIndex++)
		{
			if (!(lpPaletteEntries[u].peFlags & PC_RESERVED))
				continue;
			DRVCALL_COLORS(PLH_ANIMATEPALETTE, 0,
				uAnimatePaletteIndex, lpPaletteEntries + u);
		}

		APISTR((LF_APIRET, "AnimatePalette: returns BOOL TRUE\n"));
		return (TRUE);
	}

	ASSERT_PALETTE(lpPalette, hPalette, FALSE);

	if (!(lpLogPalette = lpPalette->lpLogPalette)
	 || (uPaletteIndex >= lpLogPalette->palNumEntries)
	 || (uPaletteIndex + uNumPaletteEntries > lpLogPalette->palNumEntries)
	 || !lpPaletteEntries)
	{
		UNLOCK_PALETTE(hPalette);
		SetLastErrorEx(1, 0);
		APISTR((LF_APIRET, "AnimatePalette: returns BOOL FALSE\n"));
		return (FALSE);
	}

	for (u = 0; u < uNumPaletteEntries; u++)
	{
		if (!(lpLogPalette->palPalEntry[uPaletteIndex+u].peFlags &
			PC_RESERVED))
		{
			continue;
		}
		if (!(lpLogPalette->palPalEntry[uPaletteIndex+u].peFlags &
			PC_EXPLICIT))
		{
			continue;
		}
		r = lpLogPalette->palPalEntry[uPaletteIndex+u].peRed;
		g = lpLogPalette->palPalEntry[uPaletteIndex+u].peGreen;
		uAnimatePaletteIndex = r | (g << 8);
		if (uAnimatePaletteIndex == 0)
		{
			continue;
		}
		else
		{
			bSuccess = DRVCALL_COLORS(PLH_ANIMATEPALETTE, 0,
				uAnimatePaletteIndex, lpPaletteEntries + u);
		}
	}

	UNLOCK_PALETTE(hPalette);

	APISTR((LF_APIRET, "AnimatePalette: returns BOOL %d\n",bSuccess));
	return (bSuccess);

}
Exemplo n.º 15
0
DWORD
lsd_display_realizepal(WORD wMsg,
	LPDC lpDC,
	DWORD dwParam,
	LPLSDS_PARAMS lpParam)
{
	LPPALETTE lpPalette;
	LPLOGPALETTE lpLogPalette;
	LPUINT lpSystemPaletteIndex;
	BOOL bForegroundPalette, bInitSystemPalette;
	UINT u;

	APISTR((LF_API, "lsd_display_realizepal: wMsg %d lpDC %p\n",
		wMsg, lpDC));

	ASSERT_PALETTE(lpPalette, lpDC->hPalette, GDI_ERROR);

	if (!(lpLogPalette = lpPalette->lpLogPalette))
	{
		SetLastErrorEx(1, 0);
		return (DWORD)((UINT) GDI_ERROR);
	}

	if (!(lpSystemPaletteIndex = (LPUINT)
		WinRealloc(lpDC->lpSystemPaletteIndex,
		(lpLogPalette->palNumEntries + 1) * sizeof(UINT))))
	{
		SetLastErrorEx(1, 0);
		return (DWORD)((UINT) GDI_ERROR);
	}

	if (0)
	{
		LOGSTR((LF_LOG, "lsd_display_realizepal:"
			" realizing foreground palette\n"));
/*
		DRVCALL_COLORS(PLG_,
*/


	}
	bForegroundPalette = TRUE;



/* SEND WM_PALETTECHANGED here */
/* OR let SetFocus() send WM_PALETTE... */


	for (u = 0; u < lpLogPalette->palNumEntries; u++)
	{
		bInitSystemPalette = ((u == 0) && (bForegroundPalette == TRUE))
			? TRUE : FALSE;
		lpSystemPaletteIndex[u] = (UINT)
			DRVCALL_COLORS(PLH_SETSYSTEMPALETTE,
				(DWORD) lpDC->lpDrvData,
				(DWORD) bInitSystemPalette,
				(LPPALETTEENTRY)
					&(lpLogPalette->palPalEntry[u]));
		LOGSTR((LF_LOG, "lsd_display_realizepal:\n"
			" palette index [%d] rgb (%d, %d, %d) flags %d"
			" <-> system palette index [%d]\n", u,
			lpLogPalette->palPalEntry[u].peRed,
			lpLogPalette->palPalEntry[u].peGreen,
			lpLogPalette->palPalEntry[u].peBlue,
			lpLogPalette->palPalEntry[u].peFlags,
			lpSystemPaletteIndex[u]));
	}
	lpDC->lpSystemPaletteIndex = lpSystemPaletteIndex;

	lpPalette->fIsRealized = TRUE;

	UNLOCK_PALETTE(hPalette);

	return (u);

}
Exemplo n.º 16
0
/*----------------------------------------------------------------------
FUNCTION        :   InitTOOLHELP32
DISCUSSION      :
    Retrieves the function pointers needed to access the tool help
routines.  Since this code is supposed to work on NT4, it cannot link
to the non-existant addresses in KERNEL32.DLL.
    This is pretty much lifter right from the MSDN.
PARAMETERS      :
    None.
RETURNS         :
    TRUE  - Everything initialized properly.
    FALSE - There was a problem.
----------------------------------------------------------------------*/
static BOOL InitTOOLHELP32 ( void )
{
    if ( TRUE == g_bInitialized )
    {
        return ( TRUE ) ;
    }

    BOOL      bRet    = FALSE ;
    HINSTANCE hKernel = NULL  ;

    // Obtain the module handle of the kernel to retrieve addresses of
    // the tool helper functions.
    hKernel = GetModuleHandleA ( "KERNEL32.DLL" ) ;
    ASSERT ( NULL != hKernel ) ;

    if ( NULL != hKernel )
    {
        g_pCreateToolhelp32Snapshot =
           (CREATESNAPSHOT)GetProcAddress ( hKernel ,
                                            "CreateToolhelp32Snapshot");
        ASSERT ( NULL != g_pCreateToolhelp32Snapshot ) ;

        g_pModule32First = (MODULEWALK)GetProcAddress (hKernel ,
                                                       "Module32First");
        ASSERT ( NULL != g_pModule32First ) ;

        g_pModule32Next = (MODULEWALK)GetProcAddress (hKernel        ,
                                                      "Module32Next"  );
        ASSERT ( NULL != g_pModule32Next ) ;

        g_pProcess32First =
                (PROCESSWALK)GetProcAddress ( hKernel          ,
                                              "Process32First"  ) ;
        ASSERT ( NULL != g_pProcess32First ) ;

        g_pProcess32Next =
                (PROCESSWALK)GetProcAddress ( hKernel         ,
                                              "Process32Next" ) ;
        ASSERT ( NULL != g_pProcess32Next ) ;

        g_pThread32First =
                (THREADWALK)GetProcAddress ( hKernel         ,
                                             "Thread32First"  ) ;
        ASSERT ( NULL != g_pThread32First ) ;

        g_pThread32Next =
                (THREADWALK)GetProcAddress ( hKernel        ,
                                             "Thread32Next"  ) ;
        ASSERT ( NULL != g_pThread32Next ) ;

        // All addresses must be non-NULL to be successful.  If one of
        // these addresses is NULL, one of the needed lists cannot be
        // walked.

        bRet =  g_pModule32First            &&
                g_pModule32Next             &&
                g_pProcess32First           &&
                g_pProcess32Next            &&
                g_pThread32First            &&
                g_pThread32Next             &&
                g_pCreateToolhelp32Snapshot    ;
    }
    else
    {
        // Could not get the module handle of kernel.
        SetLastErrorEx ( ERROR_DLL_INIT_FAILED , SLE_ERROR ) ;
        bRet = FALSE ;
    }

    ASSERT ( TRUE == bRet ) ;

    if ( TRUE == bRet )
    {
        // All OK, Jumpmaster!
        g_bInitialized = TRUE ;
    }
    return ( bRet ) ;
}
Exemplo n.º 17
0
DWORD __stdcall TLHELPGetModuleFileNameEx ( DWORD     dwPID        ,
                                            HANDLE    /*hProcess*/ ,
                                            HMODULE   hModule      ,
                                            LPTSTR    szFilename   ,
                                            DWORD     nSize         )
{
    if ( FALSE == InitTOOLHELP32 ( ) )
    {
        ASSERT ( !"InitTOOLHELP32 failed" ) ;
        SetLastErrorEx ( ERROR_DLL_INIT_FAILED , SLE_ERROR ) ;
        return ( 0 ) ;
    }

    // The snapshot handle.
    HANDLE        hModSnap     = NULL ;
    // The module structure.
    MODULEENTRY32 stME32              ;

    // Get the snapshot for the specified process.
    hModSnap = g_pCreateToolhelp32Snapshot ( TH32CS_SNAPMODULE ,
                                             dwPID              ) ;
    ASSERT ( INVALID_HANDLE_VALUE != hModSnap ) ;
    if ( INVALID_HANDLE_VALUE == hModSnap )
    {
        TRACE1 ( "Unable to get module snapshot for %08X\n" , dwPID ) ;
        return ( 0 ) ;
    }

    FillMemory ( &stME32 , sizeof ( MODULEENTRY32 ), NULL ) ;
    stME32.dwSize = sizeof ( MODULEENTRY32 ) ;

    DWORD dwRet = 0 ;

    // Start getting the module values.
    if ( TRUE == g_pModule32First ( hModSnap , &stME32 ) )
    {
        do
        {
            // Is this the one?
            if ( hModule == stME32.hModule )
            {
                DWORD dwLen = _tcslen ( stME32.szExePath ) ;
                if ( dwLen > nSize )
                {
                    _tcsncpy ( szFilename       ,
                               stME32.szExePath ,
                               nSize - 1         ) ;
                    szFilename[ nSize ] = _T ( '\0' ) ;
                    dwRet = nSize ;
                }
                else
                {
                    _tcscpy ( szFilename , stME32.szExePath ) ;
                    dwRet = dwLen ;
                }
                break ;
            }
        }
        while ( ( TRUE == g_pModule32Next ( hModSnap , &stME32 ) ) ) ;
    }
    else
    {
        DWORD dwLastErr = GetLastError ( ) ;
        ASSERT ( !"Failed to get first module!\n" ) ;
        SetLastErrorEx ( dwLastErr , SLE_ERROR ) ;
        return ( 0 ) ;
    }

    // Close the snapshot handle.
    VERIFY ( CloseHandle ( hModSnap ) ) ;

    // All OK, Jumpmaster!
    SetLastError ( ERROR_SUCCESS ) ;
    return ( dwRet ) ;

}
Exemplo n.º 18
0
/*----------------------------------------------------------------------
FUNCTION        :   TLHELPGetLoadedModules
DISCUSSION      :
    The TOOLHELP32 specific version of GetLoadedModules.  This function
assumes that GetLoadedModules does the work to validate the parameters.
PARAMETERS      :
    dwPID        - The process ID to look into.
    uiCount      - The number of slots in the paModArray buffer.  If
                   this value is 0, then the return value will be TRUE
                   and pdwRealCount will hold the number of items
                   needed.
    paModArray   - The array to place the HMODULES into.  If this buffer
                   is too small to hold the result and uiCount is not
                   zero, then FALSE is returned, but pdwRealCount will
                   be the real number of items needed.
    pdwRealCount - The count of items needed in paModArray, if uiCount
                   is zero, or the real number of items in paModArray.
RETURNS         :
    FALSE - There was a problem, check GetLastError.
    TRUE  - The function succeeded.  See the parameter discussion for
            the output parameters.
----------------------------------------------------------------------*/
BOOL __stdcall TLHELPGetLoadedModules ( DWORD     dwPID        ,
                                        UINT      uiCount      ,
                                        HMODULE * paModArray   ,
                                        LPDWORD   pdwRealCount   )
{

    // Always set pdwRealCount to a know value before anything else.
    *pdwRealCount = 0 ;

    if ( FALSE == InitTOOLHELP32 ( ) )
    {
        ASSERT ( !"InitTOOLHELP32 failed" ) ;
        SetLastErrorEx ( ERROR_DLL_INIT_FAILED , SLE_ERROR ) ;
        return ( FALSE ) ;
    }

    // The snapshot handle.
    HANDLE        hModSnap     = NULL ;
    // The module structure.
    MODULEENTRY32 stME32              ;
    // A flag kept to report if the buffer was too small.
    BOOL          bBuffToSmall = FALSE ;


    // Get the snapshot for the specified process.
    hModSnap = g_pCreateToolhelp32Snapshot ( TH32CS_SNAPMODULE ,
                                             dwPID              ) ;
    ASSERT ( INVALID_HANDLE_VALUE != hModSnap ) ;
    if ( INVALID_HANDLE_VALUE == hModSnap )
    {
        TRACE1 ( "Unable to get module snapshot for %08X\n" , dwPID ) ;
        return ( FALSE ) ;
    }

    FillMemory ( &stME32 , sizeof ( MODULEENTRY32 ), NULL ) ;
    stME32.dwSize = sizeof ( MODULEENTRY32 ) ;

    // Start getting the module values.
    if ( TRUE == g_pModule32First ( hModSnap , &stME32 ) )
    {
        do
        {
            // If uiCount is not zero, copy values.
            if ( 0 != uiCount )
            {
                // If the passed in buffer is to small, set the flag.
                // This is so we match the functionality of the NT4
                // version of this function which will return the
                // correct total needed.
                if ( ( TRUE == bBuffToSmall     ) ||
                     ( *pdwRealCount == uiCount )   )
                {
                    bBuffToSmall = TRUE ;
                    break ;
                }
                else
                {
                    // Copy this value in.
                    paModArray[ *pdwRealCount ] =
                                         (HINSTANCE)stME32.modBaseAddr ;
                }
            }
            // Bump up the real total count.
            *pdwRealCount += 1 ;
        }
        while ( ( TRUE == g_pModule32Next ( hModSnap , &stME32 ) ) ) ;
    }
    else
    {
        DWORD dwLastErr = GetLastError ( ) ;
        ASSERT ( !"Failed to get first module!\n" ) ;
        SetLastErrorEx ( dwLastErr , SLE_ERROR ) ;
        return ( FALSE ) ;
    }

    // Close the snapshot handle.
    VERIFY ( CloseHandle ( hModSnap ) ) ;

    // Check if the buffer was too small.
    if ( TRUE == bBuffToSmall )
    {
        ASSERT ( !"Buffer to small in TLHELPGetLoadedModules\n" ) ;
        SetLastErrorEx ( ERROR_INSUFFICIENT_BUFFER , SLE_ERROR ) ;
        return ( FALSE ) ;
    }

    // All OK, Jumpmaster!
    SetLastError ( ERROR_SUCCESS ) ;
    return ( TRUE ) ;
}
BOOL  __stdcall
                        HookOrdinalExport ( HMODULE hModule     ,
                                            LPCTSTR szImportMod ,
                                            DWORD   dwOrdinal   ,
                                            PROC    pHookFunc   ,
                                            PROC *  ppOrigAddr   )
{
    // Assert the parameters.
    ASSERT ( NULL != hModule ) ;
    ASSERT ( FALSE == IsBadStringPtr ( szImportMod , MAX_PATH ) ) ;
    ASSERT ( 0 != dwOrdinal ) ;
    ASSERT ( FALSE == IsBadCodePtr ( pHookFunc ) ) ;

    // Perform the error checking for the parameters.
    if ( ( NULL  == hModule                                   ) ||
         ( TRUE  == IsBadStringPtr ( szImportMod , MAX_PATH ) ) ||
         ( 0     == dwOrdinal                                 ) ||
         ( TRUE  == IsBadCodePtr ( pHookFunc )                )   )
    {
        SetLastErrorEx ( ERROR_INVALID_PARAMETER , SLE_ERROR ) ;
        return ( FALSE ) ;
    }

    if ( NULL != ppOrigAddr )
    {
        ASSERT ( FALSE ==
                     IsBadWritePtr ( ppOrigAddr , sizeof ( PROC ) ) ) ;
        if ( TRUE == IsBadWritePtr ( ppOrigAddr , sizeof ( PROC ) ) )
        {
            SetLastErrorEx ( ERROR_INVALID_PARAMETER , SLE_ERROR ) ;
            return ( FALSE ) ;
        }
    }

    // Get the specific import descriptor.
    PIMAGE_IMPORT_DESCRIPTOR pImportDesc =
                    GetNamedImportDescriptor ( hModule , szImportMod ) ;

    if ( NULL == pImportDesc )
    {
        // The requested module wasn't imported. Don't return an error.
        return ( TRUE ) ;
    }

    // Get the original thunk information for this DLL. I can't use
    // the thunk information stored in pImportDesc->FirstThunk
    // because the loader has already changed that array to fix up
    // all the imports. The original thunk gives me access to the
    // function names.
    PIMAGE_THUNK_DATA pOrigThunk =
                        MakePtr ( PIMAGE_THUNK_DATA       ,
                                  hModule                 ,
                                  pImportDesc->OriginalFirstThunk  ) ;
    // Get the array that pImportDesc->FirstThunk points to because I'll
    // do the actual hooking there.
    PIMAGE_THUNK_DATA pRealThunk = MakePtr ( PIMAGE_THUNK_DATA       ,
                                             hModule                 ,
                                             pImportDesc->FirstThunk  );

    // The flag is going to be set from the thunk, so make it
    // easier to look up.
    DWORD dwCompareOrdinal = IMAGE_ORDINAL_FLAG | dwOrdinal ;

    // Loop through and find the function to hook.
    while ( NULL != pOrigThunk->u1.Function )
    {
        // Look only at functions that are imported by ordinal value,
        // not those that are imported by name.
        if (  IMAGE_ORDINAL_FLAG ==
                        ( pOrigThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG ))
        {
            // Did I find the function to hook?
            if ( dwCompareOrdinal == pOrigThunk->u1.Ordinal )
            {
                // I found the function to hook. Now I need to change
                // the memory protection to writable before I overwrite
                // the function pointer. Note that I'm now writing into
                // the real thunk area!
                MEMORY_BASIC_INFORMATION mbi_thunk ;

                VirtualQuery ( pRealThunk                          ,
                               &mbi_thunk                          ,
                               sizeof ( MEMORY_BASIC_INFORMATION )  ) ;

                if ( FALSE == VirtualProtect ( mbi_thunk.BaseAddress ,
                                               mbi_thunk.RegionSize  ,
                                               PAGE_READWRITE        ,
                                               &mbi_thunk.Protect     ))
                {
                    ASSERT ( !"VirtualProtect failed!" ) ;
                    // There's nothing I can do but fail the function.
                    SetLastErrorEx ( ERROR_INVALID_PARAMETER ,
                                     SLE_ERROR                ) ;
                    return ( FALSE ) ;
                }

                // Save the original address if requested.
                if ( NULL != ppOrigAddr )
                {
                    *ppOrigAddr = (PROC)pRealThunk->u1.Function ;
                }

                // Microsoft has two different definitions of the
                // PIMAGE_THUNK_DATA fields as they are moving to
                // support Win64. The W2K RC2 Platform SDK is the
                // latest header, so I'll use that one and force the
                // Visual C++ 6 Service Pack 3 headers to deal with it.

                // Hook the function.
                DWORD * pTemp = (DWORD*)&pRealThunk->u1.Function ;
                *pTemp = (DWORD)(pHookFunc) ;

                DWORD dwOldProtect ;

                // Change the protection back to what it was before I
                // overwrote the function pointer.
                VERIFY ( VirtualProtect ( mbi_thunk.BaseAddress ,
                                          mbi_thunk.RegionSize  ,
                                          mbi_thunk.Protect     ,
                                          &dwOldProtect          ) ) ;
                // Life is good.
                SetLastError ( ERROR_SUCCESS ) ;
                return ( TRUE ) ;
            }
        }
        // Increment both tables.
        pOrigThunk++ ;
        pRealThunk++ ;
    }

    // Nothing was hooked. Technically, this isn't an error. It just
    // means that the module is imported but the function isn't.
    SetLastError ( ERROR_SUCCESS ) ;
    return ( FALSE ) ;
}