| /* |
| * explorer.exe |
| * |
| * Copyright 2004 CodeWeavers, Mike Hearn |
| * Copyright 2005,2006 CodeWeavers, Aric Stewart |
| * |
| * 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 |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
| */ |
| |
| #include <windows.h> |
| |
| #include "wine/unicode.h" |
| #include "explorer_private.h" |
| |
| typedef struct parametersTAG { |
| BOOL explorer_mode; |
| WCHAR root[MAX_PATH]; |
| WCHAR selection[MAX_PATH]; |
| } parameters_struct; |
| |
| |
| static int CopyPathString(LPWSTR target, LPWSTR source) |
| { |
| INT i = 0; |
| |
| while (isspaceW(*source)) source++; |
| |
| if (*source == '\"') |
| { |
| source ++; |
| while (*source != '\"') target[i++] = *source++; |
| target[i] = 0; |
| source ++; |
| i+=2; |
| } |
| else |
| { |
| while (*source && !isspaceW(*source)) target[i++] = *source++; |
| target[i] = 0; |
| } |
| 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 |
| */ |
| static void ParseCommandLine(LPWSTR commandline,parameters_struct *parameters) |
| { |
| 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; |
| |
| p2 = commandline; |
| p = strchrW(commandline,'/'); |
| while(p) |
| { |
| if (strncmpW(p, arg_n, sizeof(arg_n)/sizeof(WCHAR))==0) |
| { |
| parameters->explorer_mode = FALSE; |
| p += sizeof(arg_n)/sizeof(WCHAR); |
| } |
| else if (strncmpW(p, arg_e, sizeof(arg_e)/sizeof(WCHAR))==0) |
| { |
| parameters->explorer_mode = TRUE; |
| p += sizeof(arg_e)/sizeof(WCHAR); |
| } |
| else if (strncmpW(p, arg_root, sizeof(arg_root)/sizeof(WCHAR))==0) |
| { |
| p += sizeof(arg_root)/sizeof(WCHAR); |
| p+=CopyPathString(parameters->root,p); |
| } |
| else if (strncmpW(p, arg_select, sizeof(arg_select)/sizeof(WCHAR))==0) |
| { |
| p += sizeof(arg_select)/sizeof(WCHAR); |
| p+=CopyPathString(parameters->selection,p); |
| if (!parameters->root[0]) |
| CopyPathRoot(parameters->root, |
| parameters->selection); |
| } |
| else if (strncmpW(p, arg_desktop, sizeof(arg_desktop)/sizeof(WCHAR))==0) |
| { |
| p += sizeof(arg_desktop)/sizeof(WCHAR); |
| manage_desktop( p ); /* the rest of the command line is handled by desktop mode */ |
| } |
| else p++; |
| |
| p2 = p; |
| p = strchrW(p,'/'); |
| } |
| if (p2 && *p2) |
| { |
| /* left over command line is generally the path to be opened */ |
| CopyPathString(parameters->root,p2); |
| } |
| } |
| |
| int WINAPI wWinMain(HINSTANCE hinstance, |
| HINSTANCE previnstance, |
| LPWSTR cmdline, |
| int cmdshow) |
| { |
| STARTUPINFOW si; |
| PROCESS_INFORMATION info; |
| parameters_struct parameters; |
| BOOL rc; |
| static const WCHAR winefile[] = {'\\','w','i','n','e','f','i','l','e','.','e','x','e',0}; |
| static const WCHAR space[] = {' ',0}; |
| WCHAR app[MAX_PATH]; |
| LPWSTR winefile_commandline = NULL; |
| DWORD len = 0; |
| |
| memset(¶meters,0,sizeof(parameters)); |
| memset(&si,0,sizeof(STARTUPINFOW)); |
| |
| ParseCommandLine(cmdline,¶meters); |
| 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( app, MAX_PATH - sizeof(winefile)/sizeof(WCHAR) ); |
| strcatW( app, winefile ); |
| strcpyW( winefile_commandline, app ); |
| |
| if (parameters.selection[0]) |
| { |
| 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(app, winefile_commandline, NULL, NULL, FALSE, 0, NULL, |
| parameters.root[0] ? parameters.root:NULL, &si, &info); |
| |
| HeapFree(GetProcessHeap(),0,winefile_commandline); |
| |
| if (!rc) |
| return 0; |
| |
| CloseHandle(info.hThread); |
| WaitForSingleObject(info.hProcess,INFINITE); |
| CloseHandle(info.hProcess); |
| return 0; |
| } |