[shell32,shlwapi] Implement the IShellLinkDataList interface
Thomas Weidenmueller
wine-patches at reactsoft.com
Sun Apr 23 15:24:01 CDT 2006
The following patch reads and write the data lists appended by shortcuts
created with windows. Fixes the "Last word was not zero" error message
when reading such a .lnk file.
- Implement IShellLinkDataList::AddDataBlock(),
IShellLinkDataList::CopyDataBlock() and
IShellLinkDataList::RemoveDataBlock()
- Read the data list appended to .lnk files
- Write list size for empty lists in SHWriteDataBlockList()
- Thomas
--
P.S.: Please let me know if there's something wrong with this patch or
tell me why it was rejected. Otherwise I'm going to assume the fixes
aren't appreciated or necessary because the implementation is considered
mature and stable.
-------------- next part --------------
Index: dlls/shell32/shelllink.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/shelllink.c,v
retrieving revision 1.114
diff -u -r1.114 shelllink.c
--- dlls/shell32/shelllink.c 10 Nov 2005 12:14:58 -0000 1.114
+++ dlls/shell32/shelllink.c 23 Apr 2006 19:43:23 -0000
@@ -161,6 +161,7 @@
BOOL bDirty;
INT iIdOpen; /* id of the "Open" entry in the context menu */
IUnknown *site;
+ LPSHLWAPI_CLIST pDataList;
} IShellLinkImpl;
static inline IShellLinkImpl *impl_from_IShellLinkW( IShellLinkW *iface )
@@ -305,6 +306,9 @@
HeapFree(GetProcessHeap(), 0, This->sDescription);
HeapFree(GetProcessHeap(),0,This->sPath);
+ if (This->pDataList)
+ SHFreeDataBlockList(This->pDataList);
+
if (This->site)
IUnknown_Release( This->site );
@@ -782,7 +786,6 @@
ULONG dwBytesRead;
BOOL unicode;
HRESULT r;
- DWORD zero;
IShellLinkImpl *This = impl_from_IPersistStream(iface);
@@ -915,9 +918,9 @@
if( FAILED( r ) )
goto end;
- r = IStream_Read(stm, &zero, sizeof zero, &dwBytesRead);
- if( FAILED( r ) || zero || dwBytesRead != sizeof zero )
- ERR("Last word was not zero\n");
+ r = SHReadDataBlockList( stm, &This->pDataList);
+ if( FAILED( r ) )
+ goto end;
TRACE("OK\n");
@@ -1054,7 +1057,6 @@
LINK_HEADER header;
WCHAR exePath[MAX_PATH];
ULONG count;
- DWORD zero;
HRESULT r;
IShellLinkImpl *This = impl_from_IPersistStream(iface);
@@ -1149,11 +1151,9 @@
if( This->sComponent )
r = Stream_WriteAdvertiseInfo( stm, This->sComponent, EXP_DARWIN_ID_SIG );
- /* the last field is a single zero dword */
- zero = 0;
- r = IStream_Write( stm, &zero, sizeof zero, &count );
+ r = SHWriteDataBlockList (stm, This->pDataList );
- return S_OK;
+ return r;
}
/************************************************************************
@@ -2248,46 +2248,57 @@
static HRESULT WINAPI
ShellLink_AddDataBlock( IShellLinkDataList* iface, void* pDataBlock )
{
- FIXME("\n");
- return E_NOTIMPL;
+ IShellLinkImpl *This = impl_from_IShellLinkDataList(iface);
+ HRESULT hr;
+
+ hr = SHAddDataBlock(&This->pDataList, (LPCSHLWAPI_CLIST)pDataBlock);
+ if (SUCCEEDED(hr))
+ This->bDirty = TRUE;
+
+ return hr;
}
static HRESULT WINAPI
ShellLink_CopyDataBlock( IShellLinkDataList* iface, DWORD dwSig, void** ppDataBlock )
{
IShellLinkImpl *This = impl_from_IShellLinkDataList(iface);
- LPVOID block = NULL;
- HRESULT r = E_FAIL;
-
- TRACE("%p %08lx %p\n", iface, dwSig, ppDataBlock );
+ LPSHLWAPI_CLIST pdbh;
+ HRESULT hr = S_OK;
- switch (dwSig)
+ pdbh = SHFindDataBlock(This->pDataList, dwSig);
+ if (pdbh)
{
- case EXP_DARWIN_ID_SIG:
- if (!This->sComponent)
- break;
- block = shelllink_build_darwinid( This->sComponent, dwSig );
- r = S_OK;
- break;
- case EXP_SZ_LINK_SIG:
- case NT_CONSOLE_PROPS_SIG:
- case NT_FE_CONSOLE_PROPS_SIG:
- case EXP_SPECIAL_FOLDER_SIG:
- case EXP_SZ_ICON_SIG:
- FIXME("valid but unhandled datablock %08lx\n", dwSig);
- break;
- default:
- ERR("unknown datablock %08lx\n", dwSig);
+ *ppDataBlock = LocalAlloc(LPTR, pdbh->ulSize);
+ if (*ppDataBlock)
+ {
+ CopyMemory(*ppDataBlock,
+ pdbh,
+ pdbh->ulSize);
+ }
+ else
+ hr = E_OUTOFMEMORY;
}
- *ppDataBlock = block;
- return r;
+ else
+ {
+ *ppDataBlock = NULL;
+ hr = E_FAIL;
+ }
+
+ return hr;
}
static HRESULT WINAPI
ShellLink_RemoveDataBlock( IShellLinkDataList* iface, DWORD dwSig )
{
- FIXME("\n");
- return E_NOTIMPL;
+ IShellLinkImpl *This = impl_from_IShellLinkDataList(iface);
+ HRESULT hr = S_OK;
+
+ if (SHRemoveDataBlock(&This->pDataList, dwSig))
+ This->bDirty = TRUE;
+ else
+ hr = E_FAIL;
+
+ return hr;
}
static HRESULT WINAPI
Index: dlls/shell32/undocshell.h
===================================================================
RCS file: /home/wine/wine/dlls/shell32/undocshell.h,v
retrieving revision 1.29
diff -u -r1.29 undocshell.h
--- dlls/shell32/undocshell.h 24 Jul 2005 16:17:29 -0000 1.29
+++ dlls/shell32/undocshell.h 23 Apr 2006 19:41:07 -0000
@@ -566,6 +566,29 @@
/* policy functions */
BOOL WINAPI SHInitRestricted(LPCVOID unused, LPCVOID inpRegKey);
+/* CLIST functions */
+
+#include "pshpack1.h"
+
+/* DataBlock list element (ordinals 17-22) */
+typedef struct tagSHLWAPI_CLIST
+{
+ ULONG ulSize; /* Size of this list element and its data */
+ ULONG ulId; /* If 0xFFFFFFFF, The real element follows */
+ /* Item data (or a contained SHLWAPI_CLIST) follows... */
+} SHLWAPI_CLIST, *LPSHLWAPI_CLIST;
+
+#include "poppack.h"
+
+typedef const SHLWAPI_CLIST* LPCSHLWAPI_CLIST;
+
+HRESULT WINAPI SHWriteDataBlockList(IStream*,LPSHLWAPI_CLIST);
+HRESULT WINAPI SHReadDataBlockList(IStream*,LPSHLWAPI_CLIST*);
+VOID WINAPI SHFreeDataBlockList(LPSHLWAPI_CLIST);
+HRESULT WINAPI SHAddDataBlock(LPSHLWAPI_CLIST*,LPCSHLWAPI_CLIST);
+BOOL WINAPI SHRemoveDataBlock(LPSHLWAPI_CLIST*,ULONG);
+LPSHLWAPI_CLIST WINAPI SHFindDataBlock(LPSHLWAPI_CLIST,ULONG);
+
#ifdef __cplusplus
} /* extern "C" */
#endif /* defined(__cplusplus) */
Index: dlls/shlwapi/clist.c
===================================================================
RCS file: /home/wine/wine/dlls/shlwapi/clist.c,v
retrieving revision 1.11
diff -u -r1.11 clist.c
--- dlls/shlwapi/clist.c 13 Sep 2005 15:00:32 -0000 1.11
+++ dlls/shlwapi/clist.c 23 Apr 2006 19:49:15 -0000
@@ -29,6 +29,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(shell);
+#include "pshpack1.h"
+
/* DataBlock list element (ordinals 17-22) */
typedef struct tagSHLWAPI_CLIST
{
@@ -37,6 +39,8 @@
/* Item data (or a contained SHLWAPI_CLIST) follows... */
} SHLWAPI_CLIST, *LPSHLWAPI_CLIST;
+#include "poppack.h"
+
typedef const SHLWAPI_CLIST* LPCSHLWAPI_CLIST;
/* ulId for contained SHLWAPI_CLIST items */
@@ -96,12 +100,13 @@
HRESULT WINAPI SHWriteDataBlockList(IStream* lpStream, LPSHLWAPI_CLIST lpList)
{
ULONG ulSize;
- HRESULT hRet = E_FAIL;
+ HRESULT hRet = S_OK;
TRACE("(%p,%p)\n", lpStream, lpList);
if(lpList)
{
+ hRet = E_FAIL;
while (lpList->ulSize)
{
LPSHLWAPI_CLIST lpItem = lpList;
More information about the wine-patches
mailing list