| 1996 | } |
| 1997 | |
| 1998 | LONG WINAPI DetourAttachEx(_Inout_ PVOID *ppPointer, |
| 1999 | _In_ PVOID pDetour, |
| 2000 | _Out_opt_ PDETOUR_TRAMPOLINE *ppRealTrampoline, |
| 2001 | _Out_opt_ PVOID *ppRealTarget, |
| 2002 | _Out_opt_ PVOID *ppRealDetour) |
| 2003 | { |
| 2004 | LONG error = NO_ERROR; |
| 2005 | |
| 2006 | if (ppRealTrampoline != NULL) { |
| 2007 | *ppRealTrampoline = NULL; |
| 2008 | } |
| 2009 | if (ppRealTarget != NULL) { |
| 2010 | *ppRealTarget = NULL; |
| 2011 | } |
| 2012 | if (ppRealDetour != NULL) { |
| 2013 | *ppRealDetour = NULL; |
| 2014 | } |
| 2015 | if (pDetour == NULL) { |
| 2016 | DETOUR_TRACE(("empty detour\n")); |
| 2017 | return ERROR_INVALID_PARAMETER; |
| 2018 | } |
| 2019 | |
| 2020 | if (s_nPendingThreadId != (LONG)GetCurrentThreadId()) { |
| 2021 | DETOUR_TRACE(("transaction conflict with thread id=%ld\n", s_nPendingThreadId)); |
| 2022 | return ERROR_INVALID_OPERATION; |
| 2023 | } |
| 2024 | |
| 2025 | // If any of the pending operations failed, then we don't need to do this. |
| 2026 | if (s_nPendingError != NO_ERROR) { |
| 2027 | DETOUR_TRACE(("pending transaction error=%ld\n", s_nPendingError)); |
| 2028 | return s_nPendingError; |
| 2029 | } |
| 2030 | |
| 2031 | if (ppPointer == NULL) { |
| 2032 | DETOUR_TRACE(("ppPointer is null\n")); |
| 2033 | return ERROR_INVALID_HANDLE; |
| 2034 | } |
| 2035 | if (*ppPointer == NULL) { |
| 2036 | error = ERROR_INVALID_HANDLE; |
| 2037 | s_nPendingError = error; |
| 2038 | s_ppPendingError = ppPointer; |
| 2039 | DETOUR_TRACE(("*ppPointer is null (ppPointer=%p)\n", ppPointer)); |
| 2040 | DETOUR_BREAK(); |
| 2041 | return error; |
| 2042 | } |
| 2043 | |
| 2044 | PBYTE pbTarget = (PBYTE)*ppPointer; |
| 2045 | PDETOUR_TRAMPOLINE pTrampoline = NULL; |
| 2046 | DetourOperation *o = NULL; |
| 2047 | |
| 2048 | #ifdef DETOURS_IA64 |
| 2049 | PPLABEL_DESCRIPTOR ppldDetour = (PPLABEL_DESCRIPTOR)pDetour; |
| 2050 | PPLABEL_DESCRIPTOR ppldTarget = (PPLABEL_DESCRIPTOR)pbTarget; |
| 2051 | PVOID pDetourGlobals = NULL; |
| 2052 | PVOID pTargetGlobals = NULL; |
| 2053 | |
| 2054 | pDetour = (PBYTE)DetourCodeFromPointer(ppldDetour, &pDetourGlobals); |
| 2055 | pbTarget = (PBYTE)DetourCodeFromPointer(ppldTarget, &pTargetGlobals); |
no test coverage detected
searching dependent graphs…