* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include <precomp.h>
+#include "precomp.h"
+#include "shell32_version.h"
+#include <reactos/version.h>
WINE_DEFAULT_DEBUG_CHANNEL(shell);
-const char * const SHELL_Authors[] = { "Copyright 1993-2009 WINE team", "Copyright 1998-2009 ReactOS Team", 0 };
+const char * const SHELL_Authors[] = { "Copyright 1993-"COPYRIGHT_YEAR" WINE team", "Copyright 1998-"COPYRIGHT_YEAR" ReactOS Team", 0 };
#define MORE_DEBUG 1
/*************************************************************************
* '"a b"' -> 'a b'
* - escaped quotes must be converted back to '"'
* '\"' -> '"'
- * - an odd number of '\'s followed by '"' correspond to half that number
- * of '\' followed by a '"' (extension of the above)
- * '\\\"' -> '\"'
- * '\\\\\"' -> '\\"'
- * - an even number of '\'s followed by a '"' correspond to half that number
- * of '\', plus a regular quote serving as an argument delimiter (which
- * means it does not appear in the result)
- * 'a\\"b c"' -> 'a\b c'
- * 'a\\\\"b c"' -> 'a\\b c'
- * - '\' that are not followed by a '"' are copied literally
+ * - consecutive backslashes preceding a quote see their number halved with
+ * the remainder escaping the quote:
+ * 2n backslashes + quote -> n backslashes + quote as an argument delimiter
+ * 2n+1 backslashes + quote -> n backslashes + literal quote
+ * - backslashes that are not followed by a quote are copied literally:
* 'a\b' -> 'a\b'
* 'a\\b' -> 'a\\b'
- *
- * Note:
- * '\t' == 0x0009
- * ' ' == 0x0020
- * '"' == 0x0022
- * '\\' == 0x005c
+ * - in quoted strings, consecutive quotes see their number divided by three
+ * with the remainder modulo 3 deciding whether to close the string or not.
+ * Note that the opening quote must be counted in the consecutive quotes,
+ * that's the (1+) below:
+ * (1+) 3n quotes -> n quotes
+ * (1+) 3n+1 quotes -> n quotes plus closes the quoted string
+ * (1+) 3n+2 quotes -> n+1 quotes plus closes the quoted string
+ * - in unquoted strings, the first quote opens the quoted string and the
+ * remaining consecutive quotes follow the above rule.
*/
LPWSTR* WINAPI CommandLineToArgvW(LPCWSTR lpCmdline, int* numargs)
{
DWORD argc;
LPWSTR *argv;
- LPCWSTR cs;
- LPWSTR arg,s,d;
+ LPCWSTR s;
+ LPWSTR d;
LPWSTR cmdline;
- int in_quotes,bcount;
+ int qcount,bcount;
+
+ if(!numargs)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
if (*lpCmdline==0)
{
/* Return the path to the executable */
- DWORD len, size=16;
+ DWORD len, deslen=MAX_PATH, size;
- argv = (LPWSTR *)LocalAlloc(LMEM_FIXED, size);
+ size = sizeof(LPWSTR) + deslen*sizeof(WCHAR) + sizeof(LPWSTR);
for (;;)
{
- len = GetModuleFileNameW(0, (LPWSTR)(argv+1), (size-sizeof(LPWSTR))/sizeof(WCHAR));
+ if (!(argv = (LPWSTR *)LocalAlloc(LMEM_FIXED, size))) return NULL;
+ len = GetModuleFileNameW(0, (LPWSTR)(argv+1), deslen);
if (!len)
{
LocalFree(argv);
return NULL;
}
- if (len < size) break;
- size*=2;
- argv = (LPWSTR *)LocalReAlloc(argv, size, 0);
+ if (len < deslen) break;
+ deslen*=2;
+ size = sizeof(LPWSTR) + deslen*sizeof(WCHAR) + sizeof(LPWSTR);
+ LocalFree( argv );
}
argv[0]=(LPWSTR)(argv+1);
- if (numargs)
- *numargs=1;
+ *numargs=1;
return argv;
}
- /* to get a writable copy */
- argc=0;
- bcount=0;
- in_quotes=0;
- cs=lpCmdline;
- while (1)
+ /* --- First count the arguments */
+ argc=1;
+ s=lpCmdline;
+ /* The first argument, the executable path, follows special rules */
+ if (*s=='"')
{
- if (*cs==0 || ((*cs==0x0009 || *cs==0x0020) && !in_quotes))
- {
- /* space */
- argc++;
- /* skip the remaining spaces */
- while (*cs==0x0009 || *cs==0x0020)
- {
- cs++;
- }
- if (*cs==0)
+ /* The executable path ends at the next quote, no matter what */
+ s++;
+ while (*s)
+ if (*s++=='"')
break;
+ }
+ else
+ {
+ /* The executable path ends at the next space, no matter what */
+ while (*s && *s!=' ' && *s!='\t')
+ s++;
+ }
+ /* skip to the first argument, if any */
+ while (*s==' ' || *s=='\t')
+ s++;
+ if (*s)
+ argc++;
+
+ /* Analyze the remaining arguments */
+ qcount=bcount=0;
+ while (*s)
+ {
+ if ((*s==' ' || *s=='\t') && qcount==0)
+ {
+ /* skip to the next argument and count it if any */
+ while (*s==' ' || *s=='\t')
+ s++;
+ if (*s)
+ argc++;
bcount=0;
- continue;
}
- else if (*cs==0x005c)
+ else if (*s=='\\')
{
/* '\', count them */
bcount++;
+ s++;
}
- else if ((*cs==0x0022) && ((bcount & 1)==0))
+ else if (*s=='"')
{
- /* unescaped '"' */
- in_quotes=!in_quotes;
+ /* '"' */
+ if ((bcount & 1)==0)
+ qcount++; /* unescaped '"' */
+ s++;
bcount=0;
+ /* consecutive quotes, see comment in copying code below */
+ while (*s=='"')
+ {
+ qcount++;
+ s++;
+ }
+ qcount=qcount % 3;
+ if (qcount==2)
+ qcount=0;
}
else
{
/* a regular character */
bcount=0;
+ s++;
}
- cs++;
}
- /* Allocate in a single lump, the string array, and the strings that go with it.
- * This way the caller can make a single GlobalFree call to free both, as per MSDN.
+
+ /* Allocate in a single lump, the string array, and the strings that go
+ * with it. This way the caller can make a single LocalFree() call to free
+ * both, as per MSDN.
*/
- argv = (LPWSTR *)LocalAlloc(LMEM_FIXED, argc*sizeof(LPWSTR)+(wcslen(lpCmdline)+1)*sizeof(WCHAR));
-
+ argv=(LPWSTR *)LocalAlloc(LMEM_FIXED, argc*sizeof(LPWSTR)+(strlenW(lpCmdline)+1)*sizeof(WCHAR));
if (!argv)
return NULL;
-
cmdline=(LPWSTR)(argv+argc);
- wcscpy(cmdline, lpCmdline);
+ strcpyW(cmdline, lpCmdline);
- argc=0;
- bcount=0;
- in_quotes=0;
- arg=d=s=cmdline;
+ /* --- Then split and copy the arguments */
+ argv[0]=d=cmdline;
+ argc=1;
+ /* The first argument, the executable path, follows special rules */
+ if (*d=='"')
+ {
+ /* The executable path ends at the next quote, no matter what */
+ s=d+1;
+ while (*s)
+ {
+ if (*s=='"')
+ {
+ s++;
+ break;
+ }
+ *d++=*s++;
+ }
+ }
+ else
+ {
+ /* The executable path ends at the next space, no matter what */
+ while (*d && *d!=' ' && *d!='\t')
+ d++;
+ s=d;
+ if (*s)
+ s++;
+ }
+ /* close the executable path */
+ *d++=0;
+ /* skip to the first argument and initialize it if any */
+ while (*s==' ' || *s=='\t')
+ s++;
+ if (!*s)
+ {
+ /* There are no parameters so we are all done */
+ *numargs=argc;
+ return argv;
+ }
+
+ /* Split and copy the remaining arguments */
+ argv[argc++]=d;
+ qcount=bcount=0;
while (*s)
{
- if ((*s==0x0009 || *s==0x0020) && !in_quotes)
+ if ((*s==' ' || *s=='\t') && qcount==0)
{
- /* Close the argument and copy it */
- *d=0;
- argv[argc++]=arg;
+ /* close the argument */
+ *d++=0;
+ bcount=0;
- /* skip the remaining spaces */
+ /* skip to the next one and initialize it if any */
do {
s++;
- } while (*s==0x0009 || *s==0x0020);
-
- /* Start with a new argument */
- arg=d=s;
- bcount=0;
+ } while (*s==' ' || *s=='\t');
+ if (*s)
+ argv[argc++]=d;
}
- else if (*s==0x005c)
+ else if (*s=='\\')
{
- /* '\\' */
*d++=*s++;
bcount++;
}
- else if (*s==0x0022)
+ else if (*s=='"')
{
- /* '"' */
if ((bcount & 1)==0)
{
/* Preceded by an even number of '\', this is half that
* number of '\', plus a quote which we erase.
*/
d-=bcount/2;
- in_quotes=!in_quotes;
- s++;
+ qcount++;
}
else
{
*/
d=d-bcount/2-1;
*d++='"';
- s++;
}
+ s++;
bcount=0;
+ /* Now count the number of consecutive quotes. Note that qcount
+ * already takes into account the opening quote if any, as well as
+ * the quote that lead us here.
+ */
+ while (*s=='"')
+ {
+ if (++qcount==3)
+ {
+ *d++='"';
+ qcount=0;
+ }
+ s++;
+ }
+ if (qcount==2)
+ qcount=0;
}
else
{
bcount=0;
}
}
- if (*arg)
- {
- *d='\0';
- argv[argc++]=arg;
- }
- if (numargs)
- *numargs=argc;
+ *d='\0';
+ *numargs=argc;
return argv;
}
SetFilePointer( hfile, mz_header.e_lfanew, NULL, SEEK_SET );
ReadFile( hfile, magic, sizeof(magic), &len, NULL );
-
+
if ( *(DWORD*)magic == IMAGE_NT_SIGNATURE )
{
SetFilePointer( hfile, mz_header.e_lfanew, NULL, SEEK_SET );
ReadFile( hfile, &nt, sizeof(nt), &len, NULL );
CloseHandle( hfile );
-
+
/* DLL files are not executable and should return 0 */
if (nt.FileHeader.Characteristics & IMAGE_FILE_DLL)
return 0;
-
+
if (nt.OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI)
{
return IMAGE_NT_SIGNATURE |
SetFilePointer( hfile, mz_header.e_lfanew, NULL, SEEK_SET );
ReadFile( hfile, &ne, sizeof(ne), &len, NULL );
CloseHandle( hfile );
-
+
if (ne.ne_exetyp == 2)
return IMAGE_OS2_SIGNATURE | (ne.ne_expver << 16);
return 0;
GetSystemMetrics( SM_CXICON),
GetSystemMetrics( SM_CYICON),
&psfi->hIcon, 0, 1, 0);
-
+
if (ret != 0 && ret != 0xFFFFFFFF)
{
IconNotYetLoaded=FALSE;
const char* const *pstr = SHELL_Authors;
// Add the authors to the list
- SendDlgItemMessageW( hWnd, IDC_SHELL_ABOUT_AUTHORS_LISTBOX, WM_SETREDRAW, FALSE, 0 );
+ SendDlgItemMessageW( hWnd, IDC_ABOUT_AUTHORS_LISTBOX, WM_SETREDRAW, FALSE, 0 );
while (*pstr)
{
/* authors list is in utf-8 format */
MultiByteToWideChar( CP_UTF8, 0, *pstr, -1, name, sizeof(name)/sizeof(WCHAR) );
- SendDlgItemMessageW( hWnd, IDC_SHELL_ABOUT_AUTHORS_LISTBOX, LB_ADDSTRING, (WPARAM)-1, (LPARAM)name );
+ SendDlgItemMessageW( hWnd, IDC_ABOUT_AUTHORS_LISTBOX, LB_ADDSTRING, (WPARAM)-1, (LPARAM)name );
pstr++;
}
- SendDlgItemMessageW( hWnd, IDC_SHELL_ABOUT_AUTHORS_LISTBOX, WM_SETREDRAW, TRUE, 0 );
+ SendDlgItemMessageW( hWnd, IDC_ABOUT_AUTHORS_LISTBOX, WM_SETREDRAW, TRUE, 0 );
return TRUE;
}
}
// Set App-specific stuff (icon, app name, szOtherStuff string)
- SendDlgItemMessageW(hWnd, IDC_SHELL_ABOUT_ICON, STM_SETICON, (WPARAM)info->hIcon, 0);
+ SendDlgItemMessageW(hWnd, IDC_ABOUT_ICON, STM_SETICON, (WPARAM)info->hIcon, 0);
GetWindowTextW( hWnd, szAppTitleTemplate, sizeof(szAppTitleTemplate) / sizeof(WCHAR) );
swprintf( szAppTitle, szAppTitleTemplate, info->szApp );
SetWindowTextW( hWnd, szAppTitle );
- SetDlgItemTextW( hWnd, IDC_SHELL_ABOUT_APPNAME, info->szApp );
- SetDlgItemTextW( hWnd, IDC_SHELL_ABOUT_OTHERSTUFF, info->szOtherStuff );
+ SetDlgItemTextW( hWnd, IDC_ABOUT_APPNAME, info->szApp );
+ SetDlgItemTextW( hWnd, IDC_ABOUT_OTHERSTUFF, info->szOtherStuff );
// Set the registered user and organization name
if(RegOpenKeyExW( HKEY_LOCAL_MACHINE, szRegKey, 0, KEY_QUERY_VALUE, &hRegKey ) == ERROR_SUCCESS)
{
- SetRegTextData( hWnd, hRegKey, L"RegisteredOwner", IDC_SHELL_ABOUT_REG_USERNAME );
- SetRegTextData( hWnd, hRegKey, L"RegisteredOrganization", IDC_SHELL_ABOUT_REG_ORGNAME );
+ SetRegTextData( hWnd, hRegKey, L"RegisteredOwner", IDC_ABOUT_REG_USERNAME );
+ SetRegTextData( hWnd, hRegKey, L"RegisteredOrganization", IDC_ABOUT_REG_ORGNAME );
RegCloseKey( hRegKey );
}
swprintf( szBuf, L"%u MB", (UINT)MemStat.ullTotalPhys / 1024 / 1024 );
}
- SetDlgItemTextW( hWnd, IDC_SHELL_ABOUT_PHYSMEM, szBuf);
+ SetDlgItemTextW( hWnd, IDC_ABOUT_PHYSMEM, szBuf);
}
// Add the Authors dialog
- hWndAuthors = CreateDialogW( shell32_hInstance, MAKEINTRESOURCEW(IDD_SHELL_ABOUT_AUTHORS), hWnd, AboutAuthorsDlgProc );
+ hWndAuthors = CreateDialogW( shell32_hInstance, MAKEINTRESOURCEW(IDD_ABOUT_AUTHORS), hWnd, AboutAuthorsDlgProc );
LoadStringW( shell32_hInstance, IDS_SHELL_ABOUT_AUTHORS, szAuthorsText, sizeof(szAuthorsText) / sizeof(WCHAR) );
- SetDlgItemTextW( hWnd, IDC_SHELL_ABOUT_AUTHORS, szAuthorsText );
+ SetDlgItemTextW( hWnd, IDC_ABOUT_AUTHORS, szAuthorsText );
}
return TRUE;
PAINTSTRUCT ps;
HDC hdc;
HDC hdcMem;
-
+
hdc = BeginPaint(hWnd, &ps);
hdcMem = CreateCompatibleDC(hdc);
EndDialog(hWnd, TRUE);
return TRUE;
- case IDC_SHELL_ABOUT_AUTHORS:
+ case IDC_ABOUT_AUTHORS:
{
static BOOL bShowingAuthors = FALSE;
WCHAR szAuthorsText[20];
ShowWindow( hWndAuthors, SW_SHOW );
}
- SetDlgItemTextW( hWnd, IDC_SHELL_ABOUT_AUTHORS, szAuthorsText );
+ SetDlgItemTextW( hWnd, IDC_ABOUT_AUTHORS, szAuthorsText );
bShowingAuthors = !bShowingAuthors;
return TRUE;
}
TRACE("\n");
// DialogBoxIndirectParamW will be called with the hInstance of the calling application, so we have to preload the dialog template
- if(!(hRes = FindResourceW(shell32_hInstance, MAKEINTRESOURCEW(IDD_SHELL_ABOUT), (LPWSTR)RT_DIALOG)))
+ hRes = FindResourceW(shell32_hInstance, MAKEINTRESOURCEW(IDD_ABOUT), (LPWSTR)RT_DIALOG);
+ if(!hRes)
return FALSE;
- if(!(DlgTemplate = (DLGTEMPLATE *)LoadResource(shell32_hInstance, hRes)))
+
+ DlgTemplate = (DLGTEMPLATE *)LoadResource(shell32_hInstance, hRes);
+ if(!DlgTemplate)
return FALSE;
info.szApp = szApp;
/*************************************************************************
* SHLoadNonloadedIconOverlayIdentifiers (SHELL32.@)
*/
-EXTERN_C HRESULT WINAPI SHLoadNonloadedIconOverlayIdentifiers( VOID )
+EXTERN_C HRESULT WINAPI SHLoadNonloadedIconOverlayIdentifiers(VOID)
{
FIXME("stub\n");
return S_OK;
BEGIN_OBJECT_MAP(ObjectMap)
-OBJECT_ENTRY(CLSID_ShellFSFolder, CFSFolder)
-OBJECT_ENTRY(CLSID_MyComputer, CDrivesFolder)
-OBJECT_ENTRY(CLSID_ShellDesktop, CDesktopFolder)
-OBJECT_ENTRY(CLSID_ShellItem, ShellItem)
-OBJECT_ENTRY(CLSID_ShellLink, ShellLink)
-OBJECT_ENTRY(CLSID_DragDropHelper, IDropTargetHelperImpl)
-OBJECT_ENTRY(CLSID_ControlPanel, CControlPanelFolder)
-OBJECT_ENTRY(CLSID_AutoComplete, CAutoComplete)
-OBJECT_ENTRY(CLSID_MyDocuments, CMyDocsFolder)
-OBJECT_ENTRY(CLSID_NetworkPlaces, CNetFolder)
-OBJECT_ENTRY(CLSID_FontsFolderShortcut, CFontsFolder)
-OBJECT_ENTRY(CLSID_Printers, CPrinterFolder)
-OBJECT_ENTRY(CLSID_AdminFolderShortcut, CAdminToolsFolder)
-OBJECT_ENTRY(CLSID_RecycleBin, CBitBucket)
-OBJECT_ENTRY(CLSID_OpenWithMenu, COpenWithMenu)
-OBJECT_ENTRY(CLSID_NewMenu, CNewMenu)
-OBJECT_ENTRY(CLSID_StartMenu, CStartMenuCallback)
-OBJECT_ENTRY(CLSID_MenuBandSite, CMenuBandSite)
+ OBJECT_ENTRY(CLSID_ShellFSFolder, CFSFolder)
+ OBJECT_ENTRY(CLSID_MyComputer, CDrivesFolder)
+ OBJECT_ENTRY(CLSID_ShellDesktop, CDesktopFolder)
+ OBJECT_ENTRY(CLSID_ShellItem, CShellItem)
+ OBJECT_ENTRY(CLSID_ShellLink, CShellLink)
+ OBJECT_ENTRY(CLSID_DragDropHelper, CDropTargetHelper)
+ OBJECT_ENTRY(CLSID_ControlPanel, CControlPanelFolder)
+ OBJECT_ENTRY(CLSID_AutoComplete, CAutoComplete)
+ OBJECT_ENTRY(CLSID_MyDocuments, CMyDocsFolder)
+ OBJECT_ENTRY(CLSID_NetworkPlaces, CNetFolder)
+ OBJECT_ENTRY(CLSID_FontsFolderShortcut, CFontsFolder)
+ OBJECT_ENTRY(CLSID_Printers, CPrinterFolder)
+ OBJECT_ENTRY(CLSID_AdminFolderShortcut, CAdminToolsFolder)
+ OBJECT_ENTRY(CLSID_RecycleBin, CRecycleBin)
+ OBJECT_ENTRY(CLSID_OpenWithMenu, COpenWithMenu)
+ OBJECT_ENTRY(CLSID_NewMenu, CNewMenu)
+ OBJECT_ENTRY(CLSID_StartMenu, CStartMenu)
+ OBJECT_ENTRY(CLSID_MenuBandSite, CMenuBandSite)
+ OBJECT_ENTRY(CLSID_MenuBand, CMenuBand)
END_OBJECT_MAP()
CShell32Module gModule;
-/*
-static const struct {
- REFIID riid;
- LPFNCREATEINSTANCE lpfnCI;
-} InterfaceTable[] = {
- {CLSID_ShellFSFolder, &IFSFolder_Constructor},
- {CLSID_MyComputer, &ISF_MyComputer_Constructor},
- {CLSID_ShellDesktop, &ISF_Desktop_Constructor},
- {CLSID_ShellItem, &IShellItem_Constructor},
- {CLSID_ShellLink, &IShellLink_Constructor},
- {CLSID_DragDropHelper, &IDropTargetHelper_Constructor},
- {CLSID_ControlPanel, &IControlPanel_Constructor},
- {CLSID_AutoComplete, &IAutoComplete_Constructor},
- {CLSID_MyDocuments, &ISF_MyDocuments_Constructor},
- {CLSID_NetworkPlaces, &ISF_NetworkPlaces_Constructor},
- {CLSID_FontsFolderShortcut, &ISF_Fonts_Constructor},
- {CLSID_Printers, &ISF_Printers_Constructor},
- {CLSID_AdminFolderShortcut, &ISF_AdminTools_Constructor},
- {CLSID_RecycleBin, &RecycleBin_Constructor},
- {CLSID_OpenWithMenu, &SHEOW_Constructor},
- {CLSID_NewMenu, &INewItem_Constructor},
- {CLSID_StartMenu, &StartMenu_Constructor},
- {CLSID_MenuBandSite, &MenuBandSite_Constructor},
-};
-*/
-
/***********************************************************************
* DllGetVersion [SHELL32.@]
*
}
/***********************************************************************
- * DllRegisterServer (BROWSEUI.@)
+ * DllRegisterServer (SHELL32.@)
*/
STDAPI DllRegisterServer()
{
- return gModule.DllRegisterServer(FALSE);
+ HRESULT hr;
+
+ hr = gModule.DllRegisterServer(FALSE);
+ if (FAILED(hr))
+ return hr;
+
+ hr = gModule.UpdateRegistryFromResource(IDR_FOLDEROPTIONS, TRUE, NULL);
+ if (FAILED(hr))
+ return hr;
+
+ hr = SHELL_RegisterShellFolders();
+ if (FAILED(hr))
+ return hr;
+
+ return S_OK;
}
/***********************************************************************
- * DllUnregisterServer (BROWSEUI.@)
+ * DllUnregisterServer (SHELL32.@)
*/
STDAPI DllUnregisterServer()
{
- return gModule.DllUnregisterServer(FALSE);
+ HRESULT hr;
+
+ hr = gModule.DllUnregisterServer(FALSE);
+ if (FAILED(hr))
+ return hr;
+
+ hr = gModule.UpdateRegistryFromResource(IDR_FOLDEROPTIONS, FALSE, NULL);
+ if (FAILED(hr))
+ return hr;
+
+ return S_OK;
}
/*************************************************************************