Author: rharabien
Date: Sun Jan 15 00:59:29 2012
New Revision: 54967
URL:
http://svn.reactos.org/svn/reactos?rev=54967&view=rev
Log:
- Try to fix KVM
Modified:
trunk/reactos/dll/win32/shell32/control.cpp
Modified: trunk/reactos/dll/win32/shell32/control.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/control.…
==============================================================================
--- trunk/reactos/dll/win32/shell32/control.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/control.cpp [iso-8859-1] Sun Jan 15 00:59:29 2012
@@ -348,102 +348,146 @@
Control_DoInterface(panel, hWnd, hInst);
}
-static void Control_DoLaunch(CPanel *pPanel, HWND hWnd, LPCWSTR pwszCmd)
-{
- /* Make a pwszCmd copy so we can modify it */
- LPWSTR pwszCmdCopy = _wcsdup(pwszCmd);
- if (!pwszCmdCopy)
+static void Control_DoLaunch(CPanel* panel, HWND hWnd, LPCWSTR wszCmd)
+ /* forms to parse:
+ * foo.cpl,@sp,str
+ * foo.cpl,@sp
+ * foo.cpl,,str
+ * foo.cpl @sp
+ * foo.cpl str
+ * "a path\foo.cpl"
+ */
+{
+ LPWSTR buffer;
+ LPWSTR beg = NULL;
+ LPWSTR end;
+ WCHAR ch;
+ LPCWSTR ptr, ptr2;
+ WCHAR szName[MAX_PATH];
+ unsigned sp = 0;
+ LPWSTR extraPmts = NULL;
+ int quoted = 0;
+ BOOL spSet = FALSE;
+ HANDLE hMutex;
+ UINT Length;
+
+ ptr = wcsrchr(wszCmd, L'\\');
+ ptr2 = wcsrchr(wszCmd, L',');
+ if (!ptr2)
+ {
+ ptr2 = wszCmd + wcslen(wszCmd) + 1;
+ }
+
+ if (ptr)
+ ptr++;
+ else
+ ptr = wszCmd;
+
+ Length = (ptr2 - ptr);
+ if (Length >= MAX_PATH)
return;
- LPWSTR pwszPath = pwszCmdCopy, pwszArg = NULL, pwszArg2 = NULL;
-
- /* Path can be quoted */
- if (pwszPath[0] == L'"')
- {
- ++pwszPath;
- pwszArg = wcschr(pwszPath, L'"');
- if (pwszArg)
- *(pwszArg++) = '\0';
- }
- else
- pwszArg = pwszCmdCopy;
-
- /* First argument starts after space or ','. Note: we ignore characters
between '"' and ',' or ' '. */
- if (pwszArg)
- pwszArg = wcspbrk(pwszArg, L" ,");
- if (pwszArg)
- {
- /* NULL terminate path and find first character of arg */
- *(pwszArg++) = L'\0';
- if (pwszArg[0] == L'"')
- {
- ++pwszArg;
- pwszArg2 = wcschr(pwszArg, L'"');
- if (pwszArg2)
- *(pwszArg2++) = L'\0';
- } else
- pwszArg2 = pwszArg;
-
- /* Second argument always starts with ','. Note: we ignore characters
between '"' and ','. */
- if (pwszArg2)
- pwszArg2 = wcschr(pwszArg2, L',');
- }
-
- TRACE("Launch %ls, arg %ls, arg2 %ls\n", pwszPath, pwszArg, pwszArg2);
-
- /* Create a mutex to disallow running multiple instances */
- HANDLE hMutex = CreateMutexW(NULL, TRUE, PathFindFileNameW(pwszPath));
- if (!hMutex || GetLastError() == ERROR_ALREADY_EXISTS)
- {
- TRACE("Next instance disallowed\n");
- if (hMutex)
- CloseHandle(hMutex);
+ memcpy(szName, (LPVOID)ptr, Length * sizeof(WCHAR));
+ szName[Length] = L'\0';
+ hMutex = CreateMutexW(NULL, TRUE, szName);
+
+ if ((!hMutex) || (GetLastError() == ERROR_ALREADY_EXISTS))
return;
- }
-
- /* Load applet cpl */
- TRACE("Load applet %ls\n", pwszPath);
- Control_LoadApplet(hWnd, pwszPath, pPanel);
- if (pPanel->first)
- {
- /* First pPanel applet is the new one */
- CPlApplet *pApplet = pPanel->first;
- assert(pApplet && pApplet->next == NULL);
- TRACE("pApplet->count %d\n", pApplet->count);
-
- /* Note: if there is only one applet, first argument is ignored */
- INT i = 0;
- if (pApplet->count > 1 && pwszArg && pwszArg[0])
- {
- /* If arg begins with '@', number specifies applet index */
- if (pwszArg[0] == L'@')
- i = _wtoi(pwszArg + 1);
- else
- {
- /* Otherwise it's applet name */
- for (i = 0; i < (INT)pApplet->count; ++i)
- if (!wcscmp(pwszArg, pApplet->info[i].szName))
- break;
- }
- }
-
- if (i >= 0 && i < (INT)pApplet->count &&
pApplet->info[i].dwSize)
- {
- /* Start the applet */
- TRACE("Starting applet %d\n", i);
- if (!pApplet->proc(pApplet->hWnd, CPL_DBLCLK, i,
pApplet->info[i].lData))
- pApplet->proc(pApplet->hWnd, CPL_STARTWPARMSA, i,
(LPARAM)pwszArg);
- } else
- ERR("Applet not found: %ls\n", pwszArg ? pwszArg :
L"NULL");
-
- Control_UnloadApplet(pApplet);
- }
- else
- ERR("Failed to load applet %ls\n", pwszPath);
+ buffer = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, (wcslen(wszCmd) + 1) *
sizeof(*wszCmd));
+ if (!buffer)
+ {
+ CloseHandle(hMutex);
+ return;
+ }
+
+ TRACE("[shell32, Control_DoLaunch] wszCmd = %ws\n", wszCmd);
+
+ end = wcscpy(buffer, wszCmd);
+ for (;;)
+ {
+ ch = *end;
+ if (ch == '"')
+ quoted = !quoted;
+
+ if (!quoted && (ch == ',' || ch == '\0'))
+ {
+ *end = '\0';
+ if (beg)
+ {
+ if (*beg == '@')
+ {
+ sp = atoiW(beg + 1);
+ spSet = TRUE;
+ }
+ else if (*beg == '\0')
+ {
+ sp = 0;
+ spSet = TRUE;
+ }
+ else
+ {
+ extraPmts = beg;
+ }
+ }
+
+ if (ch == '\0') break;
+ beg = end + 1;
+ if (ch == ' ')
+ while (end[1] == ' ')
+ end++;
+ }
+ end++;
+ }
+ while ((ptr = StrChrW(buffer, '"')))
+ memmove((LPVOID)ptr, ptr+1, wcslen(ptr)*sizeof(WCHAR));
+
+ while ((ptr = StrChrW(extraPmts, '"')))
+ memmove((LPVOID)ptr, ptr+1, wcslen(ptr)*sizeof(WCHAR));
+
+ TRACE("[shell32, Control_DoLaunch] cmd %s, extra %s, sp %d\n",
debugstr_w(buffer), debugstr_w(extraPmts), sp);
+
+ Control_LoadApplet(hWnd, buffer, panel);
+
+ if (panel->first)
+ {
+ CPlApplet* applet = panel->first;
+
+ TRACE("[shell32, Control_DoLaunch] applet->count %d,
applet->info[sp].szName %ws\n", applet->count, applet->info[sp].szName);
+
+ assert(applet && applet->next == NULL);
+ if (sp >= applet->count)
+ {
+ WARN("Out of bounds (%u >= %u), setting to 0\n", sp,
applet->count);
+ sp = 0;
+ }
+
+ if ((extraPmts) && extraPmts[0] && (!spSet))
+ {
+ while ((lstrcmpiW(extraPmts, applet->info[sp].szName)) && (sp <
applet->count))
+ sp++;
+
+ if (sp >= applet->count)
+ {
+ ReleaseMutex(hMutex);
+ CloseHandle(hMutex);
+ Control_UnloadApplet(applet);
+ HeapFree(GetProcessHeap(), 0, buffer);
+ return;
+ }
+ }
+
+ if (applet->info[sp].dwSize)
+ {
+ if (!applet->proc(applet->hWnd, CPL_DBLCLK, sp,
applet->info[sp].lData))
+ applet->proc(applet->hWnd, CPL_STARTWPARMSA, sp,
(LPARAM)extraPmts);
+ }
+
+ Control_UnloadApplet(applet);
+ }
ReleaseMutex(hMutex);
CloseHandle(hMutex);
- free(pwszCmdCopy);
+ HeapFree(GetProcessHeap(), 0, buffer);
}
/*************************************************************************
@@ -452,22 +496,22 @@
*/
EXTERN_C void WINAPI Control_RunDLLW(HWND hWnd, HINSTANCE hInst, LPCWSTR cmd, DWORD
nCmdShow)
{
- CPanel Panel;
+ CPanel panel;
TRACE("(%p, %p, %s, 0x%08x)\n",
hWnd, hInst, debugstr_w(cmd), nCmdShow);
- memset(&Panel, 0, sizeof(Panel));
+ memset(&panel, 0, sizeof(panel));
if (!cmd || !*cmd)
{
TRACE("[shell32, Control_RunDLLW] Calling Control_DoWindow\n");
- Control_DoWindow(&Panel, hWnd, hInst);
+ Control_DoWindow(&panel, hWnd, hInst);
}
else
{
TRACE("[shell32, Control_RunDLLW] Calling Control_DoLaunch\n");
- Control_DoLaunch(&Panel, hWnd, cmd);
+ Control_DoLaunch(&panel, hWnd, cmd);
}
}