diff --git a/win/nvfbcwrp/.gitignore b/win/nvfbcwrp/.gitignore new file mode 100644 index 0000000..259148f --- /dev/null +++ b/win/nvfbcwrp/.gitignore @@ -0,0 +1,32 @@ +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app diff --git a/win/nvfbcwrp/framework.h b/win/nvfbcwrp/framework.h new file mode 100644 index 0000000..61ca0b6 --- /dev/null +++ b/win/nvfbcwrp/framework.h @@ -0,0 +1,5 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN // Исключите редко используемые компоненты из заголовков Windows +// Файлы заголовков Windows +#include diff --git a/win/nvfbcwrp/nvfbcbody.asm b/win/nvfbcwrp/nvfbcbody.asm new file mode 100644 index 0000000..69f0c47 --- /dev/null +++ b/win/nvfbcwrp/nvfbcbody.asm @@ -0,0 +1,37 @@ +.data + +extern ORIG_NvFBC_Create : qword, ORIG_NvFBC_Enable : qword, + ORIG_NvFBC_GetSDKVersion : qword, ORIG_NvFBC_GetStatus : qword, + ORIG_NvFBC_GetStatusEx : qword, ORIG_NvFBC_SetGlobalFlags : qword, + ORIG_NvOptimusEnablement : qword + +.code +PROXY_NvFBC_Create proc +jmp qword ptr [ORIG_NvFBC_Create] +PROXY_NvFBC_Create endp + +PROXY_NvFBC_Enable proc +jmp qword ptr [ORIG_NvFBC_Enable] +PROXY_NvFBC_Enable endp + +PROXY_NvFBC_GetSDKVersion proc +jmp qword ptr [ORIG_NvFBC_GetSDKVersion] +PROXY_NvFBC_GetSDKVersion endp + +PROXY_NvFBC_GetStatus proc +jmp qword ptr [ORIG_NvFBC_GetStatus] +PROXY_NvFBC_GetStatus endp + +PROXY_NvFBC_GetStatusEx proc +jmp qword ptr [ORIG_NvFBC_GetStatusEx] +PROXY_NvFBC_GetStatusEx endp + +PROXY_NvFBC_SetGlobalFlags proc +jmp qword ptr [ORIG_NvFBC_SetGlobalFlags] +PROXY_NvFBC_SetGlobalFlags endp + +PROXY_NvOptimusEnablement proc +jmp qword ptr [ORIG_NvOptimusEnablement] +PROXY_NvOptimusEnablement endp + +end \ No newline at end of file diff --git a/win/nvfbcwrp/nvfbcdefs.h b/win/nvfbcwrp/nvfbcdefs.h new file mode 100644 index 0000000..09b2dc5 --- /dev/null +++ b/win/nvfbcwrp/nvfbcdefs.h @@ -0,0 +1,79 @@ +#pragma once + +// Magic code which is passed as pPrivateData and enables NvFBC to work on GeForce +int magic[] = { 0x0D7BC620, 0x4C17E142, 0x5E6B5997, 0x4B5A855B }; + +typedef unsigned long NvU32; /* 0 to 4294967295 */ + +/** + * \ingroup NVFBC + * Macro to define the NVFBC API version corresponding to this distribution. + */ +#define NVFBC_DLL_VERSION 0x70 + + /** + * \ingroup NVFBC + * Calling Convention + */ +#define NVFBCAPI __stdcall + + /** + * \ingroup NVFBC + * Macro to construct version numbers for parameter structs. + */ +#define NVFBC_STRUCT_VERSION(typeName, ver) (NvU32)(sizeof(typeName) | ((ver)<<16) | (NVFBC_DLL_VERSION << 24)) + +typedef enum _NVFBCRESULT +{ + NVFBC_SUCCESS = 0, + NVFBC_ERROR_GENERIC = -1, /**< Unexpected failure in NVFBC. */ + NVFBC_ERROR_INVALID_PARAM = -2, /**< One or more of the paramteres passed to NvFBC are invalid [This include NULL pointers]. */ + NVFBC_ERROR_INVALIDATED_SESSION = -3, /**< NvFBC session is invalid. Client needs to recreate session. */ + NVFBC_ERROR_PROTECTED_CONTENT = -4, /**< Protected content detected. Capture failed. */ + NVFBC_ERROR_DRIVER_FAILURE = -5, /**< GPU driver returned failure to process NvFBC command. */ + NVFBC_ERROR_CUDA_FAILURE = -6, /**< CUDA driver returned failure to process NvFBC command. */ + NVFBC_ERROR_UNSUPPORTED = -7, /**< API Unsupported on this version of NvFBC. */ + NVFBC_ERROR_HW_ENC_FAILURE = -8, /**< HW Encoder returned failure to process NVFBC command. */ + NVFBC_ERROR_INCOMPATIBLE_DRIVER = -9, /**< NVFBC is not compatible with this version of the GPU driver. */ + NVFBC_ERROR_UNSUPPORTED_PLATFORM = -10, /**< NVFBC is not supported on this platform. */ + NVFBC_ERROR_OUT_OF_MEMORY = -11, /**< Failed to allocate memory. */ + NVFBC_ERROR_INVALID_PTR = -12, /**< A NULL pointer was passed. */ + NVFBC_ERROR_INCOMPATIBLE_VERSION = -13, /**< An API was called with a parameter struct that has an incompatible version. Check dwVersion field of paramter struct. */ + NVFBC_ERROR_OPT_CAPTURE_FAILURE = -14, /**< Desktop Capture failed. */ + NVFBC_ERROR_INSUFFICIENT_PRIVILEGES = -15, /**< User doesn't have appropriate previlages. */ + NVFBC_ERROR_INVALID_CALL = -16, /**< NVFBC APIs called in wrong sequence. */ + NVFBC_ERROR_SYSTEM_ERROR = -17, /**< Win32 error. */ + NVFBC_ERROR_INVALID_TARGET = -18, /**< The target adapter idx can not be used for NVFBC capture. It may not correspond to an NVIDIA GPU, or may not be attached to desktop. */ + NVFBC_ERROR_NVAPI_FAILURE = -19, /**< NvAPI Error */ + NVFBC_ERROR_DYNAMIC_DISABLE = -20, /**< NvFBC is dynamically disabled. Cannot continue to capture */ + NVFBC_ERROR_IPC_FAILURE = -21, /**< NVFBC encountered an error in state management */ + NVFBC_ERROR_CURSOR_CAPTURE_FAILURE = -22, /**< Hardware cursor capture failed */ +} NVFBCRESULT; + + +typedef struct _NvFBCCreateParams +{ + NvU32 dwVersion; /**< [in] Struct version. Set to NVFBC_CREATE_PARAMS_VER. */ + NvU32 dwInterfaceType; /**< [in] ID of the NVFBC interface Type being requested. */ + NvU32 dwMaxDisplayWidth; /**< [out] Max. display width allowed. */ + NvU32 dwMaxDisplayHeight; /**< [out] Max. display height allowed. */ + void* pDevice; /**< [in] Device pointer. */ + void* pPrivateData; /**< [in] Private data [optional]. */ + NvU32 dwPrivateDataSize; /**< [in] Size of private data. */ + NvU32 dwInterfaceVersion; /**< [in] Version of the capture interface. */ + void* pNvFBC; /**< [out] A pointer to the requested NVFBC object. */ + NvU32 dwAdapterIdx; /**< [in] Adapter Ordinal corresponding to the display to be grabbed. If pDevice is set, this parameter is ignored. */ + NvU32 dwNvFBCVersion; /**< [out] Indicates the highest NvFBC interface version supported by the loaded NVFBC library. */ + void* cudaCtx; /**< [in] CUDA context created using cuD3D9CtxCreate with the D3D9 device passed as pDevice. Only used for NvFBCCuda interface. + It is mandatory to pass a valid D3D9 device if cudaCtx is passed. The call will fail otherwise. + Client must release NvFBCCuda object before destroying the cudaCtx. */ + void* pPrivateData2; /**< [in] Private data [optional]. */ + NvU32 dwPrivateData2Size; /**< [in] Size of private data. */ + NvU32 dwReserved[55]; /**< [in] Reserved. Should be set to 0. */ + void* pReserved[27]; /**< [in] Reserved. Should be set to NULL. */ +}NvFBCCreateParams; +#define NVFBC_CREATE_PARAMS_VER_1 NVFBC_STRUCT_VERSION(NvFBCCreateParams, 1) +#define NVFBC_CREATE_PARAMS_VER_2 NVFBC_STRUCT_VERSION(NvFBCCreateParams, 2) +#define NVFBC_CREATE_PARAMS_VER NVFBC_CREATE_PARAMS_VER_2 + +typedef NVFBCRESULT(NVFBCAPI* NvFBC_CreateFunctionExType) (void* pCreateParams); \ No newline at end of file diff --git a/win/nvfbcwrp/nvfbcwrp.def b/win/nvfbcwrp/nvfbcwrp.def new file mode 100644 index 0000000..dd72c9f --- /dev/null +++ b/win/nvfbcwrp/nvfbcwrp.def @@ -0,0 +1,10 @@ +LIBRARY nvfbcwrp +EXPORTS + NvFBC_Create=PROXY_NvFBC_Create @1 + NvFBC_CreateEx=PROXY_NvFBC_CreateEx @2 + NvFBC_Enable=PROXY_NvFBC_Enable @3 + NvFBC_GetSDKVersion=PROXY_NvFBC_GetSDKVersion @4 + NvFBC_GetStatus=PROXY_NvFBC_GetStatus @5 + NvFBC_GetStatusEx=PROXY_NvFBC_GetStatusEx @6 + NvFBC_SetGlobalFlags=PROXY_NvFBC_SetGlobalFlags @7 + NvOptimusEnablement=PROXY_NvOptimusEnablement @8 diff --git a/win/nvfbcwrp/nvfbcwrp.sln b/win/nvfbcwrp/nvfbcwrp.sln new file mode 100644 index 0000000..b10df9f --- /dev/null +++ b/win/nvfbcwrp/nvfbcwrp.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29519.87 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nvfbcwrp", "nvfbcwrp.vcxproj", "{F2E7530B-BA35-4592-A0A9-CBE9CAD9A3CB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F2E7530B-BA35-4592-A0A9-CBE9CAD9A3CB}.Debug|x64.ActiveCfg = Debug|x64 + {F2E7530B-BA35-4592-A0A9-CBE9CAD9A3CB}.Debug|x64.Build.0 = Debug|x64 + {F2E7530B-BA35-4592-A0A9-CBE9CAD9A3CB}.Debug|x86.ActiveCfg = Debug|Win32 + {F2E7530B-BA35-4592-A0A9-CBE9CAD9A3CB}.Debug|x86.Build.0 = Debug|Win32 + {F2E7530B-BA35-4592-A0A9-CBE9CAD9A3CB}.Release|x64.ActiveCfg = Release|x64 + {F2E7530B-BA35-4592-A0A9-CBE9CAD9A3CB}.Release|x64.Build.0 = Release|x64 + {F2E7530B-BA35-4592-A0A9-CBE9CAD9A3CB}.Release|x86.ActiveCfg = Release|Win32 + {F2E7530B-BA35-4592-A0A9-CBE9CAD9A3CB}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {8A014521-63BA-4C47-A9A0-D97C80423FA4} + EndGlobalSection +EndGlobal diff --git a/win/nvfbcwrp/nvfbcwrp.vcxproj b/win/nvfbcwrp/nvfbcwrp.vcxproj new file mode 100644 index 0000000..b3dd0da --- /dev/null +++ b/win/nvfbcwrp/nvfbcwrp.vcxproj @@ -0,0 +1,187 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + {F2E7530B-BA35-4592-A0A9-CBE9CAD9A3CB} + Win32Proj + nvfbcwrp + 10.0 + + + + DynamicLibrary + true + v142 + Unicode + + + DynamicLibrary + false + v142 + true + Unicode + + + DynamicLibrary + true + v142 + MultiByte + + + DynamicLibrary + false + v142 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + Use + Level3 + Disabled + true + WIN32;_DEBUG;NVFBCWRP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + pch.h + + + Windows + true + false + + + + + Use + Level3 + Disabled + true + _DEBUG;NVFBCWRP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + pch.h + + + Windows + true + false + nvfbcwrp.def + + + false + + + + + Use + Level3 + MaxSpeed + true + true + true + WIN32;NDEBUG;NVFBCWRP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + pch.h + + + Windows + true + true + true + false + + + + + Use + Level3 + MaxSpeed + true + true + true + NDEBUG;NVFBCWRP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + pch.h + + + Windows + true + true + true + false + nvfbcwrp.def + + + + + + + + + + + Create + Create + Create + Create + + + + + + + + + + + + + \ No newline at end of file diff --git a/win/nvfbcwrp/nvfbcwrp.vcxproj.filters b/win/nvfbcwrp/nvfbcwrp.vcxproj.filters new file mode 100644 index 0000000..e6510e8 --- /dev/null +++ b/win/nvfbcwrp/nvfbcwrp.vcxproj.filters @@ -0,0 +1,46 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Файлы заголовков + + + Файлы заголовков + + + Файлы заголовков + + + + + Исходные файлы + + + Исходные файлы + + + + + Исходные файлы + + + + + Исходные файлы + + + \ No newline at end of file diff --git a/win/nvfbcwrp/nvfbcwrp.vcxproj.user b/win/nvfbcwrp/nvfbcwrp.vcxproj.user new file mode 100644 index 0000000..0f14913 --- /dev/null +++ b/win/nvfbcwrp/nvfbcwrp.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/win/nvfbcwrp/nvfbcwrp_main.cpp b/win/nvfbcwrp/nvfbcwrp_main.cpp new file mode 100644 index 0000000..7e495f1 --- /dev/null +++ b/win/nvfbcwrp/nvfbcwrp_main.cpp @@ -0,0 +1,65 @@ +#include "pch.h" +#include "nvfbcdefs.h" +#include + +HINSTANCE hLThis = 0; +extern "C" { + FARPROC ORIG_NvFBC_Create, ORIG_NvFBC_Enable, ORIG_NvFBC_GetSDKVersion, + ORIG_NvFBC_GetStatus, ORIG_NvFBC_GetStatusEx, ORIG_NvFBC_SetGlobalFlags, + ORIG_NvOptimusEnablement; +} +NvFBC_CreateFunctionExType ORIG_NvFBC_CreateEx; +HINSTANCE hL = 0; + +BOOL WINAPI DllMain(HINSTANCE hInst,DWORD reason,LPVOID) +{ + if (reason == DLL_PROCESS_ATTACH) + { + //hLThis = hInst; + hL = LoadLibrary(".\\NvFBC64_.dll"); + if (!hL) return false; + ORIG_NvFBC_Create = GetProcAddress(hL, "NvFBC_Create"); + if (!ORIG_NvFBC_Create) return false; + ORIG_NvFBC_CreateEx = (NvFBC_CreateFunctionExType)::GetProcAddress(hL, "NvFBC_CreateEx"); + if (!ORIG_NvFBC_CreateEx) return false; + ORIG_NvFBC_Enable = GetProcAddress(hL, "NvFBC_Enable"); + if (!ORIG_NvFBC_Enable) return false; + ORIG_NvFBC_GetSDKVersion = GetProcAddress(hL, "NvFBC_GetSDKVersion"); + if (!ORIG_NvFBC_GetSDKVersion) return false; + ORIG_NvFBC_GetStatus = GetProcAddress(hL, "NvFBC_GetStatus"); + if (!ORIG_NvFBC_GetStatus) return false; + ORIG_NvFBC_GetStatusEx = GetProcAddress(hL, "NvFBC_GetStatusEx"); + if (!ORIG_NvFBC_GetStatusEx) return false; + ORIG_NvFBC_SetGlobalFlags = GetProcAddress(hL, "NvFBC_SetGlobalFlags"); + if (!ORIG_NvFBC_SetGlobalFlags) return false; + ORIG_NvOptimusEnablement = GetProcAddress(hL, "NvOptimusEnablement"); + if (!ORIG_NvOptimusEnablement) return false; + } + if (reason == DLL_PROCESS_DETACH) + { + FreeLibrary(hL); + return true; + } + + return true; +} + +NVFBCRESULT NVFBCAPI PROXY_NvFBC_CreateEx(NvFBCCreateParams* params) { + if (params->dwPrivateDataSize == 0 && params->pPrivateData == NULL) { + //Backup old values + void* bkp_privdata = params->pPrivateData; + NvU32 bkp_privdatasize = params->dwPrivateDataSize; + // Inject private keys into structure + params->dwPrivateDataSize = sizeof(magic); + params->pPrivateData = &magic; + // Invoke original function + NVFBCRESULT res = ORIG_NvFBC_CreateEx(params); + // Rollback private data changes in params structure + params->pPrivateData = bkp_privdata; + params->dwPrivateDataSize = bkp_privdatasize; + return res; + } + else { + return ORIG_NvFBC_CreateEx((void*)params); + } +} \ No newline at end of file diff --git a/win/nvfbcwrp/pch.cpp b/win/nvfbcwrp/pch.cpp new file mode 100644 index 0000000..9211a5e --- /dev/null +++ b/win/nvfbcwrp/pch.cpp @@ -0,0 +1,5 @@ +// pch.cpp: файл исходного кода, соответствующий предварительно скомпилированному заголовочному файлу + +#include "pch.h" + +// При использовании предварительно скомпилированных заголовочных файлов необходим следующий файл исходного кода для выполнения сборки. diff --git a/win/nvfbcwrp/pch.h b/win/nvfbcwrp/pch.h new file mode 100644 index 0000000..42d0757 --- /dev/null +++ b/win/nvfbcwrp/pch.h @@ -0,0 +1,13 @@ +// pch.h: это предварительно скомпилированный заголовочный файл. +// Перечисленные ниже файлы компилируются только один раз, что ускоряет последующие сборки. +// Это также влияет на работу IntelliSense, включая многие функции просмотра и завершения кода. +// Однако изменение любого из приведенных здесь файлов между операциями сборки приведет к повторной компиляции всех(!) этих файлов. +// Не добавляйте сюда файлы, которые планируете часто изменять, так как в этом случае выигрыша в производительности не будет. + +#ifndef PCH_H +#define PCH_H + +// Добавьте сюда заголовочные файлы для предварительной компиляции +#include "framework.h" + +#endif //PCH_H