microsoft / Detours

Detours is a software package for monitoring and instrumenting API calls on Windows. It is distributed in source code form.
MIT License
5.02k stars 981 forks source link

Feature: Annotate API's with [[nodiscard]] if the compiler supports it. #170

Open bgianfo opened 3 years ago

bgianfo commented 3 years ago

It would be nice if the functions which return values like DetourAttach(..) were marked as [[nodiscard]] to catch bugs where the caller does not properly observe the return value of the operation.

You can feature detect [[nodiscard]] support by using the __has_cpp_attribute(nodiscard) macro.

bgianfo commented 3 years ago

Here's a preliminary diff, it needs to be cleaned up as some APIs don't really make sense being annotated as [[nodiscard]] as most callers don't care if they fail.

diff --git a/samples/setdll/setdll.cpp b/samples/setdll/setdll.cpp
index fd39b03..9c45cbb 100644
--- a/samples/setdll/setdll.cpp
+++ b/samples/setdll/setdll.cpp
@@ -67,7 +67,14 @@ BOOL DoesDllExportOrdinal1(PCHAR pszDllPath)
     }

     BOOL validFlag = FALSE;
-    DetourEnumerateExports(hDll, &validFlag, ExportCallback);
+    if (!DetourEnumerateExports(hDll, &validFlag, ExportCallback)) {
+        printf("setdll.exe: DetourEnumerateExports(%s) failed with error %ld.\n",
+               pszDllPath,
+               GetLastError());
+        FreeLibrary(hDll);
+        return FALSE;
+    }
+
     FreeLibrary(hDll);
     return validFlag;
 }
@@ -170,7 +177,7 @@ BOOL SetFile(PCHAR pszPath)
     {
         BOOL bAddedDll = FALSE;

-        DetourBinaryResetImports(pBinary);
+        (void)DetourBinaryResetImports(pBinary);

         if (!s_fRemove) {
             if (!DetourBinaryEditImports(pBinary,
diff --git a/samples/simple/simple.cpp b/samples/simple/simple.cpp
index bc902f1..eb01fab 100644
--- a/samples/simple/simple.cpp
+++ b/samples/simple/simple.cpp
@@ -39,15 +39,15 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
     }

     if (dwReason == DLL_PROCESS_ATTACH) {
-        DetourRestoreAfterWith();
+        (void)DetourRestoreAfterWith();

         printf("simple" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
                " Starting.\n");
         fflush(stdout);

-        DetourTransactionBegin();
-        DetourUpdateThread(GetCurrentThread());
-        DetourAttach(&(PVOID&)TrueSleepEx, TimedSleepEx);
+        (void)DetourTransactionBegin();
+        (void)DetourUpdateThread(GetCurrentThread());
+        (void)DetourAttach(&(PVOID&)TrueSleepEx, TimedSleepEx);
         error = DetourTransactionCommit();

         if (error == NO_ERROR) {
@@ -60,9 +60,9 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
         }
     }
     else if (dwReason == DLL_PROCESS_DETACH) {
-        DetourTransactionBegin();
-        DetourUpdateThread(GetCurrentThread());
-        DetourDetach(&(PVOID&)TrueSleepEx, TimedSleepEx);
+        (void)DetourTransactionBegin();
+        (void)DetourUpdateThread(GetCurrentThread());
+        (void)DetourDetach(&(PVOID&)TrueSleepEx, TimedSleepEx);
         error = DetourTransactionCommit();

         printf("simple" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
diff --git a/samples/slept/dslept.cpp b/samples/slept/dslept.cpp
index 3929820..404c43b 100644
--- a/samples/slept/dslept.cpp
+++ b/samples/slept/dslept.cpp
@@ -53,9 +53,9 @@ int WINAPI TimedEntryPoint(VOID)
     TrueSleepEx = (DWORD (WINAPI *)(DWORD, BOOL))
         DetourFindFunction("kernel32.dll", "SleepEx");

-    DetourTransactionBegin();
-    DetourUpdateThread(GetCurrentThread());
-    DetourAttach(&(PVOID&)TrueSleepEx, TimedSleepEx);
+    (void)DetourTransactionBegin();
+    (void)DetourUpdateThread(GetCurrentThread());
+    (void)DetourAttach(&(PVOID&)TrueSleepEx, TimedSleepEx);
     error = DetourTransactionCommit();

     if (error == NO_ERROR) {
@@ -90,7 +90,7 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
     }

     if (dwReason == DLL_PROCESS_ATTACH) {
-        DetourRestoreAfterWith();
+        (void)DetourRestoreAfterWith();

         printf("dslept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: "
                " Starting.\n");
@@ -104,9 +104,9 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)

         Verify("EntryPoint", RawEntryPoint);

-        DetourTransactionBegin();
-        DetourUpdateThread(GetCurrentThread());
-        DetourAttach(&(PVOID&)TrueEntryPoint, TimedEntryPoint);
+        (void)DetourTransactionBegin();
+        (void)DetourUpdateThread(GetCurrentThread());
+        (void)DetourAttach(&(PVOID&)TrueEntryPoint, TimedEntryPoint);
         error = DetourTransactionCommit();

         Verify("EntryPoint after attach", RawEntryPoint);
@@ -122,12 +122,12 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
         }
     }
     else if (dwReason == DLL_PROCESS_DETACH) {
-        DetourTransactionBegin();
-        DetourUpdateThread(GetCurrentThread());
+        (void)DetourTransactionBegin();
+        (void)DetourUpdateThread(GetCurrentThread());
         if (TrueSleepEx != NULL) {
-            DetourDetach(&(PVOID&)TrueSleepEx, (PVOID)TimedSleepEx);
+            (void)DetourDetach(&(PVOID&)TrueSleepEx, (PVOID)TimedSleepEx);
         }
-        DetourDetach(&(PVOID&)TrueEntryPoint, TimedEntryPoint);
+        (void)DetourDetach(&(PVOID&)TrueEntryPoint, TimedEntryPoint);
         error = DetourTransactionCommit();

         printf("dslept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: "
diff --git a/samples/slept/sleepbed.cpp b/samples/slept/sleepbed.cpp
index 49b7934..528e734 100644
--- a/samples/slept/sleepbed.cpp
+++ b/samples/slept/sleepbed.cpp
@@ -57,9 +57,9 @@ int __cdecl main(void)
     printf("\n");
     fflush(stdout);

-    DetourTransactionBegin();
-    DetourUpdateThread(GetCurrentThread());
-    DetourAttach(&(PVOID&)TrueSleepEx, TimedSleepEx);
+    (void)DetourTransactionBegin();
+    (void)DetourUpdateThread(GetCurrentThread());
+    (void)DetourAttach(&(PVOID&)TrueSleepEx, TimedSleepEx);
     error = DetourTransactionCommit();

     if (error == NO_ERROR) {
@@ -88,9 +88,9 @@ int __cdecl main(void)
     UntimedSleepEx(1000, false);
     printf("sleepbed.exe: Done sleeping.\n\n");

-    DetourTransactionBegin();
-    DetourUpdateThread(GetCurrentThread());
-    DetourDetach(&(PVOID&)TrueSleepEx, TimedSleepEx);
+    (void)DetourTransactionBegin();
+    (void)DetourUpdateThread(GetCurrentThread());
+    (void)DetourDetach(&(PVOID&)TrueSleepEx, TimedSleepEx);
     error = DetourTransactionCommit();
     printf("sleepbed.exe: Removed SleepEx() detour (%d), slept %ld ticks.\n",
            error, dwSlept);
diff --git a/samples/slept/slept.cpp b/samples/slept/slept.cpp
index 5903295..f1e27f5 100644
--- a/samples/slept/slept.cpp
+++ b/samples/slept/slept.cpp
@@ -87,7 +87,7 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
     }

     if (dwReason == DLL_PROCESS_ATTACH) {
-        DetourRestoreAfterWith();
+        (void)DetourRestoreAfterWith();

         printf("slept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: "
                " Starting.\n");
@@ -100,9 +100,9 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
         printf("\n");
         fflush(stdout);

-        DetourTransactionBegin();
-        DetourUpdateThread(GetCurrentThread());
-        DetourAttach(&(PVOID&)TrueSleepEx, TimedSleepEx);
+        (void)DetourTransactionBegin();
+        (void)DetourUpdateThread(GetCurrentThread());
+        (void)DetourAttach(&(PVOID&)TrueSleepEx, TimedSleepEx);
         error = DetourTransactionCommit();

         if (error == NO_ERROR) {
@@ -115,9 +115,9 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
         }
     }
     else if (dwReason == DLL_PROCESS_DETACH) {
-        DetourTransactionBegin();
-        DetourUpdateThread(GetCurrentThread());
-        DetourDetach(&(PVOID&)TrueSleepEx, TimedSleepEx);
+        (void)DetourTransactionBegin();
+        (void)DetourUpdateThread(GetCurrentThread());
+        (void)DetourDetach(&(PVOID&)TrueSleepEx, TimedSleepEx);
         error = DetourTransactionCommit();
         printf("slept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: "
                " Removed SleepEx() detour (%ld), slept %ld ticks.\n", error, dwSlept);
diff --git a/src/detours.cpp b/src/detours.cpp
index 34f2458..463796a 100644
--- a/src/detours.cpp
+++ b/src/detours.cpp
@@ -1668,7 +1668,7 @@ LONG WINAPI DetourTransactionCommitEx(_Out_opt_ PVOID **pppFailedPointer)
     // If any of the pending operations failed, then we abort the whole transaction.
     if (s_nPendingError != NO_ERROR) {
         DETOUR_BREAK();
-        DetourTransactionAbort();
+        (void)DetourTransactionAbort();
         return s_nPendingError;
     }

diff --git a/src/detours.h b/src/detours.h
index 45e4c09..9b9613d 100644
--- a/src/detours.h
+++ b/src/detours.h
@@ -361,7 +361,15 @@ typedef struct  _GUID
 #define ARRAYSIZE(x)    (sizeof(x)/sizeof(x[0]))
 #endif

+
+/////////////////////////////////////////////////////// C++ Feature Macros.
 //
+#if defined(__cplusplus) && defined(__has_cpp_attribute) && __has_cpp_attribute(nodiscard)
+#define DETOURS_NODISCARD [[nodiscard]]
+#else
+#define DETOURS_NODISCARD
+#endif
+
 //////////////////////////////////////////////////////////////////////////////

 #ifdef __cplusplus
@@ -549,60 +557,99 @@ typedef VOID * PDETOUR_LOADED_BINARY;

 //////////////////////////////////////////////////////////// Transaction APIs.
 //
+DETOURS_NODISCARD
 LONG WINAPI DetourTransactionBegin(VOID);
+
+DETOURS_NODISCARD
 LONG WINAPI DetourTransactionAbort(VOID);
+
+DETOURS_NODISCARD
 LONG WINAPI DetourTransactionCommit(VOID);
+
+DETOURS_NODISCARD
 LONG WINAPI DetourTransactionCommitEx(_Out_opt_ PVOID **pppFailedPointer);

+DETOURS_NODISCARD
 LONG WINAPI DetourUpdateThread(_In_ HANDLE hThread);

+DETOURS_NODISCARD
 LONG WINAPI DetourAttach(_Inout_ PVOID *ppPointer,
                          _In_ PVOID pDetour);

+DETOURS_NODISCARD
 LONG WINAPI DetourAttachEx(_Inout_ PVOID *ppPointer,
                            _In_ PVOID pDetour,
                            _Out_opt_ PDETOUR_TRAMPOLINE *ppRealTrampoline,
                            _Out_opt_ PVOID *ppRealTarget,
                            _Out_opt_ PVOID *ppRealDetour);

+DETOURS_NODISCARD
 LONG WINAPI DetourDetach(_Inout_ PVOID *ppPointer,
                          _In_ PVOID pDetour);

+DETOURS_NODISCARD
 BOOL WINAPI DetourSetIgnoreTooSmall(_In_ BOOL fIgnore);
+
+DETOURS_NODISCARD
 BOOL WINAPI DetourSetRetainRegions(_In_ BOOL fRetain);
+
+DETOURS_NODISCARD
 PVOID WINAPI DetourSetSystemRegionLowerBound(_In_ PVOID pSystemRegionLowerBound);
+
+DETOURS_NODISCARD
 PVOID WINAPI DetourSetSystemRegionUpperBound(_In_ PVOID pSystemRegionUpperBound);

 ////////////////////////////////////////////////////////////// Code Functions.
 //
+DETOURS_NODISCARD
 PVOID WINAPI DetourFindFunction(_In_ LPCSTR pszModule,
                                 _In_ LPCSTR pszFunction);
+
+DETOURS_NODISCARD
 PVOID WINAPI DetourCodeFromPointer(_In_ PVOID pPointer,
                                    _Out_opt_ PVOID *ppGlobals);
+
+DETOURS_NODISCARD
 PVOID WINAPI DetourCopyInstruction(_In_opt_ PVOID pDst,
                                    _Inout_opt_ PVOID *ppDstPool,
                                    _In_ PVOID pSrc,
                                    _Out_opt_ PVOID *ppTarget,
                                    _Out_opt_ LONG *plExtra);
+
+DETOURS_NODISCARD
 BOOL WINAPI DetourSetCodeModule(_In_ HMODULE hModule,
                                 _In_ BOOL fLimitReferencesToModule);
+
+DETOURS_NODISCARD
 PVOID WINAPI DetourAllocateRegionWithinJumpBounds(_In_ LPCVOID pbTarget,
                                                   _Out_ PDWORD pcbAllocatedSize);

 ///////////////////////////////////////////////////// Loaded Binary Functions.
 //
+DETOURS_NODISCARD
 HMODULE WINAPI DetourGetContainingModule(_In_ PVOID pvAddr);
+
+DETOURS_NODISCARD
 HMODULE WINAPI DetourEnumerateModules(_In_opt_ HMODULE hModuleLast);
+
+DETOURS_NODISCARD
 PVOID WINAPI DetourGetEntryPoint(_In_opt_ HMODULE hModule);
+
+DETOURS_NODISCARD
 ULONG WINAPI DetourGetModuleSize(_In_opt_ HMODULE hModule);
+
+DETOURS_NODISCARD
 BOOL WINAPI DetourEnumerateExports(_In_ HMODULE hModule,
                                    _In_opt_ PVOID pContext,
                                    _In_ PF_DETOUR_ENUMERATE_EXPORT_CALLBACK pfExport);
+
+DETOURS_NODISCARD
 BOOL WINAPI DetourEnumerateImports(_In_opt_ HMODULE hModule,
                                    _In_opt_ PVOID pContext,
                                    _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile,
                                    _In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK pfImportFunc);

+DETOURS_NODISCARD
 BOOL WINAPI DetourEnumerateImportsEx(_In_opt_ HMODULE hModule,
                                      _In_opt_ PVOID pContext,
                                      _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile,
@@ -611,6 +658,7 @@ BOOL WINAPI DetourEnumerateImportsEx(_In_opt_ HMODULE hModule,
 _Writable_bytes_(*pcbData)
 _Readable_bytes_(*pcbData)
 _Success_(return != NULL)
+DETOURS_NODISCARD
 PVOID WINAPI DetourFindPayload(_In_opt_ HMODULE hModule,
                                _In_ REFGUID rguid,
                                _Out_ DWORD *pcbData);
@@ -618,19 +666,23 @@ PVOID WINAPI DetourFindPayload(_In_opt_ HMODULE hModule,
 _Writable_bytes_(*pcbData)
 _Readable_bytes_(*pcbData)
 _Success_(return != NULL)
+DETOURS_NODISCARD
 PVOID WINAPI DetourFindPayloadEx(_In_ REFGUID rguid,
                                  _Out_ DWORD * pcbData);

+DETOURS_NODISCARD
 DWORD WINAPI DetourGetSizeOfPayloads(_In_opt_ HMODULE hModule);

 ///////////////////////////////////////////////// Persistent Binary Functions.
 //

+DETOURS_NODISCARD
 PDETOUR_BINARY WINAPI DetourBinaryOpen(_In_ HANDLE hFile);

 _Writable_bytes_(*pcbData)
 _Readable_bytes_(*pcbData)
 _Success_(return != NULL)
+DETOURS_NODISCARD
 PVOID WINAPI DetourBinaryEnumeratePayloads(_In_ PDETOUR_BINARY pBinary,
                                            _Out_opt_ GUID *pGuid,
                                            _Out_ DWORD *pcbData,
@@ -639,24 +691,38 @@ PVOID WINAPI DetourBinaryEnumeratePayloads(_In_ PDETOUR_BINARY pBinary,
 _Writable_bytes_(*pcbData)
 _Readable_bytes_(*pcbData)
 _Success_(return != NULL)
+DETOURS_NODISCARD
 PVOID WINAPI DetourBinaryFindPayload(_In_ PDETOUR_BINARY pBinary,
                                      _In_ REFGUID rguid,
                                      _Out_ DWORD *pcbData);

+
+DETOURS_NODISCARD
 PVOID WINAPI DetourBinarySetPayload(_In_ PDETOUR_BINARY pBinary,
                                     _In_ REFGUID rguid,
                                     _In_reads_opt_(cbData) PVOID pData,
                                     _In_ DWORD cbData);
+
+DETOURS_NODISCARD
 BOOL WINAPI DetourBinaryDeletePayload(_In_ PDETOUR_BINARY pBinary, _In_ REFGUID rguid);
+
+DETOURS_NODISCARD
 BOOL WINAPI DetourBinaryPurgePayloads(_In_ PDETOUR_BINARY pBinary);
+
+DETOURS_NODISCARD
 BOOL WINAPI DetourBinaryResetImports(_In_ PDETOUR_BINARY pBinary);
+
+DETOURS_NODISCARD
 BOOL WINAPI DetourBinaryEditImports(_In_ PDETOUR_BINARY pBinary,
                                     _In_opt_ PVOID pContext,
                                     _In_opt_ PF_DETOUR_BINARY_BYWAY_CALLBACK pfByway,
                                     _In_opt_ PF_DETOUR_BINARY_FILE_CALLBACK pfFile,
                                     _In_opt_ PF_DETOUR_BINARY_SYMBOL_CALLBACK pfSymbol,
                                     _In_opt_ PF_DETOUR_BINARY_COMMIT_CALLBACK pfCommit);
+
+DETOURS_NODISCARD
 BOOL WINAPI DetourBinaryWrite(_In_ PDETOUR_BINARY pBinary, _In_ HANDLE hFile);
+
 BOOL WINAPI DetourBinaryClose(_In_ PDETOUR_BINARY pBinary);

 /////////////////////////////////////////////////// Create Process & Load Dll.
@@ -685,6 +751,7 @@ typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEW)(
     _In_ LPSTARTUPINFOW lpStartupInfo,
     _Out_ LPPROCESS_INFORMATION lpProcessInformation);

+DETOURS_NODISCARD
 BOOL WINAPI DetourCreateProcessWithDllA(_In_opt_ LPCSTR lpApplicationName,
                                         _Inout_opt_ LPSTR lpCommandLine,
                                         _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
@@ -698,6 +765,7 @@ BOOL WINAPI DetourCreateProcessWithDllA(_In_opt_ LPCSTR lpApplicationName,
                                         _In_ LPCSTR lpDllName,
                                         _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA);

+DETOURS_NODISCARD
 BOOL WINAPI DetourCreateProcessWithDllW(_In_opt_ LPCWSTR lpApplicationName,
                                         _Inout_opt_ LPWSTR lpCommandLine,
                                         _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
@@ -719,6 +787,7 @@ BOOL WINAPI DetourCreateProcessWithDllW(_In_opt_ LPCWSTR lpApplicationName,
 #define PDETOUR_CREATE_PROCESS_ROUTINE  PDETOUR_CREATE_PROCESS_ROUTINEA
 #endif // !UNICODE

+DETOURS_NODISCARD
 BOOL WINAPI DetourCreateProcessWithDllExA(_In_opt_ LPCSTR lpApplicationName,
                                           _Inout_opt_ LPSTR lpCommandLine,
                                           _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
@@ -732,6 +801,7 @@ BOOL WINAPI DetourCreateProcessWithDllExA(_In_opt_ LPCSTR lpApplicationName,
                                           _In_ LPCSTR lpDllName,
                                           _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA);

+DETOURS_NODISCARD
 BOOL WINAPI DetourCreateProcessWithDllExW(_In_opt_ LPCWSTR lpApplicationName,
                                           _Inout_opt_  LPWSTR lpCommandLine,
                                           _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
@@ -751,6 +821,7 @@ BOOL WINAPI DetourCreateProcessWithDllExW(_In_opt_ LPCWSTR lpApplicationName,
 #define DetourCreateProcessWithDllEx    DetourCreateProcessWithDllExA
 #endif // !UNICODE

+DETOURS_NODISCARD
 BOOL WINAPI DetourCreateProcessWithDllsA(_In_opt_ LPCSTR lpApplicationName,
                                          _Inout_opt_ LPSTR lpCommandLine,
                                          _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
@@ -765,6 +836,7 @@ BOOL WINAPI DetourCreateProcessWithDllsA(_In_opt_ LPCSTR lpApplicationName,
                                          _In_reads_(nDlls) LPCSTR *rlpDlls,
                                          _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA);

+DETOURS_NODISCARD
 BOOL WINAPI DetourCreateProcessWithDllsW(_In_opt_ LPCWSTR lpApplicationName,
                                          _Inout_opt_ LPWSTR lpCommandLine,
                                          _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
@@ -785,10 +857,12 @@ BOOL WINAPI DetourCreateProcessWithDllsW(_In_opt_ LPCWSTR lpApplicationName,
 #define DetourCreateProcessWithDlls     DetourCreateProcessWithDllsA
 #endif // !UNICODE

+DETOURS_NODISCARD
 BOOL WINAPI DetourProcessViaHelperA(_In_ DWORD dwTargetPid,
                                     _In_ LPCSTR lpDllName,
                                     _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA);

+DETOURS_NODISCARD
 BOOL WINAPI DetourProcessViaHelperW(_In_ DWORD dwTargetPid,
                                     _In_ LPCSTR lpDllName,
                                     _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW);
@@ -799,11 +873,13 @@ BOOL WINAPI DetourProcessViaHelperW(_In_ DWORD dwTargetPid,
 #define DetourProcessViaHelper          DetourProcessViaHelperA
 #endif // !UNICODE

+DETOURS_NODISCARD
 BOOL WINAPI DetourProcessViaHelperDllsA(_In_ DWORD dwTargetPid,
                                         _In_ DWORD nDlls,
                                         _In_reads_(nDlls) LPCSTR *rlpDlls,
                                         _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA);

+DETOURS_NODISCARD
 BOOL WINAPI DetourProcessViaHelperDllsW(_In_ DWORD dwTargetPid,
                                         _In_ DWORD nDlls,
                                         _In_reads_(nDlls) LPCSTR *rlpDlls,
@@ -815,24 +891,35 @@ BOOL WINAPI DetourProcessViaHelperDllsW(_In_ DWORD dwTargetPid,
 #define DetourProcessViaHelperDlls      DetourProcessViaHelperDllsA
 #endif // !UNICODE

+DETOURS_NODISCARD
 BOOL WINAPI DetourUpdateProcessWithDll(_In_ HANDLE hProcess,
                                        _In_reads_(nDlls) LPCSTR *rlpDlls,
                                        _In_ DWORD nDlls);

+DETOURS_NODISCARD
 BOOL WINAPI DetourUpdateProcessWithDllEx(_In_ HANDLE hProcess,
                                          _In_ HMODULE hImage,
                                          _In_ BOOL bIs32Bit,
                                          _In_reads_(nDlls) LPCSTR *rlpDlls,
                                          _In_ DWORD nDlls);

+DETOURS_NODISCARD
 BOOL WINAPI DetourCopyPayloadToProcess(_In_ HANDLE hProcess,
                                        _In_ REFGUID rguid,
                                        _In_reads_bytes_(cbData) PVOID pvData,
                                        _In_ DWORD cbData);
+
+DETOURS_NODISCARD
 BOOL WINAPI DetourRestoreAfterWith(VOID);
+
+DETOURS_NODISCARD
 BOOL WINAPI DetourRestoreAfterWithEx(_In_reads_bytes_(cbData) PVOID pvData,
                                      _In_ DWORD cbData);
+
+DETOURS_NODISCARD
 BOOL WINAPI DetourIsHelperProcess(VOID);
+
+DETOURS_NODISCARD
 VOID CALLBACK DetourFinishHelperProcess(_In_ HWND,
                                         _In_ HINSTANCE,
                                         _In_ LPSTR,