@@ -2986,3 +2986,88 @@ RealShellExecuteW(
29862986 lphProcess,
29872987 0 );
29882988}
2989+
2990+ // The common helper of ShellExec_RunDLLA and ShellExec_RunDLLW
2991+ static VOID
2992+ ShellExec_RunDLL_Helper (
2993+ _In_opt_ HWND hwnd,
2994+ _In_opt_ HINSTANCE hInstance,
2995+ _In_ PCWSTR pszCmdLine,
2996+ _In_ INT nCmdShow)
2997+ {
2998+ TRACE (" (%p, %p, %s, 0x%X)\n " , hwnd, hInstance, wine_dbgstr_w (pszCmdLine), nCmdShow);
2999+
3000+ if (!pszCmdLine || !*pszCmdLine)
3001+ return ;
3002+
3003+ // '?' enables us to specify the additional mask value
3004+ ULONG fNewMask = SEE_MASK_NOASYNC;
3005+ if (*pszCmdLine == L' ?' ) // 1st question
3006+ {
3007+ INT MaskValue;
3008+ if (StrToIntExW (pszCmdLine + 1 , STIF_SUPPORT_HEX, &MaskValue))
3009+ fNewMask |= MaskValue;
3010+
3011+ PCWSTR pch2ndQuestion = StrChrW (pszCmdLine + 1 , L' ?' ); // 2nd question
3012+ if (pch2ndQuestion)
3013+ pszCmdLine = pch2ndQuestion + 1 ;
3014+ }
3015+
3016+ WCHAR szPath[2 * MAX_PATH];
3017+ if (PathProcessCommandAW (pszCmdLine, szPath, _countof (szPath), L' C' ) == -1 )
3018+ StrCpyNW (szPath, pszCmdLine, _countof (szPath));
3019+
3020+ // Split arguments from the path
3021+ LPWSTR Args = PathGetArgsW (szPath);
3022+ if (*Args)
3023+ *(Args - 1 ) = UNICODE_NULL;
3024+
3025+ PathUnquoteSpacesW (szPath);
3026+
3027+ // Execute
3028+ SHELLEXECUTEINFOW execInfo = { sizeof (execInfo) };
3029+ execInfo.fMask = fNewMask ;
3030+ execInfo.hwnd = hwnd;
3031+ execInfo.lpFile = szPath;
3032+ execInfo.lpParameters = Args;
3033+ execInfo.nShow = nCmdShow;
3034+ if (!ShellExecuteExW (&execInfo))
3035+ {
3036+ DWORD dwError = GetLastError ();
3037+ if (SHELL_InRunDllProcess ()) // Is it a RUNDLL process?
3038+ ExitProcess (dwError); // Terminate it now
3039+ }
3040+ }
3041+
3042+ /* ************************************************************************
3043+ * ShellExec_RunDLLA [SHELL32.358]
3044+ *
3045+ * @see https://www.hexacorn.com/blog/2024/11/30/1-little-known-secret-of-shellexec_rundll/
3046+ */
3047+ EXTERN_C
3048+ VOID WINAPI
3049+ ShellExec_RunDLLA (
3050+ _In_opt_ HWND hwnd,
3051+ _In_opt_ HINSTANCE hInstance,
3052+ _In_ PCSTR pszCmdLine,
3053+ _In_ INT nCmdShow)
3054+ {
3055+ CStringW strCmdLine = pszCmdLine; // Keep
3056+ ShellExec_RunDLL_Helper (hwnd, hInstance, strCmdLine, nCmdShow);
3057+ }
3058+
3059+ /* ************************************************************************
3060+ * ShellExec_RunDLLW [SHELL32.359]
3061+ *
3062+ * @see https://www.hexacorn.com/blog/2024/11/30/1-little-known-secret-of-shellexec_rundll/
3063+ */
3064+ EXTERN_C
3065+ VOID WINAPI
3066+ ShellExec_RunDLLW (
3067+ _In_opt_ HWND hwnd,
3068+ _In_opt_ HINSTANCE hInstance,
3069+ _In_ PCWSTR pszCmdLine,
3070+ _In_ INT nCmdShow)
3071+ {
3072+ ShellExec_RunDLL_Helper (hwnd, hInstance, pszCmdLine, nCmdShow);
3073+ }
0 commit comments