systray: Correctly handle icon addition/deletion.
[wine] / programs / explorer / explorer.c
1 /*
2  * explorer.exe
3  *
4  * Copyright 2004 CodeWeavers, Mike Hearn
5  * Copyright 2005,2006 CodeWeavers, Aric Stewart
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * 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 #include <windows.h>
23 #include <ctype.h>
24
25 #include "explorer_private.h"
26
27 typedef struct parametersTAG {
28     BOOL    explorer_mode;
29     WCHAR   root[MAX_PATH];
30     WCHAR   selection[MAX_PATH];
31 } parameters_struct;
32
33
34 static int CopyPathString(LPWSTR target, LPSTR source)
35 {
36     CHAR temp_buf[MAX_PATH];
37     INT i = 0;
38
39     while (isspace(*source)) source++;
40
41     if (*source == '\"')
42     {
43         source ++;
44         while (*source != '\"')
45         {
46             temp_buf[i] = *source;
47             i++;
48             source++;
49         }
50         temp_buf[i] = 0;
51         source ++;
52         i+=2;
53     }
54     else
55     {
56         while (*source && !isspace(*source))
57         {
58             temp_buf[i] = *source;
59             i++;
60             source++;
61         }
62         temp_buf[i] = 0;
63     }
64     MultiByteToWideChar(CP_ACP,0,temp_buf,-1,target,MAX_PATH);
65     return i;
66 }
67
68
69 static void CopyPathRoot(LPWSTR root, LPWSTR path)
70 {
71     LPWSTR p,p2;
72     INT i = 0;
73
74     p = path;
75     while (*p!=0)
76         p++;
77
78     while (*p!='\\' && p > path)
79         p--;
80
81     if (p == path)
82         return;
83
84     p2 = path;
85     while (p2 != p)
86     {
87         root[i] = *p2;
88         i++;
89         p2++;
90     }
91     root[i] = 0;
92 }
93
94 /*
95  * Command Line parameters are:
96  * [/n]  Opens in single-paned view for each selected items. This is default
97  * [/e,] Uses Windows Explorer View
98  * [/root,object] Specifies the root level of the view
99  * [/select,object] parent folder is opened and specified object is selected
100  */
101 static void ParseCommandLine(LPSTR commandline,parameters_struct *parameters)
102 {
103     LPSTR p;
104     LPSTR p2;
105    
106     p2 = commandline;
107     p = strchr(commandline,'/');
108     while(p)
109     {
110         p++;
111         if (strncmp(p,"n",1)==0)
112         {
113             parameters->explorer_mode = FALSE;
114             p++;
115         }
116         else if (strncmp(p,"e,",2)==0)
117         {
118             parameters->explorer_mode = TRUE;
119             p+=2;
120         }
121         else if (strncmp(p,"root,",5)==0)
122         {
123             p+=5;
124             p+=CopyPathString(parameters->root,p);
125         }
126         else if (strncmp(p,"select,",7)==0)
127         {
128             p+=7;
129             p+=CopyPathString(parameters->selection,p);
130             if (!parameters->root[0])
131                 CopyPathRoot(parameters->root,
132                         parameters->selection);
133         }
134         else if (strncmp(p,"desktop",7)==0)
135         {
136             manage_desktop( p + 7 );  /* the rest of the command line is handled by desktop mode */
137         }
138         p2 = p;
139         p = strchr(p,'/');
140     }
141     if (p2 && *p2)
142     {
143         /* left over command line is generally the path to be opened */
144         CopyPathString(parameters->root,p2);
145     }
146 }
147
148 int WINAPI WinMain(HINSTANCE hinstance,
149                    HINSTANCE previnstance,
150                    LPSTR cmdline,
151                    int cmdshow)
152 {
153     STARTUPINFOW si;
154     PROCESS_INFORMATION info;
155     parameters_struct   parameters;
156     BOOL rc;
157     static const WCHAR winefile[] = {'\\','w','i','n','e','f','i','l','e','.','e','x','e',0};
158     static const WCHAR space[] = {' ',0};
159     LPWSTR winefile_commandline = NULL;
160     DWORD len = 0;
161
162     memset(&parameters,0,sizeof(parameters));
163     memset(&si,0,sizeof(STARTUPINFOW));
164
165     ParseCommandLine(cmdline,&parameters);
166     len = GetSystemDirectoryW( NULL, 0 ) + sizeof(winefile)/sizeof(WCHAR);
167
168     if (parameters.selection[0]) len += lstrlenW(parameters.selection) + 2;
169     else if (parameters.root[0]) len += lstrlenW(parameters.root) + 3;
170
171     winefile_commandline = HeapAlloc(GetProcessHeap(),0,len*sizeof(WCHAR));
172     GetSystemDirectoryW( winefile_commandline, len );
173     lstrcatW(winefile_commandline,winefile);
174
175     if (parameters.selection[0])
176     {
177         lstrcatW(winefile_commandline,space);
178         lstrcatW(winefile_commandline,parameters.selection);
179     }
180     else if (parameters.root[0])
181     {
182         lstrcatW(winefile_commandline,space);
183         lstrcatW(winefile_commandline,parameters.root);
184         if (winefile_commandline[lstrlenW(winefile_commandline)-1]!='\\')
185         {
186             static const WCHAR slash[] = {'\\',0};
187             lstrcatW(winefile_commandline,slash);
188         }
189     }
190
191     rc = CreateProcessW(NULL, winefile_commandline, NULL, NULL, FALSE, 0, NULL,
192                         parameters.root, &si, &info);
193
194     HeapFree(GetProcessHeap(),0,winefile_commandline);
195
196     if (!rc)
197         return 0;
198
199     WaitForSingleObject(info.hProcess,INFINITE);
200     return 0;
201 }