SHAllocShared fixes
Francois Gouget
fgouget at free.fr
Mon Aug 30 22:15:15 CDT 2004
On Mon, 30 Aug 2004, Alexandre Julliard wrote:
> Francois Gouget <fgouget at free.fr> writes:
>
> > This actually calls for two more notes:
> > * This looks very much what one would get by calling the corresponding
> > functions in shlwapi (which seems much more complete). However in
> > shell32 there is talk of sending messages around (WM_USER+2) so maybe
> > it's the same concept but a different implementation?
>
> The WM_USER+2 thing is something a specific caller was doing, it's not
> part of the function itself.
Yes that would make more sense. The same is probably true of the pidl
thingy.
> I think the shell32 functions should simply forward to the shlwapi
> ones.
Ok. Done.
I also moved the conformance test to the shlwapi dll since the
implementation is there. Compiling and running this test on Windows also
turned up a bug in the prototype of shlwapi.SHAllocShared.
Changelog:
* dlls/shell32/shell32.spec
dlls/shell32/shellord.c
dlls/shell32/undocshell.h
dlls/shlwapi/ordinal.c
dlls/shlwapi/shlwapi.spec
dlls/shlwapi/tests/Makefile.in
dlls/shlwapi/tests/alloc.c
Don't export the shell32 SHAllocShared functions by name.
Implement them by calling out their shlwapi equivalent (which had a
much more complete implementation anyway).
Fix the prototype of shlwapi's SHAllocShared().
Don't crash if lpvData is NULL in SHAllocShared().
Add a conformance test to shlwapi.
--
Francois Gouget fgouget at free.fr http://fgouget.free.fr/
La terre est une b\xEAta...
-------------- next part --------------
Index: dlls/shell32/shell32.spec
===================================================================
RCS file: /var/cvs/wine/dlls/shell32/shell32.spec,v
retrieving revision 1.85
diff -u -r1.85 shell32.spec
--- dlls/shell32/shell32.spec 9 Jul 2004 22:51:19 -0000 1.85
+++ dlls/shell32/shell32.spec 30 Aug 2004 22:29:31 -0000
@@ -278,10 +278,10 @@
511 stdcall SHRegQueryValueExW (long wstr ptr ptr ptr ptr)
512 stdcall SHRegDeleteKeyW (long wstr)
- 520 stdcall SHAllocShared (long long long)
- 521 stdcall SHLockShared (long long)
- 522 stdcall SHUnlockShared (long)
- 523 stdcall SHFreeShared (long long)
+ 520 stdcall @(long long long) SHAllocShared
+ 521 stdcall @(long long) SHLockShared
+ 522 stdcall @(long) SHUnlockShared
+ 523 stdcall @(long long) SHFreeShared
524 stdcall RealDriveType (long long)
525 stub RealDriveTypeFlags
Index: dlls/shell32/shellord.c
===================================================================
RCS file: /var/cvs/wine/dlls/shell32/shellord.c,v
retrieving revision 1.124
diff -u -r1.124 shellord.c
--- dlls/shell32/shellord.c 22 Aug 2004 22:27:31 -0000 1.124
+++ dlls/shell32/shellord.c 30 Aug 2004 22:57:39 -0000
@@ -69,6 +69,25 @@
extern INT WINAPI FindMRUData(HANDLE hList, LPCVOID lpData, DWORD cbData, LPINT lpRegNum);
extern INT WINAPI EnumMRUListA(HANDLE hList, INT nItemPos, LPVOID lpBuffer, DWORD nBufferSize);
+
+/* Get a function pointer from a DLL handle */
+#define GET_FUNC(func, module, name, fail) \
+ do { \
+ if (!func) { \
+ if (!SHELL32_h##module && !(SHELL32_h##module = LoadLibraryA(#module ".dll"))) return fail; \
+ func = (void*)GetProcAddress(SHELL32_h##module, name); \
+ if (!func) return fail; \
+ } \
+ } while (0)
+
+/* Function pointers for GET_FUNC macro */
+static HMODULE SHELL32_hshlwapi=NULL;
+static HANDLE (WINAPI *pSHAllocShared)(LPCVOID,DWORD,DWORD);
+static LPVOID (WINAPI *pSHLockShared)(HANDLE,DWORD);
+static BOOL (WINAPI *pSHUnlockShared)(LPVOID);
+static BOOL (WINAPI *pSHFreeShared)(HANDLE,DWORD);
+
+
/*************************************************************************
* ParseFieldA [internal]
*
@@ -1189,70 +1208,45 @@
/*************************************************************************
* SHAllocShared [SHELL32.520]
*
- * NOTES
- * parameter1 is return value from HeapAlloc
- * parameter2 is equal to the size allocated with HeapAlloc
- * parameter3 is return value from GetCurrentProcessId
- *
- * the return value is posted as lParam with 0x402 (WM_USER+2) to somewhere
- * WM_USER+2 could be the undocumented CWM_SETPATH
- * the allocated memory contains a pidl
- */
-HGLOBAL WINAPI SHAllocShared(LPVOID psrc, DWORD size, DWORD procID)
-{ HGLOBAL hmem;
- LPVOID pmem;
-
- TRACE("ptr=%p size=0x%04lx procID=0x%04lx\n",psrc,size,procID);
- hmem = GlobalAlloc(GMEM_FIXED, size);
- if (!hmem)
- return 0;
-
- pmem = GlobalLock (hmem);
-
- if (! pmem)
- return 0;
-
- memcpy (pmem, psrc, size);
- GlobalUnlock(hmem);
- return hmem;
+ * See shlwapi.SHAllocShared
+ */
+HANDLE WINAPI SHAllocShared(LPVOID lpvData, DWORD dwSize, DWORD dwProcId)
+{
+ GET_FUNC(pSHAllocShared, shlwapi, (char*)7, NULL);
+ return pSHAllocShared(lpvData, dwSize, dwProcId);
}
+
/*************************************************************************
- * SHLockShared [SHELL32.521]
+ * @ [SHELL32.521]
*
- * NOTES
- * parameter1 is return value from SHAllocShared
- * parameter2 is return value from GetCurrentProcessId
- * the receiver of (WM_USER+2) tries to lock the HANDLE (?)
- * the return value seems to be a memory address
+ * See shlwapi.SHLockShared
*/
-LPVOID WINAPI SHLockShared(HANDLE hmem, DWORD procID)
-{ TRACE("handle=%p procID=0x%04lx\n",hmem,procID);
- return GlobalLock(hmem);
+LPVOID WINAPI SHLockShared(HANDLE hShared, DWORD dwProcId)
+{
+ GET_FUNC(pSHLockShared, shlwapi, (char*)8, NULL);
+ return pSHLockShared(hShared, dwProcId);
}
+
/*************************************************************************
- * SHUnlockShared [SHELL32.522]
+ * @ [SHELL32.522]
*
- * NOTES
- * parameter1 is return value from SHLockShared
+ * See shlwapi.SHUnlockShared
*/
-BOOL WINAPI SHUnlockShared(LPVOID pv)
+BOOL WINAPI SHUnlockShared(LPVOID lpView)
{
- TRACE("%p\n",pv);
- return GlobalUnlock((HANDLE)pv);
+ GET_FUNC(pSHUnlockShared, shlwapi, (char*)9, FALSE);
+ return pSHUnlockShared(lpView);
}
+
/*************************************************************************
- * SHFreeShared [SHELL32.523]
+ * @ [SHELL32.523]
*
- * NOTES
- * parameter1 is return value from SHAllocShared
- * parameter2 is return value from GetCurrentProcessId
+ * See shlwapi.SHFreeShared
*/
-BOOL WINAPI SHFreeShared(
- HANDLE hMem,
- DWORD pid)
+BOOL WINAPI SHFreeShared(HANDLE hShared, DWORD dwProcId)
{
- TRACE("handle=%p 0x%04lx\n",hMem,pid);
- return (BOOL)GlobalFree(hMem);
+ GET_FUNC(pSHFreeShared, shlwapi, (char*)10, FALSE);
+ return pSHFreeShared(hShared, dwProcId);
}
/*************************************************************************
Index: dlls/shell32/undocshell.h
===================================================================
RCS file: /var/cvs/wine/dlls/shell32/undocshell.h,v
retrieving revision 1.25
diff -u -r1.25 undocshell.h
--- dlls/shell32/undocshell.h 22 Aug 2004 22:27:31 -0000 1.25
+++ dlls/shell32/undocshell.h 30 Aug 2004 14:35:57 -0000
@@ -154,6 +154,11 @@
* Memory Routines
*/
+/* The Platform SDK's shlobj.h header defines similar functions with a
+ * leading underscore. However those are unusable because of the leading
+ * underscore, because they have an incorrect calling convention, and
+ * because these functions are not exported by name anyway.
+ */
HANDLE WINAPI SHAllocShared(
LPVOID pv,
ULONG cb,
Index: dlls/shlwapi/ordinal.c
===================================================================
RCS file: /var/cvs/wine/dlls/shlwapi/ordinal.c,v
retrieving revision 1.93
diff -u -r1.93 ordinal.c
--- dlls/shlwapi/ordinal.c 22 Aug 2004 21:38:46 -0000 1.93
+++ dlls/shlwapi/ordinal.c 30 Aug 2004 22:56:15 -0000
@@ -77,8 +77,6 @@
extern DWORD SHLWAPI_ThreadRef_index;
-typedef HANDLE HSHARED; /* Shared memory */
-
/* following is GUID for IObjectWithSite::SetSite -- see _174 */
static DWORD id1[4] = {0xfc4801a3, 0x11cf2ba9, 0xaa0029a2, 0x52733d00};
/* following is GUID for IPersistMoniker::GetClassID -- see _174 */
@@ -145,7 +143,7 @@
for unicode functions to provide these functions on systems without
unicode functions eg. win95/win98. Since we have such functions we just
call these. If running Wine with native DLL's, some late bound calls may
- fail. However, its better to implement the functions in the forward DLL
+ fail. However, it is better to implement the functions in the forward DLL
and recommend the builtin rather than reimplementing the calls here!
*/
@@ -155,15 +153,15 @@
* Internal implemetation of SHLWAPI_11.
*/
static
-HSHARED WINAPI SHLWAPI_DupSharedHandle(HSHARED hShared, DWORD dwDstProcId,
+HANDLE WINAPI SHLWAPI_DupSharedHandle(HANDLE hShared, DWORD dwDstProcId,
DWORD dwSrcProcId, DWORD dwAccess,
DWORD dwOptions)
{
HANDLE hDst, hSrc;
DWORD dwMyProcId = GetCurrentProcessId();
- HSHARED hRet = (HSHARED)NULL;
+ HANDLE hRet = NULL;
- TRACE("(%p,%ld,%ld,%08lx,%08lx)\n", (PVOID)hShared, dwDstProcId, dwSrcProcId,
+ TRACE("(%p,%ld,%ld,%08lx,%08lx)\n", hShared, dwDstProcId, dwSrcProcId,
dwAccess, dwOptions);
/* Get dest process handle */
@@ -183,9 +181,9 @@
if (hSrc)
{
/* Make handle available to dest process */
- if (!DuplicateHandle(hDst, (HANDLE)hShared, hSrc, &hRet,
+ if (!DuplicateHandle(hDst, hShared, hSrc, &hRet,
dwAccess, 0, dwOptions | DUPLICATE_SAME_ACCESS))
- hRet = (HSHARED)NULL;
+ hRet = NULL;
if (dwSrcProcId != dwMyProcId)
CloseHandle(hSrc);
@@ -195,7 +193,7 @@
CloseHandle(hDst);
}
- TRACE("Returning handle %p\n", (PVOID)hRet);
+ TRACE("Returning handle %p\n", hRet);
return hRet;
}
@@ -205,9 +203,9 @@
* Create a block of sharable memory and initialise it with data.
*
* PARAMS
- * dwProcId [I] ID of process owning data
* lpvData [I] Pointer to data to write
* dwSize [I] Size of data
+ * dwProcId [I] ID of process owning data
*
* RETURNS
* Success: A shared memory handle
@@ -221,13 +219,13 @@
* the view pointer returned by this size.
*
*/
-HSHARED WINAPI SHAllocShared(DWORD dwProcId, DWORD dwSize, LPCVOID lpvData)
+HANDLE WINAPI SHAllocShared(LPCVOID lpvData, DWORD dwSize, DWORD dwProcId)
{
HANDLE hMap;
LPVOID pMapped;
- HSHARED hRet = (HSHARED)NULL;
+ HANDLE hRet = NULL;
- TRACE("(%ld,%p,%ld)\n", dwProcId, lpvData, dwSize);
+ TRACE("(%p,%ld,%ld)\n", lpvData, dwSize, dwProcId);
/* Create file mapping of the correct length */
hMap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, FILE_MAP_READ, 0,
@@ -242,12 +240,12 @@
{
/* Write size of data, followed by the data, to the view */
*((DWORD*)pMapped) = dwSize;
- if (dwSize)
+ if (lpvData)
memcpy((char *) pMapped + sizeof(dwSize), lpvData, dwSize);
/* Release view. All further views mapped will be opaque */
UnmapViewOfFile(pMapped);
- hRet = SHLWAPI_DupSharedHandle((HSHARED)hMap, dwProcId,
+ hRet = SHLWAPI_DupSharedHandle(hMap, dwProcId,
GetCurrentProcessId(), FILE_MAP_ALL_ACCESS,
DUPLICATE_SAME_ACCESS);
}
@@ -270,18 +268,18 @@
* Failure: NULL
*
*/
-PVOID WINAPI SHLockShared(HSHARED hShared, DWORD dwProcId)
+PVOID WINAPI SHLockShared(HANDLE hShared, DWORD dwProcId)
{
- HSHARED hDup;
+ HANDLE hDup;
LPVOID pMapped;
- TRACE("(%p %ld)\n", (PVOID)hShared, dwProcId);
+ TRACE("(%p %ld)\n", hShared, dwProcId);
/* Get handle to shared memory for current process */
hDup = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
FILE_MAP_ALL_ACCESS, 0);
/* Get View */
- pMapped = MapViewOfFile((HANDLE)hDup, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
+ pMapped = MapViewOfFile(hDup, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
CloseHandle(hDup);
if (pMapped)
@@ -322,17 +320,17 @@
* Failure: FALSE
*
*/
-BOOL WINAPI SHFreeShared(HSHARED hShared, DWORD dwProcId)
+BOOL WINAPI SHFreeShared(HANDLE hShared, DWORD dwProcId)
{
- HSHARED hClose;
+ HANDLE hClose;
- TRACE("(%p %ld)\n", (PVOID)hShared, dwProcId);
+ TRACE("(%p %ld)\n", hShared, dwProcId);
/* Get a copy of the handle for our process, closing the source handle */
hClose = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
FILE_MAP_ALL_ACCESS,DUPLICATE_CLOSE_SOURCE);
/* Close local copy */
- return CloseHandle((HANDLE)hClose);
+ return CloseHandle(hClose);
}
/*************************************************************************
@@ -352,10 +350,10 @@
* Failure: A NULL handle.
*
*/
-HSHARED WINAPI SHMapHandle(HSHARED hShared, DWORD dwDstProcId, DWORD dwSrcProcId,
+HANDLE WINAPI SHMapHandle(HANDLE hShared, DWORD dwDstProcId, DWORD dwSrcProcId,
DWORD dwAccess, DWORD dwOptions)
{
- HSHARED hRet;
+ HANDLE hRet;
hRet = SHLWAPI_DupSharedHandle(hShared, dwDstProcId, dwSrcProcId,
dwAccess, dwOptions);
Index: dlls/shlwapi/shlwapi.spec
===================================================================
RCS file: /var/cvs/wine/dlls/shlwapi/shlwapi.spec,v
retrieving revision 1.93
diff -u -r1.93 shlwapi.spec
--- dlls/shlwapi/shlwapi.spec 19 Jul 2004 19:32:51 -0000 1.93
+++ dlls/shlwapi/shlwapi.spec 30 Aug 2004 22:56:47 -0000
@@ -4,7 +4,7 @@
4 stdcall -noname PathFileExistsDefExtW(wstr long)
5 stdcall -noname PathFindOnPathExA(str ptr long)
6 stdcall -noname PathFindOnPathExW(wstr ptr long)
-7 stdcall -noname SHAllocShared(long long ptr)
+7 stdcall -noname SHAllocShared(ptr long long)
8 stdcall -noname SHLockShared(long long)
9 stdcall -noname SHUnlockShared(ptr)
10 stdcall -noname SHFreeShared(long long)
Index: dlls/shlwapi/tests/Makefile.in
===================================================================
RCS file: /var/cvs/wine/dlls/shlwapi/tests/Makefile.in,v
retrieving revision 1.6
diff -u -r1.6 Makefile.in
--- dlls/shlwapi/tests/Makefile.in 22 Mar 2004 20:40:03 -0000 1.6
+++ dlls/shlwapi/tests/Makefile.in 30 Aug 2004 22:38:59 -0000
@@ -6,6 +6,7 @@
IMPORTS = shlwapi advapi32 ole32 oleaut32
CTESTS = \
+ alloc.c \
clist.c \
clsid.c \
generated.c \
--- /dev/null 2004-08-10 11:44:31.000000000 +0200
+++ dlls/shlwapi/tests/alloc.c 2004-08-31 00:52:11.000000000 +0200
@@ -0,0 +1,73 @@
+/*
+ * Unit test of the SHFileOperation function.
+ *
+ * Copyright 2004 Francois Gouget
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+
+#include "wine/test.h"
+
+HANDLE (WINAPI *pSHAllocShared)(LPCVOID,DWORD,DWORD);
+LPVOID (WINAPI *pSHLockShared)(HANDLE,DWORD);
+BOOL (WINAPI *pSHUnlockShared)(LPVOID);
+BOOL (WINAPI *pSHFreeShared)(HANDLE,DWORD);
+
+
+void test_alloc_shared()
+{
+ DWORD procid;
+ HANDLE hmem;
+ int val;
+ int* p;
+
+ procid=GetCurrentProcessId();
+ hmem=pSHAllocShared(NULL,10,procid);
+ ok(hmem!=NULL,"SHAllocShared(NULL...) failed: %ld\n", GetLastError());
+ ok(pSHFreeShared(hmem, procid),
+ "SHFreeShared failed: %ld\n", GetLastError());
+
+ val=0x12345678;
+ hmem=pSHAllocShared(&val,4,procid);
+ ok(hmem!=NULL,"SHAllocShared(NULL...) failed: %ld\n", GetLastError());
+
+ p=(int*)pSHLockShared(hmem,procid);
+ ok(p!=NULL,"SHLockShared failed: %ld\n", GetLastError());
+ if (p!=NULL)
+ ok(*p==val,"Wrong value in shared memory: %d instead of %d\n",*p,val);
+ ok(pSHUnlockShared(p),"SHUnlockShared failed: %ld\n", GetLastError());
+
+ ok(pSHFreeShared(hmem, procid),
+ "SHFreeShared failed: %ld\n", GetLastError());
+}
+
+START_TEST(alloc)
+{
+ HMODULE hdll;
+
+ /* These functions are not exported by name */
+ hdll=GetModuleHandle("shlwapi");
+ pSHAllocShared=(void*)GetProcAddress(hdll,(char*)7);
+ pSHLockShared=(void*)GetProcAddress(hdll,(char*)8);
+ pSHUnlockShared=(void*)GetProcAddress(hdll,(char*)9);
+ pSHFreeShared=(void*)GetProcAddress(hdll,(char*)10);
+
+ test_alloc_shared();
+}
More information about the wine-patches
mailing list