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:
parent
4b0cb7d581
commit
3e2868b457
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue