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.
This commit is contained in:
Francois Gouget 2004-08-31 17:38:59 +00:00 committed by Alexandre Julliard
parent 4b0cb7d581
commit 3e2868b457
6 changed files with 109 additions and 76 deletions

View File

@ -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 -noname SHAllocShared (ptr long long)
521 stdcall -noname SHLockShared (long long)
522 stdcall -noname SHUnlockShared (ptr)
523 stdcall -noname SHFreeShared (long long)
524 stdcall RealDriveType (long long)
525 stub RealDriveTypeFlags

View File

@ -69,6 +69,25 @@ extern INT WINAPI AddMRUData(HANDLE hList, LPCVOID lpData, DWORD cbData);
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 @@ HRESULT WINAPI IsUserAdmin(void)
/*************************************************************************
* 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
* See shlwapi.SHAllocShared
*/
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;
HANDLE WINAPI SHAllocShared(LPVOID lpvData, DWORD dwSize, DWORD dwProcId)
{
GET_FUNC(pSHAllocShared, shlwapi, (char*)7, NULL);
return pSHAllocShared(lpvData, dwSize, dwProcId);
}
/*************************************************************************
* SHLockShared [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]
*
* 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]
*
* 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);
}
/*************************************************************************

View File

@ -154,6 +154,11 @@ DWORD WINAPI SHNetConnectionDialog(
* 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,

View File

@ -77,8 +77,6 @@ extern HMODULE SHLWAPI_hversion;
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 @@ BOOL WINAPI SHAboutInfoW(LPWSTR,DWORD);
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 @@ BOOL WINAPI SHAboutInfoW(LPWSTR,DWORD);
* 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 @@ HSHARED WINAPI SHLWAPI_DupSharedHandle(HSHARED hShared, DWORD dwDstProcId,
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 @@ HSHARED WINAPI SHLWAPI_DupSharedHandle(HSHARED hShared, DWORD dwDstProcId,
CloseHandle(hDst);
}
TRACE("Returning handle %p\n", (PVOID)hRet);
TRACE("Returning handle %p\n", hRet);
return hRet;
}
@ -205,9 +203,9 @@ HSHARED WINAPI SHLWAPI_DupSharedHandle(HSHARED hShared, DWORD dwDstProcId,
* 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 @@ HSHARED WINAPI SHLWAPI_DupSharedHandle(HSHARED hShared, DWORD dwDstProcId,
* 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 @@ HSHARED WINAPI SHAllocShared(DWORD dwProcId, DWORD dwSize, LPCVOID lpvData)
{
/* 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 @@ HSHARED WINAPI SHAllocShared(DWORD dwProcId, DWORD dwSize, LPCVOID lpvData)
* 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 @@ BOOL WINAPI SHUnlockShared(LPVOID lpView)
* 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 @@ BOOL WINAPI SHFreeShared(HSHARED hShared, DWORD dwProcId)
* 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);

View File

@ -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)

View File

@ -35,6 +35,11 @@ static HMODULE hShlwapi;
static int (WINAPI *pSHSearchMapInt)(const int*,const int*,int,int);
static HRESULT (WINAPI *pGetAcceptLanguagesA)(LPSTR,LPDWORD);
static HANDLE (WINAPI *pSHAllocShared)(LPCVOID,DWORD,DWORD);
static LPVOID (WINAPI *pSHLockShared)(HANDLE,DWORD);
static BOOL (WINAPI *pSHUnlockShared)(LPVOID);
static BOOL (WINAPI *pSHFreeShared)(HANDLE,DWORD);
static void test_GetAcceptLanguagesA(void)
{ HRESULT retval;
DWORD buffersize, buffersize2, exactsize;
@ -154,6 +159,32 @@ static void test_SHSearchMapInt(void)
ok(i == values[0], "Len 3, expected %d, got %d\n", values[0], i);
}
static 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(ordinal)
{
@ -164,8 +195,13 @@ START_TEST(ordinal)
pGetAcceptLanguagesA = (void*)GetProcAddress(hShlwapi, (LPSTR)14);
pSHSearchMapInt = (void*)GetProcAddress(hShlwapi, (LPSTR)198);
pSHAllocShared=(void*)GetProcAddress(hShlwapi,(char*)7);
pSHLockShared=(void*)GetProcAddress(hShlwapi,(char*)8);
pSHUnlockShared=(void*)GetProcAddress(hShlwapi,(char*)9);
pSHFreeShared=(void*)GetProcAddress(hShlwapi,(char*)10);
test_GetAcceptLanguagesA();
test_SHSearchMapInt();
test_alloc_shared();
FreeLibrary(hShlwapi);
}