explorer.c 5.67 KB
Newer Older
1 2 3
/*
 * explorer.exe
 *
4
 * Copyright 2004 CodeWeavers, Mike Hearn
5
 * Copyright 2005,2006 CodeWeavers, Aric Stewart
6 7 8 9 10 11 12 13 14 15 16 17 18
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 21 22 23
 */

#include <windows.h>

24
#include "wine/unicode.h"
25
#include "explorer_private.h"
26

27 28 29 30 31 32 33
typedef struct parametersTAG {
    BOOL    explorer_mode;
    WCHAR   root[MAX_PATH];
    WCHAR   selection[MAX_PATH];
} parameters_struct;


34
static int CopyPathString(LPWSTR target, LPWSTR source)
35 36 37
{
    INT i = 0;

38
    while (isspaceW(*source)) source++;
39 40 41 42

    if (*source == '\"')
    {
        source ++;
43 44
        while (*source != '\"') target[i++] = *source++;
        target[i] = 0;
45 46 47 48 49
        source ++;
        i+=2;
    }
    else
    {
50 51
        while (*source && !isspaceW(*source)) target[i++] = *source++;
        target[i] = 0;
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
    }
    return i;
}


static void CopyPathRoot(LPWSTR root, LPWSTR path)
{
    LPWSTR p,p2;
    INT i = 0;

    p = path;
    while (*p!=0)
        p++;

    while (*p!='\\' && p > path)
        p--;

    if (p == path)
        return;

    p2 = path;
    while (p2 != p)
    {
        root[i] = *p2;
        i++;
        p2++;
    }
    root[i] = 0;
}

/*
 * Command Line parameters are:
 * [/n]  Opens in single-paned view for each selected items. This is default
 * [/e,] Uses Windows Explorer View
 * [/root,object] Specifies the root level of the view
 * [/select,object] parent folder is opened and specified object is selected
 */
89
static void ParseCommandLine(LPWSTR commandline,parameters_struct *parameters)
90
{
91 92 93 94 95 96 97 98
    static const WCHAR arg_n[] = {'/','n'};
    static const WCHAR arg_e[] = {'/','e',','};
    static const WCHAR arg_root[] = {'/','r','o','o','t',','};
    static const WCHAR arg_select[] = {'/','s','e','l','e','c','t',','};
    static const WCHAR arg_desktop[] = {'/','d','e','s','k','t','o','p'};

    LPWSTR p, p2;

99
    p2 = commandline;
100
    p = strchrW(commandline,'/');
101 102
    while(p)
    {
103
        if (strncmpW(p, arg_n, sizeof(arg_n)/sizeof(WCHAR))==0)
104 105
        {
            parameters->explorer_mode = FALSE;
106
            p += sizeof(arg_n)/sizeof(WCHAR);
107
        }
108
        else if (strncmpW(p, arg_e, sizeof(arg_e)/sizeof(WCHAR))==0)
109 110
        {
            parameters->explorer_mode = TRUE;
111
            p += sizeof(arg_e)/sizeof(WCHAR);
112
        }
113
        else if (strncmpW(p, arg_root, sizeof(arg_root)/sizeof(WCHAR))==0)
114
        {
115
            p += sizeof(arg_root)/sizeof(WCHAR);
116 117
            p+=CopyPathString(parameters->root,p);
        }
118
        else if (strncmpW(p, arg_select, sizeof(arg_select)/sizeof(WCHAR))==0)
119
        {
120
            p += sizeof(arg_select)/sizeof(WCHAR);
121 122 123 124 125
            p+=CopyPathString(parameters->selection,p);
            if (!parameters->root[0])
                CopyPathRoot(parameters->root,
                        parameters->selection);
        }
126
        else if (strncmpW(p, arg_desktop, sizeof(arg_desktop)/sizeof(WCHAR))==0)
127
        {
128 129
            p += sizeof(arg_desktop)/sizeof(WCHAR);
            manage_desktop( p );  /* the rest of the command line is handled by desktop mode */
130
        }
131 132
        else p++;

133
        p2 = p;
134
        p = strchrW(p,'/');
135 136 137 138 139 140 141 142
    }
    if (p2 && *p2)
    {
        /* left over command line is generally the path to be opened */
        CopyPathString(parameters->root,p2);
    }
}

143 144 145 146
int WINAPI wWinMain(HINSTANCE hinstance,
                    HINSTANCE previnstance,
                    LPWSTR cmdline,
                    int cmdshow)
147 148 149 150 151
{
    STARTUPINFOW si;
    PROCESS_INFORMATION info;
    parameters_struct   parameters;
    BOOL rc;
152
    static const WCHAR winefile[] = {'\\','w','i','n','e','f','i','l','e','.','e','x','e',0};
153
    static const WCHAR space[] = {' ',0};
154 155
    LPWSTR winefile_commandline = NULL;
    DWORD len = 0;
156 157 158 159 160

    memset(&parameters,0,sizeof(parameters));
    memset(&si,0,sizeof(STARTUPINFOW));

    ParseCommandLine(cmdline,&parameters);
161 162 163 164 165 166 167 168
    len = GetSystemDirectoryW( NULL, 0 ) + sizeof(winefile)/sizeof(WCHAR);

    if (parameters.selection[0]) len += lstrlenW(parameters.selection) + 2;
    else if (parameters.root[0]) len += lstrlenW(parameters.root) + 3;

    winefile_commandline = HeapAlloc(GetProcessHeap(),0,len*sizeof(WCHAR));
    GetSystemDirectoryW( winefile_commandline, len );
    lstrcatW(winefile_commandline,winefile);
169

170
    if (parameters.selection[0])
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
    {
        lstrcatW(winefile_commandline,space);
        lstrcatW(winefile_commandline,parameters.selection);
    }
    else if (parameters.root[0])
    {
        lstrcatW(winefile_commandline,space);
        lstrcatW(winefile_commandline,parameters.root);
        if (winefile_commandline[lstrlenW(winefile_commandline)-1]!='\\')
        {
            static const WCHAR slash[] = {'\\',0};
            lstrcatW(winefile_commandline,slash);
        }
    }

    rc = CreateProcessW(NULL, winefile_commandline, NULL, NULL, FALSE, 0, NULL,
187
                        parameters.root[0] ? parameters.root:NULL, &si, &info);
188 189

    HeapFree(GetProcessHeap(),0,winefile_commandline);
190

191 192 193
    if (!rc)
        return 0;

194
    CloseHandle(info.hThread);
195
    WaitForSingleObject(info.hProcess,INFINITE);
196
    CloseHandle(info.hProcess);
197 198
    return 0;
}