explorer: Remove useless array NULL check (Coverity).
[wine/multimedia.git] / programs / explorer / explorer.c
blob0dc82cfa521a745e80dd44d76e4022326fafc1bf
1 /*
2 * explorer.exe
4 * Copyright 2004 CodeWeavers, Mike Hearn
5 * Copyright 2005,2006 CodeWeavers, Aric Stewart
6 * Copyright 2011 Jay Yang
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #define COBJMACROS
25 #include "wine/unicode.h"
26 #include "wine/debug.h"
27 #include "explorer_private.h"
28 #include "resource.h"
30 #include <initguid.h>
31 #include <windows.h>
32 #include <shobjidl.h>
33 #include <shlobj.h>
36 WINE_DEFAULT_DEBUG_CHANNEL(explorer);
38 #define EXPLORER_INFO_INDEX 0
40 #define DEFAULT_WIDTH 640
41 #define DEFAULT_HEIGHT 480
44 static const WCHAR EXPLORER_CLASS[] = {'W','I','N','E','_','E','X','P','L','O','R','E','R','\0'};
46 HINSTANCE explorer_hInstance;
48 typedef struct parametersTAG {
49 BOOL explorer_mode;
50 WCHAR root[MAX_PATH];
51 WCHAR selection[MAX_PATH];
52 } parameters_struct;
54 typedef struct
56 IExplorerBrowser *browser;
57 } explorer_info;
59 static void make_explorer_window(IShellFolder* startFolder)
61 RECT explorerRect;
62 HWND window;
63 FOLDERSETTINGS fs;
64 explorer_info *info;
65 HRESULT hres;
66 WCHAR explorer_title[100];
67 LoadStringW(explorer_hInstance,IDS_EXPLORER_TITLE,explorer_title,
68 sizeof(explorer_title)/sizeof(WCHAR));
69 info = HeapAlloc(GetProcessHeap(),0,sizeof(explorer_info));
70 if(!info)
72 WINE_ERR("Could not allocate a explorer_info struct\n");
73 return;
75 hres = CoCreateInstance(&CLSID_ExplorerBrowser,NULL,CLSCTX_INPROC_SERVER,
76 &IID_IExplorerBrowser,(LPVOID*)&info->browser);
77 if(!SUCCEEDED(hres))
79 WINE_ERR("Could not obtain an instance of IExplorerBrowser\n");
80 HeapFree(GetProcessHeap(),0,info);
81 return;
84 window = CreateWindowW(EXPLORER_CLASS,explorer_title,WS_OVERLAPPEDWINDOW,
85 CW_USEDEFAULT,CW_USEDEFAULT,DEFAULT_WIDTH,
86 DEFAULT_HEIGHT,NULL,NULL,explorer_hInstance,NULL);
87 fs.ViewMode = FVM_DETAILS;
88 fs.fFlags = FWF_AUTOARRANGE;
89 explorerRect.left = 0;
90 explorerRect.top = 0;
91 explorerRect.right = DEFAULT_WIDTH;
92 explorerRect.bottom = DEFAULT_HEIGHT;
94 IExplorerBrowser_Initialize(info->browser,window,&explorerRect,&fs);
95 IExplorerBrowser_SetOptions(info->browser,EBO_SHOWFRAMES);
96 SetWindowLongPtrW(window,EXPLORER_INFO_INDEX,(LONG_PTR)info);
97 IExplorerBrowser_BrowseToObject(info->browser,(IUnknown*)startFolder,
98 SBSP_ABSOLUTE);
99 ShowWindow(window,SW_SHOWDEFAULT);
100 UpdateWindow(window);
103 static void update_window_size(explorer_info *info, int height, int width)
105 RECT new_rect;
106 new_rect.left = 0;
107 new_rect.top = 0;
108 new_rect.right = width;
109 new_rect.bottom = height;
110 IExplorerBrowser_SetRect(info->browser,NULL,new_rect);
113 static void do_exit(int code)
115 OleUninitialize();
116 ExitProcess(code);
119 static LRESULT CALLBACK explorer_wnd_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
121 explorer_info *info
122 = (explorer_info*)GetWindowLongPtrW(hwnd,EXPLORER_INFO_INDEX);
123 IExplorerBrowser *browser = NULL;
125 if(info)
126 browser = info->browser;
127 switch(uMsg)
129 case WM_DESTROY:
130 IExplorerBrowser_Release(browser);
131 HeapFree(GetProcessHeap(),0,info);
132 PostQuitMessage(0);
133 break;
134 case WM_QUIT:
135 do_exit(wParam);
136 case WM_SIZE:
137 update_window_size(info,HIWORD(lParam),LOWORD(lParam));
138 break;
139 default:
140 return DefWindowProcW(hwnd,uMsg,wParam,lParam);
142 return 0;
145 static void register_explorer_window_class(void)
147 WNDCLASSEXW window_class;
148 window_class.cbSize = sizeof(WNDCLASSEXW);
149 window_class.style = 0;
150 window_class.cbClsExtra = 0;
151 window_class.cbWndExtra = sizeof(LONG_PTR);
152 window_class.lpfnWndProc = explorer_wnd_proc;
153 window_class.hInstance = explorer_hInstance;
154 window_class.hIcon = NULL;
155 window_class.hCursor = NULL;
156 window_class.hbrBackground = NULL;
157 window_class.lpszMenuName = NULL;
158 window_class.lpszClassName = EXPLORER_CLASS;
159 window_class.hIconSm = NULL;
160 RegisterClassExW(&window_class);
163 static IShellFolder* get_starting_shell_folder(parameters_struct* params)
165 IShellFolder* desktop,*folder;
166 LPITEMIDLIST root_pidl;
167 HRESULT hres;
169 SHGetDesktopFolder(&desktop);
170 if (!params->root[0])
172 return desktop;
174 hres = IShellFolder_ParseDisplayName(desktop,NULL,NULL,
175 params->root,NULL,
176 &root_pidl,NULL);
178 if(FAILED(hres))
180 return desktop;
182 hres = IShellFolder_BindToObject(desktop,root_pidl,NULL,
183 &IID_IShellFolder,
184 (void**)&folder);
185 if(FAILED(hres))
187 return desktop;
189 IShellFolder_Release(desktop);
190 return folder;
193 static int copy_path_string(LPWSTR target, LPWSTR source)
195 INT i = 0;
197 while (isspaceW(*source)) source++;
199 if (*source == '\"')
201 source ++;
202 while (*source != '\"') target[i++] = *source++;
203 target[i] = 0;
204 source ++;
205 i+=2;
207 else
209 while (*source && !isspaceW(*source)) target[i++] = *source++;
210 target[i] = 0;
212 return i;
216 static void copy_path_root(LPWSTR root, LPWSTR path)
218 LPWSTR p,p2;
219 INT i = 0;
221 p = path;
222 while (*p!=0)
223 p++;
225 while (*p!='\\' && p > path)
226 p--;
228 if (p == path)
229 return;
231 p2 = path;
232 while (p2 != p)
234 root[i] = *p2;
235 i++;
236 p2++;
238 root[i] = 0;
242 * Command Line parameters are:
243 * [/n] Opens in single-paned view for each selected items. This is default
244 * [/e,] Uses Windows Explorer View
245 * [/root,object] Specifies the root level of the view
246 * [/select,object] parent folder is opened and specified object is selected
248 static void parse_command_line(LPWSTR commandline,parameters_struct *parameters)
250 static const WCHAR arg_n[] = {'/','n'};
251 static const WCHAR arg_e[] = {'/','e',','};
252 static const WCHAR arg_root[] = {'/','r','o','o','t',','};
253 static const WCHAR arg_select[] = {'/','s','e','l','e','c','t',','};
254 static const WCHAR arg_desktop[] = {'/','d','e','s','k','t','o','p'};
256 LPWSTR p, p2;
258 p2 = commandline;
259 p = strchrW(commandline,'/');
260 while(p)
262 if (strncmpW(p, arg_n, sizeof(arg_n)/sizeof(WCHAR))==0)
264 parameters->explorer_mode = FALSE;
265 p += sizeof(arg_n)/sizeof(WCHAR);
267 else if (strncmpW(p, arg_e, sizeof(arg_e)/sizeof(WCHAR))==0)
269 parameters->explorer_mode = TRUE;
270 p += sizeof(arg_e)/sizeof(WCHAR);
272 else if (strncmpW(p, arg_root, sizeof(arg_root)/sizeof(WCHAR))==0)
274 p += sizeof(arg_root)/sizeof(WCHAR);
275 p+=copy_path_string(parameters->root,p);
277 else if (strncmpW(p, arg_select, sizeof(arg_select)/sizeof(WCHAR))==0)
279 p += sizeof(arg_select)/sizeof(WCHAR);
280 p+=copy_path_string(parameters->selection,p);
281 if (!parameters->root[0])
282 copy_path_root(parameters->root,
283 parameters->selection);
285 else if (strncmpW(p, arg_desktop, sizeof(arg_desktop)/sizeof(WCHAR))==0)
287 p += sizeof(arg_desktop)/sizeof(WCHAR);
288 manage_desktop( p ); /* the rest of the command line is handled by desktop mode */
290 else p++;
292 p2 = p;
293 p = strchrW(p,'/');
295 if (p2 && *p2)
297 /* left over command line is generally the path to be opened */
298 copy_path_string(parameters->root,p2);
302 int WINAPI wWinMain(HINSTANCE hinstance,
303 HINSTANCE previnstance,
304 LPWSTR cmdline,
305 int cmdshow)
308 parameters_struct parameters;
309 HRESULT hres;
310 MSG msg;
311 IShellFolder *folder;
313 memset(&parameters,0,sizeof(parameters));
314 explorer_hInstance = hinstance;
315 parse_command_line(cmdline,&parameters);
316 hres = OleInitialize(NULL);
317 if(!SUCCEEDED(hres))
319 WINE_ERR("Could not initialize COM\n");
320 ExitProcess(EXIT_FAILURE);
322 register_explorer_window_class();
323 folder = get_starting_shell_folder(&parameters);
324 make_explorer_window(folder);
325 IShellFolder_Release(folder);
326 while(GetMessageW( &msg, NULL, 0, 0 ) != 0)
328 TranslateMessage(&msg);
329 DispatchMessageW(&msg);
331 return 0;