Author: akhaldi
Date: Fri Sep 17 10:26:17 2010
New Revision: 48786
URL:
http://svn.reactos.org/svn/reactos?rev=48786&view=rev
Log:
[SHELL32]
Johannes Anderwald:
- Improve parameter checks for IShellLinkA interface.
- Fix heap corruption when an invalid pointer is passed.
- Implement IPersistFile_fnGetCurFile.
- TODO: Add same checks to IShellLinkW interface and fix IShellLink[A|W]::GetPath /
SetPath / SetIdList / GetIdList logic.
Modified:
trunk/reactos/dll/win32/shell32/shelllink.c
Modified: trunk/reactos/dll/win32/shell32/shelllink.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shelllin…
==============================================================================
--- trunk/reactos/dll/win32/shell32/shelllink.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/shelllink.c [iso-8859-1] Fri Sep 17 10:26:17 2010
@@ -134,6 +134,7 @@
LPWSTR sComponent;
volume_info volume;
LPWSTR sLinkPath;
+ LPWSTR sCurFile;
BOOL bRunAs;
BOOL bDirty;
INT iIdOpen; /* id of the "Open" entry in the context menu
*/
@@ -186,6 +187,7 @@
/* strdup on the process heap */
static LPWSTR __inline HEAP_strdupAtoW( HANDLE heap, DWORD flags, LPCSTR str)
{
+ assert(str);
INT len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
LPWSTR p = HeapAlloc( heap, flags, len*sizeof (WCHAR) );
if( !p )
@@ -440,12 +442,22 @@
IStream_Release( stm );
if( SUCCEEDED( r ) )
- {
+ {
+ if ( This->sCurFile )
+ {
+ HeapFree(GetProcessHeap(), 0, This->sCurFile);
+ }
+ This->sCurFile = HeapAlloc(GetProcessHeap(), 0, (wcslen(pszFileName)+1) *
sizeof(WCHAR));
+ if ( This->sCurFile )
+ {
+ wcscpy(This->sCurFile, pszFileName);
+ }
+
StartLinkProcessor( pszFileName );
This->bDirty = FALSE;
}
- else
+ else
{
DeleteFileW( pszFileName );
WARN("Failed to create shortcut %s\n", debugstr_w(pszFileName) );
@@ -464,9 +476,27 @@
static HRESULT WINAPI IPersistFile_fnGetCurFile(IPersistFile* iface, LPOLESTR
*ppszFileName)
{
- IShellLinkImpl *This = impl_from_IPersistFile(iface);
- FIXME("(%p)\n",This);
- return NOERROR;
+ IShellLinkImpl *This = impl_from_IPersistFile(iface);
+
+ *ppszFileName = NULL;
+
+ if ( !This->sCurFile)
+ {
+ /* IPersistFile::GetCurFile called before IPersistFile::Save */
+ return S_FALSE;
+ }
+
+ *ppszFileName = CoTaskMemAlloc((wcslen(This->sCurFile)+1) * sizeof(WCHAR));
+ if (!*ppszFileName)
+ {
+ /* out of memory */
+ return E_OUTOFMEMORY;
+ }
+
+ /* copy last saved filename */
+ wcscpy(*ppszFileName, This->sCurFile);
+
+ return NOERROR;
}
static const IPersistFileVtbl pfvt =
@@ -1355,9 +1385,6 @@
TRACE("(%p)->(pfile=%p len=%u find_data=%p flags=%u)(%s)\n",
This, pszFile, cchMaxPath, pfd, fFlags, debugstr_w(This->sPath));
- if (This->sComponent || This->sProduct)
- return S_FALSE;
-
if (cchMaxPath)
pszFile[0] = 0;
if (This->sPath)
@@ -1414,10 +1441,13 @@
TRACE("(%p)->(pName=%s)\n", This, pszName);
HeapFree(GetProcessHeap(), 0, This->sDescription);
- This->sDescription = HEAP_strdupAtoW( GetProcessHeap(), 0, pszName);
- if ( !This->sDescription )
- return E_OUTOFMEMORY;
-
+ This->sDescription = NULL;
+
+ if ( pszName ) {
+ This->sDescription = HEAP_strdupAtoW( GetProcessHeap(), 0, pszName);
+ if ( !This->sDescription )
+ return E_OUTOFMEMORY;
+ }
This->bDirty = TRUE;
return S_OK;
@@ -1445,10 +1475,13 @@
TRACE("(%p)->(dir=%s)\n",This, pszDir);
HeapFree(GetProcessHeap(), 0, This->sWorkDir);
- This->sWorkDir = HEAP_strdupAtoW( GetProcessHeap(), 0, pszDir);
- if ( !This->sWorkDir )
- return E_OUTOFMEMORY;
-
+ This->sWorkDir = NULL;
+
+ if ( pszDir ) {
+ This->sWorkDir = HEAP_strdupAtoW( GetProcessHeap(), 0, pszDir);
+ if ( !This->sWorkDir )
+ return E_OUTOFMEMORY;
+ }
This->bDirty = TRUE;
return S_OK;
@@ -1476,9 +1509,13 @@
TRACE("(%p)->(args=%s)\n",This, pszArgs);
HeapFree(GetProcessHeap(), 0, This->sArgs);
- This->sArgs = HEAP_strdupAtoW( GetProcessHeap(), 0, pszArgs);
- if( !This->sArgs )
- return E_OUTOFMEMORY;
+ This->sArgs = NULL;
+
+ if ( pszArgs ) {
+ This->sArgs = HEAP_strdupAtoW( GetProcessHeap(), 0, pszArgs);
+ if( !This->sArgs )
+ return E_OUTOFMEMORY;
+ }
This->bDirty = TRUE;
@@ -1611,9 +1648,13 @@
TRACE("(%p)->(path=%s iicon=%u)\n",This, pszIconPath, iIcon);
HeapFree(GetProcessHeap(), 0, This->sIcoPath);
- This->sIcoPath = HEAP_strdupAtoW(GetProcessHeap(), 0, pszIconPath);
- if ( !This->sIcoPath )
- return E_OUTOFMEMORY;
+ This->sIcoPath = NULL;
+
+ if ( pszIconPath ) {
+ This->sIcoPath = HEAP_strdupAtoW(GetProcessHeap(), 0, pszIconPath);
+ if ( !This->sIcoPath )
+ return E_OUTOFMEMORY;
+ }
This->iIcoNdx = iIcon;
This->bDirty = TRUE;
@@ -1628,7 +1669,15 @@
TRACE("(%p)->(path=%s %x)\n",This, pszPathRel, dwReserved);
HeapFree(GetProcessHeap(), 0, This->sPathRel);
- This->sPathRel = HEAP_strdupAtoW(GetProcessHeap(), 0, pszPathRel);
+ This->sPathRel = NULL;
+
+ if ( pszPathRel ) {
+ This->sPathRel = HEAP_strdupAtoW(GetProcessHeap(), 0, pszPathRel);
+
+ if ( !This->sPathRel )
+ return E_OUTOFMEMORY;
+ }
+
This->bDirty = TRUE;
return ShellLink_UpdatePath(This->sPathRel, This->sPath, This->sWorkDir,
&This->sPath);