2 * SHLWAPI ordinal functions
4 * Copyright 1997 Marcus Meissner
6 * 2001-2003 Jon Griffiths
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #define COM_NO_WINDOWS_H
25 #include "wine/port.h"
32 #define NONAMELESSUNION
33 #define NONAMELESSSTRUCT
47 #include "wine/unicode.h"
49 #include "wine/debug.h"
53 WINE_DEFAULT_DEBUG_CHANNEL(shell);
55 /* Get a function pointer from a DLL handle */
56 #define GET_FUNC(func, module, name, fail) \
59 if (!SHLWAPI_h##module && !(SHLWAPI_h##module = LoadLibraryA(#module ".dll"))) return fail; \
60 func = (fn##func)GetProcAddress(SHLWAPI_h##module, name); \
61 if (!func) return fail; \
65 /* DLL handles for late bound calls */
66 extern HINSTANCE shlwapi_hInstance;
67 extern HMODULE SHLWAPI_hshell32;
68 extern HMODULE SHLWAPI_hwinmm;
69 extern HMODULE SHLWAPI_hcomdlg32;
70 extern HMODULE SHLWAPI_hcomctl32;
71 extern HMODULE SHLWAPI_hmpr;
72 extern HMODULE SHLWAPI_hurlmon;
73 extern HMODULE SHLWAPI_hversion;
75 extern DWORD SHLWAPI_ThreadRef_index;
77 /* following is GUID for IObjectWithSite::SetSite -- see _174 */
78 static DWORD id1[4] = {0xfc4801a3, 0x11cf2ba9, 0xaa0029a2, 0x52733d00};
79 /* following is GUID for IPersistMoniker::GetClassID -- see _174 */
80 static DWORD id2[4] = {0x79eac9ee, 0x11cebaf9, 0xaa00828c, 0x0ba94b00};
82 /* Function pointers for GET_FUNC macro; these need to be global because of gcc bug */
83 typedef LPITEMIDLIST (WINAPI *fnpSHBrowseForFolderW)(LPBROWSEINFOW);
84 static fnpSHBrowseForFolderW pSHBrowseForFolderW;
85 typedef BOOL (WINAPI *fnpPlaySoundW)(LPCWSTR, HMODULE, DWORD);
86 static fnpPlaySoundW pPlaySoundW;
87 typedef DWORD (WINAPI *fnpSHGetFileInfoW)(LPCWSTR,DWORD,SHFILEINFOW*,UINT,UINT);
88 static fnpSHGetFileInfoW pSHGetFileInfoW;
89 typedef UINT (WINAPI *fnpDragQueryFileW)(HDROP, UINT, LPWSTR, UINT);
90 static fnpDragQueryFileW pDragQueryFileW;
91 typedef BOOL (WINAPI *fnpSHGetPathFromIDListW)(LPCITEMIDLIST, LPWSTR);
92 static fnpSHGetPathFromIDListW pSHGetPathFromIDListW;
93 typedef BOOL (WINAPI *fnpShellExecuteExW)(LPSHELLEXECUTEINFOW);
94 static fnpShellExecuteExW pShellExecuteExW;
95 typedef HICON (WINAPI *fnpSHFileOperationW)(LPSHFILEOPSTRUCTW);
96 static fnpSHFileOperationW pSHFileOperationW;
97 typedef UINT (WINAPI *fnpExtractIconExW)(LPCWSTR, INT,HICON *,HICON *, UINT);
98 static fnpExtractIconExW pExtractIconExW;
99 typedef BOOL (WINAPI *fnpSHGetNewLinkInfoW)(LPCWSTR, LPCWSTR, LPCWSTR, BOOL*, UINT);
100 static fnpSHGetNewLinkInfoW pSHGetNewLinkInfoW;
101 typedef HRESULT (WINAPI *fnpSHDefExtractIconW)(LPCWSTR, int, UINT, HICON*, HICON*, UINT);
102 static fnpSHDefExtractIconW pSHDefExtractIconW;
103 typedef HICON (WINAPI *fnpExtractIconW)(HINSTANCE, LPCWSTR, UINT);
104 static fnpExtractIconW pExtractIconW;
105 typedef BOOL (WINAPI *fnpGetSaveFileNameW)(LPOPENFILENAMEW);
106 static fnpGetSaveFileNameW pGetSaveFileNameW;
107 typedef DWORD (WINAPI *fnpWNetRestoreConnectionW)(HWND, LPWSTR);
108 static fnpWNetRestoreConnectionW pWNetRestoreConnectionW;
109 typedef DWORD (WINAPI *fnpWNetGetLastErrorW)(LPDWORD, LPWSTR, DWORD, LPWSTR, DWORD);
110 static fnpWNetGetLastErrorW pWNetGetLastErrorW;
111 typedef BOOL (WINAPI *fnpPageSetupDlgW)(LPPAGESETUPDLGW);
112 static fnpPageSetupDlgW pPageSetupDlgW;
113 typedef BOOL (WINAPI *fnpPrintDlgW)(LPPRINTDLGW);
114 static fnpPrintDlgW pPrintDlgW;
115 typedef BOOL (WINAPI *fnpGetOpenFileNameW)(LPOPENFILENAMEW);
116 static fnpGetOpenFileNameW pGetOpenFileNameW;
117 typedef DWORD (WINAPI *fnpGetFileVersionInfoSizeW)(LPCWSTR,LPDWORD);
118 static fnpGetFileVersionInfoSizeW pGetFileVersionInfoSizeW;
119 typedef BOOL (WINAPI *fnpGetFileVersionInfoW)(LPCWSTR,DWORD,DWORD,LPVOID);
120 static fnpGetFileVersionInfoW pGetFileVersionInfoW;
121 typedef WORD (WINAPI *fnpVerQueryValueW)(LPVOID,LPCWSTR,LPVOID*,UINT*);
122 static fnpVerQueryValueW pVerQueryValueW;
123 typedef BOOL (WINAPI *fnpCOMCTL32_417)(HDC,INT,INT,UINT,const RECT*,LPCWSTR,UINT,const INT*);
124 static fnpCOMCTL32_417 pCOMCTL32_417;
125 typedef HRESULT (WINAPI *fnpDllGetVersion)(DLLVERSIONINFO*);
126 static fnpDllGetVersion pDllGetVersion;
127 typedef HRESULT (WINAPI *fnpCreateFormatEnumerator)(UINT,FORMATETC*,IEnumFORMATETC**);
128 static fnpCreateFormatEnumerator pCreateFormatEnumerator;
129 typedef HRESULT (WINAPI *fnpRegisterFormatEnumerator)(LPBC,IEnumFORMATETC*,DWORD);
130 static fnpRegisterFormatEnumerator pRegisterFormatEnumerator;
132 HRESULT WINAPI IUnknown_QueryService(IUnknown*,REFGUID,REFIID,LPVOID*);
133 HRESULT WINAPI SHInvokeCommand(HWND,IShellFolder*,LPCITEMIDLIST,BOOL);
134 HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR,CLSID*);
135 BOOL WINAPI SHAboutInfoW(LPWSTR,DWORD);
138 NOTES: Most functions exported by ordinal seem to be superflous.
139 The reason for these functions to be there is to provide a wrapper
140 for unicode functions to provide these functions on systems without
141 unicode functions eg. win95/win98. Since we have such functions we just
142 call these. If running Wine with native DLL's, some late bound calls may
143 fail. However, it is better to implement the functions in the forward DLL
144 and recommend the builtin rather than reimplementing the calls here!
147 /*************************************************************************
148 * SHLWAPI_DupSharedHandle
150 * Internal implemetation of SHLWAPI_11.
153 HANDLE WINAPI SHLWAPI_DupSharedHandle(HANDLE hShared, DWORD dwDstProcId,
154 DWORD dwSrcProcId, DWORD dwAccess,
158 DWORD dwMyProcId = GetCurrentProcessId();
161 TRACE("(%p,%ld,%ld,%08lx,%08lx)\n", hShared, dwDstProcId, dwSrcProcId,
162 dwAccess, dwOptions);
164 /* Get dest process handle */
165 if (dwDstProcId == dwMyProcId)
166 hDst = GetCurrentProcess();
168 hDst = OpenProcess(PROCESS_DUP_HANDLE, 0, dwDstProcId);
172 /* Get src process handle */
173 if (dwSrcProcId == dwMyProcId)
174 hSrc = GetCurrentProcess();
176 hSrc = OpenProcess(PROCESS_DUP_HANDLE, 0, dwSrcProcId);
180 /* Make handle available to dest process */
181 if (!DuplicateHandle(hDst, hShared, hSrc, &hRet,
182 dwAccess, 0, dwOptions | DUPLICATE_SAME_ACCESS))
185 if (dwSrcProcId != dwMyProcId)
189 if (dwDstProcId != dwMyProcId)
193 TRACE("Returning handle %p\n", hRet);
197 /*************************************************************************
200 * Create a block of sharable memory and initialise it with data.
203 * lpvData [I] Pointer to data to write
204 * dwSize [I] Size of data
205 * dwProcId [I] ID of process owning data
208 * Success: A shared memory handle
212 * Ordinals 7-11 provide a set of calls to create shared memory between a
213 * group of processes. The shared memory is treated opaquely in that its size
214 * is not exposed to clients who map it. This is accomplished by storing
215 * the size of the map as the first DWORD of mapped data, and then offsetting
216 * the view pointer returned by this size.
219 HANDLE WINAPI SHAllocShared(LPCVOID lpvData, DWORD dwSize, DWORD dwProcId)
225 TRACE("(%p,%ld,%ld)\n", lpvData, dwSize, dwProcId);
227 /* Create file mapping of the correct length */
228 hMap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, FILE_MAP_READ, 0,
229 dwSize + sizeof(dwSize), NULL);
233 /* Get a view in our process address space */
234 pMapped = MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
238 /* Write size of data, followed by the data, to the view */
239 *((DWORD*)pMapped) = dwSize;
241 memcpy((char *) pMapped + sizeof(dwSize), lpvData, dwSize);
243 /* Release view. All further views mapped will be opaque */
244 UnmapViewOfFile(pMapped);
245 hRet = SHLWAPI_DupSharedHandle(hMap, dwProcId,
246 GetCurrentProcessId(), FILE_MAP_ALL_ACCESS,
247 DUPLICATE_SAME_ACCESS);
254 /*************************************************************************
257 * Get a pointer to a block of shared memory from a shared memory handle.
260 * hShared [I] Shared memory handle
261 * dwProcId [I] ID of process owning hShared
264 * Success: A pointer to the shared memory
268 PVOID WINAPI SHLockShared(HANDLE hShared, DWORD dwProcId)
273 TRACE("(%p %ld)\n", hShared, dwProcId);
275 /* Get handle to shared memory for current process */
276 hDup = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
277 FILE_MAP_ALL_ACCESS, 0);
279 pMapped = MapViewOfFile(hDup, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
283 return (char *) pMapped + sizeof(DWORD); /* Hide size */
287 /*************************************************************************
290 * Release a pointer to a block of shared memory.
293 * lpView [I] Shared memory pointer
300 BOOL WINAPI SHUnlockShared(LPVOID lpView)
302 TRACE("(%p)\n", lpView);
303 return UnmapViewOfFile((char *) lpView - sizeof(DWORD)); /* Include size */
306 /*************************************************************************
309 * Destroy a block of sharable memory.
312 * hShared [I] Shared memory handle
313 * dwProcId [I] ID of process owning hShared
320 BOOL WINAPI SHFreeShared(HANDLE hShared, DWORD dwProcId)
324 TRACE("(%p %ld)\n", hShared, dwProcId);
326 /* Get a copy of the handle for our process, closing the source handle */
327 hClose = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
328 FILE_MAP_ALL_ACCESS,DUPLICATE_CLOSE_SOURCE);
329 /* Close local copy */
330 return CloseHandle(hClose);
333 /*************************************************************************
336 * Copy a sharable memory handle from one process to another.
339 * hShared [I] Shared memory handle to duplicate
340 * dwDstProcId [I] ID of the process wanting the duplicated handle
341 * dwSrcProcId [I] ID of the process owning hShared
342 * dwAccess [I] Desired DuplicateHandle() access
343 * dwOptions [I] Desired DuplicateHandle() options
346 * Success: A handle suitable for use by the dwDstProcId process.
347 * Failure: A NULL handle.
350 HANDLE WINAPI SHMapHandle(HANDLE hShared, DWORD dwDstProcId, DWORD dwSrcProcId,
351 DWORD dwAccess, DWORD dwOptions)
355 hRet = SHLWAPI_DupSharedHandle(hShared, dwDstProcId, dwSrcProcId,
356 dwAccess, dwOptions);
360 /*************************************************************************
363 * Create and register a clipboard enumerator for a web browser.
366 * lpBC [I] Binding context
367 * lpUnknown [I] An object exposing the IWebBrowserApp interface
371 * Failure: An HRESULT error code.
374 * The enumerator is stored as a property of the web browser. If it does not
375 * yet exist, it is created and set before being registered.
377 HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown)
379 static const WCHAR szProperty[] = { '{','D','0','F','C','A','4','2','0',
380 '-','D','3','F','5','-','1','1','C','F', '-','B','2','1','1','-','0',
381 '0','A','A','0','0','4','A','E','8','3','7','}','\0' };
382 IEnumFORMATETC* pIEnumFormatEtc = NULL;
385 IWebBrowserApp* pBrowser = NULL;
387 TRACE("(%p, %p)\n", lpBC, lpUnknown);
389 /* Get An IWebBrowserApp interface from lpUnknown */
390 hRet = IUnknown_QueryService(lpUnknown, &IID_IWebBrowserApp, &IID_IWebBrowserApp, (PVOID)&pBrowser);
391 if (FAILED(hRet) || !pBrowser)
392 return E_NOINTERFACE;
394 V_VT(&var) = VT_EMPTY;
396 /* The property we get is the browsers clipboard enumerator */
397 hRet = IWebBrowserApp_GetProperty(pBrowser, (BSTR)szProperty, &var);
401 if (V_VT(&var) == VT_EMPTY)
403 /* Iterate through accepted documents and RegisterClipBoardFormatA() them */
404 char szKeyBuff[128], szValueBuff[128];
405 DWORD dwKeySize, dwValueSize, dwRet = 0, dwCount = 0, dwNumValues, dwType;
406 FORMATETC* formatList, *format;
409 TRACE("Registering formats and creating IEnumFORMATETC instance\n");
411 if (!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\Current"
412 "Version\\Internet Settings\\Accepted Documents", &hDocs))
415 /* Get count of values in key */
418 dwKeySize = sizeof(szKeyBuff);
419 dwRet = RegEnumValueA(hDocs,dwCount,szKeyBuff,&dwKeySize,0,&dwType,0,0);
423 dwNumValues = dwCount;
425 /* Note: dwCount = number of items + 1; The extra item is the end node */
426 format = formatList = HeapAlloc(GetProcessHeap(), 0, dwCount * sizeof(FORMATETC));
428 return E_OUTOFMEMORY;
437 /* Register clipboard formats for the values and populate format list */
438 while(!dwRet && dwCount < dwNumValues)
440 dwKeySize = sizeof(szKeyBuff);
441 dwValueSize = sizeof(szValueBuff);
442 dwRet = RegEnumValueA(hDocs, dwCount, szKeyBuff, &dwKeySize, 0, &dwType,
443 (PBYTE)szValueBuff, &dwValueSize);
447 format->cfFormat = RegisterClipboardFormatA(szValueBuff);
449 format->dwAspect = 1;
458 /* Terminate the (maybe empty) list, last entry has a cfFormat of 0 */
459 format->cfFormat = 0;
461 format->dwAspect = 1;
465 /* Create a clipboard enumerator */
466 GET_FUNC(pCreateFormatEnumerator, urlmon, "CreateFormatEnumerator", E_FAIL);
467 hRet = pCreateFormatEnumerator(dwNumValues, formatList, &pIEnumFormatEtc);
469 if (FAILED(hRet) || !pIEnumFormatEtc)
472 /* Set our enumerator as the browsers property */
473 V_VT(&var) = VT_UNKNOWN;
474 V_UNKNOWN(&var) = (IUnknown*)pIEnumFormatEtc;
476 hRet = IWebBrowserApp_PutProperty(pBrowser, (BSTR)szProperty, var);
479 IEnumFORMATETC_Release(pIEnumFormatEtc);
480 goto RegisterDefaultAcceptHeaders_Exit;
484 if (V_VT(&var) == VT_UNKNOWN)
486 /* Our variant is holding the clipboard enumerator */
487 IUnknown* pIUnknown = V_UNKNOWN(&var);
488 IEnumFORMATETC* pClone = NULL;
490 TRACE("Retrieved IEnumFORMATETC property\n");
492 /* Get an IEnumFormatEtc interface from the variants value */
493 pIEnumFormatEtc = NULL;
494 hRet = IUnknown_QueryInterface(pIUnknown, &IID_IEnumFORMATETC,
495 (PVOID)&pIEnumFormatEtc);
496 if (!hRet && pIEnumFormatEtc)
498 /* Clone and register the enumerator */
499 hRet = IEnumFORMATETC_Clone(pIEnumFormatEtc, &pClone);
502 GET_FUNC(pRegisterFormatEnumerator, urlmon, "RegisterFormatEnumerator", E_FAIL);
503 pRegisterFormatEnumerator(lpBC, pClone, 0);
505 IEnumFORMATETC_Release(pClone);
508 /* Release the IEnumFormatEtc interface */
509 IEnumFORMATETC_Release(pIUnknown);
511 IUnknown_Release(V_UNKNOWN(&var));
514 RegisterDefaultAcceptHeaders_Exit:
515 IWebBrowserApp_Release(pBrowser);
519 /*************************************************************************
522 * Get Explorers "AcceptLanguage" setting.
525 * langbuf [O] Destination for language string
526 * buflen [I] Length of langbuf
527 * [0] Success: used length of langbuf
530 * Success: S_OK. langbuf is set to the language string found.
531 * Failure: E_FAIL, If any arguments are invalid, error occurred, or Explorer
532 * does not contain the setting.
533 * E_INVALIDARG, If the buffer is not big enough
535 HRESULT WINAPI GetAcceptLanguagesW( LPWSTR langbuf, LPDWORD buflen)
537 static const WCHAR szkeyW[] = {
538 'S','o','f','t','w','a','r','e','\\',
539 'M','i','c','r','o','s','o','f','t','\\',
540 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
541 'I','n','t','e','r','n','a','t','i','o','n','a','l',0};
542 static const WCHAR valueW[] = {
543 'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0};
544 static const WCHAR enusW[] = {'e','n','-','u','s',0};
545 DWORD mystrlen, mytype;
551 if(!langbuf || !buflen || !*buflen)
554 mystrlen = (*buflen > 20) ? *buflen : 20 ;
555 mystr = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * mystrlen);
556 RegOpenKeyW(HKEY_CURRENT_USER, szkeyW, &mykey);
557 if(RegQueryValueExW(mykey, valueW, 0, &mytype, (PBYTE)mystr, &mystrlen)) {
558 /* Did not find value */
559 mylcid = GetUserDefaultLCID();
560 /* somehow the mylcid translates into "en-us"
561 * this is similar to "LOCALE_SABBREVLANGNAME"
562 * which could be gotten via GetLocaleInfo.
563 * The only problem is LOCALE_SABBREVLANGUAGE" is
564 * a 3 char string (first 2 are country code and third is
565 * letter for "sublanguage", which does not come close to
568 lstrcpyW(mystr, enusW);
569 mystrlen = lstrlenW(mystr);
571 /* handle returned string */
572 FIXME("missing code\n");
574 memcpy( langbuf, mystr, min(*buflen,strlenW(mystr)+1)*sizeof(WCHAR) );
576 if(*buflen > strlenW(mystr)) {
577 *buflen = strlenW(mystr);
581 retval = E_INVALIDARG;
582 SetLastError(ERROR_INSUFFICIENT_BUFFER);
585 HeapFree(GetProcessHeap(), 0, mystr);
589 /*************************************************************************
592 * Ascii version of GetAcceptLanguagesW.
594 HRESULT WINAPI GetAcceptLanguagesA( LPSTR langbuf, LPDWORD buflen)
597 DWORD buflenW, convlen;
600 if(!langbuf || !buflen || !*buflen) return E_FAIL;
603 langbufW = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * buflenW);
604 retval = GetAcceptLanguagesW(langbufW, &buflenW);
606 /* FIXME: this is wrong, the string may not be null-terminated */
607 convlen = WideCharToMultiByte(CP_ACP, 0, langbufW, -1, langbuf,
608 *buflen, NULL, NULL);
609 *buflen = buflenW ? convlen : 0;
611 HeapFree(GetProcessHeap(), 0, langbufW);
615 /*************************************************************************
618 * Convert a GUID to a string.
621 * guid [I] GUID to convert
622 * lpszDest [O] Destination for string
623 * cchMax [I] Length of output buffer
626 * The length of the string created.
628 INT WINAPI SHStringFromGUIDA(REFGUID guid, LPSTR lpszDest, INT cchMax)
633 TRACE("(%s,%p,%d)\n", debugstr_guid(guid), lpszDest, cchMax);
635 sprintf(xguid, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
636 guid->Data1, guid->Data2, guid->Data3,
637 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
638 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
640 iLen = strlen(xguid) + 1;
644 memcpy(lpszDest, xguid, iLen);
648 /*************************************************************************
651 * Convert a GUID to a string.
654 * guid [I] GUID to convert
655 * str [O] Destination for string
656 * cmax [I] Length of output buffer
659 * The length of the string created.
661 INT WINAPI SHStringFromGUIDW(REFGUID guid, LPWSTR lpszDest, INT cchMax)
665 static const WCHAR wszFormat[] = {'{','%','0','8','l','X','-','%','0','4','X','-','%','0','4','X','-',
666 '%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','%','0','2','X','%','0','2',
667 'X','%','0','2','X','%','0','2','X','}',0};
669 TRACE("(%s,%p,%d)\n", debugstr_guid(guid), lpszDest, cchMax);
671 sprintfW(xguid, wszFormat, guid->Data1, guid->Data2, guid->Data3,
672 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
673 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
675 iLen = strlenW(xguid) + 1;
679 memcpy(lpszDest, xguid, iLen*sizeof(WCHAR));
683 /*************************************************************************
686 * Determine if a Unicode character is a space.
689 * wc [I] Character to check.
692 * TRUE, if wc is a space,
695 BOOL WINAPI IsCharSpaceW(WCHAR wc)
699 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_SPACE);
702 /*************************************************************************
705 * Determine if a Unicode character is a blank.
708 * wc [I] Character to check.
711 * TRUE, if wc is a blank,
715 BOOL WINAPI IsCharBlankW(WCHAR wc)
719 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_BLANK);
722 /*************************************************************************
725 * Determine if a Unicode character is punctuation.
728 * wc [I] Character to check.
731 * TRUE, if wc is punctuation,
734 BOOL WINAPI IsCharPunctW(WCHAR wc)
738 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_PUNCT);
741 /*************************************************************************
744 * Determine if a Unicode character is a control character.
747 * wc [I] Character to check.
750 * TRUE, if wc is a control character,
753 BOOL WINAPI IsCharCntrlW(WCHAR wc)
757 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_CNTRL);
760 /*************************************************************************
763 * Determine if a Unicode character is a digit.
766 * wc [I] Character to check.
769 * TRUE, if wc is a digit,
772 BOOL WINAPI IsCharDigitW(WCHAR wc)
776 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_DIGIT);
779 /*************************************************************************
782 * Determine if a Unicode character is a hex digit.
785 * wc [I] Character to check.
788 * TRUE, if wc is a hex digit,
791 BOOL WINAPI IsCharXDigitW(WCHAR wc)
795 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_XDIGIT);
798 /*************************************************************************
802 BOOL WINAPI GetStringType3ExW(LPWSTR lpszStr, DWORD dwLen, LPVOID p3)
804 FIXME("(%s,0x%08lx,%p): stub\n", debugstr_w(lpszStr), dwLen, p3);
808 /*************************************************************************
811 * Insert a bitmap menu item at the bottom of a menu.
814 * hMenu [I] Menu to insert into
815 * flags [I] Flags for insertion
816 * id [I] Menu ID of the item
817 * str [I] Menu text for the item
820 * Success: TRUE, the item is inserted into the menu
821 * Failure: FALSE, if any parameter is invalid
823 BOOL WINAPI AppendMenuWrapW(HMENU hMenu, UINT flags, UINT id, LPCWSTR str)
825 TRACE("(%p,0x%08x,0x%08x,%s)\n",hMenu, flags, id, debugstr_w(str));
826 return InsertMenuW(hMenu, -1, flags | MF_BITMAP, id, str);
829 /*************************************************************************
832 * Get the text from a given dialog item.
835 * hWnd [I] Handle of dialog
836 * nItem [I] Index of item
837 * lpsDest [O] Buffer for receiving window text
838 * nDestLen [I] Length of buffer.
841 * Success: The length of the returned text.
844 INT WINAPI GetDlgItemTextWrapW(HWND hWnd, INT nItem, LPWSTR lpsDest,INT nDestLen)
846 HWND hItem = GetDlgItem(hWnd, nItem);
849 return GetWindowTextW(hItem, lpsDest, nDestLen);
851 *lpsDest = (WCHAR)'\0';
855 /*************************************************************************
858 * Set the text of a given dialog item.
861 * hWnd [I] Handle of dialog
862 * iItem [I] Index of item
863 * lpszText [O] Text to set
866 * Success: TRUE. The text of the dialog is set to lpszText.
867 * Failure: FALSE, Otherwise.
869 BOOL WINAPI SetDlgItemTextWrapW(HWND hWnd, INT iItem, LPCWSTR lpszText)
871 HWND hWndItem = GetDlgItem(hWnd, iItem);
873 return SetWindowTextW(hWndItem, lpszText);
877 /*************************************************************************
880 * Compare two Ascii strings up to a given length.
883 * lpszSrc [I] Source string
884 * lpszCmp [I] String to compare to lpszSrc
885 * len [I] Maximum length
888 * A number greater than, less than or equal to 0 depending on whether
889 * lpszSrc is greater than, less than or equal to lpszCmp.
891 DWORD WINAPI StrCmpNCA(LPCSTR lpszSrc, LPCSTR lpszCmp, INT len)
893 return strncmp(lpszSrc, lpszCmp, len);
896 /*************************************************************************
899 * Unicode version of StrCmpNCA.
901 DWORD WINAPI StrCmpNCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, INT len)
903 return strncmpW(lpszSrc, lpszCmp, len);
906 /*************************************************************************
909 * Compare two Ascii strings up to a given length, ignoring case.
912 * lpszSrc [I] Source string
913 * lpszCmp [I] String to compare to lpszSrc
914 * len [I] Maximum length
917 * A number greater than, less than or equal to 0 depending on whether
918 * lpszSrc is greater than, less than or equal to lpszCmp.
920 DWORD WINAPI StrCmpNICA(LPCSTR lpszSrc, LPCSTR lpszCmp, DWORD len)
922 return strncasecmp(lpszSrc, lpszCmp, len);
925 /*************************************************************************
928 * Unicode version of StrCmpNICA.
930 DWORD WINAPI StrCmpNICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, DWORD len)
932 return strncmpiW(lpszSrc, lpszCmp, len);
935 /*************************************************************************
938 * Compare two Ascii strings.
941 * lpszSrc [I] Source string
942 * lpszCmp [I] String to compare to lpszSrc
945 * A number greater than, less than or equal to 0 depending on whether
946 * lpszSrc is greater than, less than or equal to lpszCmp.
948 DWORD WINAPI StrCmpCA(LPCSTR lpszSrc, LPCSTR lpszCmp)
950 return strcmp(lpszSrc, lpszCmp);
953 /*************************************************************************
956 * Unicode version of StrCmpCA.
958 DWORD WINAPI StrCmpCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp)
960 return strcmpW(lpszSrc, lpszCmp);
963 /*************************************************************************
966 * Compare two Ascii strings, ignoring case.
969 * lpszSrc [I] Source string
970 * lpszCmp [I] String to compare to lpszSrc
973 * A number greater than, less than or equal to 0 depending on whether
974 * lpszSrc is greater than, less than or equal to lpszCmp.
976 DWORD WINAPI StrCmpICA(LPCSTR lpszSrc, LPCSTR lpszCmp)
978 return strcasecmp(lpszSrc, lpszCmp);
981 /*************************************************************************
984 * Unicode version of StrCmpICA.
986 DWORD WINAPI StrCmpICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp)
988 return strcmpiW(lpszSrc, lpszCmp);
991 /*************************************************************************
994 * Get an identification string for the OS and explorer.
997 * lpszDest [O] Destination for Id string
998 * dwDestLen [I] Length of lpszDest
1001 * TRUE, If the string was created successfully
1004 BOOL WINAPI SHAboutInfoA(LPSTR lpszDest, DWORD dwDestLen)
1008 TRACE("(%p,%ld)\n", lpszDest, dwDestLen);
1010 if (lpszDest && SHAboutInfoW(buff, dwDestLen))
1012 WideCharToMultiByte(CP_ACP, 0, buff, -1, lpszDest, dwDestLen, NULL, NULL);
1018 /*************************************************************************
1021 * Unicode version of SHAboutInfoA.
1023 BOOL WINAPI SHAboutInfoW(LPWSTR lpszDest, DWORD dwDestLen)
1025 static const WCHAR szIEKey[] = { 'S','O','F','T','W','A','R','E','\\',
1026 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
1027 ' ','E','x','p','l','o','r','e','r','\0' };
1028 static const WCHAR szWinNtKey[] = { 'S','O','F','T','W','A','R','E','\\',
1029 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s',' ',
1030 'N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
1031 static const WCHAR szWinKey[] = { 'S','O','F','T','W','A','R','E','\\',
1032 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
1033 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
1034 static const WCHAR szRegKey[] = { 'S','O','F','T','W','A','R','E','\\',
1035 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
1036 ' ','E','x','p','l','o','r','e','r','\\',
1037 'R','e','g','i','s','t','r','a','t','i','o','n','\0' };
1038 static const WCHAR szVersion[] = { 'V','e','r','s','i','o','n','\0' };
1039 static const WCHAR szCustomized[] = { 'C','u','s','t','o','m','i','z','e','d',
1040 'V','e','r','s','i','o','n','\0' };
1041 static const WCHAR szOwner[] = { 'R','e','g','i','s','t','e','r','e','d',
1042 'O','w','n','e','r','\0' };
1043 static const WCHAR szOrg[] = { 'R','e','g','i','s','t','e','r','e','d',
1044 'O','r','g','a','n','i','z','a','t','i','o','n','\0' };
1045 static const WCHAR szProduct[] = { 'P','r','o','d','u','c','t','I','d','\0' };
1046 static const WCHAR szUpdate[] = { 'I','E','A','K',
1047 'U','p','d','a','t','e','U','r','l','\0' };
1048 static const WCHAR szHelp[] = { 'I','E','A','K',
1049 'H','e','l','p','S','t','r','i','n','g','\0' };
1052 DWORD dwType, dwLen;
1054 TRACE("(%p,%ld)\n", lpszDest, dwDestLen);
1061 /* Try the NT key first, followed by 95/98 key */
1062 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinNtKey, 0, KEY_READ, &hReg) &&
1063 RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinKey, 0, KEY_READ, &hReg))
1069 if (!SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey, szVersion, &dwType, buff, &dwLen))
1071 DWORD dwStrLen = strlenW(buff);
1072 dwLen = 30 - dwStrLen;
1073 SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey,
1074 szCustomized, &dwType, buff+dwStrLen, &dwLen);
1076 StrCatBuffW(lpszDest, buff, dwDestLen);
1078 /* ~Registered Owner */
1081 if (SHGetValueW(hReg, szOwner, 0, &dwType, buff+1, &dwLen))
1083 StrCatBuffW(lpszDest, buff, dwDestLen);
1085 /* ~Registered Organization */
1087 if (SHGetValueW(hReg, szOrg, 0, &dwType, buff+1, &dwLen))
1089 StrCatBuffW(lpszDest, buff, dwDestLen);
1091 /* FIXME: Not sure where this number comes from */
1095 StrCatBuffW(lpszDest, buff, dwDestLen);
1099 if (SHGetValueW(HKEY_LOCAL_MACHINE, szRegKey, szProduct, &dwType, buff+1, &dwLen))
1101 StrCatBuffW(lpszDest, buff, dwDestLen);
1103 /* ~IE Update Url */
1105 if(SHGetValueW(HKEY_LOCAL_MACHINE, szWinKey, szUpdate, &dwType, buff+1, &dwLen))
1107 StrCatBuffW(lpszDest, buff, dwDestLen);
1109 /* ~IE Help String */
1111 if(SHGetValueW(hReg, szHelp, 0, &dwType, buff+1, &dwLen))
1113 StrCatBuffW(lpszDest, buff, dwDestLen);
1119 /*************************************************************************
1122 * Call IOleCommandTarget_QueryStatus() on an object.
1125 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1126 * pguidCmdGroup [I] GUID for the command group
1128 * prgCmds [O] Commands
1129 * pCmdText [O] Command text
1133 * Failure: E_FAIL, if lpUnknown is NULL.
1134 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1135 * Otherwise, an error code from IOleCommandTarget_QueryStatus().
1137 HRESULT WINAPI IUnknown_QueryStatus(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
1138 ULONG cCmds, OLECMD *prgCmds, OLECMDTEXT* pCmdText)
1140 HRESULT hRet = E_FAIL;
1142 TRACE("(%p,%p,%ld,%p,%p)\n",lpUnknown, pguidCmdGroup, cCmds, prgCmds, pCmdText);
1146 IOleCommandTarget* lpOle;
1148 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
1151 if (SUCCEEDED(hRet) && lpOle)
1153 hRet = IOleCommandTarget_QueryStatus(lpOle, pguidCmdGroup, cCmds,
1155 IOleCommandTarget_Release(lpOle);
1161 /*************************************************************************
1164 * Call IOleCommandTarget_Exec() on an object.
1167 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1168 * pguidCmdGroup [I] GUID for the command group
1172 * Failure: E_FAIL, if lpUnknown is NULL.
1173 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1174 * Otherwise, an error code from IOleCommandTarget_Exec().
1176 HRESULT WINAPI IUnknown_Exec(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
1177 DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
1180 HRESULT hRet = E_FAIL;
1182 TRACE("(%p,%p,%ld,%ld,%p,%p)\n",lpUnknown, pguidCmdGroup, nCmdID,
1183 nCmdexecopt, pvaIn, pvaOut);
1187 IOleCommandTarget* lpOle;
1189 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
1191 if (SUCCEEDED(hRet) && lpOle)
1193 hRet = IOleCommandTarget_Exec(lpOle, pguidCmdGroup, nCmdID,
1194 nCmdexecopt, pvaIn, pvaOut);
1195 IOleCommandTarget_Release(lpOle);
1201 /*************************************************************************
1204 * Retrieve, modify, and re-set a value from a window.
1207 * hWnd [I] Window to get value from
1208 * offset [I] Offset of value
1209 * wMask [I] Mask for uiFlags
1210 * wFlags [I] Bits to set in window value
1213 * The new value as it was set, or 0 if any parameter is invalid.
1216 * Any bits set in uiMask are cleared from the value, then any bits set in
1217 * uiFlags are set in the value.
1219 LONG WINAPI SHSetWindowBits(HWND hwnd, INT offset, UINT wMask, UINT wFlags)
1221 LONG ret = GetWindowLongA(hwnd, offset);
1222 LONG newFlags = (wFlags & wMask) | (ret & ~wFlags);
1224 if (newFlags != ret)
1225 ret = SetWindowLongA(hwnd, offset, newFlags);
1229 /*************************************************************************
1232 * Change a window's parent.
1235 * hWnd [I] Window to change parent of
1236 * hWndParent [I] New parent window
1239 * The old parent of hWnd.
1242 * If hWndParent is NULL (desktop), the window style is changed to WS_POPUP.
1243 * If hWndParent is NOT NULL then we set the WS_CHILD style.
1245 HWND WINAPI SHSetParentHwnd(HWND hWnd, HWND hWndParent)
1247 TRACE("%p, %p\n", hWnd, hWndParent);
1249 if(GetParent(hWnd) == hWndParent)
1253 SHSetWindowBits(hWnd, GWL_STYLE, WS_CHILD, WS_CHILD);
1255 SHSetWindowBits(hWnd, GWL_STYLE, WS_POPUP, WS_POPUP);
1257 return SetParent(hWnd, hWndParent);
1260 /*************************************************************************
1263 * Locate and advise a connection point in an IConnectionPointContainer object.
1266 * lpUnkSink [I] Sink for the connection point advise call
1267 * riid [I] REFIID of connection point to advise
1268 * bAdviseOnly [I] TRUE = Advise only, FALSE = Unadvise first
1269 * lpUnknown [I] Object supporting the IConnectionPointContainer interface
1270 * lpCookie [O] Pointer to connection point cookie
1271 * lppCP [O] Destination for the IConnectionPoint found
1274 * Success: S_OK. If lppCP is non-NULL, it is filled with the IConnectionPoint
1275 * that was advised. The caller is responsable for releasing it.
1276 * Failure: E_FAIL, if any arguments are invalid.
1277 * E_NOINTERFACE, if lpUnknown isn't an IConnectionPointContainer,
1278 * Or an HRESULT error code if any call fails.
1280 HRESULT WINAPI ConnectToConnectionPoint(IUnknown* lpUnkSink, REFIID riid, BOOL bAdviseOnly,
1281 IUnknown* lpUnknown, LPDWORD lpCookie,
1282 IConnectionPoint **lppCP)
1285 IConnectionPointContainer* lpContainer;
1286 IConnectionPoint *lpCP;
1288 if(!lpUnknown || (bAdviseOnly && !lpUnkSink))
1294 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer,
1295 (void**)&lpContainer);
1296 if (SUCCEEDED(hRet))
1298 hRet = IConnectionPointContainer_FindConnectionPoint(lpContainer, riid, &lpCP);
1300 if (SUCCEEDED(hRet))
1303 hRet = IConnectionPoint_Unadvise(lpCP, *lpCookie);
1304 hRet = IConnectionPoint_Advise(lpCP, lpUnkSink, lpCookie);
1309 if (lppCP && SUCCEEDED(hRet))
1310 *lppCP = lpCP; /* Caller keeps the interface */
1312 IConnectionPoint_Release(lpCP); /* Release it */
1315 IUnknown_Release(lpContainer);
1320 /*************************************************************************
1323 * Release an interface.
1326 * lpUnknown [I] Object to release
1331 DWORD WINAPI IUnknown_AtomicRelease(IUnknown ** lpUnknown)
1335 TRACE("(%p)\n",lpUnknown);
1337 if(!lpUnknown || !*((LPDWORD)lpUnknown)) return 0;
1341 TRACE("doing Release\n");
1343 return IUnknown_Release(temp);
1346 /*************************************************************************
1349 * Skip '//' if present in a string.
1352 * lpszSrc [I] String to check for '//'
1355 * Success: The next character after the '//' or the string if not present
1356 * Failure: NULL, if lpszStr is NULL.
1358 LPCSTR WINAPI PathSkipLeadingSlashesA(LPCSTR lpszSrc)
1360 if (lpszSrc && lpszSrc[0] == '/' && lpszSrc[1] == '/')
1365 /*************************************************************************
1368 * Check if two interfaces come from the same object.
1371 * lpInt1 [I] Interface to check against lpInt2.
1372 * lpInt2 [I] Interface to check against lpInt1.
1375 * TRUE, If the interfaces come from the same object.
1378 BOOL WINAPI SHIsSameObject(IUnknown* lpInt1, IUnknown* lpInt2)
1380 LPVOID lpUnknown1, lpUnknown2;
1382 TRACE("%p %p\n", lpInt1, lpInt2);
1384 if (!lpInt1 || !lpInt2)
1387 if (lpInt1 == lpInt2)
1390 if (!SUCCEEDED(IUnknown_QueryInterface(lpInt1, &IID_IUnknown,
1391 (LPVOID *)&lpUnknown1)))
1394 if (!SUCCEEDED(IUnknown_QueryInterface(lpInt2, &IID_IUnknown,
1395 (LPVOID *)&lpUnknown2)))
1398 if (lpUnknown1 == lpUnknown2)
1404 /*************************************************************************
1407 * Get the window handle of an object.
1410 * lpUnknown [I] Object to get the window handle of
1411 * lphWnd [O] Destination for window handle
1414 * Success: S_OK. lphWnd contains the objects window handle.
1415 * Failure: An HRESULT error code.
1418 * lpUnknown is expected to support one of the following interfaces:
1419 * IOleWindow(), IInternetSecurityMgrSite(), or IShellView().
1421 HRESULT WINAPI IUnknown_GetWindow(IUnknown *lpUnknown, HWND *lphWnd)
1423 /* FIXME: Wine has no header for this object */
1424 static const GUID IID_IInternetSecurityMgrSite = { 0x79eac9ed,
1425 0xbaf9, 0x11ce, { 0x8c, 0x82, 0x00, 0xaa, 0x00, 0x4b, 0xa9, 0x0b }};
1427 HRESULT hRet = E_FAIL;
1429 TRACE("(%p,%p)\n", lpUnknown, lphWnd);
1434 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleWindow, (void**)&lpOle);
1438 hRet = IUnknown_QueryInterface(lpUnknown,&IID_IShellView, (void**)&lpOle);
1442 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInternetSecurityMgrSite,
1447 if (SUCCEEDED(hRet))
1449 /* Lazyness here - Since GetWindow() is the first method for the above 3
1450 * interfaces, we use the same call for them all.
1452 hRet = IOleWindow_GetWindow((IOleWindow*)lpOle, lphWnd);
1453 IUnknown_Release(lpOle);
1455 TRACE("Returning HWND=%p\n", *lphWnd);
1461 /*************************************************************************
1464 * Call a method on as as yet unidentified object.
1467 * pUnk [I] Object supporting the unidentified interface,
1468 * arg [I] Argument for the call on the object.
1473 HRESULT WINAPI IUnknown_SetOwner(IUnknown *pUnk, ULONG arg)
1475 static const GUID guid_173 = {
1476 0x5836fb00, 0x8187, 0x11cf, { 0xa1,0x2b,0x00,0xaa,0x00,0x4a,0xe8,0x37 }
1480 TRACE("(%p,%ld)\n", pUnk, arg);
1482 /* Note: arg may not be a ULONG and pUnk2 is for sure not an IMalloc -
1483 * We use this interface as its vtable entry is compatible with the
1484 * object in question.
1485 * FIXME: Find out what this object is and where it should be defined.
1488 SUCCEEDED(IUnknown_QueryInterface(pUnk, &guid_173, (void**)&pUnk2)))
1490 IMalloc_Alloc(pUnk2, arg); /* Faked call!! */
1491 IMalloc_Release(pUnk2);
1496 /*************************************************************************
1499 * Call either IObjectWithSite_SetSite() or IPersistMoniker_GetClassID() on
1504 * Failure: E_FAIL, if p1 is NULL.
1505 * E_NOINTERFACE If p1 does not support the IPersist interface,
1506 * Or an HRESULT error code.
1508 DWORD WINAPI IUnknown_SetSite(
1509 IUnknown *p1, /* [in] OLE object */
1510 LPVOID *p2) /* [out] ptr for call results */
1514 if (!p1) return E_FAIL;
1516 /* see if SetSite interface exists for IObjectWithSite object */
1517 ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id1, (LPVOID *)&p1);
1518 TRACE("first IU_QI ret=%08lx, p1=%p\n", ret, p1);
1521 /* see if GetClassId interface exists for IPersistMoniker object */
1522 ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id2, (LPVOID *)&aa);
1523 TRACE("second IU_QI ret=%08lx, aa=%08lx\n", ret, aa);
1524 if (ret) return ret;
1526 /* fake a GetClassId call */
1527 ret = IOleWindow_GetWindow((IOleWindow *)aa, (HWND*)p2);
1528 TRACE("second IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1530 IUnknown_Release((IUnknown *)aa);
1533 /* fake a SetSite call */
1534 ret = IOleWindow_GetWindow((IOleWindow *)p1, (HWND*)p2);
1535 TRACE("first IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1537 IUnknown_Release((IUnknown *)p1);
1542 /*************************************************************************
1545 * Call IPersist_GetClassID() on an object.
1548 * lpUnknown [I] Object supporting the IPersist interface
1549 * lpClassId [O] Destination for Class Id
1552 * Success: S_OK. lpClassId contains the Class Id requested.
1553 * Failure: E_FAIL, If lpUnknown is NULL,
1554 * E_NOINTERFACE If lpUnknown does not support IPersist,
1555 * Or an HRESULT error code.
1557 HRESULT WINAPI IUnknown_GetClassID(IUnknown *lpUnknown, CLSID* lpClassId)
1559 IPersist* lpPersist;
1560 HRESULT hRet = E_FAIL;
1562 TRACE("(%p,%p)\n", lpUnknown, debugstr_guid(lpClassId));
1566 hRet = IUnknown_QueryInterface(lpUnknown,&IID_IPersist,(void**)&lpPersist);
1567 if (SUCCEEDED(hRet))
1569 IPersist_GetClassID(lpPersist, lpClassId);
1570 IPersist_Release(lpPersist);
1576 /*************************************************************************
1579 * Retrieve a Service Interface from an object.
1582 * lpUnknown [I] Object to get an IServiceProvider interface from
1583 * sid [I] Service ID for IServiceProvider_QueryService() call
1584 * riid [I] Function requested for QueryService call
1585 * lppOut [O] Destination for the service interface pointer
1588 * Success: S_OK. lppOut contains an object providing the requested service
1589 * Failure: An HRESULT error code
1592 * lpUnknown is expected to support the IServiceProvider interface.
1594 HRESULT WINAPI IUnknown_QueryService(IUnknown* lpUnknown, REFGUID sid, REFIID riid,
1597 IServiceProvider* pService = NULL;
1608 /* Get an IServiceProvider interface from the object */
1609 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IServiceProvider,
1610 (LPVOID*)&pService);
1612 if (!hRet && pService)
1614 TRACE("QueryInterface returned (IServiceProvider*)%p\n", pService);
1616 /* Get a Service interface from the object */
1617 hRet = IServiceProvider_QueryService(pService, sid, riid, lppOut);
1619 TRACE("(IServiceProvider*)%p returned (IUnknown*)%p\n", pService, *lppOut);
1621 /* Release the IServiceProvider interface */
1622 IUnknown_Release(pService);
1627 /*************************************************************************
1630 * Loads a popup menu.
1633 * hInst [I] Instance handle
1634 * szName [I] Menu name
1640 BOOL WINAPI SHLoadMenuPopup(HINSTANCE hInst, LPCWSTR szName)
1642 HMENU hMenu, hSubMenu;
1644 if ((hMenu = LoadMenuW(hInst, szName)))
1646 if ((hSubMenu = GetSubMenu(hMenu, 0)))
1647 RemoveMenu(hMenu, 0, MF_BYPOSITION);
1655 typedef struct _enumWndData
1660 LRESULT (WINAPI *pfnPost)(HWND,UINT,WPARAM,LPARAM);
1663 /* Callback for SHLWAPI_178 */
1664 static BOOL CALLBACK SHLWAPI_EnumChildProc(HWND hWnd, LPARAM lParam)
1666 enumWndData *data = (enumWndData *)lParam;
1668 TRACE("(%p,%p)\n", hWnd, data);
1669 data->pfnPost(hWnd, data->uiMsgId, data->wParam, data->lParam);
1673 /*************************************************************************
1676 * Send or post a message to every child of a window.
1679 * hWnd [I] Window whose children will get the messages
1680 * uiMsgId [I] Message Id
1681 * wParam [I] WPARAM of message
1682 * lParam [I] LPARAM of message
1683 * bSend [I] TRUE = Use SendMessageA(), FALSE = Use PostMessageA()
1689 * The appropriate ASCII or Unicode function is called for the window.
1691 void WINAPI SHPropagateMessage(HWND hWnd, UINT uiMsgId, WPARAM wParam, LPARAM lParam, BOOL bSend)
1695 TRACE("(%p,%u,%d,%ld,%d)\n", hWnd, uiMsgId, wParam, lParam, bSend);
1699 data.uiMsgId = uiMsgId;
1700 data.wParam = wParam;
1701 data.lParam = lParam;
1704 data.pfnPost = IsWindowUnicode(hWnd) ? (void*)SendMessageW : (void*)SendMessageA;
1706 data.pfnPost = IsWindowUnicode(hWnd) ? (void*)PostMessageW : (void*)PostMessageA;
1708 EnumChildWindows(hWnd, SHLWAPI_EnumChildProc, (LPARAM)&data);
1712 /*************************************************************************
1715 * Remove all sub-menus from a menu.
1718 * hMenu [I] Menu to remove sub-menus from
1721 * Success: 0. All sub-menus under hMenu are removed
1722 * Failure: -1, if any parameter is invalid
1724 DWORD WINAPI SHRemoveAllSubMenus(HMENU hMenu)
1726 int iItemCount = GetMenuItemCount(hMenu) - 1;
1727 while (iItemCount >= 0)
1729 HMENU hSubMenu = GetSubMenu(hMenu, iItemCount);
1731 RemoveMenu(hMenu, iItemCount, MF_BYPOSITION);
1737 /*************************************************************************
1740 * Enable or disable a menu item.
1743 * hMenu [I] Menu holding menu item
1744 * uID [I] ID of menu item to enable/disable
1745 * bEnable [I] Whether to enable (TRUE) or disable (FALSE) the item.
1748 * The return code from EnableMenuItem.
1750 UINT WINAPI SHEnableMenuItem(HMENU hMenu, UINT wItemID, BOOL bEnable)
1752 return EnableMenuItem(hMenu, wItemID, bEnable ? MF_ENABLED : MF_GRAYED);
1755 /*************************************************************************
1758 * Check or uncheck a menu item.
1761 * hMenu [I] Menu holding menu item
1762 * uID [I] ID of menu item to check/uncheck
1763 * bCheck [I] Whether to check (TRUE) or uncheck (FALSE) the item.
1766 * The return code from CheckMenuItem.
1768 DWORD WINAPI SHCheckMenuItem(HMENU hMenu, UINT uID, BOOL bCheck)
1770 return CheckMenuItem(hMenu, uID, bCheck ? MF_CHECKED : MF_UNCHECKED);
1773 /*************************************************************************
1776 * Register a window class if it isn't already.
1779 * lpWndClass [I] Window class to register
1782 * The result of the RegisterClassA call.
1784 DWORD WINAPI SHRegisterClassA(WNDCLASSA *wndclass)
1787 if (GetClassInfoA(wndclass->hInstance, wndclass->lpszClassName, &wca))
1789 return (DWORD)RegisterClassA(wndclass);
1792 /*************************************************************************
1795 BOOL WINAPI SHSimulateDrop(IDropTarget *pDrop, IDataObject *pDataObj,
1796 DWORD grfKeyState, PPOINTL lpPt, DWORD* pdwEffect)
1798 DWORD dwEffect = DROPEFFECT_LINK | DROPEFFECT_MOVE | DROPEFFECT_COPY;
1799 POINTL pt = { 0, 0 };
1805 pdwEffect = &dwEffect;
1807 IDropTarget_DragEnter(pDrop, pDataObj, grfKeyState, *lpPt, pdwEffect);
1810 return IDropTarget_Drop(pDrop, pDataObj, grfKeyState, *lpPt, pdwEffect);
1812 IDropTarget_DragLeave(pDrop);
1816 /*************************************************************************
1819 * Call IPersistPropertyBag_Load() on an object.
1822 * lpUnknown [I] Object supporting the IPersistPropertyBag interface
1823 * lpPropBag [O] Destination for loaded IPropertyBag
1827 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1829 DWORD WINAPI SHLoadFromPropertyBag(IUnknown *lpUnknown, IPropertyBag* lpPropBag)
1831 IPersistPropertyBag* lpPPBag;
1832 HRESULT hRet = E_FAIL;
1834 TRACE("(%p,%p)\n", lpUnknown, lpPropBag);
1838 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IPersistPropertyBag,
1840 if (SUCCEEDED(hRet) && lpPPBag)
1842 hRet = IPersistPropertyBag_Load(lpPPBag, lpPropBag, NULL);
1843 IPersistPropertyBag_Release(lpPPBag);
1849 /*************************************************************************
1852 * Call IOleControlSite_GetExtendedControl() on an object.
1855 * lpUnknown [I] Object supporting the IOleControlSite interface
1856 * lppDisp [O] Destination for resulting IDispatch.
1860 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1862 DWORD WINAPI IUnknown_OnFocusOCS(IUnknown *lpUnknown, IDispatch** lppDisp)
1864 IOleControlSite* lpCSite;
1865 HRESULT hRet = E_FAIL;
1867 TRACE("(%p,%p)\n", lpUnknown, lppDisp);
1870 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleControlSite,
1872 if (SUCCEEDED(hRet) && lpCSite)
1874 hRet = IOleControlSite_GetExtendedControl(lpCSite, lppDisp);
1875 IOleControlSite_Release(lpCSite);
1881 /*************************************************************************
1884 * Get a sub-menu from a menu item.
1887 * hMenu [I] Menu to get sub-menu from
1888 * uID [I] ID of menu item containing sub-menu
1891 * The sub-menu of the item, or a NULL handle if any parameters are invalid.
1893 HMENU WINAPI SHGetMenuFromID(HMENU hMenu, UINT uID)
1897 TRACE("(%p,%uld)\n", hMenu, uID);
1899 mi.cbSize = sizeof(MENUITEMINFOA);
1900 mi.fMask = MIIM_SUBMENU;
1902 if (!GetMenuItemInfoA(hMenu, uID, 0, &mi))
1908 /*************************************************************************
1911 * Get the color depth of the primary display.
1917 * The color depth of the primary display.
1919 DWORD WINAPI SHGetCurColorRes()
1927 ret = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
1932 /*************************************************************************
1935 * Wait for a message to arrive, with a timeout.
1938 * hand [I] Handle to query
1939 * dwTimeout [I] Timeout in ticks or INFINITE to never timeout
1942 * STATUS_TIMEOUT if no message is received before dwTimeout ticks passes.
1943 * Otherwise returns the value from MsgWaitForMultipleObjectsEx when a
1944 * message is available.
1946 DWORD WINAPI SHWaitForSendMessageThread(HANDLE hand, DWORD dwTimeout)
1948 DWORD dwEndTicks = GetTickCount() + dwTimeout;
1951 while ((dwRet = MsgWaitForMultipleObjectsEx(1, &hand, dwTimeout, QS_SENDMESSAGE, 0)) == 1)
1955 PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE);
1957 if (dwTimeout != INFINITE)
1959 if ((int)(dwTimeout = dwEndTicks - GetTickCount()) <= 0)
1960 return WAIT_TIMEOUT;
1967 /*************************************************************************
1970 * Blank out a region of text by drawing the background only.
1973 * hDC [I] Device context to draw in
1974 * pRect [I] Area to draw in
1975 * cRef [I] Color to draw in
1980 DWORD WINAPI SHFillRectClr(HDC hDC, LPCRECT pRect, COLORREF cRef)
1982 COLORREF cOldColor = SetBkColor(hDC, cRef);
1983 ExtTextOutA(hDC, 0, 0, ETO_OPAQUE, pRect, 0, 0, 0);
1984 SetBkColor(hDC, cOldColor);
1988 /*************************************************************************
1991 * Return the value asociated with a key in a map.
1994 * lpKeys [I] A list of keys of length iLen
1995 * lpValues [I] A list of values associated with lpKeys, of length iLen
1996 * iLen [I] Length of both lpKeys and lpValues
1997 * iKey [I] The key value to look up in lpKeys
2000 * The value in lpValues associated with iKey, or -1 if iKey is not
2004 * - If two elements in the map share the same key, this function returns
2005 * the value closest to the start of the map
2006 * - The native version of this function crashes if lpKeys or lpValues is NULL.
2008 int WINAPI SHSearchMapInt(const int *lpKeys, const int *lpValues, int iLen, int iKey)
2010 if (lpKeys && lpValues)
2016 if (lpKeys[i] == iKey)
2017 return lpValues[i]; /* Found */
2021 return -1; /* Not found */
2025 /*************************************************************************
2028 * Copy an interface pointer
2031 * lppDest [O] Destination for copy
2032 * lpUnknown [I] Source for copy
2037 VOID WINAPI IUnknown_Set(IUnknown **lppDest, IUnknown *lpUnknown)
2039 TRACE("(%p,%p)\n", lppDest, lpUnknown);
2042 IUnknown_AtomicRelease(lppDest); /* Release existing interface */
2047 IUnknown_AddRef(lpUnknown);
2048 *lppDest = lpUnknown;
2052 /*************************************************************************
2056 HRESULT WINAPI MayExecForward(IUnknown* lpUnknown, INT iUnk, REFGUID pguidCmdGroup,
2057 DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
2060 FIXME("(%p,%d,%p,%ld,%ld,%p,%p) - stub!\n", lpUnknown, iUnk, pguidCmdGroup,
2061 nCmdID, nCmdexecopt, pvaIn, pvaOut);
2062 return DRAGDROP_E_NOTREGISTERED;
2065 /*************************************************************************
2069 HRESULT WINAPI IsQSForward(REFGUID pguidCmdGroup,ULONG cCmds, OLECMD *prgCmds)
2071 FIXME("(%p,%ld,%p) - stub!\n", pguidCmdGroup, cCmds, prgCmds);
2072 return DRAGDROP_E_NOTREGISTERED;
2075 /*************************************************************************
2078 * Determine if a window is not a child of another window.
2081 * hParent [I] Suspected parent window
2082 * hChild [I] Suspected child window
2085 * TRUE: If hChild is a child window of hParent
2086 * FALSE: If hChild is not a child window of hParent, or they are equal
2088 BOOL WINAPI SHIsChildOrSelf(HWND hParent, HWND hChild)
2090 TRACE("(%p,%p)\n", hParent, hChild);
2092 if (!hParent || !hChild)
2094 else if(hParent == hChild)
2096 return !IsChild(hParent, hChild);
2099 /*************************************************************************
2102 * Some sort of memory management process.
2104 DWORD WINAPI FDSA_Initialize(
2111 FIXME("(0x%08lx 0x%08lx %p %p 0x%08lx) stub\n",
2116 /*************************************************************************
2119 * Some sort of memory management process.
2121 DWORD WINAPI FDSA_Destroy(
2124 FIXME("(%p) stub\n",
2129 /*************************************************************************
2132 * Some sort of memory management process.
2134 DWORD WINAPI FDSA_InsertItem(
2139 FIXME("(%p 0x%08lx %p) stub\n",
2144 /*************************************************************************
2147 DWORD WINAPI FDSA_DeleteItem(
2151 FIXME("(%p 0x%08lx) stub\n",
2161 /*************************************************************************
2164 * Call IUnknown_QueryInterface() on a table of objects.
2168 * Failure: E_POINTER or E_NOINTERFACE.
2170 HRESULT WINAPI QISearch(
2171 LPVOID w, /* [in] Table of interfaces */
2172 IFACE_INDEX_TBL *x, /* [in] Array of REFIIDs and indexes into the table */
2173 REFIID riid, /* [in] REFIID to get interface for */
2174 LPVOID *ppv) /* [out] Destination for interface pointer */
2178 IFACE_INDEX_TBL *xmove;
2180 TRACE("(%p %p %s %p)\n", w,x,debugstr_guid(riid),ppv);
2183 while (xmove->refid) {
2184 TRACE("trying (indx %ld) %s\n", xmove->indx, debugstr_guid(xmove->refid));
2185 if (IsEqualIID(riid, xmove->refid)) {
2186 a_vtbl = (IUnknown*)(xmove->indx + (LPBYTE)w);
2187 TRACE("matched, returning (%p)\n", a_vtbl);
2188 *ppv = (LPVOID)a_vtbl;
2189 IUnknown_AddRef(a_vtbl);
2195 if (IsEqualIID(riid, &IID_IUnknown)) {
2196 a_vtbl = (IUnknown*)(x->indx + (LPBYTE)w);
2197 TRACE("returning first for IUnknown (%p)\n", a_vtbl);
2198 *ppv = (LPVOID)a_vtbl;
2199 IUnknown_AddRef(a_vtbl);
2203 ret = E_NOINTERFACE;
2207 TRACE("-- 0x%08lx\n", ret);
2211 /*************************************************************************
2214 * Remove the "PropDlgFont" property from a window.
2217 * hWnd [I] Window to remove the property from
2220 * A handle to the removed property, or NULL if it did not exist.
2222 HANDLE WINAPI SHRemoveDefaultDialogFont(HWND hWnd)
2226 TRACE("(%p)\n", hWnd);
2228 hProp = GetPropA(hWnd, "PropDlgFont");
2232 DeleteObject(hProp);
2233 hProp = RemovePropA(hWnd, "PropDlgFont");
2238 /*************************************************************************
2241 * Load the in-process server of a given GUID.
2244 * refiid [I] GUID of the server to load.
2247 * Success: A handle to the loaded server dll.
2248 * Failure: A NULL handle.
2250 HMODULE WINAPI SHPinDllOfCLSID(REFIID refiid)
2254 CHAR value[MAX_PATH], string[MAX_PATH];
2256 strcpy(string, "CLSID\\");
2257 SHStringFromGUIDA(refiid, string + 6, sizeof(string)/sizeof(char) - 6);
2258 strcat(string, "\\InProcServer32");
2261 RegOpenKeyExA(HKEY_CLASSES_ROOT, string, 0, 1, &newkey);
2262 RegQueryValueExA(newkey, 0, 0, &type, (PBYTE)value, &count);
2263 RegCloseKey(newkey);
2264 return LoadLibraryExA(value, 0, 0);
2267 /*************************************************************************
2270 * Unicode version of SHLWAPI_183.
2272 DWORD WINAPI SHRegisterClassW(WNDCLASSW * lpWndClass)
2276 TRACE("(%p %s)\n",lpWndClass->hInstance, debugstr_w(lpWndClass->lpszClassName));
2278 if (GetClassInfoW(lpWndClass->hInstance, lpWndClass->lpszClassName, &WndClass))
2280 return RegisterClassW(lpWndClass);
2283 /*************************************************************************
2286 * Unregister a list of classes.
2289 * hInst [I] Application instance that registered the classes
2290 * lppClasses [I] List of class names
2291 * iCount [I] Number of names in lppClasses
2296 void WINAPI SHUnregisterClassesA(HINSTANCE hInst, LPCSTR *lppClasses, INT iCount)
2300 TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);
2304 if (GetClassInfoA(hInst, *lppClasses, &WndClass))
2305 UnregisterClassA(*lppClasses, hInst);
2311 /*************************************************************************
2314 * Unicode version of SHUnregisterClassesA.
2316 void WINAPI SHUnregisterClassesW(HINSTANCE hInst, LPCWSTR *lppClasses, INT iCount)
2320 TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);
2324 if (GetClassInfoW(hInst, *lppClasses, &WndClass))
2325 UnregisterClassW(*lppClasses, hInst);
2331 /*************************************************************************
2334 * Call The correct (Ascii/Unicode) default window procedure for a window.
2337 * hWnd [I] Window to call the default procedure for
2338 * uMessage [I] Message ID
2339 * wParam [I] WPARAM of message
2340 * lParam [I] LPARAM of message
2343 * The result of calling DefWindowProcA() or DefWindowProcW().
2345 LRESULT CALLBACK SHDefWindowProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
2347 if (IsWindowUnicode(hWnd))
2348 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
2349 return DefWindowProcA(hWnd, uMessage, wParam, lParam);
2352 /*************************************************************************
2355 * Create a worker window using CreateWindowExA().
2358 * wndProc [I] Window procedure
2359 * hWndParent [I] Parent window
2360 * dwExStyle [I] Extra style flags
2361 * dwStyle [I] Style flags
2362 * hMenu [I] Window menu
2366 * Success: The window handle of the newly created window.
2369 HWND WINAPI SHCreateWorkerWindowA(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
2370 DWORD dwStyle, HMENU hMenu, LONG z)
2372 static const char* szClass = "WorkerA";
2376 TRACE("(0x%08lx,%p,0x%08lx,0x%08lx,%p,0x%08lx)\n",
2377 wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2379 /* Create Window class */
2381 wc.lpfnWndProc = DefWindowProcA;
2384 wc.hInstance = shlwapi_hInstance;
2386 wc.hCursor = LoadCursorA(NULL, (LPSTR)IDC_ARROW);
2387 wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
2388 wc.lpszMenuName = NULL;
2389 wc.lpszClassName = szClass;
2391 SHRegisterClassA(&wc); /* Register class */
2393 /* FIXME: Set extra bits in dwExStyle */
2395 hWnd = CreateWindowExA(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
2396 hWndParent, hMenu, shlwapi_hInstance, 0);
2399 SetWindowLongPtrW(hWnd, DWLP_MSGRESULT, z);
2402 SetWindowLongPtrA(hWnd, GWLP_WNDPROC, wndProc);
2407 typedef struct tagPOLICYDATA
2409 DWORD policy; /* flags value passed to SHRestricted */
2410 LPCWSTR appstr; /* application str such as "Explorer" */
2411 LPCWSTR keystr; /* name of the actual registry key / policy */
2412 } POLICYDATA, *LPPOLICYDATA;
2414 #define SHELL_NO_POLICY 0xffffffff
2416 /* default shell policy registry key */
2417 static const WCHAR strRegistryPolicyW[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o',
2418 's','o','f','t','\\','W','i','n','d','o','w','s','\\',
2419 'C','u','r','r','e','n','t','V','e','r','s','i','o','n',
2420 '\\','P','o','l','i','c','i','e','s',0};
2422 /*************************************************************************
2425 * Retrieve a policy value from the registry.
2428 * lpSubKey [I] registry key name
2429 * lpSubName [I] subname of registry key
2430 * lpValue [I] value name of registry value
2433 * the value associated with the registry key or 0 if not found
2435 DWORD WINAPI SHGetRestriction(LPCWSTR lpSubKey, LPCWSTR lpSubName, LPCWSTR lpValue)
2437 DWORD retval, datsize = sizeof(retval);
2441 lpSubKey = strRegistryPolicyW;
2443 retval = RegOpenKeyW(HKEY_LOCAL_MACHINE, lpSubKey, &hKey);
2444 if (retval != ERROR_SUCCESS)
2445 retval = RegOpenKeyW(HKEY_CURRENT_USER, lpSubKey, &hKey);
2446 if (retval != ERROR_SUCCESS)
2449 SHGetValueW(hKey, lpSubName, lpValue, NULL, (LPBYTE)&retval, &datsize);
2454 /*************************************************************************
2457 * Helper function to retrieve the possibly cached value for a specific policy
2460 * policy [I] The policy to look for
2461 * initial [I] Main registry key to open, if NULL use default
2462 * polTable [I] Table of known policies, 0 terminated
2463 * polArr [I] Cache array of policy values
2466 * The retrieved policy value or 0 if not successful
2469 * This function is used by the native SHRestricted function to search for the
2470 * policy and cache it once retrieved. The current Wine implementation uses a
2471 * different POLICYDATA structure and implements a similar algorithme adapted to
2474 DWORD WINAPI SHRestrictionLookup(
2477 LPPOLICYDATA polTable,
2480 TRACE("(0x%08lx %s %p %p)\n", policy, debugstr_w(initial), polTable, polArr);
2482 if (!polTable || !polArr)
2485 for (;polTable->policy; polTable++, polArr++)
2487 if (policy == polTable->policy)
2489 /* we have a known policy */
2491 /* check if this policy has been cached */
2492 if (*polArr == SHELL_NO_POLICY)
2493 *polArr = SHGetRestriction(initial, polTable->appstr, polTable->keystr);
2497 /* we don't know this policy, return 0 */
2498 TRACE("unknown policy: (%08lx)\n", policy);
2502 /*************************************************************************
2505 * Get an interface from an object.
2508 * Success: S_OK. ppv contains the requested interface.
2509 * Failure: An HRESULT error code.
2512 * This QueryInterface asks the inner object for a interface. In case
2513 * of aggregation this request would be forwarded by the inner to the
2514 * outer object. This function asks the inner object directly for the
2515 * interface circumventing the forwarding to the outer object.
2517 HRESULT WINAPI SHWeakQueryInterface(
2518 IUnknown * pUnk, /* [in] Outer object */
2519 IUnknown * pInner, /* [in] Inner object */
2520 IID * riid, /* [in] Interface GUID to query for */
2521 LPVOID* ppv) /* [out] Destination for queried interface */
2523 HRESULT hret = E_NOINTERFACE;
2524 TRACE("(pUnk=%p pInner=%p\n\tIID: %s %p)\n",pUnk,pInner,debugstr_guid(riid), ppv);
2527 if(pUnk && pInner) {
2528 hret = IUnknown_QueryInterface(pInner, riid, (LPVOID*)ppv);
2529 if (SUCCEEDED(hret)) IUnknown_Release(pUnk);
2531 TRACE("-- 0x%08lx\n", hret);
2535 /*************************************************************************
2538 * Move a reference from one interface to another.
2541 * lpDest [O] Destination to receive the reference
2542 * lppUnknown [O] Source to give up the reference to lpDest
2547 VOID WINAPI SHWeakReleaseInterface(IUnknown *lpDest, IUnknown **lppUnknown)
2549 TRACE("(%p,%p)\n", lpDest, lppUnknown);
2554 IUnknown_AddRef(lpDest);
2555 IUnknown_AtomicRelease(lppUnknown); /* Release existing interface */
2559 /*************************************************************************
2562 * Convert an ASCII string of a CLSID into a CLSID.
2565 * idstr [I] String representing a CLSID in registry format
2566 * id [O] Destination for the converted CLSID
2569 * Success: TRUE. id contains the converted CLSID.
2572 BOOL WINAPI GUIDFromStringA(LPCSTR idstr, CLSID *id)
2575 MultiByteToWideChar(CP_ACP, 0, idstr, -1, wClsid, sizeof(wClsid)/sizeof(WCHAR));
2576 return SUCCEEDED(CLSIDFromStringWrap(wClsid, id));
2579 /*************************************************************************
2582 * Unicode version of GUIDFromStringA.
2584 BOOL WINAPI GUIDFromStringW(LPCWSTR idstr, CLSID *id)
2586 return SUCCEEDED(CLSIDFromStringWrap(idstr, id));
2589 /*************************************************************************
2592 * Determine if the browser is integrated into the shell, and set a registry
2599 * 1, If the browser is not integrated.
2600 * 2, If the browser is integrated.
2603 * The key "HKLM\Software\Microsoft\Internet Explorer\IntegratedBrowser" is
2604 * either set to TRUE, or removed depending on whether the browser is deemed
2607 DWORD WINAPI WhichPlatform()
2609 static LPCSTR szIntegratedBrowser = "IntegratedBrowser";
2610 static DWORD dwState = 0;
2612 DWORD dwRet, dwData, dwSize;
2617 /* If shell32 exports DllGetVersion(), the browser is integrated */
2618 GET_FUNC(pDllGetVersion, shell32, "DllGetVersion", 1);
2619 dwState = pDllGetVersion ? 2 : 1;
2621 /* Set or delete the key accordingly */
2622 dwRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
2623 "Software\\Microsoft\\Internet Explorer", 0,
2624 KEY_ALL_ACCESS, &hKey);
2627 dwRet = RegQueryValueExA(hKey, szIntegratedBrowser, 0, 0,
2628 (LPBYTE)&dwData, &dwSize);
2630 if (!dwRet && dwState == 1)
2632 /* Value exists but browser is not integrated */
2633 RegDeleteValueA(hKey, szIntegratedBrowser);
2635 else if (dwRet && dwState == 2)
2637 /* Browser is integrated but value does not exist */
2639 RegSetValueExA(hKey, szIntegratedBrowser, 0, REG_DWORD,
2640 (LPBYTE)&dwData, sizeof(dwData));
2647 /*************************************************************************
2650 * Unicode version of SHCreateWorkerWindowA.
2652 HWND WINAPI SHCreateWorkerWindowW(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
2653 DWORD dwStyle, HMENU hMenu, LONG z)
2655 static const WCHAR szClass[] = { 'W', 'o', 'r', 'k', 'e', 'r', 'W', '\0' };
2659 TRACE("(0x%08lx,%p,0x%08lx,0x%08lx,%p,0x%08lx)\n",
2660 wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2662 /* If our OS is natively ASCII, use the ASCII version */
2663 if (!(GetVersion() & 0x80000000)) /* NT */
2664 return SHCreateWorkerWindowA(wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2666 /* Create Window class */
2668 wc.lpfnWndProc = DefWindowProcW;
2671 wc.hInstance = shlwapi_hInstance;
2673 wc.hCursor = LoadCursorW(NULL, (LPWSTR)IDC_ARROW);
2674 wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
2675 wc.lpszMenuName = NULL;
2676 wc.lpszClassName = szClass;
2678 SHRegisterClassW(&wc); /* Register class */
2680 /* FIXME: Set extra bits in dwExStyle */
2682 hWnd = CreateWindowExW(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
2683 hWndParent, hMenu, shlwapi_hInstance, 0);
2686 SetWindowLongPtrW(hWnd, DWLP_MSGRESULT, z);
2689 SetWindowLongPtrW(hWnd, GWLP_WNDPROC, wndProc);
2694 /*************************************************************************
2697 * Get and show a context menu from a shell folder.
2700 * hWnd [I] Window displaying the shell folder
2701 * lpFolder [I] IShellFolder interface
2702 * lpApidl [I] Id for the particular folder desired
2706 * Failure: An HRESULT error code indicating the error.
2708 HRESULT WINAPI SHInvokeDefaultCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl)
2710 return SHInvokeCommand(hWnd, lpFolder, lpApidl, FALSE);
2713 /*************************************************************************
2716 * _SHPackDispParamsV
2718 HRESULT WINAPI SHPackDispParamsV(LPVOID w, LPVOID x, LPVOID y, LPVOID z)
2720 FIXME("%p %p %p %p\n",w,x,y,z);
2724 /*************************************************************************
2727 * This function seems to be a forward to SHPackDispParamsV (whatever THAT
2728 * function does...).
2730 HRESULT WINAPI SHPackDispParams(LPVOID w, LPVOID x, LPVOID y, LPVOID z)
2732 FIXME("%p %p %p %p\n", w, x, y, z);
2736 /*************************************************************************
2739 * _IConnectionPoint_SimpleInvoke
2741 DWORD WINAPI IConnectionPoint_SimpleInvoke(
2746 FIXME("(%p %p %p) stub\n",x,y,z);
2750 /*************************************************************************
2753 * Notify an IConnectionPoint object of changes.
2756 * lpCP [I] Object to notify
2761 * Failure: E_NOINTERFACE, if lpCP is NULL or does not support the
2762 * IConnectionPoint interface.
2764 HRESULT WINAPI IConnectionPoint_OnChanged(IConnectionPoint* lpCP, DISPID dispID)
2766 IEnumConnections *lpEnum;
2767 HRESULT hRet = E_NOINTERFACE;
2769 TRACE("(%p,0x%8lX)\n", lpCP, dispID);
2771 /* Get an enumerator for the connections */
2773 hRet = IConnectionPoint_EnumConnections(lpCP, &lpEnum);
2775 if (SUCCEEDED(hRet))
2777 IPropertyNotifySink *lpSink;
2778 CONNECTDATA connData;
2781 /* Call OnChanged() for every notify sink in the connection point */
2782 while (IEnumConnections_Next(lpEnum, 1, &connData, &ulFetched) == S_OK)
2784 if (SUCCEEDED(IUnknown_QueryInterface(connData.pUnk, &IID_IPropertyNotifySink, (void**)&lpSink)) &&
2787 IPropertyNotifySink_OnChanged(lpSink, dispID);
2788 IPropertyNotifySink_Release(lpSink);
2790 IUnknown_Release(connData.pUnk);
2793 IEnumConnections_Release(lpEnum);
2798 /*************************************************************************
2801 * Notify an IConnectionPointContainer object of changes.
2804 * lpUnknown [I] Object to notify
2809 * Failure: E_NOINTERFACE, if lpUnknown is NULL or does not support the
2810 * IConnectionPointContainer interface.
2812 HRESULT WINAPI IUnknown_CPContainerOnChanged(IUnknown *lpUnknown, DISPID dispID)
2814 IConnectionPointContainer* lpCPC = NULL;
2815 HRESULT hRet = E_NOINTERFACE;
2817 TRACE("(%p,0x%8lX)\n", lpUnknown, dispID);
2820 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer, (void**)&lpCPC);
2822 if (SUCCEEDED(hRet))
2824 IConnectionPoint* lpCP;
2826 hRet = IConnectionPointContainer_FindConnectionPoint(lpCPC, &IID_IPropertyNotifySink, &lpCP);
2827 IConnectionPointContainer_Release(lpCPC);
2829 hRet = IConnectionPoint_OnChanged(lpCP, dispID);
2830 IConnectionPoint_Release(lpCP);
2835 /*************************************************************************
2840 BOOL WINAPI PlaySoundWrapW(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
2842 GET_FUNC(pPlaySoundW, winmm, "PlaySoundW", FALSE);
2843 return pPlaySoundW(pszSound, hmod, fdwSound);
2846 /*************************************************************************
2849 BOOL WINAPI SHGetIniStringW(LPSTR str1, LPSTR str2, LPSTR pStr, DWORD some_len, LPCSTR lpStr2)
2852 * str1: "I" "I" pushl esp+0x20
2853 * str2: "U" "I" pushl 0x77c93810
2854 * (is "I" and "U" "integer" and "unsigned" ??)
2856 * pStr: "" "" pushl eax
2857 * some_len: 0x824 0x104 pushl 0x824
2858 * lpStr2: "%l" "%l" pushl esp+0xc
2860 * shlwapi. StrCpyNW(lpStr2, irrelevant_var, 0x104);
2861 * LocalAlloc(0x00, some_len) -> irrelevant_var
2862 * LocalAlloc(0x40, irrelevant_len) -> pStr
2863 * shlwapi.294(str1, str2, pStr, some_len, lpStr2);
2864 * shlwapi.PathRemoveBlanksW(pStr);
2866 FIXME("('%s', '%s', '%s', %08lx, '%s'): stub!\n", str1, str2, pStr, some_len, lpStr2);
2870 /*************************************************************************
2873 * Called by ICQ2000b install via SHDOCVW:
2874 * str1: "InternetShortcut"
2875 * x: some unknown pointer
2876 * str2: "http://free.aol.com/tryaolfree/index.adp?139269"
2877 * str3: "C:\\WINDOWS\\Desktop.new2\\Free AOL & Unlimited Internet.url"
2879 * In short: this one maybe creates a desktop link :-)
2881 BOOL WINAPI SHSetIniStringW(LPWSTR str1, LPVOID x, LPWSTR str2, LPWSTR str3)
2883 FIXME("('%s', %p, '%s', '%s'), stub.\n", debugstr_w(str1), x, debugstr_w(str2), debugstr_w(str3));
2887 /*************************************************************************
2892 BOOL WINAPI ExtTextOutWrapW(HDC hdc, INT x, INT y, UINT flags, const RECT *lprect,
2893 LPCWSTR str, UINT count, const INT *lpDx)
2895 GET_FUNC(pCOMCTL32_417, comctl32, (LPCSTR)417, FALSE);
2896 return pCOMCTL32_417(hdc, x, y, flags, lprect, str, count, lpDx);
2899 /*************************************************************************
2902 * See SHGetFileInfoW.
2904 DWORD WINAPI SHGetFileInfoWrapW(LPCWSTR path, DWORD dwFileAttributes,
2905 SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
2907 GET_FUNC(pSHGetFileInfoW, shell32, "SHGetFileInfoW", 0);
2908 return pSHGetFileInfoW(path, dwFileAttributes, psfi, sizeofpsfi, flags);
2911 /*************************************************************************
2914 * See DragQueryFileW.
2916 UINT WINAPI DragQueryFileWrapW(HDROP hDrop, UINT lFile, LPWSTR lpszFile, UINT lLength)
2918 GET_FUNC(pDragQueryFileW, shell32, "DragQueryFileW", 0);
2919 return pDragQueryFileW(hDrop, lFile, lpszFile, lLength);
2922 /*************************************************************************
2925 * See SHBrowseForFolderW.
2927 LPITEMIDLIST WINAPI SHBrowseForFolderWrapW(LPBROWSEINFOW lpBi)
2929 GET_FUNC(pSHBrowseForFolderW, shell32, "SHBrowseForFolderW", NULL);
2930 return pSHBrowseForFolderW(lpBi);
2933 /*************************************************************************
2936 * See SHGetPathFromIDListW.
2938 BOOL WINAPI SHGetPathFromIDListWrapW(LPCITEMIDLIST pidl,LPWSTR pszPath)
2940 GET_FUNC(pSHGetPathFromIDListW, shell32, "SHGetPathFromIDListW", 0);
2941 return pSHGetPathFromIDListW(pidl, pszPath);
2944 /*************************************************************************
2947 * See ShellExecuteExW.
2949 BOOL WINAPI ShellExecuteExWrapW(LPSHELLEXECUTEINFOW lpExecInfo)
2951 GET_FUNC(pShellExecuteExW, shell32, "ShellExecuteExW", FALSE);
2952 return pShellExecuteExW(lpExecInfo);
2955 /*************************************************************************
2958 * See SHFileOperationW.
2960 HICON WINAPI SHFileOperationWrapW(LPSHFILEOPSTRUCTW lpFileOp)
2962 GET_FUNC(pSHFileOperationW, shell32, "SHFileOperationW", 0);
2963 return pSHFileOperationW(lpFileOp);
2966 /*************************************************************************
2969 * See ExtractIconExW.
2971 UINT WINAPI ExtractIconExWrapW(LPCWSTR lpszFile, INT nIconIndex, HICON *phiconLarge,
2972 HICON *phiconSmall, UINT nIcons)
2974 GET_FUNC(pExtractIconExW, shell32, "ExtractIconExW", 0);
2975 return pExtractIconExW(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
2978 /*************************************************************************
2982 LONG WINAPI SHInterlockedCompareExchange( PLONG dest, LONG xchg, LONG compare)
2984 return InterlockedCompareExchange(dest, xchg, compare);
2987 /*************************************************************************
2990 * See GetFileVersionInfoSizeW.
2992 DWORD WINAPI GetFileVersionInfoSizeWrapW(
2998 GET_FUNC(pGetFileVersionInfoSizeW, version, "GetFileVersionInfoSizeW", 0);
2999 ret = pGetFileVersionInfoSizeW(x, y);
3003 /*************************************************************************
3006 * See GetFileVersionInfoW.
3008 BOOL WINAPI GetFileVersionInfoWrapW(
3009 LPWSTR w, /* [in] path to dll */
3010 DWORD x, /* [in] parm 2 to GetFileVersionInfoA */
3011 DWORD y, /* [in] return value from SHLWAPI_350() - assume length */
3012 LPVOID z) /* [in/out] buffer (+0x208 sent to GetFileVersionInfoA()) */
3014 GET_FUNC(pGetFileVersionInfoW, version, "GetFileVersionInfoW", 0);
3015 return pGetFileVersionInfoW(w, x, y-0x208, (char*)z+0x208);
3018 /*************************************************************************
3021 * See VerQueryValueW.
3023 WORD WINAPI VerQueryValueWrapW(
3024 LPVOID w, /* [in] Buffer from SHLWAPI_351() */
3025 LPWSTR x, /* [in] Value to retrieve - converted and passed to VerQueryValueA() as #2 */
3026 LPVOID y, /* [out] Ver buffer - passed to VerQueryValueA as #3 */
3027 UINT* z) /* [in] Ver length - passed to VerQueryValueA as #4 */
3029 GET_FUNC(pVerQueryValueW, version, "VerQueryValueW", 0);
3030 return pVerQueryValueW((char*)w+0x208, x, y, z);
3033 #define IsIface(type) SUCCEEDED((hRet = IUnknown_QueryInterface(lpUnknown, &IID_##type, (void**)&lpObj)))
3034 #define IShellBrowser_EnableModeless IShellBrowser_EnableModelessSB
3035 #define EnableModeless(type) type##_EnableModeless((type*)lpObj, bModeless)
3037 /*************************************************************************
3040 * Change the modality of a shell object.
3043 * lpUnknown [I] Object to make modeless
3044 * bModeless [I] TRUE=Make modeless, FALSE=Make modal
3047 * Success: S_OK. The modality lpUnknown is changed.
3048 * Failure: An HRESULT error code indicating the error.
3051 * lpUnknown must support the IOleInPlaceFrame interface, the
3052 * IInternetSecurityMgrSite interface, the IShellBrowser interface
3053 * or the IDocHostUIHandler interface, or this call fails.
3055 HRESULT WINAPI IUnknown_EnableModeless(IUnknown *lpUnknown, BOOL bModeless)
3060 TRACE("(%p,%d)\n", lpUnknown, bModeless);
3065 if (IsIface(IOleInPlaceFrame))
3066 EnableModeless(IOleInPlaceFrame);
3067 else if (IsIface(IShellBrowser))
3068 EnableModeless(IShellBrowser);
3070 /* FIXME: Wine has no headers for these objects yet */
3071 else if (IsIface(IInternetSecurityMgrSite))
3072 EnableModeless(IInternetSecurityMgrSite);
3073 else if (IsIface(IDocHostUIHandler))
3074 EnableModeless(IDocHostUIHandler);
3079 IUnknown_Release(lpObj);
3083 /*************************************************************************
3086 * See SHGetNewLinkInfoW.
3088 BOOL WINAPI SHGetNewLinkInfoWrapW(LPCWSTR pszLinkTo, LPCWSTR pszDir, LPWSTR pszName,
3089 BOOL *pfMustCopy, UINT uFlags)
3091 GET_FUNC(pSHGetNewLinkInfoW, shell32, "SHGetNewLinkInfoW", FALSE);
3092 return pSHGetNewLinkInfoW(pszLinkTo, pszDir, pszName, pfMustCopy, uFlags);
3095 /*************************************************************************
3098 * See SHDefExtractIconW.
3100 UINT WINAPI SHDefExtractIconWrapW(LPCWSTR pszIconFile, int iIndex, UINT uFlags, HICON* phiconLarge,
3101 HICON* phiconSmall, UINT nIconSize)
3103 GET_FUNC(pSHDefExtractIconW, shell32, "SHDefExtractIconW", 0);
3104 return pSHDefExtractIconW(pszIconFile, iIndex, uFlags, phiconLarge, phiconSmall, nIconSize);
3107 /*************************************************************************
3110 * Get and show a context menu from a shell folder.
3113 * hWnd [I] Window displaying the shell folder
3114 * lpFolder [I] IShellFolder interface
3115 * lpApidl [I] Id for the particular folder desired
3116 * bInvokeDefault [I] Whether to invoke the default menu item
3119 * Success: S_OK. If bInvokeDefault is TRUE, the default menu action was
3121 * Failure: An HRESULT error code indicating the error.
3123 HRESULT WINAPI SHInvokeCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl, BOOL bInvokeDefault)
3125 IContextMenu *iContext;
3126 HRESULT hRet = E_FAIL;
3128 TRACE("(%p,%p,%p,%d)\n", hWnd, lpFolder, lpApidl, bInvokeDefault);
3133 /* Get the context menu from the shell folder */
3134 hRet = IShellFolder_GetUIObjectOf(lpFolder, hWnd, 1, &lpApidl,
3135 &IID_IContextMenu, 0, (void**)&iContext);
3136 if (SUCCEEDED(hRet))
3139 if ((hMenu = CreatePopupMenu()))
3142 DWORD dwDefaultId = 0;
3144 /* Add the context menu entries to the popup */
3145 hQuery = IContextMenu_QueryContextMenu(iContext, hMenu, 0, 1, 0x7FFF,
3146 bInvokeDefault ? CMF_NORMAL : CMF_DEFAULTONLY);
3148 if (SUCCEEDED(hQuery))
3150 if (bInvokeDefault &&
3151 (dwDefaultId = GetMenuDefaultItem(hMenu, 0, 0)) != 0xFFFFFFFF)
3153 CMINVOKECOMMANDINFO cmIci;
3154 /* Invoke the default item */
3155 memset(&cmIci,0,sizeof(cmIci));
3156 cmIci.cbSize = sizeof(cmIci);
3157 cmIci.fMask = CMIC_MASK_ASYNCOK;
3159 cmIci.lpVerb = MAKEINTRESOURCEA(dwDefaultId);
3160 cmIci.nShow = SW_SCROLLCHILDREN;
3162 hRet = IContextMenu_InvokeCommand(iContext, &cmIci);
3167 IContextMenu_Release(iContext);
3172 /*************************************************************************
3177 HICON WINAPI ExtractIconWrapW(HINSTANCE hInstance, LPCWSTR lpszExeFileName,
3180 GET_FUNC(pExtractIconW, shell32, "ExtractIconW", NULL);
3181 return pExtractIconW(hInstance, lpszExeFileName, nIconIndex);
3184 /*************************************************************************
3187 LANGID WINAPI MLGetUILanguage()
3190 /* FIXME: This should be a forward in the .spec file to the win2k function
3191 * kernel32.GetUserDefaultUILanguage, however that function isn't there yet.
3193 return GetUserDefaultLangID();
3196 /*************************************************************************
3199 * Load a library from the directory of a particular process.
3202 * new_mod [I] Library name
3203 * inst_hwnd [I] Module whose directory is to be used
3204 * dwFlags [I] Flags controlling the load
3207 * Success: A handle to the loaded module
3208 * Failure: A NULL handle.
3210 HMODULE WINAPI MLLoadLibraryA(LPCSTR new_mod, HMODULE inst_hwnd, DWORD dwFlags)
3212 /* FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for
3214 * FIXME: Native shows calls to:
3215 * SHRegGetUSValue for "Software\Microsoft\Internet Explorer\International"
3217 * RegOpenKeyExA for "HKLM\Software\Microsoft\Internet Explorer"
3218 * RegQueryValueExA for "LPKInstalled"
3220 * RegOpenKeyExA for "HKCU\Software\Microsoft\Internet Explorer\International"
3221 * RegQueryValueExA for "ResourceLocale"
3223 * RegOpenKeyExA for "HKLM\Software\Microsoft\Active Setup\Installed Components\{guid}"
3224 * RegQueryValueExA for "Locale"
3226 * and then tests the Locale ("en" for me).
3228 * after the code then a DPA_Create (first time) and DPA_InsertPtr are done.
3230 CHAR mod_path[2*MAX_PATH];
3234 FIXME("(%s,%p,0x%08lx) semi-stub!\n", debugstr_a(new_mod), inst_hwnd, dwFlags);
3235 len = GetModuleFileNameA(inst_hwnd, mod_path, sizeof(mod_path));
3236 if (!len || len >= sizeof(mod_path)) return NULL;
3238 ptr = strrchr(mod_path, '\\');
3240 strcpy(ptr+1, new_mod);
3241 TRACE("loading %s\n", debugstr_a(mod_path));
3242 return LoadLibraryA(mod_path);
3247 /*************************************************************************
3250 * Unicode version of MLLoadLibraryA.
3252 HMODULE WINAPI MLLoadLibraryW(LPCWSTR new_mod, HMODULE inst_hwnd, DWORD dwFlags)
3254 WCHAR mod_path[2*MAX_PATH];
3258 FIXME("(%s,%p,0x%08lx) semi-stub!\n", debugstr_w(new_mod), inst_hwnd, dwFlags);
3259 len = GetModuleFileNameW(inst_hwnd, mod_path, sizeof(mod_path) / sizeof(WCHAR));
3260 if (!len || len >= sizeof(mod_path) / sizeof(WCHAR)) return NULL;
3262 ptr = strrchrW(mod_path, '\\');
3264 strcpyW(ptr+1, new_mod);
3265 TRACE("loading %s\n", debugstr_w(mod_path));
3266 return LoadLibraryW(mod_path);
3271 /*************************************************************************
3272 * ColorAdjustLuma [SHLWAPI.@]
3274 * Adjust the luminosity of a color
3277 * cRGB [I] RGB value to convert
3278 * dwLuma [I] Luma adjustment
3279 * bUnknown [I] Unknown
3282 * The adjusted RGB color.
3284 COLORREF WINAPI ColorAdjustLuma(COLORREF cRGB, int dwLuma, BOOL bUnknown)
3286 TRACE("(0x%8lx,%d,%d)\n", cRGB, dwLuma, bUnknown);
3292 ColorRGBToHLS(cRGB, &wH, &wL, &wS);
3294 FIXME("Ignoring luma adjustment\n");
3296 /* FIXME: The ajdustment is not linear */
3298 cRGB = ColorHLSToRGB(wH, wL, wS);
3303 /*************************************************************************
3306 * See GetSaveFileNameW.
3308 BOOL WINAPI GetSaveFileNameWrapW(LPOPENFILENAMEW ofn)
3310 GET_FUNC(pGetSaveFileNameW, comdlg32, "GetSaveFileNameW", FALSE);
3311 return pGetSaveFileNameW(ofn);
3314 /*************************************************************************
3317 * See WNetRestoreConnectionW.
3319 DWORD WINAPI WNetRestoreConnectionWrapW(HWND hwndOwner, LPWSTR lpszDevice)
3321 GET_FUNC(pWNetRestoreConnectionW, mpr, "WNetRestoreConnectionW", 0);
3322 return pWNetRestoreConnectionW(hwndOwner, lpszDevice);
3325 /*************************************************************************
3328 * See WNetGetLastErrorW.
3330 DWORD WINAPI WNetGetLastErrorWrapW(LPDWORD lpError, LPWSTR lpErrorBuf, DWORD nErrorBufSize,
3331 LPWSTR lpNameBuf, DWORD nNameBufSize)
3333 GET_FUNC(pWNetGetLastErrorW, mpr, "WNetGetLastErrorW", 0);
3334 return pWNetGetLastErrorW(lpError, lpErrorBuf, nErrorBufSize, lpNameBuf, nNameBufSize);
3337 /*************************************************************************
3340 * See PageSetupDlgW.
3342 BOOL WINAPI PageSetupDlgWrapW(LPPAGESETUPDLGW pagedlg)
3344 GET_FUNC(pPageSetupDlgW, comdlg32, "PageSetupDlgW", FALSE);
3345 return pPageSetupDlgW(pagedlg);
3348 /*************************************************************************
3353 BOOL WINAPI PrintDlgWrapW(LPPRINTDLGW printdlg)
3355 GET_FUNC(pPrintDlgW, comdlg32, "PrintDlgW", FALSE);
3356 return pPrintDlgW(printdlg);
3359 /*************************************************************************
3362 * See GetOpenFileNameW.
3364 BOOL WINAPI GetOpenFileNameWrapW(LPOPENFILENAMEW ofn)
3366 GET_FUNC(pGetOpenFileNameW, comdlg32, "GetOpenFileNameW", FALSE);
3367 return pGetOpenFileNameW(ofn);
3370 /* INTERNAL: Map from HLS color space to RGB */
3371 static WORD WINAPI ConvertHue(int wHue, WORD wMid1, WORD wMid2)
3373 wHue = wHue > 240 ? wHue - 240 : wHue < 0 ? wHue + 240 : wHue;
3377 else if (wHue > 120)
3382 return ((wHue * (wMid2 - wMid1) + 20) / 40) + wMid1;
3385 /* Convert to RGB and scale into RGB range (0..255) */
3386 #define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240
3388 /*************************************************************************
3389 * ColorHLSToRGB [SHLWAPI.@]
3391 * Convert from hls color space into an rgb COLORREF.
3394 * wHue [I] Hue amount
3395 * wLuminosity [I] Luminosity amount
3396 * wSaturation [I] Saturation amount
3399 * A COLORREF representing the converted color.
3402 * Input hls values are constrained to the range (0..240).
3404 COLORREF WINAPI ColorHLSToRGB(WORD wHue, WORD wLuminosity, WORD wSaturation)
3410 WORD wGreen, wBlue, wMid1, wMid2;
3412 if (wLuminosity > 120)
3413 wMid2 = wSaturation + wLuminosity - (wSaturation * wLuminosity + 120) / 240;
3415 wMid2 = ((wSaturation + 240) * wLuminosity + 120) / 240;
3417 wMid1 = wLuminosity * 2 - wMid2;
3419 wRed = GET_RGB(wHue + 80);
3420 wGreen = GET_RGB(wHue);
3421 wBlue = GET_RGB(wHue - 80);
3423 return RGB(wRed, wGreen, wBlue);
3426 wRed = wLuminosity * 255 / 240;
3427 return RGB(wRed, wRed, wRed);
3430 /*************************************************************************
3433 * Get the current docking status of the system.
3436 * dwFlags [I] DOCKINFO_ flags from "winbase.h", unused
3439 * One of DOCKINFO_UNDOCKED, DOCKINFO_UNDOCKED, or 0 if the system is not
3442 DWORD WINAPI SHGetMachineInfo(DWORD dwFlags)
3444 HW_PROFILE_INFOA hwInfo;
3446 TRACE("(0x%08lx)\n", dwFlags);
3448 GetCurrentHwProfileA(&hwInfo);
3449 switch (hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED))
3451 case DOCKINFO_DOCKED:
3452 case DOCKINFO_UNDOCKED:
3453 return hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED);
3459 /*************************************************************************
3462 * Function seems to do FreeLibrary plus other things.
3464 * FIXME native shows the following calls:
3465 * RtlEnterCriticalSection
3467 * GetProcAddress(Comctl32??, 150L)
3469 * RtlLeaveCriticalSection
3470 * followed by the FreeLibrary.
3471 * The above code may be related to .377 above.
3473 BOOL WINAPI MLFreeLibrary(HMODULE hModule)
3475 FIXME("(%p) semi-stub\n", hModule);
3476 return FreeLibrary(hModule);
3479 /*************************************************************************
3482 BOOL WINAPI SHFlushSFCacheWrap(void) {
3487 /*************************************************************************
3489 * FIXME I have no idea what this function does or what its arguments are.
3491 BOOL WINAPI MLIsMLHInstance(HINSTANCE hInst)
3493 FIXME("(%p) stub\n", hInst);
3498 /*************************************************************************
3501 DWORD WINAPI MLSetMLHInstance(HINSTANCE hInst, HANDLE hHeap)
3503 FIXME("(%p,%p) stub\n", hInst, hHeap);
3504 return E_FAIL; /* This is what is used if shlwapi not loaded */
3507 /*************************************************************************
3510 DWORD WINAPI MLClearMLHInstance(DWORD x)
3512 FIXME("(0x%08lx)stub\n", x);
3516 /*************************************************************************
3519 * Convert an Unicode string CLSID into a CLSID.
3522 * idstr [I] string containing a CLSID in text form
3523 * id [O] CLSID extracted from the string
3526 * S_OK on success or E_INVALIDARG on failure
3529 * This is really CLSIDFromString() which is exported by ole32.dll,
3530 * however the native shlwapi.dll does *not* import ole32. Nor does
3531 * ole32.dll import this ordinal from shlwapi. Therefore we must conclude
3532 * that MS duplicated the code for CLSIDFromString(), and yes they did, only
3533 * it returns an E_INVALIDARG error code on failure.
3534 * This is a duplicate (with changes for Unicode) of CLSIDFromString16()
3535 * in "dlls/ole32/compobj.c".
3537 HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR idstr, CLSID *id)
3545 memset(id, 0, sizeof(CLSID));
3548 else { /* validate the CLSID string */
3550 if (strlenW(s) != 38)
3551 return E_INVALIDARG;
3553 if ((s[0]!=L'{') || (s[9]!=L'-') || (s[14]!=L'-') || (s[19]!=L'-') || (s[24]!=L'-') || (s[37]!=L'}'))
3554 return E_INVALIDARG;
3556 for (i=1; i<37; i++)
3558 if ((i == 9)||(i == 14)||(i == 19)||(i == 24))
3560 if (!(((s[i] >= L'0') && (s[i] <= L'9')) ||
3561 ((s[i] >= L'a') && (s[i] <= L'f')) ||
3562 ((s[i] >= L'A') && (s[i] <= L'F')))
3564 return E_INVALIDARG;
3568 TRACE("%s -> %p\n", debugstr_w(s), id);
3570 /* quick lookup table */
3571 memset(table, 0, 256*sizeof(WCHAR));
3573 for (i = 0; i < 10; i++) {
3576 for (i = 0; i < 6; i++) {
3577 table['A' + i] = i+10;
3578 table['a' + i] = i+10;
3581 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
3585 s++; /* skip leading brace */
3586 for (i = 0; i < 4; i++) {
3587 p[3 - i] = table[*s]<<4 | table[*(s+1)];
3593 for (i = 0; i < 2; i++) {
3594 p[1-i] = table[*s]<<4 | table[*(s+1)];
3600 for (i = 0; i < 2; i++) {
3601 p[1-i] = table[*s]<<4 | table[*(s+1)];
3607 /* these are just sequential bytes */
3608 for (i = 0; i < 2; i++) {
3609 *p++ = table[*s]<<4 | table[*(s+1)];
3614 for (i = 0; i < 6; i++) {
3615 *p++ = table[*s]<<4 | table[*(s+1)];
3622 /*************************************************************************
3625 * Determine if the OS supports a given feature.
3628 * dwFeature [I] Feature requested (undocumented)
3631 * TRUE If the feature is available.
3632 * FALSE If the feature is not available.
3634 BOOL WINAPI IsOS(DWORD feature)
3636 OSVERSIONINFOA osvi;
3637 DWORD platform, majorv, minorv;
3639 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
3640 if(!GetVersionExA(&osvi)) {
3641 ERR("GetVersionEx failed");
3645 majorv = osvi.dwMajorVersion;
3646 minorv = osvi.dwMinorVersion;
3647 platform = osvi.dwPlatformId;
3649 #define ISOS_RETURN(x) \
3650 TRACE("(0x%lx) ret=%d\n",feature,(x)); \
3654 case OS_WIN32SORGREATER:
3655 ISOS_RETURN(platform == VER_PLATFORM_WIN32s
3656 || platform == VER_PLATFORM_WIN32_WINDOWS)
3658 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3659 case OS_WIN95ORGREATER:
3660 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS)
3661 case OS_NT4ORGREATER:
3662 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 4)
3663 case OS_WIN2000ORGREATER_ALT:
3664 case OS_WIN2000ORGREATER:
3665 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5)
3666 case OS_WIN98ORGREATER:
3667 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv >= 10)
3669 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv == 10)
3671 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5)
3672 case OS_WIN2000SERVER:
3673 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3674 case OS_WIN2000ADVSERVER:
3675 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3676 case OS_WIN2000DATACENTER:
3677 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3678 case OS_WIN2000TERMINAL:
3679 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3681 FIXME("(OS_EMBEDDED) What should we return here?\n");
3683 case OS_TERMINALCLIENT:
3684 FIXME("(OS_TERMINALCLIENT) What should we return here?\n");
3686 case OS_TERMINALREMOTEADMIN:
3687 FIXME("(OS_TERMINALREMOTEADMIN) What should we return here?\n");
3690 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv == 0)
3691 case OS_MEORGREATER:
3692 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv >= 90)
3693 case OS_XPORGREATER:
3694 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5 && minorv >= 1)
3696 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5 && minorv >= 1)
3697 case OS_PROFESSIONAL:
3698 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3700 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3702 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5)
3704 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3705 case OS_TERMINALSERVER:
3706 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3707 case OS_PERSONALTERMINALSERVER:
3708 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && minorv >= 1 && majorv >= 5)
3709 case OS_FASTUSERSWITCHING:
3710 FIXME("(OS_FASTUSERSWITCHING) What should we return here?\n");
3712 case OS_WELCOMELOGONUI:
3713 FIXME("(OS_WELCOMELOGONUI) What should we return here?\n");
3715 case OS_DOMAINMEMBER:
3716 FIXME("(OS_DOMAINMEMBER) What should we return here?\n");
3719 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3721 FIXME("(OS_WOW6432) Should we check this?\n");
3724 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3725 case OS_SMALLBUSINESSSERVER:
3726 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3728 FIXME("(OS_TABLEPC) What should we return here?\n");
3730 case OS_SERVERADMINUI:
3731 FIXME("(OS_SERVERADMINUI) What should we return here?\n");
3733 case OS_MEDIACENTER:
3734 FIXME("(OS_MEDIACENTER) What should we return here?\n");
3737 FIXME("(OS_APPLIANCE) What should we return here?\n");
3743 WARN("(0x%lx) unknown parameter\n",feature);
3748 /*************************************************************************
3749 * ColorRGBToHLS [SHLWAPI.@]
3751 * Convert an rgb COLORREF into the hls color space.
3754 * cRGB [I] Source rgb value
3755 * pwHue [O] Destination for converted hue
3756 * pwLuminance [O] Destination for converted luminance
3757 * pwSaturation [O] Destination for converted saturation
3760 * Nothing. pwHue, pwLuminance and pwSaturation are set to the converted
3764 * Output HLS values are constrained to the range (0..240).
3765 * For Achromatic conversions, Hue is set to 160.
3767 VOID WINAPI ColorRGBToHLS(COLORREF cRGB, LPWORD pwHue,
3768 LPWORD pwLuminance, LPWORD pwSaturation)
3770 int wR, wG, wB, wMax, wMin, wHue, wLuminosity, wSaturation;
3772 TRACE("(%08lx,%p,%p,%p)\n", cRGB, pwHue, pwLuminance, pwSaturation);
3774 wR = GetRValue(cRGB);
3775 wG = GetGValue(cRGB);
3776 wB = GetBValue(cRGB);
3778 wMax = max(wR, max(wG, wB));
3779 wMin = min(wR, min(wG, wB));
3782 wLuminosity = ((wMax + wMin) * 240 + 255) / 510;
3786 /* Achromatic case */
3788 /* Hue is now unrepresentable, but this is what native returns... */
3793 /* Chromatic case */
3794 int wDelta = wMax - wMin, wRNorm, wGNorm, wBNorm;
3797 if (wLuminosity <= 120)
3798 wSaturation = ((wMax + wMin)/2 + wDelta * 240) / (wMax + wMin);
3800 wSaturation = ((510 - wMax - wMin)/2 + wDelta * 240) / (510 - wMax - wMin);
3803 wRNorm = (wDelta/2 + wMax * 40 - wR * 40) / wDelta;
3804 wGNorm = (wDelta/2 + wMax * 40 - wG * 40) / wDelta;
3805 wBNorm = (wDelta/2 + wMax * 40 - wB * 40) / wDelta;
3808 wHue = wBNorm - wGNorm;
3809 else if (wG == wMax)
3810 wHue = 80 + wRNorm - wBNorm;
3812 wHue = 160 + wGNorm - wRNorm;
3815 else if (wHue > 240)
3821 *pwLuminance = wLuminosity;
3823 *pwSaturation = wSaturation;
3826 /*************************************************************************
3827 * SHCreateShellPalette [SHLWAPI.@]
3829 HPALETTE WINAPI SHCreateShellPalette(HDC hdc)
3832 return CreateHalftonePalette(hdc);
3835 /*************************************************************************
3836 * SHGetInverseCMAP (SHLWAPI.@)
3838 * Get an inverse color map table.
3841 * lpCmap [O] Destination for color map
3842 * dwSize [I] Size of memory pointed to by lpCmap
3846 * Failure: E_POINTER, If lpCmap is invalid.
3847 * E_INVALIDARG, If dwFlags is invalid
3848 * E_OUTOFMEMORY, If there is no memory available
3851 * dwSize may only be CMAP_PTR_SIZE (4) or CMAP_SIZE (8192).
3852 * If dwSize = CMAP_PTR_SIZE, *lpCmap is set to the address of this DLL's
3854 * If dwSize = CMAP_SIZE, lpCmap is filled with a copy of the data from
3855 * this DLL's internal CMap.
3857 HRESULT WINAPI SHGetInverseCMAP(LPDWORD dest, DWORD dwSize)
3860 FIXME(" - returning bogus address for SHGetInverseCMAP\n");
3861 *dest = (DWORD)0xabba1249;
3864 FIXME("(%p, %#lx) stub\n", dest, dwSize);
3868 /*************************************************************************
3869 * SHIsLowMemoryMachine [SHLWAPI.@]
3871 * Determine if the current computer has low memory.
3877 * TRUE if the users machine has 16 Megabytes of memory or less,
3880 BOOL WINAPI SHIsLowMemoryMachine (DWORD x)
3882 FIXME("(0x%08lx) stub\n", x);
3886 /*************************************************************************
3887 * GetMenuPosFromID [SHLWAPI.@]
3889 * Return the position of a menu item from its Id.
3892 * hMenu [I] Menu containing the item
3893 * wID [I] Id of the menu item
3896 * Success: The index of the menu item in hMenu.
3897 * Failure: -1, If the item is not found.
3899 INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID)
3902 INT nCount = GetMenuItemCount(hMenu), nIter = 0;
3904 while (nIter < nCount)
3907 if (!GetMenuItemInfoA(hMenu, nIter, TRUE, &mi) && mi.wID == wID)
3914 /*************************************************************************
3917 * Same as SHLWAPI.GetMenuPosFromID
3919 DWORD WINAPI SHMenuIndexFromID(HMENU hMenu, UINT uID)
3921 return GetMenuPosFromID(hMenu, uID);
3925 /*************************************************************************
3928 VOID WINAPI FixSlashesAndColonW(LPWSTR lpwstr)
3939 /*************************************************************************
3942 DWORD WINAPI SHGetAppCompatFlags(DWORD Unknown)
3949 /*************************************************************************
3952 HRESULT WINAPI SHCoCreateInstanceAC(REFCLSID rclsid, LPUNKNOWN pUnkOuter,
3953 DWORD dwClsContext, REFIID iid, LPVOID *ppv)
3955 return CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, ppv);
3958 /*************************************************************************
3959 * SHSkipJunction [SHLWAPI.@]
3961 * Determine if a bind context can be bound to an object
3964 * pbc [I] Bind context to check
3965 * pclsid [I] CLSID of object to be bound to
3968 * TRUE: If it is safe to bind
3969 * FALSE: If pbc is invalid or binding would not be safe
3972 BOOL WINAPI SHSkipJunction(IBindCtx *pbc, const CLSID *pclsid)
3974 static const WCHAR szSkipBinding[] = { 'S','k','i','p',' ',
3975 'B','i','n','d','i','n','g',' ','C','L','S','I','D','\0' };
3982 if (SUCCEEDED(IBindCtx_GetObjectParam(pbc, (LPOLESTR)szSkipBinding, &lpUnk)))
3986 if (SUCCEEDED(IUnknown_GetClassID(lpUnk, &clsid)) &&
3987 IsEqualGUID(pclsid, &clsid))
3990 IUnknown_Release(lpUnk);
3996 /***********************************************************************
3997 * SHGetShellKey (SHLWAPI.@)
3999 DWORD WINAPI SHGetShellKey(DWORD a, DWORD b, DWORD c)
4001 FIXME("(%lx, %lx, %lx): stub\n", a, b, c);
4005 /***********************************************************************
4006 * SHQueueUserWorkItem (SHLWAPI.@)
4008 HRESULT WINAPI SHQueueUserWorkItem(DWORD a, DWORD b, DWORD c, DWORD d, DWORD e, DWORD f, DWORD g)
4010 FIXME("(%lx, %lx, %lx, %lx, %lx, %lx, %lx): stub\n", a, b, c, d, e, f, g);
4014 /***********************************************************************
4015 * IUnknown_OnFocusChangeIS (SHLWAPI.@)
4017 DWORD WINAPI IUnknown_OnFocusChangeIS(IUnknown * pUnk, IUnknown * pFocusObject, BOOL bChange)
4019 FIXME("(%p, %p, %s)\n", pUnk, pFocusObject, bChange ? "TRUE" : "FALSE");
4022 IInputObjectSite * pIOS = NULL;
4023 if (SUCCEEDED(IUnknown_QueryInterface(pUnk, &IID_IInputObjectSite, (void **)&pIOS))
4024 IInputObjectSite_OnFocusChangeIS(pIOS, pFocusObject, bChange);
4030 /***********************************************************************
4031 * SHGetValueW (SHLWAPI.@)
4033 HRESULT WINAPI SKGetValueW(DWORD a, LPWSTR b, LPWSTR c, DWORD d, DWORD e, DWORD f)
4035 FIXME("(%lx, %s, %s, %lx, %lx, %lx): stub\n", a, debugstr_w(b), debugstr_w(c), d, e, f);
4039 typedef HRESULT (WINAPI *DllGetVersion_func)(DLLVERSIONINFO *);
4041 /***********************************************************************
4042 * GetUIVersion (SHLWAPI.452)
4044 DWORD WINAPI GetUIVersion(void)
4046 static DWORD version;
4050 DllGetVersion_func pDllGetVersion;
4051 HMODULE dll = LoadLibraryA("shell32.dll");
4054 pDllGetVersion = (DllGetVersion_func)GetProcAddress(dll, "DllGetVersion");
4058 dvi.cbSize = sizeof(DLLVERSIONINFO);
4059 if (pDllGetVersion(&dvi) == S_OK) version = dvi.dwMajorVersion;
4062 if (!version) version = 3; /* old shell dlls don't have DllGetVersion */