diff --git a/dlls/shell32/shell32.spec b/dlls/shell32/shell32.spec index 7f2eb436bac..bcde2480c4a 100644 --- a/dlls/shell32/shell32.spec +++ b/dlls/shell32/shell32.spec @@ -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 diff --git a/dlls/shell32/shellord.c b/dlls/shell32/shellord.c index 4c63c0076f0..53197441ecf 100644 --- a/dlls/shell32/shellord.c +++ b/dlls/shell32/shellord.c @@ -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); } /************************************************************************* diff --git a/dlls/shell32/undocshell.h b/dlls/shell32/undocshell.h index 00e69ec54c8..9eaafb685df 100644 --- a/dlls/shell32/undocshell.h +++ b/dlls/shell32/undocshell.h @@ -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, diff --git a/dlls/shlwapi/ordinal.c b/dlls/shlwapi/ordinal.c index e4cdd7a1868..0d02ae11fdb 100644 --- a/dlls/shlwapi/ordinal.c +++ b/dlls/shlwapi/ordinal.c @@ -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); diff --git a/dlls/shlwapi/shlwapi.spec b/dlls/shlwapi/shlwapi.spec index bab16119557..304cc3293f1 100644 --- a/dlls/shlwapi/shlwapi.spec +++ b/dlls/shlwapi/shlwapi.spec @@ -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) diff --git a/dlls/shlwapi/tests/ordinal.c b/dlls/shlwapi/tests/ordinal.c index 232849f6e52..abdcbe45def 100644 --- a/dlls/shlwapi/tests/ordinal.c +++ b/dlls/shlwapi/tests/ordinal.c @@ -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); }