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"
31 #define NONAMELESSUNION
32 #define NONAMELESSSTRUCT
46 #include "wine/unicode.h"
50 #include "wine/debug.h"
54 WINE_DEFAULT_DEBUG_CHANNEL(shell);
56 /* Get a function pointer from a DLL handle */
57 #define GET_FUNC(func, module, name, fail) \
60 if (!SHLWAPI_h##module && !(SHLWAPI_h##module = LoadLibraryA(#module ".dll"))) return fail; \
61 func = (fn##func)GetProcAddress(SHLWAPI_h##module, name); \
62 if (!func) return fail; \
66 /* DLL handles for late bound calls */
67 extern HINSTANCE shlwapi_hInstance;
68 extern HMODULE SHLWAPI_hshell32;
69 extern HMODULE SHLWAPI_hwinmm;
70 extern HMODULE SHLWAPI_hcomdlg32;
71 extern HMODULE SHLWAPI_hcomctl32;
72 extern HMODULE SHLWAPI_hmpr;
73 extern HMODULE SHLWAPI_hmlang;
74 extern HMODULE SHLWAPI_hurlmon;
75 extern HMODULE SHLWAPI_hversion;
77 extern DWORD SHLWAPI_ThreadRef_index;
79 typedef HANDLE HSHARED; /* Shared memory */
81 /* following is GUID for IObjectWithSite::SetSite -- see _174 */
82 static DWORD id1[4] = {0xfc4801a3, 0x11cf2ba9, 0xaa0029a2, 0x52733d00};
83 /* following is GUID for IPersistMoniker::GetClassID -- see _174 */
84 static DWORD id2[4] = {0x79eac9ee, 0x11cebaf9, 0xaa00828c, 0x0ba94b00};
86 /* Function pointers for GET_FUNC macro; these need to be global because of gcc bug */
87 typedef LPITEMIDLIST (WINAPI *fnpSHBrowseForFolderW)(LPBROWSEINFOW);
88 static fnpSHBrowseForFolderW pSHBrowseForFolderW;
89 typedef HRESULT (WINAPI *fnpConvertINetUnicodeToMultiByte)(LPDWORD,DWORD,LPCWSTR,LPINT,LPSTR,LPINT);
90 static fnpConvertINetUnicodeToMultiByte pConvertINetUnicodeToMultiByte;
91 typedef BOOL (WINAPI *fnpPlaySoundW)(LPCWSTR, HMODULE, DWORD);
92 static fnpPlaySoundW pPlaySoundW;
93 typedef DWORD (WINAPI *fnpSHGetFileInfoW)(LPCWSTR,DWORD,SHFILEINFOW*,UINT,UINT);
94 static fnpSHGetFileInfoW pSHGetFileInfoW;
95 typedef UINT (WINAPI *fnpDragQueryFileW)(HDROP, UINT, LPWSTR, UINT);
96 static fnpDragQueryFileW pDragQueryFileW;
97 typedef BOOL (WINAPI *fnpSHGetPathFromIDListW)(LPCITEMIDLIST, LPWSTR);
98 static fnpSHGetPathFromIDListW pSHGetPathFromIDListW;
99 typedef BOOL (WINAPI *fnpShellExecuteExW)(LPSHELLEXECUTEINFOW);
100 static fnpShellExecuteExW pShellExecuteExW;
101 typedef HICON (WINAPI *fnpSHFileOperationW)(LPSHFILEOPSTRUCTW);
102 static fnpSHFileOperationW pSHFileOperationW;
103 typedef UINT (WINAPI *fnpExtractIconExW)(LPCWSTR, INT,HICON *,HICON *, UINT);
104 static fnpExtractIconExW pExtractIconExW;
105 typedef BOOL (WINAPI *fnpSHGetNewLinkInfoW)(LPCWSTR, LPCWSTR, LPCWSTR, BOOL*, UINT);
106 static fnpSHGetNewLinkInfoW pSHGetNewLinkInfoW;
107 typedef HRESULT (WINAPI *fnpSHDefExtractIconW)(LPCWSTR, int, UINT, HICON*, HICON*, UINT);
108 static fnpSHDefExtractIconW pSHDefExtractIconW;
109 typedef HICON (WINAPI *fnpExtractIconW)(HINSTANCE, LPCWSTR, UINT);
110 static fnpExtractIconW pExtractIconW;
111 typedef BOOL (WINAPI *fnpGetSaveFileNameW)(LPOPENFILENAMEW);
112 static fnpGetSaveFileNameW pGetSaveFileNameW;
113 typedef DWORD (WINAPI *fnpWNetRestoreConnectionW)(HWND, LPWSTR);
114 static fnpWNetRestoreConnectionW pWNetRestoreConnectionW;
115 typedef DWORD (WINAPI *fnpWNetGetLastErrorW)(LPDWORD, LPWSTR, DWORD, LPWSTR, DWORD);
116 static fnpWNetGetLastErrorW pWNetGetLastErrorW;
117 typedef BOOL (WINAPI *fnpPageSetupDlgW)(LPPAGESETUPDLGW);
118 static fnpPageSetupDlgW pPageSetupDlgW;
119 typedef BOOL (WINAPI *fnpPrintDlgW)(LPPRINTDLGW);
120 static fnpPrintDlgW pPrintDlgW;
121 typedef BOOL (WINAPI *fnpGetOpenFileNameW)(LPOPENFILENAMEW);
122 static fnpGetOpenFileNameW pGetOpenFileNameW;
123 typedef DWORD (WINAPI *fnpGetFileVersionInfoSizeW)(LPCWSTR,LPDWORD);
124 static fnpGetFileVersionInfoSizeW pGetFileVersionInfoSizeW;
125 typedef BOOL (WINAPI *fnpGetFileVersionInfoW)(LPCWSTR,DWORD,DWORD,LPVOID);
126 static fnpGetFileVersionInfoW pGetFileVersionInfoW;
127 typedef WORD (WINAPI *fnpVerQueryValueW)(LPVOID,LPCWSTR,LPVOID*,UINT*);
128 static fnpVerQueryValueW pVerQueryValueW;
129 typedef BOOL (WINAPI *fnpCOMCTL32_417)(HDC,INT,INT,UINT,const RECT*,LPCWSTR,UINT,const INT*);
130 static fnpCOMCTL32_417 pCOMCTL32_417;
131 typedef HRESULT (WINAPI *fnpDllGetVersion)(DLLVERSIONINFO*);
132 static fnpDllGetVersion pDllGetVersion;
133 typedef HRESULT (WINAPI *fnpCreateFormatEnumerator)(UINT,FORMATETC*,IEnumFORMATETC**);
134 static fnpCreateFormatEnumerator pCreateFormatEnumerator;
135 typedef HRESULT (WINAPI *fnpRegisterFormatEnumerator)(LPBC,IEnumFORMATETC*,DWORD);
136 static fnpRegisterFormatEnumerator pRegisterFormatEnumerator;
138 HRESULT WINAPI IUnknown_QueryService(IUnknown*,REFGUID,REFIID,LPVOID*);
139 HRESULT WINAPI SHInvokeCommand(HWND,IShellFolder*,LPCITEMIDLIST,BOOL);
140 HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR,CLSID*);
141 BOOL WINAPI SHAboutInfoW(LPWSTR,DWORD);
144 NOTES: Most functions exported by ordinal seem to be superflous.
145 The reason for these functions to be there is to provide a wrapper
146 for unicode functions to provide these functions on systems without
147 unicode functions eg. win95/win98. Since we have such functions we just
148 call these. If running Wine with native DLL's, some late bound calls may
149 fail. However, its better to implement the functions in the forward DLL
150 and recommend the builtin rather than reimplementing the calls here!
153 /*************************************************************************
154 * SHLWAPI_DupSharedHandle
156 * Internal implemetation of SHLWAPI_11.
159 HSHARED WINAPI SHLWAPI_DupSharedHandle(HSHARED hShared, DWORD dwDstProcId,
160 DWORD dwSrcProcId, DWORD dwAccess,
164 DWORD dwMyProcId = GetCurrentProcessId();
165 HSHARED hRet = (HSHARED)NULL;
167 TRACE("(%p,%ld,%ld,%08lx,%08lx)\n", (PVOID)hShared, dwDstProcId, dwSrcProcId,
168 dwAccess, dwOptions);
170 /* Get dest process handle */
171 if (dwDstProcId == dwMyProcId)
172 hDst = GetCurrentProcess();
174 hDst = OpenProcess(PROCESS_DUP_HANDLE, 0, dwDstProcId);
178 /* Get src process handle */
179 if (dwSrcProcId == dwMyProcId)
180 hSrc = GetCurrentProcess();
182 hSrc = OpenProcess(PROCESS_DUP_HANDLE, 0, dwSrcProcId);
186 /* Make handle available to dest process */
187 if (!DuplicateHandle(hDst, (HANDLE)hShared, hSrc, &hRet,
188 dwAccess, 0, dwOptions | DUPLICATE_SAME_ACCESS))
189 hRet = (HSHARED)NULL;
191 if (dwSrcProcId != dwMyProcId)
195 if (dwDstProcId != dwMyProcId)
199 TRACE("Returning handle %p\n", (PVOID)hRet);
203 /*************************************************************************
206 * Create a block of sharable memory and initialise it with data.
209 * dwProcId [I] ID of process owning data
210 * lpvData [I] Pointer to data to write
211 * dwSize [I] Size of data
214 * Success: A shared memory handle
218 * Ordinals 7-11 provide a set of calls to create shared memory between a
219 * group of processes. The shared memory is treated opaquely in that its size
220 * is not exposed to clients who map it. This is accomplished by storing
221 * the size of the map as the first DWORD of mapped data, and then offsetting
222 * the view pointer returned by this size.
225 HSHARED WINAPI SHAllocShared(DWORD dwProcId, DWORD dwSize, LPCVOID lpvData)
229 HSHARED hRet = (HSHARED)NULL;
231 TRACE("(%ld,%p,%ld)\n", dwProcId, lpvData, dwSize);
233 /* Create file mapping of the correct length */
234 hMap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, FILE_MAP_READ, 0,
235 dwSize + sizeof(dwSize), NULL);
239 /* Get a view in our process address space */
240 pMapped = MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
244 /* Write size of data, followed by the data, to the view */
245 *((DWORD*)pMapped) = dwSize;
247 memcpy((char *) pMapped + sizeof(dwSize), lpvData, dwSize);
249 /* Release view. All further views mapped will be opaque */
250 UnmapViewOfFile(pMapped);
251 hRet = SHLWAPI_DupSharedHandle((HSHARED)hMap, dwProcId,
252 GetCurrentProcessId(), FILE_MAP_ALL_ACCESS,
253 DUPLICATE_SAME_ACCESS);
260 /*************************************************************************
263 * Get a pointer to a block of shared memory from a shared memory handle.
266 * hShared [I] Shared memory handle
267 * dwProcId [I] ID of process owning hShared
270 * Success: A pointer to the shared memory
274 PVOID WINAPI SHLockShared(HSHARED hShared, DWORD dwProcId)
279 TRACE("(%p %ld)\n", (PVOID)hShared, dwProcId);
281 /* Get handle to shared memory for current process */
282 hDup = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
283 FILE_MAP_ALL_ACCESS, 0);
285 pMapped = MapViewOfFile((HANDLE)hDup, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
289 return (char *) pMapped + sizeof(DWORD); /* Hide size */
293 /*************************************************************************
296 * Release a pointer to a block of shared memory.
299 * lpView [I] Shared memory pointer
306 BOOL WINAPI SHUnlockShared(LPVOID lpView)
308 TRACE("(%p)\n", lpView);
309 return UnmapViewOfFile((char *) lpView - sizeof(DWORD)); /* Include size */
312 /*************************************************************************
315 * Destroy a block of sharable memory.
318 * hShared [I] Shared memory handle
319 * dwProcId [I] ID of process owning hShared
326 BOOL WINAPI SHFreeShared(HSHARED hShared, DWORD dwProcId)
330 TRACE("(%p %ld)\n", (PVOID)hShared, dwProcId);
332 /* Get a copy of the handle for our process, closing the source handle */
333 hClose = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
334 FILE_MAP_ALL_ACCESS,DUPLICATE_CLOSE_SOURCE);
335 /* Close local copy */
336 return CloseHandle((HANDLE)hClose);
339 /*************************************************************************
342 * Copy a sharable memory handle from one process to another.
345 * hShared [I] Shared memory handle to duplicate
346 * dwDstProcId [I] ID of the process wanting the duplicated handle
347 * dwSrcProcId [I] ID of the process owning hShared
348 * dwAccess [I] Desired DuplicateHandle() access
349 * dwOptions [I] Desired DuplicateHandle() options
352 * Success: A handle suitable for use by the dwDstProcId process.
353 * Failure: A NULL handle.
356 HSHARED WINAPI SHMapHandle(HSHARED hShared, DWORD dwDstProcId, DWORD dwSrcProcId,
357 DWORD dwAccess, DWORD dwOptions)
361 hRet = SHLWAPI_DupSharedHandle(hShared, dwDstProcId, dwSrcProcId,
362 dwAccess, dwOptions);
366 /*************************************************************************
369 * Create and register a clipboard enumerator for a web browser.
372 * lpBC [I] Binding context
373 * lpUnknown [I] An object exposing the IWebBrowserApp interface
377 * Failure: An HRESULT error code.
380 * The enumerator is stored as a property of the web browser. If it does not
381 * yet exist, it is created and set before being registered.
383 HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown)
385 static const WCHAR szProperty[] = { '{','D','0','F','C','A','4','2','0',
386 '-','D','3','F','5','-','1','1','C','F', '-','B','2','1','1','-','0',
387 '0','A','A','0','0','4','A','E','8','3','7','}','\0' };
388 IEnumFORMATETC* pIEnumFormatEtc = NULL;
391 IWebBrowserApp* pBrowser = NULL;
393 TRACE("(%p, %p)\n", lpBC, lpUnknown);
395 /* Get An IWebBrowserApp interface from lpUnknown */
396 hRet = IUnknown_QueryService(lpUnknown, &IID_IWebBrowserApp, &IID_IWebBrowserApp, (PVOID)&pBrowser);
397 if (FAILED(hRet) || !pBrowser)
398 return E_NOINTERFACE;
400 V_VT(&var) = VT_EMPTY;
402 /* The property we get is the browsers clipboard enumerator */
403 hRet = IWebBrowserApp_GetProperty(pBrowser, (BSTR)szProperty, &var);
407 if (V_VT(&var) == VT_EMPTY)
409 /* Iterate through accepted documents and RegisterClipBoardFormatA() them */
410 char szKeyBuff[128], szValueBuff[128];
411 DWORD dwKeySize, dwValueSize, dwRet = 0, dwCount = 0, dwNumValues, dwType;
412 FORMATETC* formatList, *format;
415 TRACE("Registering formats and creating IEnumFORMATETC instance\n");
417 if (!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\Current"
418 "Version\\Internet Settings\\Accepted Documents", &hDocs))
421 /* Get count of values in key */
424 dwKeySize = sizeof(szKeyBuff);
425 dwRet = RegEnumValueA(hDocs,dwCount,szKeyBuff,&dwKeySize,0,&dwType,0,0);
429 dwNumValues = dwCount;
431 /* Note: dwCount = number of items + 1; The extra item is the end node */
432 format = formatList = HeapAlloc(GetProcessHeap(), 0, dwCount * sizeof(FORMATETC));
434 return E_OUTOFMEMORY;
443 /* Register clipboard formats for the values and populate format list */
444 while(!dwRet && dwCount < dwNumValues)
446 dwKeySize = sizeof(szKeyBuff);
447 dwValueSize = sizeof(szValueBuff);
448 dwRet = RegEnumValueA(hDocs, dwCount, szKeyBuff, &dwKeySize, 0, &dwType,
449 (PBYTE)szValueBuff, &dwValueSize);
453 format->cfFormat = RegisterClipboardFormatA(szValueBuff);
455 format->dwAspect = 1;
464 /* Terminate the (maybe empty) list, last entry has a cfFormat of 0 */
465 format->cfFormat = 0;
467 format->dwAspect = 1;
471 /* Create a clipboard enumerator */
472 GET_FUNC(pCreateFormatEnumerator, urlmon, "CreateFormatEnumerator", E_FAIL);
473 hRet = pCreateFormatEnumerator(dwNumValues, formatList, &pIEnumFormatEtc);
475 if (FAILED(hRet) || !pIEnumFormatEtc)
478 /* Set our enumerator as the browsers property */
479 V_VT(&var) = VT_UNKNOWN;
480 V_UNKNOWN(&var) = (IUnknown*)pIEnumFormatEtc;
482 hRet = IWebBrowserApp_PutProperty(pBrowser, (BSTR)szProperty, var);
485 IEnumFORMATETC_Release(pIEnumFormatEtc);
486 goto RegisterDefaultAcceptHeaders_Exit;
490 if (V_VT(&var) == VT_UNKNOWN)
492 /* Our variant is holding the clipboard enumerator */
493 IUnknown* pIUnknown = V_UNKNOWN(&var);
494 IEnumFORMATETC* pClone = NULL;
496 TRACE("Retrieved IEnumFORMATETC property\n");
498 /* Get an IEnumFormatEtc interface from the variants value */
499 pIEnumFormatEtc = NULL;
500 hRet = IUnknown_QueryInterface(pIUnknown, &IID_IEnumFORMATETC,
501 (PVOID)&pIEnumFormatEtc);
502 if (!hRet && pIEnumFormatEtc)
504 /* Clone and register the enumerator */
505 hRet = IEnumFORMATETC_Clone(pIEnumFormatEtc, &pClone);
508 GET_FUNC(pRegisterFormatEnumerator, urlmon, "RegisterFormatEnumerator", E_FAIL);
509 pRegisterFormatEnumerator(lpBC, pClone, 0);
511 IEnumFORMATETC_Release(pClone);
514 /* Release the IEnumFormatEtc interface */
515 IEnumFORMATETC_Release(pIUnknown);
517 IUnknown_Release(V_UNKNOWN(&var));
520 RegisterDefaultAcceptHeaders_Exit:
521 IWebBrowserApp_Release(pBrowser);
525 /*************************************************************************
528 * Get Explorers "AcceptLanguage" setting.
531 * langbuf [O] Destination for language string
532 * buflen [I] Length of langbuf
535 * Success: S_OK. langbuf is set to the language string found.
536 * Failure: E_FAIL, If any arguments are invalid, error occurred, or Explorer
537 * does not contain the setting.
539 HRESULT WINAPI GetAcceptLanguagesA(
544 DWORD mystrlen, mytype;
548 mystrlen = (*buflen > 6) ? *buflen : 6;
549 mystr = (CHAR*)HeapAlloc(GetProcessHeap(),
550 HEAP_ZERO_MEMORY, mystrlen);
551 RegOpenKeyA(HKEY_CURRENT_USER,
552 "Software\\Microsoft\\Internet Explorer\\International",
554 if (RegQueryValueExA(mykey, "AcceptLanguage",
555 0, &mytype, (PBYTE)mystr, &mystrlen)) {
556 /* Did not find value */
557 mylcid = GetUserDefaultLCID();
558 /* somehow the mylcid translates into "en-us"
559 * this is similar to "LOCALE_SABBREVLANGNAME"
560 * which could be gotten via GetLocaleInfo.
561 * The only problem is LOCALE_SABBREVLANGUAGE" is
562 * a 3 char string (first 2 are country code and third is
563 * letter for "sublanguage", which does not come close to
566 lstrcpyA(mystr, "en-us");
567 mystrlen = lstrlenA(mystr);
570 /* handle returned string */
571 FIXME("missing code\n");
573 if (mystrlen > *buflen)
574 lstrcpynA(langbuf, mystr, *buflen);
576 lstrcpyA(langbuf, mystr);
577 *buflen = lstrlenA(langbuf);
580 HeapFree(GetProcessHeap(), 0, mystr);
581 TRACE("language is %s\n", debugstr_a(langbuf));
585 /*************************************************************************
588 * Unicode version of SHLWAPI_14.
590 HRESULT WINAPI GetAcceptLanguagesW(
595 DWORD mystrlen, mytype;
599 mystrlen = (*buflen > 6) ? *buflen : 6;
600 mystr = (CHAR*)HeapAlloc(GetProcessHeap(),
601 HEAP_ZERO_MEMORY, mystrlen);
602 RegOpenKeyA(HKEY_CURRENT_USER,
603 "Software\\Microsoft\\Internet Explorer\\International",
605 if (RegQueryValueExA(mykey, "AcceptLanguage",
606 0, &mytype, (PBYTE)mystr, &mystrlen)) {
607 /* Did not find value */
608 mylcid = GetUserDefaultLCID();
609 /* somehow the mylcid translates into "en-us"
610 * this is similar to "LOCALE_SABBREVLANGNAME"
611 * which could be gotten via GetLocaleInfo.
612 * The only problem is LOCALE_SABBREVLANGUAGE" is
613 * a 3 char string (first 2 are country code and third is
614 * letter for "sublanguage", which does not come close to
617 lstrcpyA(mystr, "en-us");
618 mystrlen = lstrlenA(mystr);
621 /* handle returned string */
622 FIXME("missing code\n");
625 *buflen = MultiByteToWideChar(0, 0, mystr, -1, langbuf, (*buflen)-1);
626 HeapFree(GetProcessHeap(), 0, mystr);
627 TRACE("language is %s\n", debugstr_w(langbuf));
631 /*************************************************************************
634 * Convert a GUID to a string.
637 * guid [I] GUID to convert
638 * str [O] Destination for string
639 * cmax [I] Length of output buffer
642 * The length of the string created.
644 INT WINAPI SHStringFromGUIDA(REFGUID guid, LPSTR lpszDest, INT cchMax)
649 TRACE("(%s,%p,%d)\n", debugstr_guid(guid), lpszDest, cchMax);
651 sprintf(xguid, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
652 guid->Data1, guid->Data2, guid->Data3,
653 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
654 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
656 iLen = strlen(xguid) + 1;
660 memcpy(lpszDest, xguid, iLen);
664 /*************************************************************************
667 * Unicode version of SHStringFromGUIDA.
669 INT WINAPI SHStringFromGUIDW(REFGUID guid, LPWSTR lpszDest, INT cchMax)
672 INT iLen = SHStringFromGUIDA(guid, xguid, cchMax);
675 MultiByteToWideChar(CP_ACP, 0, xguid, -1, lpszDest, cchMax);
679 /*************************************************************************
682 * Determine if a Unicode character is alphabetic.
685 * wc [I] Character to check.
688 * TRUE, if wc is alphabetic,
691 BOOL WINAPI IsCharAlphaWrapW(WCHAR wc)
693 return (get_char_typeW(wc) & C1_ALPHA) != 0;
696 /*************************************************************************
699 * Determine if a Unicode character is upper-case.
702 * wc [I] Character to check.
705 * TRUE, if wc is upper-case,
708 BOOL WINAPI IsCharUpperWrapW(WCHAR wc)
710 return (get_char_typeW(wc) & C1_UPPER) != 0;
713 /*************************************************************************
716 * Determine if a Unicode character is lower-case.
719 * wc [I] Character to check.
722 * TRUE, if wc is lower-case,
725 BOOL WINAPI IsCharLowerWrapW(WCHAR wc)
727 return (get_char_typeW(wc) & C1_LOWER) != 0;
730 /*************************************************************************
733 * Determine if a Unicode character is alphabetic or a digit.
736 * wc [I] Character to check.
739 * TRUE, if wc is alphabetic or a digit,
742 BOOL WINAPI IsCharAlphaNumericWrapW(WCHAR wc)
744 return (get_char_typeW(wc) & (C1_ALPHA|C1_DIGIT)) != 0;
747 /*************************************************************************
750 * Determine if a Unicode character is a space.
753 * wc [I] Character to check.
756 * TRUE, if wc is a space,
759 BOOL WINAPI IsCharSpaceW(WCHAR wc)
761 return (get_char_typeW(wc) & C1_SPACE) != 0;
764 /*************************************************************************
767 * Determine if a Unicode character is a blank.
770 * wc [I] Character to check.
773 * TRUE, if wc is a blank,
777 BOOL WINAPI IsCharBlankW(WCHAR wc)
779 return (get_char_typeW(wc) & C1_BLANK) != 0;
782 /*************************************************************************
785 * Determine if a Unicode character is punctuation.
788 * wc [I] Character to check.
791 * TRUE, if wc is punctuation,
794 BOOL WINAPI IsCharPunctW(WCHAR wc)
796 return (get_char_typeW(wc) & C1_PUNCT) != 0;
799 /*************************************************************************
802 * Determine if a Unicode character is a control character.
805 * wc [I] Character to check.
808 * TRUE, if wc is a control character,
811 BOOL WINAPI IsCharCntrlW(WCHAR wc)
813 return (get_char_typeW(wc) & C1_CNTRL) != 0;
816 /*************************************************************************
819 * Determine if a Unicode character is a digit.
822 * wc [I] Character to check.
825 * TRUE, if wc is a digit,
828 BOOL WINAPI IsCharDigitW(WCHAR wc)
830 return (get_char_typeW(wc) & C1_DIGIT) != 0;
833 /*************************************************************************
836 * Determine if a Unicode character is a hex digit.
839 * wc [I] Character to check.
842 * TRUE, if wc is a hex digit,
845 BOOL WINAPI IsCharXDigitW(WCHAR wc)
847 return (get_char_typeW(wc) & C1_XDIGIT) != 0;
850 /*************************************************************************
854 BOOL WINAPI GetStringType3ExW(LPWSTR lpszStr, DWORD dwLen, LPVOID p3)
856 FIXME("(%s,0x%08lx,%p): stub\n", debugstr_w(lpszStr), dwLen, p3);
860 /*************************************************************************
863 * Insert a bitmap menu item at the bottom of a menu.
866 * hMenu [I] Menu to insert into
867 * flags [I] Flags for insertion
868 * id [I] Menu ID of the item
869 * str [I] Menu text for the item
872 * Success: TRUE, the item is inserted into the menu
873 * Failure: FALSE, if any parameter is invalid
875 BOOL WINAPI AppendMenuWrapW(HMENU hMenu, UINT flags, UINT id, LPCWSTR str)
877 TRACE("(%p,0x%08x,0x%08x,%s)\n",hMenu, flags, id, debugstr_w(str));
878 return InsertMenuW(hMenu, -1, flags | MF_BITMAP, id, str);
881 /*************************************************************************
884 * Get the text from a given dialog item.
887 * hWnd [I] Handle of dialog
888 * nItem [I] Index of item
889 * lpsDest [O] Buffer for receiving window text
890 * nDestLen [I] Length of buffer.
893 * Success: The length of the returned text.
896 INT WINAPI GetDlgItemTextWrapW(HWND hWnd, INT nItem, LPWSTR lpsDest,INT nDestLen)
898 HWND hItem = GetDlgItem(hWnd, nItem);
901 return GetWindowTextW(hItem, lpsDest, nDestLen);
903 *lpsDest = (WCHAR)'\0';
907 /*************************************************************************
910 * Set the text of a given dialog item.
913 * hWnd [I] Handle of dialog
914 * iItem [I] Index of item
915 * lpszText [O] Text to set
918 * Success: TRUE. The text of the dialog is set to lpszText.
919 * Failure: FALSE, Otherwise.
921 BOOL WINAPI SetDlgItemTextWrapW(HWND hWnd, INT iItem, LPCWSTR lpszText)
923 HWND hWndItem = GetDlgItem(hWnd, iItem);
925 return SetWindowTextW(hWndItem, lpszText);
929 /*************************************************************************
932 * Compare two Ascii strings up to a given length.
935 * lpszSrc [I] Source string
936 * lpszCmp [I] String to compare to lpszSrc
937 * len [I] Maximum length
940 * A number greater than, less than or equal to 0 depending on whether
941 * lpszSrc is greater than, less than or equal to lpszCmp.
943 DWORD WINAPI StrCmpNCA(LPCSTR lpszSrc, LPCSTR lpszCmp, INT len)
945 return strncmp(lpszSrc, lpszCmp, len);
948 /*************************************************************************
951 * Unicode version of StrCmpNCA.
953 DWORD WINAPI StrCmpNCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, INT len)
955 return strncmpW(lpszSrc, lpszCmp, len);
958 /*************************************************************************
961 * Compare two Ascii strings up to a given length, ignoring case.
964 * lpszSrc [I] Source string
965 * lpszCmp [I] String to compare to lpszSrc
966 * len [I] Maximum length
969 * A number greater than, less than or equal to 0 depending on whether
970 * lpszSrc is greater than, less than or equal to lpszCmp.
972 DWORD WINAPI StrCmpNICA(LPCSTR lpszSrc, LPCSTR lpszCmp, DWORD len)
974 return strncasecmp(lpszSrc, lpszCmp, len);
977 /*************************************************************************
980 * Unicode version of StrCmpNICA.
982 DWORD WINAPI StrCmpNICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, DWORD len)
984 return strncmpiW(lpszSrc, lpszCmp, len);
987 /*************************************************************************
990 * Compare two Ascii strings.
993 * lpszSrc [I] Source string
994 * lpszCmp [I] String to compare to lpszSrc
997 * A number greater than, less than or equal to 0 depending on whether
998 * lpszSrc is greater than, less than or equal to lpszCmp.
1000 DWORD WINAPI StrCmpCA(LPCSTR lpszSrc, LPCSTR lpszCmp)
1002 return strcmp(lpszSrc, lpszCmp);
1005 /*************************************************************************
1008 * Unicode version of StrCmpCA.
1010 DWORD WINAPI StrCmpCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp)
1012 return strcmpW(lpszSrc, lpszCmp);
1015 /*************************************************************************
1018 * Compare two Ascii strings, ignoring case.
1021 * lpszSrc [I] Source string
1022 * lpszCmp [I] String to compare to lpszSrc
1025 * A number greater than, less than or equal to 0 depending on whether
1026 * lpszSrc is greater than, less than or equal to lpszCmp.
1028 DWORD WINAPI StrCmpICA(LPCSTR lpszSrc, LPCSTR lpszCmp)
1030 return strcasecmp(lpszSrc, lpszCmp);
1033 /*************************************************************************
1036 * Unicode version of StrCmpICA.
1038 DWORD WINAPI StrCmpICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp)
1040 return strcmpiW(lpszSrc, lpszCmp);
1043 /*************************************************************************
1046 * Get an identification string for the OS and explorer.
1049 * lpszDest [O] Destination for Id string
1050 * dwDestLen [I] Length of lpszDest
1053 * TRUE, If the string was created successfully
1056 BOOL WINAPI SHAboutInfoA(LPSTR lpszDest, DWORD dwDestLen)
1060 TRACE("(%p,%ld)\n", lpszDest, dwDestLen);
1062 if (lpszDest && SHAboutInfoW(buff, dwDestLen))
1064 WideCharToMultiByte(CP_ACP, 0, buff, -1, lpszDest, dwDestLen, NULL, NULL);
1070 /*************************************************************************
1073 * Unicode version of SHAboutInfoA.
1075 BOOL WINAPI SHAboutInfoW(LPWSTR lpszDest, DWORD dwDestLen)
1077 static const WCHAR szIEKey[] = { 'S','O','F','T','W','A','R','E','\\',
1078 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
1079 ' ','E','x','p','l','o','r','e','r','\0' };
1080 static const WCHAR szWinNtKey[] = { 'S','O','F','T','W','A','R','E','\\',
1081 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s',' ',
1082 'N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
1083 static const WCHAR szWinKey[] = { 'S','O','F','T','W','A','R','E','\\',
1084 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
1085 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
1086 static const WCHAR szRegKey[] = { 'S','O','F','T','W','A','R','E','\\',
1087 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
1088 ' ','E','x','p','l','o','r','e','r','\\',
1089 'R','e','g','i','s','t','r','a','t','i','o','n','\0' };
1090 static const WCHAR szVersion[] = { 'V','e','r','s','i','o','n','\0' };
1091 static const WCHAR szCustomized[] = { 'C','u','s','t','o','m','i','z','e','d',
1092 'V','e','r','s','i','o','n','\0' };
1093 static const WCHAR szOwner[] = { 'R','e','g','i','s','t','e','r','e','d',
1094 'O','w','n','e','r','\0' };
1095 static const WCHAR szOrg[] = { 'R','e','g','i','s','t','e','r','e','d',
1096 'O','r','g','a','n','i','z','a','t','i','o','n','\0' };
1097 static const WCHAR szProduct[] = { 'P','r','o','d','u','c','t','I','d','\0' };
1098 static const WCHAR szUpdate[] = { 'I','E','A','K',
1099 'U','p','d','a','t','e','U','r','l','\0' };
1100 static const WCHAR szHelp[] = { 'I','E','A','K',
1101 'H','e','l','p','S','t','r','i','n','g','\0' };
1104 DWORD dwType, dwLen;
1106 TRACE("(%p,%ld)\n", lpszDest, dwDestLen);
1113 /* Try the NT key first, followed by 95/98 key */
1114 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinNtKey, 0, KEY_READ, &hReg) &&
1115 RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinKey, 0, KEY_READ, &hReg))
1121 if (!SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey, szVersion, &dwType, buff, &dwLen))
1123 DWORD dwStrLen = strlenW(buff);
1124 dwLen = 30 - dwStrLen;
1125 SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey,
1126 szCustomized, &dwType, buff+dwStrLen, &dwLen);
1128 StrCatBuffW(lpszDest, buff, dwDestLen);
1130 /* ~Registered Owner */
1133 if (SHGetValueW(hReg, szOwner, 0, &dwType, buff+1, &dwLen))
1135 StrCatBuffW(lpszDest, buff, dwDestLen);
1137 /* ~Registered Organization */
1139 if (SHGetValueW(hReg, szOrg, 0, &dwType, buff+1, &dwLen))
1141 StrCatBuffW(lpszDest, buff, dwDestLen);
1143 /* FIXME: Not sure where this number comes from */
1147 StrCatBuffW(lpszDest, buff, dwDestLen);
1151 if (SHGetValueW(HKEY_LOCAL_MACHINE, szRegKey, szProduct, &dwType, buff+1, &dwLen))
1153 StrCatBuffW(lpszDest, buff, dwDestLen);
1155 /* ~IE Update Url */
1157 if(SHGetValueW(HKEY_LOCAL_MACHINE, szWinKey, szUpdate, &dwType, buff+1, &dwLen))
1159 StrCatBuffW(lpszDest, buff, dwDestLen);
1161 /* ~IE Help String */
1163 if(SHGetValueW(hReg, szHelp, 0, &dwType, buff+1, &dwLen))
1165 StrCatBuffW(lpszDest, buff, dwDestLen);
1171 /*************************************************************************
1174 * Remove a hanging lead byte from the end of a string, if present.
1177 * lpStr [I] String to check for a hanging lead byte
1178 * size [I] Length of lpStr
1181 * Success: The new length of the string. Any hanging lead bytes are removed.
1182 * Failure: 0, if any parameters are invalid.
1184 DWORD WINAPI SHTruncateString(LPSTR lpStr, DWORD size)
1188 LPSTR lastByte = lpStr + size - 1;
1190 while(lpStr < lastByte)
1191 lpStr += IsDBCSLeadByte(*lpStr) ? 2 : 1;
1193 if(lpStr == lastByte && IsDBCSLeadByte(*lpStr))
1203 /*************************************************************************
1206 * Call IOleCommandTarget_QueryStatus() on an object.
1209 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1210 * pguidCmdGroup [I] GUID for the command group
1212 * prgCmds [O] Commands
1213 * pCmdText [O] Command text
1217 * Failure: E_FAIL, if lpUnknown is NULL.
1218 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1219 * Otherwise, an error code from IOleCommandTarget_QueryStatus().
1221 HRESULT WINAPI IUnknown_QueryStatus(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
1222 ULONG cCmds, OLECMD *prgCmds, OLECMDTEXT* pCmdText)
1224 HRESULT hRet = E_FAIL;
1226 TRACE("(%p,%p,%ld,%p,%p)\n",lpUnknown, pguidCmdGroup, cCmds, prgCmds, pCmdText);
1230 IOleCommandTarget* lpOle;
1232 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
1235 if (SUCCEEDED(hRet) && lpOle)
1237 hRet = IOleCommandTarget_QueryStatus(lpOle, pguidCmdGroup, cCmds,
1239 IOleCommandTarget_Release(lpOle);
1245 /*************************************************************************
1248 * Call IOleCommandTarget_Exec() on an object.
1251 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1252 * pguidCmdGroup [I] GUID for the command group
1256 * Failure: E_FAIL, if lpUnknown is NULL.
1257 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1258 * Otherwise, an error code from IOleCommandTarget_Exec().
1260 HRESULT WINAPI IUnknown_Exec(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
1261 DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
1264 HRESULT hRet = E_FAIL;
1266 TRACE("(%p,%p,%ld,%ld,%p,%p)\n",lpUnknown, pguidCmdGroup, nCmdID,
1267 nCmdexecopt, pvaIn, pvaOut);
1271 IOleCommandTarget* lpOle;
1273 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
1275 if (SUCCEEDED(hRet) && lpOle)
1277 hRet = IOleCommandTarget_Exec(lpOle, pguidCmdGroup, nCmdID,
1278 nCmdexecopt, pvaIn, pvaOut);
1279 IOleCommandTarget_Release(lpOle);
1285 /*************************************************************************
1288 * Retrieve, modify, and re-set a value from a window.
1291 * hWnd [I] Window to get value from
1292 * offset [I] Offset of value
1293 * wMask [I] Mask for uiFlags
1294 * wFlags [I] Bits to set in window value
1297 * The new value as it was set, or 0 if any parameter is invalid.
1300 * Any bits set in uiMask are cleared from the value, then any bits set in
1301 * uiFlags are set in the value.
1303 LONG WINAPI SHSetWindowBits(HWND hwnd, INT offset, UINT wMask, UINT wFlags)
1305 LONG ret = GetWindowLongA(hwnd, offset);
1306 LONG newFlags = (wFlags & wMask) | (ret & ~wFlags);
1308 if (newFlags != ret)
1309 ret = SetWindowLongA(hwnd, offset, newFlags);
1313 /*************************************************************************
1316 * Change a window's parent.
1319 * hWnd [I] Window to change parent of
1320 * hWndParent [I] New parent window
1323 * The old parent of hWnd.
1326 * If hWndParent is NULL (desktop), the window style is changed to WS_POPUP.
1327 * If hWndParent is NOT NULL then we set the WS_CHILD style.
1329 HWND WINAPI SHSetParentHwnd(HWND hWnd, HWND hWndParent)
1331 TRACE("%p, %p\n", hWnd, hWndParent);
1333 if(GetParent(hWnd) == hWndParent)
1337 SHSetWindowBits(hWnd, GWL_STYLE, WS_CHILD, WS_CHILD);
1339 SHSetWindowBits(hWnd, GWL_STYLE, WS_POPUP, WS_POPUP);
1341 return SetParent(hWnd, hWndParent);
1344 /*************************************************************************
1347 * Locate and advise a connection point in an IConnectionPointContainer object.
1350 * lpUnkSink [I] Sink for the connection point advise call
1351 * riid [I] REFIID of connection point to advise
1352 * bAdviseOnly [I] TRUE = Advise only, FALSE = Unadvise first
1353 * lpUnknown [I] Object supporting the IConnectionPointContainer interface
1354 * lpCookie [O] Pointer to connection point cookie
1355 * lppCP [O] Destination for the IConnectionPoint found
1358 * Success: S_OK. If lppCP is non-NULL, it is filled with the IConnectionPoint
1359 * that was advised. The caller is responsable for releasing it.
1360 * Failure: E_FAIL, if any arguments are invalid.
1361 * E_NOINTERFACE, if lpUnknown isn't an IConnectionPointContainer,
1362 * Or an HRESULT error code if any call fails.
1364 HRESULT WINAPI ConnectToConnectionPoint(IUnknown* lpUnkSink, REFIID riid, BOOL bAdviseOnly,
1365 IUnknown* lpUnknown, LPDWORD lpCookie,
1366 IConnectionPoint **lppCP)
1369 IConnectionPointContainer* lpContainer;
1370 IConnectionPoint *lpCP;
1372 if(!lpUnknown || (bAdviseOnly && !lpUnkSink))
1378 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer,
1379 (void**)&lpContainer);
1380 if (SUCCEEDED(hRet))
1382 hRet = IConnectionPointContainer_FindConnectionPoint(lpContainer, riid, &lpCP);
1384 if (SUCCEEDED(hRet))
1387 hRet = IConnectionPoint_Unadvise(lpCP, *lpCookie);
1388 hRet = IConnectionPoint_Advise(lpCP, lpUnkSink, lpCookie);
1393 if (lppCP && SUCCEEDED(hRet))
1394 *lppCP = lpCP; /* Caller keeps the interface */
1396 IConnectionPoint_Release(lpCP); /* Release it */
1399 IUnknown_Release(lpContainer);
1404 /*************************************************************************
1407 * Release an interface.
1410 * lpUnknown [I] Object to release
1415 DWORD WINAPI IUnknown_AtomicRelease(IUnknown ** lpUnknown)
1419 TRACE("(%p)\n",lpUnknown);
1421 if(!lpUnknown || !*((LPDWORD)lpUnknown)) return 0;
1425 TRACE("doing Release\n");
1427 return IUnknown_Release(temp);
1430 /*************************************************************************
1433 * Skip '//' if present in a string.
1436 * lpszSrc [I] String to check for '//'
1439 * Success: The next character after the '//' or the string if not present
1440 * Failure: NULL, if lpszStr is NULL.
1442 LPCSTR WINAPI PathSkipLeadingSlashesA(LPCSTR lpszSrc)
1444 if (lpszSrc && lpszSrc[0] == '/' && lpszSrc[1] == '/')
1449 /*************************************************************************
1452 * Check if two interfaces come from the same object.
1455 * lpInt1 [I] Interface to check against lpInt2.
1456 * lpInt2 [I] Interface to check against lpInt1.
1459 * TRUE, If the interfaces come from the same object.
1462 BOOL WINAPI SHIsSameObject(IUnknown* lpInt1, IUnknown* lpInt2)
1464 LPVOID lpUnknown1, lpUnknown2;
1466 TRACE("%p %p\n", lpInt1, lpInt2);
1468 if (!lpInt1 || !lpInt2)
1471 if (lpInt1 == lpInt2)
1474 if (!SUCCEEDED(IUnknown_QueryInterface(lpInt1, &IID_IUnknown,
1475 (LPVOID *)&lpUnknown1)))
1478 if (!SUCCEEDED(IUnknown_QueryInterface(lpInt2, &IID_IUnknown,
1479 (LPVOID *)&lpUnknown2)))
1482 if (lpUnknown1 == lpUnknown2)
1488 /*************************************************************************
1491 * Get the window handle of an object.
1494 * lpUnknown [I] Object to get the window handle of
1495 * lphWnd [O] Destination for window handle
1498 * Success: S_OK. lphWnd contains the objects window handle.
1499 * Failure: An HRESULT error code.
1502 * lpUnknown is expected to support one of the following interfaces:
1503 * IOleWindow(), IInternetSecurityMgrSite(), or IShellView().
1505 HRESULT WINAPI IUnknown_GetWindow(IUnknown *lpUnknown, HWND *lphWnd)
1507 /* FIXME: Wine has no header for this object */
1508 static const GUID IID_IInternetSecurityMgrSite = { 0x79eac9ed,
1509 0xbaf9, 0x11ce, { 0x8c, 0x82, 0x00, 0xaa, 0x00, 0x4b, 0xa9, 0x0b }};
1511 HRESULT hRet = E_FAIL;
1513 TRACE("(%p,%p)\n", lpUnknown, lphWnd);
1518 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleWindow, (void**)&lpOle);
1522 hRet = IUnknown_QueryInterface(lpUnknown,&IID_IShellView, (void**)&lpOle);
1526 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInternetSecurityMgrSite,
1531 if (SUCCEEDED(hRet))
1533 /* Lazyness here - Since GetWindow() is the first method for the above 3
1534 * interfaces, we use the same call for them all.
1536 hRet = IOleWindow_GetWindow((IOleWindow*)lpOle, lphWnd);
1537 IUnknown_Release(lpOle);
1539 TRACE("Returning HWND=%p\n", *lphWnd);
1545 /*************************************************************************
1548 * Call a method on as as yet unidentified object.
1551 * pUnk [I] Object supporting the unidentified interface,
1552 * arg [I] Argument for the call on the object.
1557 HRESULT WINAPI IUnknown_SetOwner(IUnknown *pUnk, ULONG arg)
1559 static const GUID guid_173 = {
1560 0x5836fb00, 0x8187, 0x11cf, { 0xa1,0x2b,0x00,0xaa,0x00,0x4a,0xe8,0x37 }
1564 TRACE("(%p,%ld)\n", pUnk, arg);
1566 /* Note: arg may not be a ULONG and pUnk2 is for sure not an IMalloc -
1567 * We use this interface as its vtable entry is compatible with the
1568 * object in question.
1569 * FIXME: Find out what this object is and where it should be defined.
1572 SUCCEEDED(IUnknown_QueryInterface(pUnk, &guid_173, (void**)&pUnk2)))
1574 IMalloc_Alloc(pUnk2, arg); /* Faked call!! */
1575 IMalloc_Release(pUnk2);
1580 /*************************************************************************
1583 * Call either IObjectWithSite_SetSite() or IPersistMoniker_GetClassID() on
1588 * Failure: E_FAIL, if p1 is NULL.
1589 * E_NOINTERFACE If p1 does not support the IPersist interface,
1590 * Or an HRESULT error code.
1592 DWORD WINAPI IUnknown_SetSite(
1593 IUnknown *p1, /* [in] OLE object */
1594 LPVOID *p2) /* [out] ptr for call results */
1598 if (!p1) return E_FAIL;
1600 /* see if SetSite interface exists for IObjectWithSite object */
1601 ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id1, (LPVOID *)&p1);
1602 TRACE("first IU_QI ret=%08lx, p1=%p\n", ret, p1);
1605 /* see if GetClassId interface exists for IPersistMoniker object */
1606 ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id2, (LPVOID *)&aa);
1607 TRACE("second IU_QI ret=%08lx, aa=%08lx\n", ret, aa);
1608 if (ret) return ret;
1610 /* fake a GetClassId call */
1611 ret = IOleWindow_GetWindow((IOleWindow *)aa, (HWND*)p2);
1612 TRACE("second IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1614 IUnknown_Release((IUnknown *)aa);
1617 /* fake a SetSite call */
1618 ret = IOleWindow_GetWindow((IOleWindow *)p1, (HWND*)p2);
1619 TRACE("first IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1621 IUnknown_Release((IUnknown *)p1);
1626 /*************************************************************************
1629 * Call IPersist_GetClassID() on an object.
1632 * lpUnknown [I] Object supporting the IPersist interface
1633 * lpClassId [O] Destination for Class Id
1636 * Success: S_OK. lpClassId contains the Class Id requested.
1637 * Failure: E_FAIL, If lpUnknown is NULL,
1638 * E_NOINTERFACE If lpUnknown does not support IPersist,
1639 * Or an HRESULT error code.
1641 HRESULT WINAPI IUnknown_GetClassID(IUnknown *lpUnknown, CLSID* lpClassId)
1643 IPersist* lpPersist;
1644 HRESULT hRet = E_FAIL;
1646 TRACE("(%p,%p)\n", lpUnknown, debugstr_guid(lpClassId));
1650 hRet = IUnknown_QueryInterface(lpUnknown,&IID_IPersist,(void**)&lpPersist);
1651 if (SUCCEEDED(hRet))
1653 IPersist_GetClassID(lpPersist, lpClassId);
1654 IPersist_Release(lpPersist);
1660 /*************************************************************************
1663 * Retrieve a Service Interface from an object.
1666 * lpUnknown [I] Object to get an IServiceProvider interface from
1667 * sid [I] Service ID for IServiceProvider_QueryService() call
1668 * riid [I] Function requested for QueryService call
1669 * lppOut [O] Destination for the service interface pointer
1672 * Success: S_OK. lppOut contains an object providing the requested service
1673 * Failure: An HRESULT error code
1676 * lpUnknown is expected to support the IServiceProvider interface.
1678 HRESULT WINAPI IUnknown_QueryService(IUnknown* lpUnknown, REFGUID sid, REFIID riid,
1681 IServiceProvider* pService = NULL;
1692 /* Get an IServiceProvider interface from the object */
1693 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IServiceProvider,
1694 (LPVOID*)&pService);
1696 if (!hRet && pService)
1698 TRACE("QueryInterface returned (IServiceProvider*)%p\n", pService);
1700 /* Get a Service interface from the object */
1701 hRet = IServiceProvider_QueryService(pService, sid, riid, lppOut);
1703 TRACE("(IServiceProvider*)%p returned (IUnknown*)%p\n", pService, *lppOut);
1705 /* Release the IServiceProvider interface */
1706 IUnknown_Release(pService);
1711 /*************************************************************************
1714 * Loads a popup menu.
1717 * hInst [I] Instance handle
1718 * szName [I] Menu name
1724 BOOL WINAPI SHLoadMenuPopup(HINSTANCE hInst, LPCWSTR szName)
1726 HMENU hMenu, hSubMenu;
1728 if ((hMenu = LoadMenuW(hInst, szName)))
1730 if ((hSubMenu = GetSubMenu(hMenu, 0)))
1731 RemoveMenu(hMenu, 0, MF_BYPOSITION);
1739 typedef struct _enumWndData
1744 LRESULT (WINAPI *pfnPost)(HWND,UINT,WPARAM,LPARAM);
1747 /* Callback for SHLWAPI_178 */
1748 static BOOL CALLBACK SHLWAPI_EnumChildProc(HWND hWnd, LPARAM lParam)
1750 enumWndData *data = (enumWndData *)lParam;
1752 TRACE("(%p,%p)\n", hWnd, data);
1753 data->pfnPost(hWnd, data->uiMsgId, data->wParam, data->lParam);
1757 /*************************************************************************
1760 * Send or post a message to every child of a window.
1763 * hWnd [I] Window whose children will get the messages
1764 * uiMsgId [I] Message Id
1765 * wParam [I] WPARAM of message
1766 * lParam [I] LPARAM of message
1767 * bSend [I] TRUE = Use SendMessageA(), FALSE = Use PostMessageA()
1773 * The appropriate ASCII or Unicode function is called for the window.
1775 void WINAPI SHPropagateMessage(HWND hWnd, UINT uiMsgId, WPARAM wParam, LPARAM lParam, BOOL bSend)
1779 TRACE("(%p,%u,%d,%ld,%d)\n", hWnd, uiMsgId, wParam, lParam, bSend);
1783 data.uiMsgId = uiMsgId;
1784 data.wParam = wParam;
1785 data.lParam = lParam;
1788 data.pfnPost = IsWindowUnicode(hWnd) ? (void*)SendMessageW : (void*)SendMessageA;
1790 data.pfnPost = IsWindowUnicode(hWnd) ? (void*)PostMessageW : (void*)PostMessageA;
1792 EnumChildWindows(hWnd, SHLWAPI_EnumChildProc, (LPARAM)&data);
1796 /*************************************************************************
1799 * Remove all sub-menus from a menu.
1802 * hMenu [I] Menu to remove sub-menus from
1805 * Success: 0. All sub-menus under hMenu are removed
1806 * Failure: -1, if any parameter is invalid
1808 DWORD WINAPI SHRemoveAllSubMenus(HMENU hMenu)
1810 int iItemCount = GetMenuItemCount(hMenu) - 1;
1811 while (iItemCount >= 0)
1813 HMENU hSubMenu = GetSubMenu(hMenu, iItemCount);
1815 RemoveMenu(hMenu, iItemCount, MF_BYPOSITION);
1821 /*************************************************************************
1824 * Enable or disable a menu item.
1827 * hMenu [I] Menu holding menu item
1828 * uID [I] ID of menu item to enable/disable
1829 * bEnable [I] Whether to enable (TRUE) or disable (FALSE) the item.
1832 * The return code from EnableMenuItem.
1834 UINT WINAPI SHEnableMenuItem(HMENU hMenu, UINT wItemID, BOOL bEnable)
1836 return EnableMenuItem(hMenu, wItemID, bEnable ? MF_ENABLED : MF_GRAYED);
1839 /*************************************************************************
1842 * Check or uncheck a menu item.
1845 * hMenu [I] Menu holding menu item
1846 * uID [I] ID of menu item to check/uncheck
1847 * bCheck [I] Whether to check (TRUE) or uncheck (FALSE) the item.
1850 * The return code from CheckMenuItem.
1852 DWORD WINAPI SHCheckMenuItem(HMENU hMenu, UINT uID, BOOL bCheck)
1854 return CheckMenuItem(hMenu, uID, bCheck ? MF_CHECKED : MF_UNCHECKED);
1857 /*************************************************************************
1860 * Register a window class if it isn't already.
1863 * lpWndClass [I] Window class to register
1866 * The result of the RegisterClassA call.
1868 DWORD WINAPI SHRegisterClassA(WNDCLASSA *wndclass)
1871 if (GetClassInfoA(wndclass->hInstance, wndclass->lpszClassName, &wca))
1873 return (DWORD)RegisterClassA(wndclass);
1876 /*************************************************************************
1879 * Call IPersistPropertyBag_Load() on an object.
1882 * lpUnknown [I] Object supporting the IPersistPropertyBag interface
1883 * lpPropBag [O] Destination for loaded IPropertyBag
1887 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1889 DWORD WINAPI SHLoadFromPropertyBag(IUnknown *lpUnknown, IPropertyBag* lpPropBag)
1891 IPersistPropertyBag* lpPPBag;
1892 HRESULT hRet = E_FAIL;
1894 TRACE("(%p,%p)\n", lpUnknown, lpPropBag);
1898 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IPersistPropertyBag,
1900 if (SUCCEEDED(hRet) && lpPPBag)
1902 hRet = IPersistPropertyBag_Load(lpPPBag, lpPropBag, NULL);
1903 IPersistPropertyBag_Release(lpPPBag);
1909 /*************************************************************************
1912 * Call IOleControlSite_GetExtendedControl() on an object.
1915 * lpUnknown [I] Object supporting the IOleControlSite interface
1916 * lppDisp [O] Destination for resulting IDispatch.
1920 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1922 DWORD WINAPI IUnknown_OnFocusOCS(IUnknown *lpUnknown, IDispatch** lppDisp)
1924 IOleControlSite* lpCSite;
1925 HRESULT hRet = E_FAIL;
1927 TRACE("(%p,%p)\n", lpUnknown, lppDisp);
1930 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleControlSite,
1932 if (SUCCEEDED(hRet) && lpCSite)
1934 hRet = IOleControlSite_GetExtendedControl(lpCSite, lppDisp);
1935 IOleControlSite_Release(lpCSite);
1941 static const WCHAR szDontShowKey[] = { 'S','o','f','t','w','a','r','e','\\',
1942 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
1943 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
1944 'E','x','p','l','o','r','e','r','\\','D','o','n','t','S','h','o','w',
1945 'M','e','T','h','i','s','D','i','a','l','o','g','A','g','a','i','n','\0'
1948 /*************************************************************************
1951 * Pop up a 'Don't show this message again' error dialog box.
1954 * hWnd [I] Window to own the dialog box
1959 * lpszValue [I] Registry value holding boolean show/don't show.
1964 void WINAPI SHMessageBoxCheckW(HWND hWnd, PVOID arg2, PVOID arg3, PVOID arg4, PVOID arg5, LPCWSTR lpszValue)
1966 FIXME("(%p,%p,%p,%p,%p,%s) - stub!\n", hWnd, arg2, arg3, arg4, arg5, debugstr_w(lpszValue));
1968 if (SHRegGetBoolUSValueW(szDontShowKey, lpszValue, FALSE, TRUE))
1970 /* FIXME: Should use DialogBoxParamW to load a dialog box; its dlgproc
1971 * should accept clicks on 'Don't show' and set the reg value appropriately.
1976 /*************************************************************************
1979 * Get a sub-menu from a menu item.
1982 * hMenu [I] Menu to get sub-menu from
1983 * uID [I] ID of menu item containing sub-menu
1986 * The sub-menu of the item, or a NULL handle if any parameters are invalid.
1988 HMENU WINAPI SHGetMenuFromID(HMENU hMenu, UINT uID)
1992 TRACE("(%p,%uld)\n", hMenu, uID);
1994 mi.cbSize = sizeof(MENUITEMINFOA);
1995 mi.fMask = MIIM_SUBMENU;
1997 if (!GetMenuItemInfoA(hMenu, uID, 0, &mi))
2003 /*************************************************************************
2006 * Get the color depth of the primary display.
2012 * The color depth of the primary display.
2014 DWORD WINAPI SHGetCurColorRes()
2022 ret = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
2027 /*************************************************************************
2030 * Blank out a region of text by drawing the background only.
2033 * hDC [I] Device context to draw in
2034 * pRect [I] Area to draw in
2035 * cRef [I] Color to draw in
2040 DWORD WINAPI SHFillRectClr(HDC hDC, LPCRECT pRect, COLORREF cRef)
2042 COLORREF cOldColor = SetBkColor(hDC, cRef);
2043 ExtTextOutA(hDC, 0, 0, ETO_OPAQUE, pRect, 0, 0, 0);
2044 SetBkColor(hDC, cOldColor);
2048 /*************************************************************************
2051 * Copy an interface pointer
2054 * lppDest [O] Destination for copy
2055 * lpUnknown [I] Source for copy
2060 VOID WINAPI IUnknown_Set(IUnknown **lppDest, IUnknown *lpUnknown)
2062 TRACE("(%p,%p)\n", lppDest, lpUnknown);
2065 IUnknown_AtomicRelease(lppDest); /* Release existing interface */
2070 IUnknown_AddRef(lpUnknown);
2071 *lppDest = lpUnknown;
2075 /*************************************************************************
2079 HRESULT WINAPI MayExecForward(IUnknown* lpUnknown, INT iUnk, REFGUID pguidCmdGroup,
2080 DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
2083 FIXME("(%p,%d,%p,%ld,%ld,%p,%p) - stub!\n", lpUnknown, iUnk, pguidCmdGroup,
2084 nCmdID, nCmdexecopt, pvaIn, pvaOut);
2085 return DRAGDROP_E_NOTREGISTERED;
2088 /*************************************************************************
2092 HRESULT WINAPI IsQSForward(REFGUID pguidCmdGroup,ULONG cCmds, OLECMD *prgCmds)
2094 FIXME("(%p,%ld,%p) - stub!\n", pguidCmdGroup, cCmds, prgCmds);
2095 return DRAGDROP_E_NOTREGISTERED;
2098 /*************************************************************************
2101 * Determine if a window is not a child of another window.
2104 * hParent [I] Suspected parent window
2105 * hChild [I] Suspected child window
2108 * TRUE: If hChild is a child window of hParent
2109 * FALSE: If hChild is not a child window of hParent, or they are equal
2111 BOOL WINAPI SHIsChildOrSelf(HWND hParent, HWND hChild)
2113 TRACE("(%p,%p)\n", hParent, hChild);
2115 if (!hParent || !hChild)
2117 else if(hParent == hChild)
2119 return !IsChild(hParent, hChild);
2122 /*************************************************************************
2125 * Some sort of memory management process.
2127 DWORD WINAPI FDSA_Initialize(
2134 FIXME("(0x%08lx 0x%08lx %p %p 0x%08lx) stub\n",
2139 /*************************************************************************
2142 * Some sort of memory management process.
2144 DWORD WINAPI FDSA_Destroy(
2147 FIXME("(%p) stub\n",
2152 /*************************************************************************
2155 * Some sort of memory management process.
2157 DWORD WINAPI FDSA_InsertItem(
2162 FIXME("(%p 0x%08lx %p) stub\n",
2167 /*************************************************************************
2170 DWORD WINAPI FDSA_DeleteItem(
2174 FIXME("(%p 0x%08lx) stub\n",
2179 /*************************************************************************
2185 DWORD WINAPI SHAnsiToUnicode(
2192 len_a = lstrlenA(lpStrSrc);
2193 ret = MultiByteToWideChar(0, 0, lpStrSrc, len_a, lpwStrDest, len);
2194 TRACE("%s %s %d, ret=%d\n",
2195 debugstr_a(lpStrSrc), debugstr_w(lpwStrDest), len, ret);
2199 /*************************************************************************
2202 * WideCharToMultiByte with support for multiple codepages.
2205 * CodePage [I] Code page to use for the conversion
2206 * lpSrcStr [I] Source Unicode string to convert
2207 * lpDstStr [O] Destination for converted Ascii string
2208 * lpnMultiCharCount [O] Input length of lpDstStr/destination for length of lpDstStr
2211 * Success: The number of characters that result from the conversion.
2214 INT WINAPI SHUnicodeToAnsiCP(UINT CodePage, LPCWSTR lpSrcStr, LPSTR lpDstStr,
2215 LPINT lpnMultiCharCount)
2217 WCHAR emptyW[] = { '\0' };
2221 if (!lpDstStr || !lpnMultiCharCount)
2229 len = strlenW(lpSrcStr) + 1;
2234 CodePage = CP_UTF8; /* Fall through... */
2235 case 0x0000C350: /* FIXME: CP_ #define */
2240 INT nWideCharCount = len - 1;
2242 GET_FUNC(pConvertINetUnicodeToMultiByte, mlang, "ConvertINetUnicodeToMultiByte", 0);
2243 if (!pConvertINetUnicodeToMultiByte(&dwMode, CodePage, lpSrcStr, &nWideCharCount, lpDstStr,
2247 if (nWideCharCount < len - 1)
2249 mem = (LPSTR)HeapAlloc(GetProcessHeap(), 0, *lpnMultiCharCount);
2253 *lpnMultiCharCount = 0;
2255 if (pConvertINetUnicodeToMultiByte(&dwMode, CodePage, lpSrcStr, &len, mem, lpnMultiCharCount))
2257 SHTruncateString(mem, *lpnMultiCharCount);
2258 lstrcpynA(lpDstStr, mem, *lpnMultiCharCount + 1);
2259 return *lpnMultiCharCount + 1;
2261 HeapFree(GetProcessHeap(), 0, mem);
2262 return *lpnMultiCharCount;
2264 lpDstStr[*lpnMultiCharCount] = '\0';
2265 return *lpnMultiCharCount;
2272 reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, lpDstStr,
2273 *lpnMultiCharCount, NULL, NULL);
2275 if (!reqLen && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
2277 reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, NULL, 0, NULL, NULL);
2280 mem = (LPSTR)HeapAlloc(GetProcessHeap(), 0, reqLen);
2283 reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, mem,
2284 reqLen, NULL, NULL);
2286 reqLen = SHTruncateString(mem, *lpnMultiCharCount);
2289 lstrcpynA(lpDstStr, mem, *lpnMultiCharCount);
2291 HeapFree(GetProcessHeap(), 0, mem);
2298 /*************************************************************************
2301 * WideCharToMultiByte with support for multiple codepages.
2304 * lpSrcStr [I] Source Unicode string to convert
2305 * lpDstStr [O] Destination for converted Ascii string
2306 * lpnMultiCharCount [O] Input length of lpDstStr/destination for length of lpDstStr
2309 * See SHUnicodeToAnsiCP
2312 * This function simply calls SHUnicodeToAnsiCP with CodePage = CP_ACP.
2314 INT WINAPI SHUnicodeToAnsi(LPCWSTR lpSrcStr, LPSTR lpDstStr, INT MultiCharCount)
2316 INT myint = MultiCharCount;
2318 return SHUnicodeToAnsiCP(CP_ACP, lpSrcStr, lpDstStr, &myint);
2326 /*************************************************************************
2329 * Call IUnknown_QueryInterface() on a table of objects.
2333 * Failure: E_POINTER or E_NOINTERFACE.
2335 HRESULT WINAPI QISearch(
2336 LPVOID w, /* [in] Table of interfaces */
2337 IFACE_INDEX_TBL *x, /* [in] Array of REFIIDs and indexes into the table */
2338 REFIID riid, /* [in] REFIID to get interface for */
2339 LPVOID *ppv) /* [out] Destination for interface pointer */
2343 IFACE_INDEX_TBL *xmove;
2345 TRACE("(%p %p %s %p)\n", w,x,debugstr_guid(riid),ppv);
2348 while (xmove->refid) {
2349 TRACE("trying (indx %ld) %s\n", xmove->indx, debugstr_guid(xmove->refid));
2350 if (IsEqualIID(riid, xmove->refid)) {
2351 a_vtbl = (IUnknown*)(xmove->indx + (LPBYTE)w);
2352 TRACE("matched, returning (%p)\n", a_vtbl);
2353 *ppv = (LPVOID)a_vtbl;
2354 IUnknown_AddRef(a_vtbl);
2360 if (IsEqualIID(riid, &IID_IUnknown)) {
2361 a_vtbl = (IUnknown*)(x->indx + (LPBYTE)w);
2362 TRACE("returning first for IUnknown (%p)\n", a_vtbl);
2363 *ppv = (LPVOID)a_vtbl;
2364 IUnknown_AddRef(a_vtbl);
2368 ret = E_NOINTERFACE;
2372 TRACE("-- 0x%08lx\n", ret);
2376 /*************************************************************************
2379 * Remove the "PropDlgFont" property from a window.
2382 * hWnd [I] Window to remove the property from
2385 * A handle to the removed property, or NULL if it did not exist.
2387 HANDLE WINAPI SHRemoveDefaultDialogFont(HWND hWnd)
2391 TRACE("(%p)\n", hWnd);
2393 hProp = GetPropA(hWnd, "PropDlgFont");
2397 DeleteObject(hProp);
2398 hProp = RemovePropA(hWnd, "PropDlgFont");
2403 /*************************************************************************
2406 * Load the in-process server of a given GUID.
2409 * refiid [I] GUID of the server to load.
2412 * Success: A handle to the loaded server dll.
2413 * Failure: A NULL handle.
2415 HMODULE WINAPI SHPinDllOfCLSID(REFIID refiid)
2419 CHAR value[MAX_PATH], string[MAX_PATH];
2421 strcpy(string, "CLSID\\");
2422 SHStringFromGUIDA(refiid, string + 6, sizeof(string)/sizeof(char) - 6);
2423 strcat(string, "\\InProcServer32");
2426 RegOpenKeyExA(HKEY_CLASSES_ROOT, string, 0, 1, &newkey);
2427 RegQueryValueExA(newkey, 0, 0, &type, (PBYTE)value, &count);
2428 RegCloseKey(newkey);
2429 return LoadLibraryExA(value, 0, 0);
2432 /*************************************************************************
2435 * Unicode version of SHLWAPI_183.
2437 DWORD WINAPI SHRegisterClassW(WNDCLASSW * lpWndClass)
2441 TRACE("(%p %s)\n",lpWndClass->hInstance, debugstr_w(lpWndClass->lpszClassName));
2443 if (GetClassInfoW(lpWndClass->hInstance, lpWndClass->lpszClassName, &WndClass))
2445 return RegisterClassW(lpWndClass);
2448 /*************************************************************************
2451 * Unregister a list of classes.
2454 * hInst [I] Application instance that registered the classes
2455 * lppClasses [I] List of class names
2456 * iCount [I] Number of names in lppClasses
2461 void WINAPI SHUnregisterClassesA(HINSTANCE hInst, LPCSTR *lppClasses, INT iCount)
2465 TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);
2469 if (GetClassInfoA(hInst, *lppClasses, &WndClass))
2470 UnregisterClassA(*lppClasses, hInst);
2476 /*************************************************************************
2479 * Unicode version of SHUnregisterClassesA.
2481 void WINAPI SHUnregisterClassesW(HINSTANCE hInst, LPCWSTR *lppClasses, INT iCount)
2485 TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);
2489 if (GetClassInfoW(hInst, *lppClasses, &WndClass))
2490 UnregisterClassW(*lppClasses, hInst);
2496 /*************************************************************************
2499 * Call The correct (Ascii/Unicode) default window procedure for a window.
2502 * hWnd [I] Window to call the default procedure for
2503 * uMessage [I] Message ID
2504 * wParam [I] WPARAM of message
2505 * lParam [I] LPARAM of message
2508 * The result of calling DefWindowProcA() or DefWindowProcW().
2510 LRESULT CALLBACK SHDefWindowProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
2512 if (IsWindowUnicode(hWnd))
2513 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
2514 return DefWindowProcA(hWnd, uMessage, wParam, lParam);
2517 /*************************************************************************
2521 DWORD WINAPI StopWatchMode()
2524 return /* 0xabba1243 */ 0;
2527 /*************************************************************************
2530 * Create a worker window using CreateWindowExA().
2533 * wndProc [I] Window procedure
2534 * hWndParent [I] Parent window
2535 * dwExStyle [I] Extra style flags
2536 * dwStyle [I] Style flags
2537 * hMenu [I] Window menu
2541 * Success: The window handle of the newly created window.
2544 HWND WINAPI SHCreateWorkerWindowA(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
2545 DWORD dwStyle, HMENU hMenu, LONG z)
2547 static const char* szClass = "WorkerA";
2551 TRACE("(0x%08lx,%p,0x%08lx,0x%08lx,%p,0x%08lx)\n",
2552 wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2554 /* Create Window class */
2556 wc.lpfnWndProc = DefWindowProcA;
2559 wc.hInstance = shlwapi_hInstance;
2560 wc.hIcon = (HICON)0;
2561 wc.hCursor = LoadCursorA((HINSTANCE)0, (LPSTR)IDC_ARROW);
2562 wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
2563 wc.lpszMenuName = NULL;
2564 wc.lpszClassName = szClass;
2566 SHRegisterClassA(&wc); /* Register class */
2568 /* FIXME: Set extra bits in dwExStyle */
2570 hWnd = CreateWindowExA(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
2571 hWndParent, hMenu, shlwapi_hInstance, 0);
2574 SetWindowLongA(hWnd, DWL_MSGRESULT, z);
2577 SetWindowLongA(hWnd, GWL_WNDPROC, wndProc);
2582 typedef struct tagPOLICYDATA
2584 DWORD policy; /* flags value passed to SHRestricted */
2585 LPCWSTR appstr; /* application str such as "Explorer" */
2586 LPCWSTR keystr; /* name of the actual registry key / policy */
2587 } POLICYDATA, *LPPOLICYDATA;
2589 #define SHELL_NO_POLICY 0xffffffff
2591 /* default shell policy registry key */
2592 static WCHAR strRegistryPolicyW[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o',
2593 's','o','f','t','\\','W','i','n','d','o','w','s','\\',
2594 'C','u','r','r','e','n','t','V','e','r','s','i','o','n',
2595 '\\','P','o','l','i','c','i','e','s',0};
2597 /*************************************************************************
2600 * Retrieve a policy value from the registry.
2603 * lpSubKey [I] registry key name
2604 * lpSubName [I] subname of registry key
2605 * lpValue [I] value name of registry value
2608 * the value associated with the registry key or 0 if not found
2610 DWORD WINAPI SHGetRestriction(LPCWSTR lpSubKey, LPCWSTR lpSubName, LPCWSTR lpValue)
2612 DWORD retval, datsize = 4;
2616 lpSubKey = (LPCWSTR)strRegistryPolicyW;
2618 retval = RegOpenKeyW(HKEY_LOCAL_MACHINE, lpSubKey, &hKey);
2619 if (retval != ERROR_SUCCESS)
2620 retval = RegOpenKeyW(HKEY_CURRENT_USER, lpSubKey, &hKey);
2621 if (retval != ERROR_SUCCESS)
2624 SHGetValueW(hKey, lpSubName, lpValue, NULL, (LPBYTE)&retval, &datsize);
2629 /*************************************************************************
2632 * Helper function to retrieve the possibly cached value for a specific policy
2635 * policy [I] The policy to look for
2636 * initial [I] Main registry key to open, if NULL use default
2637 * polTable [I] Table of known policies, 0 terminated
2638 * polArr [I] Cache array of policy values
2641 * The retrieved policy value or 0 if not successful
2644 * This function is used by the native SHRestricted function to search for the
2645 * policy and cache it once retrieved. The current Wine implementation uses a
2646 * different POLICYDATA structure and implements a similar algorithme adapted to
2649 DWORD WINAPI SHRestrictionLookup(
2652 LPPOLICYDATA polTable,
2655 TRACE("(0x%08lx %s %p %p)\n", policy, debugstr_w(initial), polTable, polArr);
2657 if (!polTable || !polArr)
2660 for (;polTable->policy; polTable++, polArr++)
2662 if (policy == polTable->policy)
2664 /* we have a known policy */
2666 /* check if this policy has been cached */
2667 if (*polArr == SHELL_NO_POLICY)
2668 *polArr = SHGetRestriction(initial, polTable->appstr, polTable->keystr);
2672 /* we don't know this policy, return 0 */
2673 TRACE("unknown policy: (%08lx)\n", policy);
2677 /*************************************************************************
2680 * Get an interface from an object.
2683 * Success: S_OK. ppv contains the requested interface.
2684 * Failure: An HRESULT error code.
2687 * This QueryInterface asks the inner object for a interface. In case
2688 * of aggregation this request would be forwarded by the inner to the
2689 * outer object. This function asks the inner object directly for the
2690 * interface circumventing the forwarding to the outer object.
2692 HRESULT WINAPI SHWeakQueryInterface(
2693 IUnknown * pUnk, /* [in] Outer object */
2694 IUnknown * pInner, /* [in] Inner object */
2695 IID * riid, /* [in] Interface GUID to query for */
2696 LPVOID* ppv) /* [out] Destination for queried interface */
2698 HRESULT hret = E_NOINTERFACE;
2699 TRACE("(pUnk=%p pInner=%p\n\tIID: %s %p)\n",pUnk,pInner,debugstr_guid(riid), ppv);
2702 if(pUnk && pInner) {
2703 hret = IUnknown_QueryInterface(pInner, riid, (LPVOID*)ppv);
2704 if (SUCCEEDED(hret)) IUnknown_Release(pUnk);
2706 TRACE("-- 0x%08lx\n", hret);
2710 /*************************************************************************
2713 * Move a reference from one interface to another.
2716 * lpDest [O] Destination to receive the reference
2717 * lppUnknown [O] Source to give up the reference to lpDest
2722 VOID WINAPI SHWeakReleaseInterface(IUnknown *lpDest, IUnknown **lppUnknown)
2724 TRACE("(%p,%p)\n", lpDest, lppUnknown);
2729 IUnknown_AddRef(lpDest);
2730 IUnknown_AtomicRelease(lppUnknown); /* Release existing interface */
2734 /*************************************************************************
2737 * Convert an ASCII string of a CLSID into a CLSID.
2740 * idstr [I] String representing a CLSID in registry format
2741 * id [O] Destination for the converted CLSID
2744 * Success: TRUE. id contains the converted CLSID.
2747 BOOL WINAPI GUIDFromStringA(LPCSTR idstr, CLSID *id)
2750 MultiByteToWideChar(CP_ACP, 0, idstr, -1, wClsid, sizeof(wClsid)/sizeof(WCHAR));
2751 return SUCCEEDED(CLSIDFromStringWrap(wClsid, id));
2754 /*************************************************************************
2757 * Unicode version of GUIDFromStringA.
2759 BOOL WINAPI GUIDFromStringW(LPCWSTR idstr, CLSID *id)
2761 return SUCCEEDED(CLSIDFromStringWrap(idstr, id));
2764 /*************************************************************************
2767 * Determine if the browser is integrated into the shell, and set a registry
2774 * 1, If the browser is not integrated.
2775 * 2, If the browser is integrated.
2778 * The key "HKLM\Software\Microsoft\Internet Explorer\IntegratedBrowser" is
2779 * either set to TRUE, or removed depending on whether the browser is deemed
2782 DWORD WINAPI WhichPlatform()
2784 static LPCSTR szIntegratedBrowser = "IntegratedBrowser";
2785 static DWORD dwState = 0;
2787 DWORD dwRet, dwData, dwSize;
2792 /* If shell32 exports DllGetVersion(), the browser is integrated */
2793 GET_FUNC(pDllGetVersion, shell32, "DllGetVersion", 1);
2794 dwState = pDllGetVersion ? 2 : 1;
2796 /* Set or delete the key accordinly */
2797 dwRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
2798 "Software\\Microsoft\\Internet Explorer", 0,
2799 KEY_ALL_ACCESS, &hKey);
2802 dwRet = RegQueryValueExA(hKey, szIntegratedBrowser, 0, 0,
2803 (LPBYTE)&dwData, &dwSize);
2805 if (!dwRet && dwState == 1)
2807 /* Value exists but browser is not integrated */
2808 RegDeleteValueA(hKey, szIntegratedBrowser);
2810 else if (dwRet && dwState == 2)
2812 /* Browser is integrated but value does not exist */
2814 RegSetValueExA(hKey, szIntegratedBrowser, 0, REG_DWORD,
2815 (LPBYTE)&dwData, sizeof(dwData));
2822 /*************************************************************************
2825 * Unicode version of SHCreateWorkerWindowA.
2827 HWND WINAPI SHCreateWorkerWindowW(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
2828 DWORD dwStyle, HMENU hMenu, LONG z)
2830 static const WCHAR szClass[] = { 'W', 'o', 'r', 'k', 'e', 'r', 'W', '\0' };
2834 TRACE("(0x%08lx,%p,0x%08lx,0x%08lx,%p,0x%08lx)\n",
2835 wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2837 /* If our OS is natively ASCII, use the ASCII version */
2838 if (!(GetVersion() & 0x80000000)) /* NT */
2839 return SHCreateWorkerWindowA(wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2841 /* Create Window class */
2843 wc.lpfnWndProc = DefWindowProcW;
2846 wc.hInstance = shlwapi_hInstance;
2847 wc.hIcon = (HICON)0;
2848 wc.hCursor = LoadCursorA((HINSTANCE)0, (LPSTR)IDC_ARROW);
2849 wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
2850 wc.lpszMenuName = NULL;
2851 wc.lpszClassName = szClass;
2853 SHRegisterClassW(&wc); /* Register class */
2855 /* FIXME: Set extra bits in dwExStyle */
2857 hWnd = CreateWindowExW(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
2858 hWndParent, hMenu, shlwapi_hInstance, 0);
2861 SetWindowLongA(hWnd, DWL_MSGRESULT, z);
2864 SetWindowLongA(hWnd, GWL_WNDPROC, wndProc);
2869 /*************************************************************************
2872 * Get and show a context menu from a shell folder.
2875 * hWnd [I] Window displaying the shell folder
2876 * lpFolder [I] IShellFolder interface
2877 * lpApidl [I] Id for the particular folder desired
2881 * Failure: An HRESULT error code indicating the error.
2883 HRESULT WINAPI SHInvokeDefaultCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl)
2885 return SHInvokeCommand(hWnd, lpFolder, lpApidl, FALSE);
2888 /*************************************************************************
2891 * _SHPackDispParamsV
2893 HRESULT WINAPI SHPackDispParamsV(LPVOID w, LPVOID x, LPVOID y, LPVOID z)
2895 FIXME("%p %p %p %p\n",w,x,y,z);
2899 /*************************************************************************
2902 * This function seems to be a forward to SHPackDispParamsV (whatever THAT
2903 * function does...).
2905 HRESULT WINAPI SHPackDispParams(LPVOID w, LPVOID x, LPVOID y, LPVOID z)
2907 FIXME("%p %p %p %p\n", w, x, y, z);
2911 /*************************************************************************
2914 * _IConnectionPoint_SimpleInvoke
2916 DWORD WINAPI IConnectionPoint_SimpleInvoke(
2921 FIXME("(%p %p %p) stub\n",x,y,z);
2925 /*************************************************************************
2928 * Notify an IConnectionPoint object of changes.
2931 * lpCP [I] Object to notify
2936 * Failure: E_NOINTERFACE, if lpCP is NULL or does not support the
2937 * IConnectionPoint interface.
2939 HRESULT WINAPI IConnectionPoint_OnChanged(IConnectionPoint* lpCP, DISPID dispID)
2941 IEnumConnections *lpEnum;
2942 HRESULT hRet = E_NOINTERFACE;
2944 TRACE("(%p,0x%8lX)\n", lpCP, dispID);
2946 /* Get an enumerator for the connections */
2948 hRet = IConnectionPoint_EnumConnections(lpCP, &lpEnum);
2950 if (SUCCEEDED(hRet))
2952 IPropertyNotifySink *lpSink;
2953 CONNECTDATA connData;
2956 /* Call OnChanged() for every notify sink in the connection point */
2957 while (IEnumConnections_Next(lpEnum, 1, &connData, &ulFetched) == S_OK)
2959 if (SUCCEEDED(IUnknown_QueryInterface(connData.pUnk, &IID_IPropertyNotifySink, (void**)&lpSink)) &&
2962 IPropertyNotifySink_OnChanged(lpSink, dispID);
2963 IPropertyNotifySink_Release(lpSink);
2965 IUnknown_Release(connData.pUnk);
2968 IEnumConnections_Release(lpEnum);
2973 /*************************************************************************
2976 * Notify an IConnectionPointContainer object of changes.
2979 * lpUnknown [I] Object to notify
2984 * Failure: E_NOINTERFACE, if lpUnknown is NULL or does not support the
2985 * IConnectionPointContainer interface.
2987 HRESULT WINAPI IUnknown_CPContainerOnChanged(IUnknown *lpUnknown, DISPID dispID)
2989 IConnectionPointContainer* lpCPC = NULL;
2990 HRESULT hRet = E_NOINTERFACE;
2992 TRACE("(%p,0x%8lX)\n", lpUnknown, dispID);
2995 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer, (void**)&lpCPC);
2997 if (SUCCEEDED(hRet))
2999 IConnectionPoint* lpCP;
3001 hRet = IConnectionPointContainer_FindConnectionPoint(lpCPC, &IID_IPropertyNotifySink, &lpCP);
3002 IConnectionPointContainer_Release(lpCPC);
3004 hRet = IConnectionPoint_OnChanged(lpCP, dispID);
3005 IConnectionPoint_Release(lpCP);
3010 /*************************************************************************
3015 BOOL WINAPI PlaySoundWrapW(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
3017 GET_FUNC(pPlaySoundW, winmm, "PlaySoundW", FALSE);
3018 return pPlaySoundW(pszSound, hmod, fdwSound);
3021 /*************************************************************************
3024 BOOL WINAPI SHGetIniStringW(LPSTR str1, LPSTR str2, LPSTR pStr, DWORD some_len, LPCSTR lpStr2)
3027 * str1: "I" "I" pushl esp+0x20
3028 * str2: "U" "I" pushl 0x77c93810
3029 * (is "I" and "U" "integer" and "unsigned" ??)
3031 * pStr: "" "" pushl eax
3032 * some_len: 0x824 0x104 pushl 0x824
3033 * lpStr2: "%l" "%l" pushl esp+0xc
3035 * shlwapi. StrCpyNW(lpStr2, irrelevant_var, 0x104);
3036 * LocalAlloc(0x00, some_len) -> irrelevant_var
3037 * LocalAlloc(0x40, irrelevant_len) -> pStr
3038 * shlwapi.294(str1, str2, pStr, some_len, lpStr2);
3039 * shlwapi.PathRemoveBlanksW(pStr);
3041 FIXME("('%s', '%s', '%s', %08lx, '%s'): stub!\n", str1, str2, pStr, some_len, lpStr2);
3045 /*************************************************************************
3048 * Called by ICQ2000b install via SHDOCVW:
3049 * str1: "InternetShortcut"
3050 * x: some unknown pointer
3051 * str2: "http://free.aol.com/tryaolfree/index.adp?139269"
3052 * str3: "C:\\WINDOWS\\Desktop.new2\\Free AOL & Unlimited Internet.url"
3054 * In short: this one maybe creates a desktop link :-)
3056 BOOL WINAPI SHSetIniStringW(LPWSTR str1, LPVOID x, LPWSTR str2, LPWSTR str3)
3058 FIXME("('%s', %p, '%s', '%s'), stub.\n", debugstr_w(str1), x, debugstr_w(str2), debugstr_w(str3));
3062 /*************************************************************************
3067 BOOL WINAPI ExtTextOutWrapW(HDC hdc, INT x, INT y, UINT flags, const RECT *lprect,
3068 LPCWSTR str, UINT count, const INT *lpDx)
3070 GET_FUNC(pCOMCTL32_417, comctl32, (LPCSTR)417, FALSE);
3071 return pCOMCTL32_417(hdc, x, y, flags, lprect, str, count, lpDx);
3074 /*************************************************************************
3077 * See SHGetFileInfoW.
3079 DWORD WINAPI SHGetFileInfoWrapW(LPCWSTR path, DWORD dwFileAttributes,
3080 SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
3082 GET_FUNC(pSHGetFileInfoW, shell32, "SHGetFileInfoW", 0);
3083 return pSHGetFileInfoW(path, dwFileAttributes, psfi, sizeofpsfi, flags);
3086 /*************************************************************************
3089 * See DragQueryFileW.
3091 UINT WINAPI DragQueryFileWrapW(HDROP hDrop, UINT lFile, LPWSTR lpszFile, UINT lLength)
3093 GET_FUNC(pDragQueryFileW, shell32, "DragQueryFileW", 0);
3094 return pDragQueryFileW(hDrop, lFile, lpszFile, lLength);
3097 /*************************************************************************
3100 * See SHBrowseForFolderW.
3102 LPITEMIDLIST WINAPI SHBrowseForFolderWrapW(LPBROWSEINFOW lpBi)
3104 GET_FUNC(pSHBrowseForFolderW, shell32, "SHBrowseForFolderW", NULL);
3105 return pSHBrowseForFolderW(lpBi);
3108 /*************************************************************************
3111 * See SHGetPathFromIDListW.
3113 BOOL WINAPI SHGetPathFromIDListWrapW(LPCITEMIDLIST pidl,LPWSTR pszPath)
3115 GET_FUNC(pSHGetPathFromIDListW, shell32, "SHGetPathFromIDListW", 0);
3116 return pSHGetPathFromIDListW(pidl, pszPath);
3119 /*************************************************************************
3122 * See ShellExecuteExW.
3124 BOOL WINAPI ShellExecuteExWrapW(LPSHELLEXECUTEINFOW lpExecInfo)
3126 GET_FUNC(pShellExecuteExW, shell32, "ShellExecuteExW", FALSE);
3127 return pShellExecuteExW(lpExecInfo);
3130 /*************************************************************************
3133 * See SHFileOperationW.
3135 HICON WINAPI SHFileOperationWrapW(LPSHFILEOPSTRUCTW lpFileOp)
3137 GET_FUNC(pSHFileOperationW, shell32, "SHFileOperationW", 0);
3138 return pSHFileOperationW(lpFileOp);
3141 /*************************************************************************
3144 * See ExtractIconExW.
3146 UINT WINAPI ExtractIconExWrapW(LPCWSTR lpszFile, INT nIconIndex, HICON *phiconLarge,
3147 HICON *phiconSmall, UINT nIcons)
3149 GET_FUNC(pExtractIconExW, shell32, "ExtractIconExW", 0);
3150 return pExtractIconExW(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
3153 /*************************************************************************
3157 LONG WINAPI SHInterlockedCompareExchange( PLONG dest, LONG xchg, LONG compare)
3159 return InterlockedCompareExchange(dest, xchg, compare);
3162 /*************************************************************************
3165 DWORD WINAPI SHUnicodeToUnicode(
3170 FIXME("(%s %p 0x%08x)stub\n",debugstr_w(src),dest,len);
3171 lstrcpynW(dest, src, len);
3172 return lstrlenW(dest)+1;
3175 /*************************************************************************
3178 * See GetFileVersionInfoSizeW.
3180 DWORD WINAPI GetFileVersionInfoSizeWrapW(
3186 GET_FUNC(pGetFileVersionInfoSizeW, version, "GetFileVersionInfoSizeW", 0);
3187 ret = pGetFileVersionInfoSizeW(x, y);
3191 /*************************************************************************
3194 * See GetFileVersionInfoW.
3196 BOOL WINAPI GetFileVersionInfoWrapW(
3197 LPWSTR w, /* [in] path to dll */
3198 DWORD x, /* [in] parm 2 to GetFileVersionInfoA */
3199 DWORD y, /* [in] return value from SHLWAPI_350() - assume length */
3200 LPVOID z) /* [in/out] buffer (+0x208 sent to GetFileVersionInfoA()) */
3202 GET_FUNC(pGetFileVersionInfoW, version, "GetFileVersionInfoW", 0);
3203 return pGetFileVersionInfoW(w, x, y-0x208, (char*)z+0x208);
3206 /*************************************************************************
3209 * See VerQueryValueW.
3211 WORD WINAPI VerQueryValueWrapW(
3212 LPVOID w, /* [in] Buffer from SHLWAPI_351() */
3213 LPWSTR x, /* [in] Value to retrieve - converted and passed to VerQueryValueA() as #2 */
3214 LPVOID y, /* [out] Ver buffer - passed to VerQueryValueA as #3 */
3215 UINT* z) /* [in] Ver length - passed to VerQueryValueA as #4 */
3217 GET_FUNC(pVerQueryValueW, version, "VerQueryValueW", 0);
3218 return pVerQueryValueW((char*)w+0x208, x, y, z);
3221 #define IsIface(type) SUCCEEDED((hRet = IUnknown_QueryInterface(lpUnknown, &IID_##type, (void**)&lpObj)))
3222 #define IShellBrowser_EnableModeless IShellBrowser_EnableModelessSB
3223 #define EnableModeless(type) type##_EnableModeless((type*)lpObj, bModeless)
3225 /*************************************************************************
3228 * Change the modality of a shell object.
3231 * lpUnknown [I] Object to make modeless
3232 * bModeless [I] TRUE=Make modeless, FALSE=Make modal
3235 * Success: S_OK. The modality lpUnknown is changed.
3236 * Failure: An HRESULT error code indicating the error.
3239 * lpUnknown must support the IOleInPlaceFrame interface, the
3240 * IInternetSecurityMgrSite interface, the IShellBrowser interface
3241 * or the IDocHostUIHandler interface, or this call fails.
3243 HRESULT WINAPI IUnknown_EnableModeless(IUnknown *lpUnknown, BOOL bModeless)
3248 TRACE("(%p,%d)\n", lpUnknown, bModeless);
3253 if (IsIface(IOleInPlaceFrame))
3254 EnableModeless(IOleInPlaceFrame);
3255 else if (IsIface(IShellBrowser))
3256 EnableModeless(IShellBrowser);
3258 /* FIXME: Wine has no headers for these objects yet */
3259 else if (IsIface(IInternetSecurityMgrSite))
3260 EnableModeless(IInternetSecurityMgrSite);
3261 else if (IsIface(IDocHostUIHandler))
3262 EnableModeless(IDocHostUIHandler);
3267 IUnknown_Release(lpObj);
3271 /*************************************************************************
3274 * See SHGetNewLinkInfoW.
3276 BOOL WINAPI SHGetNewLinkInfoWrapW(LPCWSTR pszLinkTo, LPCWSTR pszDir, LPWSTR pszName,
3277 BOOL *pfMustCopy, UINT uFlags)
3279 GET_FUNC(pSHGetNewLinkInfoW, shell32, "SHGetNewLinkInfoW", FALSE);
3280 return pSHGetNewLinkInfoW(pszLinkTo, pszDir, pszName, pfMustCopy, uFlags);
3283 /*************************************************************************
3286 * See SHDefExtractIconW.
3288 UINT WINAPI SHDefExtractIconWrapW(LPCWSTR pszIconFile, int iIndex, UINT uFlags, HICON* phiconLarge,
3289 HICON* phiconSmall, UINT nIconSize)
3291 GET_FUNC(pSHDefExtractIconW, shell32, "SHDefExtractIconW", 0);
3292 return pSHDefExtractIconW(pszIconFile, iIndex, uFlags, phiconLarge, phiconSmall, nIconSize);
3295 /*************************************************************************
3298 * Get and show a context menu from a shell folder.
3301 * hWnd [I] Window displaying the shell folder
3302 * lpFolder [I] IShellFolder interface
3303 * lpApidl [I] Id for the particular folder desired
3304 * bInvokeDefault [I] Whether to invoke the default menu item
3307 * Success: S_OK. If bInvokeDefault is TRUE, the default menu action was
3309 * Failure: An HRESULT error code indicating the error.
3311 HRESULT WINAPI SHInvokeCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl, BOOL bInvokeDefault)
3313 IContextMenu *iContext;
3314 HRESULT hRet = E_FAIL;
3316 TRACE("(%p,%p,%p,%d)\n", hWnd, lpFolder, lpApidl, bInvokeDefault);
3321 /* Get the context menu from the shell folder */
3322 hRet = IShellFolder_GetUIObjectOf(lpFolder, hWnd, 1, &lpApidl,
3323 &IID_IContextMenu, 0, (void**)&iContext);
3324 if (SUCCEEDED(hRet))
3327 if ((hMenu = CreatePopupMenu()))
3330 DWORD dwDefaultId = 0;
3332 /* Add the context menu entries to the popup */
3333 hQuery = IContextMenu_QueryContextMenu(iContext, hMenu, 0, 1, 0x7FFF,
3334 bInvokeDefault ? CMF_NORMAL : CMF_DEFAULTONLY);
3336 if (SUCCEEDED(hQuery))
3338 if (bInvokeDefault &&
3339 (dwDefaultId = GetMenuDefaultItem(hMenu, 0, 0)) != 0xFFFFFFFF)
3341 CMINVOKECOMMANDINFO cmIci;
3342 /* Invoke the default item */
3343 memset(&cmIci,0,sizeof(cmIci));
3344 cmIci.cbSize = sizeof(cmIci);
3345 cmIci.fMask = CMIC_MASK_ASYNCOK;
3347 cmIci.lpVerb = MAKEINTRESOURCEA(dwDefaultId);
3348 cmIci.nShow = SW_SCROLLCHILDREN;
3350 hRet = IContextMenu_InvokeCommand(iContext, &cmIci);
3355 IContextMenu_Release(iContext);
3360 /*************************************************************************
3363 * Copy one string to another, up to a given length.
3366 * lpszSrc [I] Source string to copy
3367 * lpszDst [O] Destination for copied string
3368 * iLen [I] Number of characters to copy
3373 DWORD WINAPI DoesStringRoundTripA(LPCSTR lpszSrc, LPSTR lpszDst, INT iLen)
3375 lstrcpynA(lpszDst, lpszSrc, iLen);
3379 /*************************************************************************
3384 HICON WINAPI ExtractIconWrapW(HINSTANCE hInstance, LPCWSTR lpszExeFileName,
3387 GET_FUNC(pExtractIconW, shell32, "ExtractIconW", NULL);
3388 return pExtractIconW(hInstance, lpszExeFileName, nIconIndex);
3391 /*************************************************************************
3394 LANGID WINAPI MLGetUILanguage()
3397 /* FIXME: This should be a forward in the .spec file to the win2k function
3398 * kernel32.GetUserDefaultUILanguage, however that function isn't there yet.
3400 return GetUserDefaultLangID();
3403 /*************************************************************************
3406 * Load a library from the directory of a particular process.
3409 * new_mod [I] Library name
3410 * inst_hwnd [I] Module whose directory is to be used
3411 * dwFlags [I] Flags controlling the load
3414 * Success: A handle to the loaded module
3415 * Failure: A NULL handle.
3417 HMODULE WINAPI MLLoadLibraryA(LPCSTR new_mod, HMODULE inst_hwnd, DWORD dwFlags)
3419 /* FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for
3421 * FIXME: Native shows calls to:
3422 * SHRegGetUSValue for "Software\Microsoft\Internet Explorer\International"
3424 * RegOpenKeyExA for "HKLM\Software\Microsoft\Internet Explorer"
3425 * RegQueryValueExA for "LPKInstalled"
3427 * RegOpenKeyExA for "HKCU\Software\Microsoft\Internet Explorer\International"
3428 * RegQueryValueExA for "ResourceLocale"
3430 * RegOpenKeyExA for "HKLM\Software\Microsoft\Active Setup\Installed Components\{guid}"
3431 * RegQueryValueExA for "Locale"
3433 * and then tests the Locale ("en" for me).
3435 * after the code then a DPA_Create (first time) and DPA_InsertPtr are done.
3437 CHAR mod_path[2*MAX_PATH];
3440 FIXME("(%s,%p,0x%08lx) semi-stub!\n", debugstr_a(new_mod), inst_hwnd, dwFlags);
3441 GetModuleFileNameA(inst_hwnd, mod_path, 2*MAX_PATH);
3442 ptr = strrchr(mod_path, '\\');
3444 strcpy(ptr+1, new_mod);
3445 TRACE("loading %s\n", debugstr_a(mod_path));
3446 return LoadLibraryA(mod_path);
3451 /*************************************************************************
3454 * Unicode version of MLLoadLibraryA.
3456 HMODULE WINAPI MLLoadLibraryW(LPCWSTR new_mod, HMODULE inst_hwnd, DWORD dwFlags)
3458 WCHAR mod_path[2*MAX_PATH];
3461 FIXME("(%s,%p,0x%08lx) semi-stub!\n", debugstr_w(new_mod), inst_hwnd, dwFlags);
3462 GetModuleFileNameW(inst_hwnd, mod_path, 2*MAX_PATH);
3463 ptr = strrchrW(mod_path, '\\');
3465 strcpyW(ptr+1, new_mod);
3466 TRACE("loading %s\n", debugstr_w(mod_path));
3467 return LoadLibraryW(mod_path);
3472 /*************************************************************************
3473 * ColorAdjustLuma [SHLWAPI.@]
3475 * Adjust the luminosity of a color
3478 * cRGB [I] RGB value to convert
3479 * dwLuma [I] Luma adjustment
3480 * bUnknown [I] Unknown
3483 * The adjusted RGB color.
3485 COLORREF WINAPI ColorAdjustLuma(COLORREF cRGB, int dwLuma, BOOL bUnknown)
3487 TRACE("(0x%8lx,%d,%d)\n", cRGB, dwLuma, bUnknown);
3493 ColorRGBToHLS(cRGB, &wH, &wL, &wS);
3495 FIXME("Ignoring luma adjustment\n");
3497 /* FIXME: The ajdustment is not linear */
3499 cRGB = ColorHLSToRGB(wH, wL, wS);
3504 /*************************************************************************
3507 * See GetSaveFileNameW.
3509 BOOL WINAPI GetSaveFileNameWrapW(LPOPENFILENAMEW ofn)
3511 GET_FUNC(pGetSaveFileNameW, comdlg32, "GetSaveFileNameW", FALSE);
3512 return pGetSaveFileNameW(ofn);
3515 /*************************************************************************
3518 * See WNetRestoreConnectionW.
3520 DWORD WINAPI WNetRestoreConnectionWrapW(HWND hwndOwner, LPWSTR lpszDevice)
3522 GET_FUNC(pWNetRestoreConnectionW, mpr, "WNetRestoreConnectionW", 0);
3523 return pWNetRestoreConnectionW(hwndOwner, lpszDevice);
3526 /*************************************************************************
3529 * See WNetGetLastErrorW.
3531 DWORD WINAPI WNetGetLastErrorWrapW(LPDWORD lpError, LPWSTR lpErrorBuf, DWORD nErrorBufSize,
3532 LPWSTR lpNameBuf, DWORD nNameBufSize)
3534 GET_FUNC(pWNetGetLastErrorW, mpr, "WNetGetLastErrorW", 0);
3535 return pWNetGetLastErrorW(lpError, lpErrorBuf, nErrorBufSize, lpNameBuf, nNameBufSize);
3538 /*************************************************************************
3541 * See PageSetupDlgW.
3543 BOOL WINAPI PageSetupDlgWrapW(LPPAGESETUPDLGW pagedlg)
3545 GET_FUNC(pPageSetupDlgW, comdlg32, "PageSetupDlgW", FALSE);
3546 return pPageSetupDlgW(pagedlg);
3549 /*************************************************************************
3554 BOOL WINAPI PrintDlgWrapW(LPPRINTDLGW printdlg)
3556 GET_FUNC(pPrintDlgW, comdlg32, "PrintDlgW", FALSE);
3557 return pPrintDlgW(printdlg);
3560 /*************************************************************************
3563 * See GetOpenFileNameW.
3565 BOOL WINAPI GetOpenFileNameWrapW(LPOPENFILENAMEW ofn)
3567 GET_FUNC(pGetOpenFileNameW, comdlg32, "GetOpenFileNameW", FALSE);
3568 return pGetOpenFileNameW(ofn);
3571 /* INTERNAL: Map from HLS color space to RGB */
3572 static WORD WINAPI ConvertHue(int wHue, WORD wMid1, WORD wMid2)
3574 wHue = wHue > 240 ? wHue - 240 : wHue < 0 ? wHue + 240 : wHue;
3578 else if (wHue > 120)
3583 return ((wHue * (wMid2 - wMid1) + 20) / 40) + wMid1;
3586 /* Convert to RGB and scale into RGB range (0..255) */
3587 #define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240
3589 /*************************************************************************
3590 * ColorHLSToRGB [SHLWAPI.@]
3592 * Convert from hls color space into an rgb COLORREF.
3595 * wHue [I] Hue amount
3596 * wLuminosity [I] Luminosity amount
3597 * wSaturation [I] Saturation amount
3600 * A COLORREF representing the converted color.
3603 * Input hls values are constrained to the range (0..240).
3605 COLORREF WINAPI ColorHLSToRGB(WORD wHue, WORD wLuminosity, WORD wSaturation)
3611 WORD wGreen, wBlue, wMid1, wMid2;
3613 if (wLuminosity > 120)
3614 wMid2 = wSaturation + wLuminosity - (wSaturation * wLuminosity + 120) / 240;
3616 wMid2 = ((wSaturation + 240) * wLuminosity + 120) / 240;
3618 wMid1 = wLuminosity * 2 - wMid2;
3620 wRed = GET_RGB(wHue + 80);
3621 wGreen = GET_RGB(wHue);
3622 wBlue = GET_RGB(wHue - 80);
3624 return RGB(wRed, wGreen, wBlue);
3627 wRed = wLuminosity * 255 / 240;
3628 return RGB(wRed, wRed, wRed);
3631 /*************************************************************************
3634 * Get the current docking status of the system.
3637 * dwFlags [I] DOCKINFO_ flags from "winbase.h", unused
3640 * One of DOCKINFO_UNDOCKED, DOCKINFO_UNDOCKED, or 0 if the system is not
3643 DWORD WINAPI SHGetMachineInfo(DWORD dwFlags)
3645 HW_PROFILE_INFOA hwInfo;
3647 TRACE("(0x%08lx)\n", dwFlags);
3649 GetCurrentHwProfileA(&hwInfo);
3650 switch (hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED))
3652 case DOCKINFO_DOCKED:
3653 case DOCKINFO_UNDOCKED:
3654 return hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED);
3660 /*************************************************************************
3663 * Function seems to do FreeLibrary plus other things.
3665 * FIXME native shows the following calls:
3666 * RtlEnterCriticalSection
3668 * GetProcAddress(Comctl32??, 150L)
3670 * RtlLeaveCriticalSection
3671 * followed by the FreeLibrary.
3672 * The above code may be related to .377 above.
3674 BOOL WINAPI MLFreeLibrary(HMODULE hModule)
3676 FIXME("(%p) semi-stub\n", hModule);
3677 return FreeLibrary(hModule);
3680 /*************************************************************************
3682 * FIXME I have no idea what this function does or what its arguments are.
3684 BOOL WINAPI MLIsMLHInstance(HINSTANCE hInst)
3686 FIXME("(%p) stub\n", hInst);
3691 /*************************************************************************
3694 DWORD WINAPI MLSetMLHInstance(HINSTANCE hInst, HANDLE hHeap)
3696 FIXME("(%p,%p) stub\n", hInst, hHeap);
3697 return E_FAIL; /* This is what is used if shlwapi not loaded */
3700 /*************************************************************************
3703 DWORD WINAPI MLClearMLHInstance(DWORD x)
3705 FIXME("(0x%08lx)stub\n", x);
3709 /*************************************************************************
3712 * Convert an Unicode string CLSID into a CLSID.
3715 * idstr [I] string containing a CLSID in text form
3716 * id [O] CLSID extracted from the string
3719 * S_OK on success or E_INVALIDARG on failure
3722 * This is really CLSIDFromString() which is exported by ole32.dll,
3723 * however the native shlwapi.dll does *not* import ole32. Nor does
3724 * ole32.dll import this ordinal from shlwapi. Therefore we must conclude
3725 * that MS duplicated the code for CLSIDFromString(), and yes they did, only
3726 * it returns an E_INVALIDARG error code on failure.
3727 * This is a duplicate (with changes for Unicode) of CLSIDFromString16()
3728 * in "dlls/ole32/compobj.c".
3730 HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR idstr, CLSID *id)
3738 memset(id, 0, sizeof(CLSID));
3741 else { /* validate the CLSID string */
3743 if (strlenW(s) != 38)
3744 return E_INVALIDARG;
3746 if ((s[0]!=L'{') || (s[9]!=L'-') || (s[14]!=L'-') || (s[19]!=L'-') || (s[24]!=L'-') || (s[37]!=L'}'))
3747 return E_INVALIDARG;
3749 for (i=1; i<37; i++)
3751 if ((i == 9)||(i == 14)||(i == 19)||(i == 24))
3753 if (!(((s[i] >= L'0') && (s[i] <= L'9')) ||
3754 ((s[i] >= L'a') && (s[i] <= L'f')) ||
3755 ((s[i] >= L'A') && (s[i] <= L'F')))
3757 return E_INVALIDARG;
3761 TRACE("%s -> %p\n", debugstr_w(s), id);
3763 /* quick lookup table */
3764 memset(table, 0, 256*sizeof(WCHAR));
3766 for (i = 0; i < 10; i++) {
3769 for (i = 0; i < 6; i++) {
3770 table['A' + i] = i+10;
3771 table['a' + i] = i+10;
3774 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
3778 s++; /* skip leading brace */
3779 for (i = 0; i < 4; i++) {
3780 p[3 - i] = table[*s]<<4 | table[*(s+1)];
3786 for (i = 0; i < 2; i++) {
3787 p[1-i] = table[*s]<<4 | table[*(s+1)];
3793 for (i = 0; i < 2; i++) {
3794 p[1-i] = table[*s]<<4 | table[*(s+1)];
3800 /* these are just sequential bytes */
3801 for (i = 0; i < 2; i++) {
3802 *p++ = table[*s]<<4 | table[*(s+1)];
3807 for (i = 0; i < 6; i++) {
3808 *p++ = table[*s]<<4 | table[*(s+1)];
3815 /*************************************************************************
3818 * Determine if the OS supports a given feature.
3821 * dwFeature [I] Feature requested (undocumented)
3824 * TRUE If the feature is available.
3825 * FALSE If the feature is not available.
3827 DWORD WINAPI IsOS(DWORD feature)
3829 FIXME("(0x%08lx) stub\n", feature);
3835 /*************************************************************************
3836 * ColorRGBToHLS [SHLWAPI.@]
3838 * Convert an rgb COLORREF into the hls color space.
3841 * cRGB [I] Source rgb value
3842 * pwHue [O] Destination for converted hue
3843 * pwLuminance [O] Destination for converted luminance
3844 * pwSaturation [O] Destination for converted saturation
3847 * Nothing. pwHue, pwLuminance and pwSaturation are set to the converted
3851 * Output HLS values are constrained to the range (0..240).
3852 * For Achromatic conversions, Hue is set to 160.
3854 VOID WINAPI ColorRGBToHLS(COLORREF cRGB, LPWORD pwHue,
3855 LPWORD pwLuminance, LPWORD pwSaturation)
3857 int wR, wG, wB, wMax, wMin, wHue, wLuminosity, wSaturation;
3859 TRACE("(%08lx,%p,%p,%p)\n", cRGB, pwHue, pwLuminance, pwSaturation);
3861 wR = GetRValue(cRGB);
3862 wG = GetGValue(cRGB);
3863 wB = GetBValue(cRGB);
3865 wMax = max(wR, max(wG, wB));
3866 wMin = min(wR, min(wG, wB));
3869 wLuminosity = ((wMax + wMin) * 240 + 255) / 510;
3873 /* Achromatic case */
3875 /* Hue is now unrepresentable, but this is what native returns... */
3880 /* Chromatic case */
3881 int wDelta = wMax - wMin, wRNorm, wGNorm, wBNorm;
3884 if (wLuminosity <= 120)
3885 wSaturation = ((wMax + wMin)/2 + wDelta * 240) / (wMax + wMin);
3887 wSaturation = ((510 - wMax - wMin)/2 + wDelta * 240) / (510 - wMax - wMin);
3890 wRNorm = (wDelta/2 + wMax * 40 - wR * 40) / wDelta;
3891 wGNorm = (wDelta/2 + wMax * 40 - wG * 40) / wDelta;
3892 wBNorm = (wDelta/2 + wMax * 40 - wB * 40) / wDelta;
3895 wHue = wBNorm - wGNorm;
3896 else if (wG == wMax)
3897 wHue = 80 + wRNorm - wBNorm;
3899 wHue = 160 + wGNorm - wRNorm;
3902 else if (wHue > 240)
3908 *pwLuminance = wLuminosity;
3910 *pwSaturation = wSaturation;
3913 /*************************************************************************
3914 * SHCreateShellPalette [SHLWAPI.@]
3916 HPALETTE WINAPI SHCreateShellPalette(HDC hdc)
3919 return CreateHalftonePalette(hdc);
3922 /*************************************************************************
3923 * SHGetInverseCMAP (SHLWAPI.@)
3925 * Get an inverse color map table.
3928 * lpCmap [O] Destination for color map
3929 * dwSize [I] Size of memory pointed to by lpCmap
3933 * Failure: E_POINTER, If lpCmap is invalid.
3934 * E_INVALIDARG, If dwFlags is invalid
3935 * E_OUTOFMEMORY, If there is no memory available
3938 * dwSize may only be CMAP_PTR_SIZE (4) or CMAP_SIZE (8192).
3939 * If dwSize = CMAP_PTR_SIZE, *lpCmap is set to the address of this DLL's
3941 * If dwSize = CMAP_SIZE, lpCmap is filled with a copy of the data from
3942 * this DLL's internal CMap.
3944 HRESULT WINAPI SHGetInverseCMAP(LPDWORD dest, DWORD dwSize)
3947 FIXME(" - returning bogus address for SHGetInverseCMAP\n");
3948 *dest = (DWORD)0xabba1249;
3951 FIXME("(%p, %#lx) stub\n", dest, dwSize);
3955 /*************************************************************************
3956 * SHIsLowMemoryMachine [SHLWAPI.@]
3958 * Determine if the current computer has low memory.
3964 * TRUE if the users machine has 16 Megabytes of memory or less,
3967 BOOL WINAPI SHIsLowMemoryMachine (DWORD x)
3969 FIXME("(0x%08lx) stub\n", x);
3973 /*************************************************************************
3974 * GetMenuPosFromID [SHLWAPI.@]
3976 * Return the position of a menu item from its Id.
3979 * hMenu [I] Menu containing the item
3980 * wID [I] Id of the menu item
3983 * Success: The index of the menu item in hMenu.
3984 * Failure: -1, If the item is not found.
3986 INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID)
3989 INT nCount = GetMenuItemCount(hMenu), nIter = 0;
3991 while (nIter < nCount)
3994 if (!GetMenuItemInfoA(hMenu, nIter, TRUE, &mi) && mi.wID == wID)
4001 /*************************************************************************
4002 * SHSkipJunction [SHLWAPI.@]
4004 * Determine if a bind context can be bound to an object
4007 * pbc [I] Bind context to check
4008 * pclsid [I] CLSID of object to be bound to
4011 * TRUE: If it is safe to bind
4012 * FALSE: If pbc is invalid or binding would not be safe
4015 BOOL WINAPI SHSkipJunction(IBindCtx *pbc, const CLSID *pclsid)
4017 static WCHAR szSkipBinding[] = { 'S','k','i','p',' ',
4018 'B','i','n','d','i','n','g',' ','C','L','S','I','D','\0' };
4025 if (SUCCEEDED(IBindCtx_GetObjectParam(pbc, szSkipBinding, &lpUnk)))
4029 if (SUCCEEDED(IUnknown_GetClassID(lpUnk, &clsid)) &&
4030 IsEqualGUID(pclsid, &clsid))
4033 IUnknown_Release(lpUnk);
4039 DWORD WINAPI SHGetShellKey(DWORD a, DWORD b, DWORD c)
4041 FIXME("(%lx, %lx, %lx): stub\n", a, b, c);
4045 HRESULT WINAPI SHQueueUserWorkItem(DWORD a, DWORD b, DWORD c, DWORD d, DWORD e, DWORD f, DWORD g)
4047 FIXME("(%lx, %lx, %lx, %lx, %lx, %lx, %lx): stub\n", a, b, c, d, e, f, g);
4051 DWORD WINAPI IUnknown_OnFocusChangeIS(IUnknown * pUnk, IUnknown * pFocusObject, BOOL bChange)
4053 FIXME("(%p, %p, %s)\n", pUnk, pFocusObject, bChange ? "TRUE" : "FALSE");
4056 IInputObjectSite * pIOS = NULL;
4057 if (SUCCEEDED(IUnknown_QueryInterface(pUnk, &IID_IInputObjectSite, (void **)&pIOS))
4058 IInputObjectSite_OnFocusChangeIS(pIOS, pFocusObject, bChange);
4064 HRESULT WINAPI SKGetValueW(DWORD a, LPWSTR b, LPWSTR c, DWORD d, DWORD e, DWORD f)
4066 FIXME("(%lx, %s, %s, %lx, %lx, %lx): stub\n", a, debugstr_w(b), debugstr_w(c), d, e, f);