Example #1
0
static DWORD Dde_OnExecute(HCONV hconv, HSZ hszTopic, HDDEDATA hdata)
{
    WCHAR szTopic[MAX_PATH];
    WCHAR szCommand[MAX_PATH];
    WCHAR *pszCommand;

    DdeQueryStringW(dwDDEInst, hszTopic, szTopic, _countof(szTopic), CP_WINUNICODE);

    pszCommand = (WCHAR*) DdeAccessData(hdata, NULL);
    if (!pszCommand)
        return DDE_FNOTPROCESSED;

    StringCchCopyW(szCommand, _countof(szCommand), pszCommand);

    DdeUnaccessData(hdata);

    TRACE("Dde_OnExecute: hconv=%p, topic=%S, command=%S\n", hconv, szTopic, pszCommand);

    /*
    [ViewFolder("%l", %I, %S)]    -- Open a folder in standard mode
    [ExploreFolder("%l", %I, %S)] -- Open a folder in "explore" mode (file tree is shown to the left by default)
    [FindFolder("%l", %I)]        -- Open a folder in "find" mode (search panel is shown to the left by default)
    [ShellFile("%1","%1",%S)]     -- Execute the contents of the specified .SCF file

    Approximate grammar (Upper names define rules, <lower> names define terminals, single-quotes are literals):

        Rules
            Command = ('[' Function ']') | Function
            Function = <identifier> '(' Parameters ')'
            Parameters = (<quoted-string> (',' <idlist> (',' <number>)?)?)?

        Terminals
            <identifier> =  [a-zA-Z]+
            <quoted-string> = \"([^\"]|\\.)\"
            <idlist> = \:[0-9]+\:[0-9]+
            <number> = [0-9]+
    */

    WCHAR Command[MAX_PATH] = L"";
    WCHAR Path[MAX_PATH] = L"";
    LPITEMIDLIST IdList = NULL;
    INT UnknownParameter = 0;

    // Simplified parsing (assumes the command will not be TOO broken):

    PWSTR cmd = szCommand;
    //    1. if starts with [, skip first char
    if (*cmd == L'[')
        cmd++;

    if (*cmd == L']')
    {
        ERR("Empty command. Nothing to run.\n");
        return DDE_FNOTPROCESSED;
    }

    // Read until first (, and take text before ( as command name
    {
        PWSTR cmdEnd = StrChrW(cmd, L'(');

        if (!cmdEnd)
        {
            ERR("Could not find '('. Invalid command.\n");
            return DDE_FNOTPROCESSED;
        }

        *cmdEnd = 0;

        StringCchCopy(Command, _countof(Command), cmd);

        cmd = cmdEnd + 1;
    }

    // Read first param after (, expecting quoted string
    if (*cmd != L')')
    {
        // Copy unescaped string
        PWSTR dst = Path;
        BOOL isQuote = FALSE;

        PWSTR arg = cmd;

        while (*arg && (isQuote || *arg != L','))
        {
            if (*arg == L'"')
            {
                isQuote = !isQuote;
                if (isQuote && arg != cmd) // do not copy the " at the beginning of the string
                {
                    *(dst++) = L'"';
                }
            }
            else
            {
                *(dst++) = *arg;
            }

            arg++;
        }

        cmd = arg + 1;

        while (*cmd == L' ')
            cmd++;
    }

    // Read second param, expecting an idlist in shared memory
    if (*cmd != L')')
    {
        if (*cmd != ':')
        {
            ERR("Expected ':'. Invalid command.\n");
            return DDE_FNOTPROCESSED;
        }

        PWSTR idlistEnd = StrChrW(cmd, L',');

        if (!idlistEnd)
            idlistEnd = StrChrW(cmd, L')');

        if (!idlistEnd)
        {
            ERR("Expected ',' or ')'. Invalid command.\n");
            return DDE_FNOTPROCESSED;
        }

        IdList = _ILReadFromSharedMemory(cmd);

        cmd = idlistEnd + 1;
    }

    // Read third param, expecting an integer
    if (*cmd != L')')
    {
        UnknownParameter = StrToIntW(cmd);
    }

    TRACE("Parse end: cmd=%S, S=%d, pidl=%p, path=%S\n", Command, UnknownParameter, IdList, Path);

    // Find handler in list
    for (int i = 0; i < HandlerListLength; i++)
    {
        DDECommandHandler & handler = HandlerList[i];
        if (StrCmpW(handler.Command, Command) == 0)
        {
            return handler.Handler(Command, Path, IdList, UnknownParameter);
        }
    }

    // No handler found
    ERR("Unknown command %S\n", Command);
    return DDE_FNOTPROCESSED;
}
Example #2
0
UINT
WINAPI
SHExplorerParseCmdLine(ExplorerCommandLineParseResults * pInfo)
{
    WCHAR   strField[MAX_PATH];
    WCHAR   strDir[MAX_PATH];

    PCWSTR strCmdLine = GetCommandLineW();
    PCWSTR strFieldArray = PathGetArgsW(strCmdLine);

    if (!*strFieldArray)
    {
        pInfo->dwFlags = 9;
        pInfo->pidlPath = _GetDocumentsPidl();
        if (!pInfo->pidlPath)
        {
            GetWindowsDirectoryW(strDir, MAX_PATH);
            PathStripToRootW(strDir);
            pInfo->pidlPath = ILCreateFromPathW(strDir);
        }
        return (LONG) (pInfo->pidlPath);
    }

    PCWSTR strNextArg = _FindFirstField(strFieldArray);

    BOOL hasNext = TRUE;

    hasNext = _ReadNextArg(&strNextArg, strField, _countof(strField));
    while (TRUE)
    {
        // Basic flags-only params first
        if (!StrCmpIW(strField, L"/N"))
        {
            pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_N | SH_EXPLORER_CMDLINE_FLAG_ONE;
            TRACE("CmdLine Parser: Parsed %S flag. dwFlags=%08lx\n", strField, pInfo->dwFlags);
        }
        else if (!StrCmpIW(strField, L"/S"))
        {
            pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_S;
            TRACE("CmdLine Parser: Parsed %S flag. dwFlags=%08lx\n", strField, pInfo->dwFlags);
        }
        else if (!StrCmpIW(strField, L"/E"))
        {
            pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_E;
            TRACE("CmdLine Parser: Parsed %S flag. dwFlags=%08lx\n", strField, pInfo->dwFlags);
        }
        else if (!StrCmpIW(strField, L"/SELECT"))
        {
            pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_SELECT;
            TRACE("CmdLine Parser: Parsed %S flag. dwFlags=%08lx\n", strField, pInfo->dwFlags);
        }
        else if (!StrCmpIW(strField, L"/NOUI"))
        {
            pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_NOUI;
            TRACE("CmdLine Parser: Parsed %S flag. dwFlags=%08lx\n", strField, pInfo->dwFlags);
        }
        else if (!StrCmpIW(strField, L"-embedding"))
        {
            pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_EMBED;
            TRACE("CmdLine Parser: Parsed %S flag. dwFlags=%08lx\n", strField, pInfo->dwFlags);
        }
        else if (!StrCmpIW(strField, L"/SEPARATE"))
        {
            pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_SEPARATE;
            TRACE("CmdLine Parser: Parsed %S flag. dwFlags=%08lx\n", strField, pInfo->dwFlags);
        }
        else if (!StrCmpIW(strField, L"/INPROC"))
        {
            // No idea what Inproc is supposed to do, but it gets a GUID, and parses it.

            TRACE("CmdLine Parser: Found %S flag\n", strField);

            if (!hasNext)
                return FALSE;

            hasNext = _ReadNextArg(&strNextArg, strField, _countof(strField));

            if (!GUIDFromStringW(strField, &(pInfo->guidInproc)))
                return FALSE;

            pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_INPROC;

            TRACE("CmdLine Parser: Parsed /INPROC flag. dwFlags=%08lx, guidInproc=%S\n", pInfo->dwFlags, strField);
        }
        else if (!StrCmpIW(strField, L"/ROOT"))
        {
            LPITEMIDLIST pidlRoot = NULL;

            // The window should be rooted

            TRACE("CmdLine Parser: Found %S flag\n", strField);

            if (!pInfo->pidlPath)
                return FALSE;

            if (!hasNext)
                return FALSE;

            hasNext = _ReadNextArg(&strNextArg, strField, _countof(strField));

            // Root may be a pidl
            if (!StrCmpIW(strField, L"/IDLIST"))
            {
                if (hasNext)
                {
                    hasNext = _ReadNextArg(&strNextArg, strField, _countof(strField));
                }
                pidlRoot = _ILReadFromSharedMemory(strField);
            }
            else
            {
                // Or just a path string
                _ParsePathToPidl(strField, &pidlRoot);
            }

            pInfo->pidlRoot = pidlRoot;

            // The root defaults to the desktop
            if (!pidlRoot)
            {
                if (FAILED(SHGetSpecialFolderLocation(0, CSIDL_DESKTOP, &(pInfo->pidlRoot))))
                    pInfo->pidlRoot = NULL;
            }

            // TODO: Create rooted PIDL from pInfo->pidlPath and pInfo->pidlRoot

            TRACE("CmdLine Parser: Parsed /ROOT flag. dwFlags=%08lx, pidlRoot=%p\n", pInfo->dwFlags, pInfo->pidlRoot);
        }
        else
        {
            // Anything else is part of the target path to browse to
            TRACE("CmdLine Parser: Found target path %S\n", strField);

            // Which can be a shared-memory itemidlist
            if (!StrCmpIW(strField, L"/IDLIST"))
            {
                LPITEMIDLIST pidlArg;

                if (!hasNext)
                    return FALSE;

                hasNext = _ReadNextArg(&strNextArg, strField, _countof(strField));
                pidlArg = _ILReadFromSharedMemory(strField);
                if (!pidlArg)
                    return FALSE;

                if (pInfo->pidlPath)
                    ILFree(pInfo->pidlPath);
                pInfo->pidlPath = pidlArg;

                TRACE("CmdLine Parser: Parsed target path. dwFlags=%08lx, pidlPath=%p\n", pInfo->dwFlags, pInfo->pidlPath);
            }
            else
            {
                // Or just a plain old string.

                WCHAR szPath[MAX_PATH];
                DWORD result = GetFullPathNameW(strField, _countof(szPath), szPath, NULL);

                if (result != 0 && result <= _countof(szPath) && PathFileExistsW(szPath))
                    StringCchCopyW(strField, _countof(strField), szPath);

                LPITEMIDLIST pidlPath = ILCreateFromPathW(strField);

                pInfo->pidlPath = pidlPath;

                if (pidlPath)
                {
                    pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_IDLIST;
                    TRACE("CmdLine Parser: Parsed target path. dwFlags=%08lx, pidlPath=%p\n", pInfo->dwFlags, pInfo->pidlPath);
                }
                else
                {
                    // The path could not be parsed into an ID List,
                    // so pass it on as a plain string.

                    PWSTR field = StrDupW(strField);
                    pInfo->strPath = field;
                    if (field)
                    {
                        pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_STRING;
                        TRACE("CmdLine Parser: Parsed target path. dwFlags=%08lx, strPath=%S\n", pInfo->dwFlags, field);
                    }
                }

            }
        }

        if (!hasNext)
            break;
        hasNext = _ReadNextArg(&strNextArg, strField, _countof(strField));
    }

    return TRUE;
}