From: Hermès BÉLUSCA - MAÏTO Subject: shell32: Automatically expand CPL applet path string (try 2) Message-Id: <003701cf53f7$75e56870$61b03950$@sfr.fr> Date: Wed, 9 Apr 2014 15:27:31 +0200 Symptom: when running control.exe %systemroot%\system32\some_custom_cpl.cpl (or rundll32.exe shell32.dll,Control_RunDLL %systemroot%\system32\some_custom_cpl.cpl, or even, loading a CPL registered in HKLM\Software\Microsoft\Windows\Control Panel\Cpls), it fails because the path string is not expanded. Solution: always expand the CPL applet path string, so that, if it contains environment variables, they get expanded, and if not, the usual behaviour is obtained. dlls/shell32/control.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/dlls/shell32/control.c b/dlls/shell32/control.c index fe392e3..b393154 100644 --- a/dlls/shell32/control.c +++ b/dlls/shell32/control.c @@ -62,6 +62,7 @@ void Control_UnloadApplet(CPlApplet* applet) CPlApplet* Control_LoadApplet(HWND hWnd, LPCWSTR cmd, CPanel* panel) { CPlApplet* applet; + DWORD len; unsigned i; CPLINFO info; NEWCPLINFOW newinfo; @@ -69,21 +70,30 @@ CPlApplet* Control_LoadApplet(HWND hWnd, LPCWSTR cmd, CPanel* panel) if (!(applet = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*applet)))) return applet; - if (!(applet->cmd = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(cmd)+1) * sizeof(WCHAR)))) { - WARN("Cannot allocate memory for applet path\n"); + len = ExpandEnvironmentStringsW(cmd, NULL, 0); + if (len > 0) + { + if (!(applet->cmd = HeapAlloc(GetProcessHeap(), 0, (len+1) * sizeof(WCHAR)))) + { + WARN("Cannot allocate memory for applet path\n"); + goto theError; + } + ExpandEnvironmentStringsW(cmd, applet->cmd, len+1); + } + else + { + WARN("Cannot expand applet path\n"); goto theError; } - lstrcpyW(applet->cmd, cmd); - applet->hWnd = hWnd; - if (!(applet->hModule = LoadLibraryW(cmd))) { - WARN("Cannot load control panel applet %s\n", debugstr_w(cmd)); + if (!(applet->hModule = LoadLibraryW(applet->cmd))) { + WARN("Cannot load control panel applet %s\n", debugstr_w(applet->cmd)); goto theError; } if (!(applet->proc = (APPLET_PROC)GetProcAddress(applet->hModule, "CPlApplet"))) { - WARN("Not a valid control panel applet %s\n", debugstr_w(cmd)); + WARN("Not a valid control panel applet %s\n", debugstr_w(applet->cmd)); goto theError; } if (!applet->proc(hWnd, CPL_INIT, 0L, 0L)) {