Hi, This patch implements the Assoc* functions for SHLWAPI. We need to decide whether to duplicate or share the code for the underlying COM object though (i.e. can I include the c file from the shell dir?). You'll need to re-run configure after applying this. Cheers, Jon ChangeLog: Jon Griffiths <jon_p_griffiths@yahoo.com> +dlls/shlwapi/Makefile.in, dlls/shlwapi/shlwapi.spec, dlls/shlwapi/assoc.c Add Assoc* funcs (but not underlying IQueryAssociations object). ===== "Don't wait for the seas to part, or messiahs to come; Don't you sit around and waste this chance..." - Live jon_p_griffiths@yahoo.com __________________________________________________ Do You Yahoo!? Yahoo! Finance - Get real-time stock quotes http://finance.yahoo.com
--- /home/jon/develop/wine/dlls/shlwapi/shlwapi.spec Thu Aug 29 11:14:14 2002 +++ /home/jon/develop/wine-develop/dlls/shlwapi/shlwapi.spec Sat Aug 31 16:32:09 2002 @@ -252,9 +252,9 @@ 250 stub @ 251 stub @ 252 stub @ -253 stub AssocCreate -254 stub AssocQueryKeyA -255 stub AssocQueryKeyW +253 stdcall AssocCreate(long ptr ptr) AssocCreate +254 stdcall AssocQueryKeyA(long long str ptr ptr) AssocQueryKeyA +255 stdcall AssocQueryKeyW(long long wstr ptr ptr) AssocQueryKeyW 256 stub @ 257 stub @ 258 stub @ @@ -380,10 +380,10 @@ 378 stdcall @(wstr long long) SHLWAPI_378 379 stub @ 380 stub @ -381 stub AssocQueryStringA -382 stub AssocQueryStringByKeyA -383 stub AssocQueryStringByKeyW -384 stub AssocQueryStringW +381 stdcall AssocQueryStringA(long long ptr ptr str ptr) AssocQueryStringA +382 stdcall AssocQueryStringByKeyA(long long ptr ptr str ptr) AssocQueryStringByKeyA +383 stdcall AssocQueryStringByKeyW(long long ptr ptr wstr ptr) AssocQueryStringByKeyW +384 stdcall AssocQueryStringW(long long ptr ptr wstr ptr) AssocQueryStringW 385 stdcall ChrCmpIA(long long) ChrCmpIA 386 stdcall ChrCmpIW(long long) ChrCmpIW 387 stub ColorAdjustLuma --- /dev/null Thu Jan 1 00:00:00 1970 +++ /home/jon/develop/wine-develop/dlls/shlwapi/assoc.c Sat Aug 31 14:45:52 2002 @@ -0,0 +1,356 @@ +/* + * SHLWAPI IQueryAssociations helper functions + * + * Copyright 2002 Jon Griffiths + * + * 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 + * + * NOTES + * These function simplify the process of using the IQueryAssociations + * interface, primarily by providing the means to get an interface pointer. + * For those not interested in the object, the AssocQuery* functions hide + * the object completely and simply provide the functionality. + * + * We require the implementation from shell32 because there is no interface + * for exporting an IQueryAssociations object available from that dll - + * as it is, we need the constructor. + */ +#include "windef.h" +#include "winnls.h" +#include "winreg.h" +#include "shlguid.h" +#include "shlwapi.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(shell); + +/* Default IQueryAssociations::Init() flags */ +#define SHLWAPI_DEF_ASSOCF (ASSOCF_INIT_BYEXENAME|ASSOCF_INIT_DEFAULTTOSTAR| \ + ASSOCF_INIT_DEFAULTTOFOLDER) + +/* FIXME: + * This is a temporary placeholder. We need the whole IQueryAssociations object. + */ +static IQueryAssociations* IQueryAssociations_Constructor() +{ + FIXME("() stub!\n"); + return NULL; +} + +/************************************************************************* + * SHLWAPI_ParamAToW + * + * Internal helper function: Convert ASCII parameter to Unicode. + */ +static BOOL SHLWAPI_ParamAToW(LPCSTR lpszParam, LPWSTR lpszBuff, DWORD dwLen, + LPWSTR* lpszOut) +{ + if (lpszParam) + { + DWORD dwStrLen = lstrlenA(lpszParam); + + if (dwStrLen < dwLen) + { + *lpszOut = lpszBuff; /* Use Buffer, it is big enough */ + } + else + { + /* Create a new buffer big enough for the string */ + *lpszOut = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, + (dwStrLen + 1) * sizeof(WCHAR)); + if (!*lpszOut) + return FALSE; + } + MultiByteToWideChar(0, 0, lpszParam, -1, *lpszOut, -1); + } + else + *lpszOut = NULL; + return TRUE; +} + +/************************************************************************* + * AssocCreate [SHLWAPI.253] + * + * Create a new IQueryAssociations object. + * + * PARAMS + * clsid [I] CLSID of object + * refiid [I] REFIID of interface + * lpInterface [O] Destination for the created IQueryAssociations object + * + * RETURNS + * Success: S_OK. lpInterface contains the new object + * Failure: An HRESULT error value + */ +HRESULT WINAPI AssocCreate(CLSID clsid, REFIID refiid, void **lpInterface) +{ + HRESULT hRet; + IQueryAssociations* lpAssoc; + + TRACE("(%s,%s,%p)\n", debugstr_guid(&clsid), debugstr_guid(refiid), + lpInterface); + + if (!lpInterface) + return E_INVALIDARG; + + *(DWORD*)lpInterface = 0; + + if (!IsEqualGUID(&clsid, &IID_IQueryAssociations)) + return E_NOTIMPL; + + lpAssoc = IQueryAssociations_Constructor(); + + if (!lpAssoc) + return E_OUTOFMEMORY; + + hRet = IQueryAssociations_QueryInterface(lpAssoc, refiid, lpInterface); + IQueryAssociations_Release(lpAssoc); + return hRet; +} + +/************************************************************************* + * AssocQueryKeyW [SHLWAPI.255] + * + * See AssocQueryKeyA. + */ +HRESULT WINAPI AssocQueryKeyW(ASSOCF flags, ASSOCKEY key, LPCWSTR pszAssoc, + LPCWSTR pszExtra, HKEY *phkeyOut) +{ + HRESULT hRet; + IQueryAssociations* lpAssoc; + + lpAssoc = IQueryAssociations_Constructor(); + + if (!lpAssoc) + return E_OUTOFMEMORY; + + flags &= SHLWAPI_DEF_ASSOCF; + hRet = IQueryAssociations_Init(lpAssoc, flags, pszAssoc, (HKEY)0, (HWND)0); + + if (SUCCEEDED(hRet)) + hRet = IQueryAssociations_GetKey(lpAssoc, flags, key, pszExtra, phkeyOut); + + IQueryAssociations_Release(lpAssoc); + return hRet; +} + +/************************************************************************* + * AssocQueryKeyA [SHLWAPI.254] + * + * Get a file association key from the registry. + * + * PARAMS + * flags [I] Flags for the search + * key [I] Type of key to get + * pszAssoc [I] Key name to search below + * pszExtra [I] Extra information about the key location + * phkeyOut [O] Destination for the association key + * + * RETURNS + * Success: S_OK. phkeyOut contains the key + * Failure: An HRESULT error code + */ +HRESULT WINAPI AssocQueryKeyA(ASSOCF flags, ASSOCKEY key, LPCSTR pszAssoc, + LPCSTR pszExtra, HKEY *phkeyOut) +{ + WCHAR szAssocW[MAX_PATH], *lpszAssocW = NULL; + WCHAR szExtraW[MAX_PATH], *lpszExtraW = NULL; + HRESULT hRet = E_OUTOFMEMORY; + + if (SHLWAPI_ParamAToW(pszAssoc, szAssocW, MAX_PATH, &lpszAssocW) && + SHLWAPI_ParamAToW(pszExtra, szExtraW, MAX_PATH, &lpszExtraW)) + { + hRet = AssocQueryKeyW(flags, key, lpszAssocW, lpszExtraW, phkeyOut); + } + + if (lpszAssocW && lpszAssocW != szAssocW) + HeapFree(GetProcessHeap(), 0, lpszAssocW); + + if (lpszExtraW && lpszExtraW != szExtraW) + HeapFree(GetProcessHeap(), 0, lpszExtraW); + + return hRet; +} + +/************************************************************************* + * AssocQueryStringW [SHLWAPI.384] + * + * See AssocQueryStringA. + */ +HRESULT WINAPI AssocQueryStringW(ASSOCF flags, ASSOCSTR str, LPCWSTR pszAssoc, + LPCWSTR pszExtra, LPWSTR pszOut, DWORD *pcchOut) +{ + HRESULT hRet; + IQueryAssociations* lpAssoc; + + if (!pcchOut) + return E_INVALIDARG; + + lpAssoc = IQueryAssociations_Constructor(); + + if (!lpAssoc) + return E_OUTOFMEMORY; + + hRet = IQueryAssociations_Init(lpAssoc, flags & SHLWAPI_DEF_ASSOCF, + pszAssoc, (HKEY)0, (HWND)0); + + if (SUCCEEDED(hRet)) + hRet = IQueryAssociations_GetString(lpAssoc, flags, str, pszExtra, + pszOut, pcchOut); + + IQueryAssociations_Release(lpAssoc); + return hRet; +} + +/************************************************************************* + * AssocQueryStringA [SHLWAPI.381] + * + * Get a file association string from the registry. + * + * PARAMS + * flags [I] Flags for the search + * str [I] Type of string to get + * pszAssoc [I] Key name to search below + * pszExtra [I] Extra information about the string location + * pszOut [O] Destination for the association string + * pcchOut [O] Length of pszOut + * + * RETURNS + * Success: S_OK. pszOut contains the string. + * Failure: An HRESULT error code. + */ +HRESULT WINAPI AssocQueryStringA(ASSOCF flags, ASSOCSTR str, LPCSTR pszAssoc, + LPCSTR pszExtra, LPSTR pszOut, DWORD *pcchOut) +{ + WCHAR szAssocW[MAX_PATH], *lpszAssocW = NULL; + WCHAR szExtraW[MAX_PATH], *lpszExtraW = NULL; + HRESULT hRet = E_OUTOFMEMORY; + + if (!pcchOut) + hRet = E_INVALIDARG; + else if (SHLWAPI_ParamAToW(pszAssoc, szAssocW, MAX_PATH, &lpszAssocW) && + SHLWAPI_ParamAToW(pszExtra, szExtraW, MAX_PATH, &lpszExtraW)) + { + WCHAR szReturnW[MAX_PATH], *lpszReturnW = szReturnW; + DWORD dwLenOut = *pcchOut; + + if (dwLenOut >= MAX_PATH) + lpszReturnW = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, + (dwLenOut + 1) * sizeof(WCHAR)); + + if (!lpszReturnW) + hRet = E_OUTOFMEMORY; + else + { + hRet = AssocQueryStringW(flags, str, lpszAssocW, lpszExtraW, + lpszReturnW, &dwLenOut); + + if (SUCCEEDED(hRet)) + WideCharToMultiByte(CP_ACP,0,szReturnW,-1,pszOut,dwLenOut,0,0); + *pcchOut = dwLenOut; + + if (lpszReturnW && lpszReturnW != szReturnW) + HeapFree(GetProcessHeap(), 0, lpszReturnW); + } + } + + if (lpszAssocW && lpszAssocW != szAssocW) + HeapFree(GetProcessHeap(), 0, lpszAssocW); + if (lpszExtraW && lpszExtraW != szExtraW) + HeapFree(GetProcessHeap(), 0, lpszExtraW); + return hRet; +} + +/************************************************************************* + * AssocQueryStringByKeyW [SHLWAPI.383] + * + * See AssocQueryStringByKeyA. + */ +HRESULT WINAPI AssocQueryStringByKeyW(ASSOCF flags, ASSOCSTR str, HKEY hkAssoc, + LPCWSTR pszExtra, LPWSTR pszOut, + DWORD *pcchOut) +{ + HRESULT hRet; + IQueryAssociations* lpAssoc; + + lpAssoc = IQueryAssociations_Constructor(); + + if (!lpAssoc) + return E_OUTOFMEMORY; + + flags &= SHLWAPI_DEF_ASSOCF; + hRet = IQueryAssociations_Init(lpAssoc, flags, 0, hkAssoc, (HWND)0); + + if (SUCCEEDED(hRet)) + hRet = IQueryAssociations_GetString(lpAssoc, flags, str, pszExtra, + pszOut, pcchOut); + + IQueryAssociations_Release(lpAssoc); + return hRet; +} + +/************************************************************************* + * AssocQueryStringByKeyA [SHLWAPI.382] + * + * Get a file association string from the registry, given a starting key. + * + * PARAMS + * flags [I] Flags for the search + * str [I] Type of string to get + * hkAssoc [I] Key to search below + * pszExtra [I] Extra information about the string location + * pszOut [O] Destination for the association string + * pcchOut [O] Length of pszOut + * + * RETURNS + * Success: S_OK. pszOut contains the string. + * Failure: An HRESULT error code. + */ +HRESULT WINAPI AssocQueryStringByKeyA(ASSOCF flags, ASSOCSTR str, HKEY hkAssoc, + LPCSTR pszExtra, LPSTR pszOut, + DWORD *pcchOut) +{ + WCHAR szExtraW[MAX_PATH], *lpszExtraW; + WCHAR szReturnW[MAX_PATH], *lpszReturnW = szReturnW; + HRESULT hRet = E_OUTOFMEMORY; + + if (!pcchOut) + hRet = E_INVALIDARG; + else if (SHLWAPI_ParamAToW(pszExtra, szExtraW, MAX_PATH, &lpszExtraW)) + { + DWORD dwLenOut = *pcchOut; + if (dwLenOut >= MAX_PATH) + lpszReturnW = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, + (dwLenOut + 1) * sizeof(WCHAR)); + + if (lpszReturnW) + { + hRet = AssocQueryStringByKeyW(flags, str, hkAssoc, lpszExtraW, + lpszReturnW, &dwLenOut); + + if (SUCCEEDED(hRet)) + WideCharToMultiByte(CP_ACP,0,szReturnW,-1,pszOut,dwLenOut,0,0); + *pcchOut = dwLenOut; + + if (lpszReturnW != szReturnW) + HeapFree(GetProcessHeap(), 0, lpszReturnW); + } + } + + if (lpszExtraW && lpszExtraW != szExtraW) + HeapFree(GetProcessHeap(), 0, lpszExtraW); + return hRet; +} + --- /home/jon/develop/wine/dlls/shlwapi/Makefile.in Sun Aug 11 17:22:24 2002 +++ /home/jon/develop/wine-develop/dlls/shlwapi/Makefile.in Sat Aug 31 16:36:42 2002 @@ -4,7 +4,6 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = shlwapi.dll -# fixme: avoid ole32.dll import IMPORTS = ole32 user32 gdi32 advapi32 kernel32 EXTRALIBS = $(LIBUUID) $(LIBUNICODE) @@ -12,6 +11,7 @@ SYMBOLFILE = $(MODULE).tmp.o C_SRCS = \ + assoc.c \ clist.c \ istream.c \ ordinal.c \