Implement FixSlashesAndColonW and add stub for SHGetAppCompatFlags.
[wine.git] / dlls / shlwapi / ordinal.c
blob4c0766e6260152335a5e4ba0219ced9a04d10f82
1 /*
2 * SHLWAPI ordinal functions
4 * Copyright 1997 Marcus Meissner
5 * 1998 Jürgen Schmied
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
24 #include "config.h"
25 #include "wine/port.h"
27 #include <stdarg.h>
28 #include <stdio.h>
29 #include <string.h>
31 #define NONAMELESSUNION
32 #define NONAMELESSSTRUCT
33 #include "windef.h"
34 #include "winbase.h"
35 #include "winuser.h"
36 #include "winnls.h"
37 #include "docobj.h"
38 #include "exdisp.h"
39 #include "shlguid.h"
40 #include "wingdi.h"
41 #include "shlobj.h"
42 #include "olectl.h"
43 #include "shellapi.h"
44 #include "commdlg.h"
45 #include "wine/unicode.h"
46 #include "servprov.h"
47 #include "winreg.h"
48 #include "wine/debug.h"
49 #include "shlwapi.h"
52 WINE_DEFAULT_DEBUG_CHANNEL(shell);
54 /* Get a function pointer from a DLL handle */
55 #define GET_FUNC(func, module, name, fail) \
56 do { \
57 if (!func) { \
58 if (!SHLWAPI_h##module && !(SHLWAPI_h##module = LoadLibraryA(#module ".dll"))) return fail; \
59 func = (fn##func)GetProcAddress(SHLWAPI_h##module, name); \
60 if (!func) return fail; \
61 } \
62 } while (0)
64 /* DLL handles for late bound calls */
65 extern HINSTANCE shlwapi_hInstance;
66 extern HMODULE SHLWAPI_hshell32;
67 extern HMODULE SHLWAPI_hwinmm;
68 extern HMODULE SHLWAPI_hcomdlg32;
69 extern HMODULE SHLWAPI_hcomctl32;
70 extern HMODULE SHLWAPI_hmpr;
71 extern HMODULE SHLWAPI_hurlmon;
72 extern HMODULE SHLWAPI_hversion;
74 extern DWORD SHLWAPI_ThreadRef_index;
76 typedef HANDLE HSHARED; /* Shared memory */
78 /* following is GUID for IObjectWithSite::SetSite -- see _174 */
79 static DWORD id1[4] = {0xfc4801a3, 0x11cf2ba9, 0xaa0029a2, 0x52733d00};
80 /* following is GUID for IPersistMoniker::GetClassID -- see _174 */
81 static DWORD id2[4] = {0x79eac9ee, 0x11cebaf9, 0xaa00828c, 0x0ba94b00};
83 /* Function pointers for GET_FUNC macro; these need to be global because of gcc bug */
84 typedef LPITEMIDLIST (WINAPI *fnpSHBrowseForFolderW)(LPBROWSEINFOW);
85 static fnpSHBrowseForFolderW pSHBrowseForFolderW;
86 typedef BOOL (WINAPI *fnpPlaySoundW)(LPCWSTR, HMODULE, DWORD);
87 static fnpPlaySoundW pPlaySoundW;
88 typedef DWORD (WINAPI *fnpSHGetFileInfoW)(LPCWSTR,DWORD,SHFILEINFOW*,UINT,UINT);
89 static fnpSHGetFileInfoW pSHGetFileInfoW;
90 typedef UINT (WINAPI *fnpDragQueryFileW)(HDROP, UINT, LPWSTR, UINT);
91 static fnpDragQueryFileW pDragQueryFileW;
92 typedef BOOL (WINAPI *fnpSHGetPathFromIDListW)(LPCITEMIDLIST, LPWSTR);
93 static fnpSHGetPathFromIDListW pSHGetPathFromIDListW;
94 typedef BOOL (WINAPI *fnpShellExecuteExW)(LPSHELLEXECUTEINFOW);
95 static fnpShellExecuteExW pShellExecuteExW;
96 typedef HICON (WINAPI *fnpSHFileOperationW)(LPSHFILEOPSTRUCTW);
97 static fnpSHFileOperationW pSHFileOperationW;
98 typedef UINT (WINAPI *fnpExtractIconExW)(LPCWSTR, INT,HICON *,HICON *, UINT);
99 static fnpExtractIconExW pExtractIconExW;
100 typedef BOOL (WINAPI *fnpSHGetNewLinkInfoW)(LPCWSTR, LPCWSTR, LPCWSTR, BOOL*, UINT);
101 static fnpSHGetNewLinkInfoW pSHGetNewLinkInfoW;
102 typedef HRESULT (WINAPI *fnpSHDefExtractIconW)(LPCWSTR, int, UINT, HICON*, HICON*, UINT);
103 static fnpSHDefExtractIconW pSHDefExtractIconW;
104 typedef HICON (WINAPI *fnpExtractIconW)(HINSTANCE, LPCWSTR, UINT);
105 static fnpExtractIconW pExtractIconW;
106 typedef BOOL (WINAPI *fnpGetSaveFileNameW)(LPOPENFILENAMEW);
107 static fnpGetSaveFileNameW pGetSaveFileNameW;
108 typedef DWORD (WINAPI *fnpWNetRestoreConnectionW)(HWND, LPWSTR);
109 static fnpWNetRestoreConnectionW pWNetRestoreConnectionW;
110 typedef DWORD (WINAPI *fnpWNetGetLastErrorW)(LPDWORD, LPWSTR, DWORD, LPWSTR, DWORD);
111 static fnpWNetGetLastErrorW pWNetGetLastErrorW;
112 typedef BOOL (WINAPI *fnpPageSetupDlgW)(LPPAGESETUPDLGW);
113 static fnpPageSetupDlgW pPageSetupDlgW;
114 typedef BOOL (WINAPI *fnpPrintDlgW)(LPPRINTDLGW);
115 static fnpPrintDlgW pPrintDlgW;
116 typedef BOOL (WINAPI *fnpGetOpenFileNameW)(LPOPENFILENAMEW);
117 static fnpGetOpenFileNameW pGetOpenFileNameW;
118 typedef DWORD (WINAPI *fnpGetFileVersionInfoSizeW)(LPCWSTR,LPDWORD);
119 static fnpGetFileVersionInfoSizeW pGetFileVersionInfoSizeW;
120 typedef BOOL (WINAPI *fnpGetFileVersionInfoW)(LPCWSTR,DWORD,DWORD,LPVOID);
121 static fnpGetFileVersionInfoW pGetFileVersionInfoW;
122 typedef WORD (WINAPI *fnpVerQueryValueW)(LPVOID,LPCWSTR,LPVOID*,UINT*);
123 static fnpVerQueryValueW pVerQueryValueW;
124 typedef BOOL (WINAPI *fnpCOMCTL32_417)(HDC,INT,INT,UINT,const RECT*,LPCWSTR,UINT,const INT*);
125 static fnpCOMCTL32_417 pCOMCTL32_417;
126 typedef HRESULT (WINAPI *fnpDllGetVersion)(DLLVERSIONINFO*);
127 static fnpDllGetVersion pDllGetVersion;
128 typedef HRESULT (WINAPI *fnpCreateFormatEnumerator)(UINT,FORMATETC*,IEnumFORMATETC**);
129 static fnpCreateFormatEnumerator pCreateFormatEnumerator;
130 typedef HRESULT (WINAPI *fnpRegisterFormatEnumerator)(LPBC,IEnumFORMATETC*,DWORD);
131 static fnpRegisterFormatEnumerator pRegisterFormatEnumerator;
133 HRESULT WINAPI IUnknown_QueryService(IUnknown*,REFGUID,REFIID,LPVOID*);
134 HRESULT WINAPI SHInvokeCommand(HWND,IShellFolder*,LPCITEMIDLIST,BOOL);
135 HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR,CLSID*);
136 BOOL WINAPI SHAboutInfoW(LPWSTR,DWORD);
139 NOTES: Most functions exported by ordinal seem to be superflous.
140 The reason for these functions to be there is to provide a wrapper
141 for unicode functions to provide these functions on systems without
142 unicode functions eg. win95/win98. Since we have such functions we just
143 call these. If running Wine with native DLL's, some late bound calls may
144 fail. However, its better to implement the functions in the forward DLL
145 and recommend the builtin rather than reimplementing the calls here!
148 /*************************************************************************
149 * SHLWAPI_DupSharedHandle
151 * Internal implemetation of SHLWAPI_11.
153 static
154 HSHARED WINAPI SHLWAPI_DupSharedHandle(HSHARED hShared, DWORD dwDstProcId,
155 DWORD dwSrcProcId, DWORD dwAccess,
156 DWORD dwOptions)
158 HANDLE hDst, hSrc;
159 DWORD dwMyProcId = GetCurrentProcessId();
160 HSHARED hRet = (HSHARED)NULL;
162 TRACE("(%p,%ld,%ld,%08lx,%08lx)\n", (PVOID)hShared, dwDstProcId, dwSrcProcId,
163 dwAccess, dwOptions);
165 /* Get dest process handle */
166 if (dwDstProcId == dwMyProcId)
167 hDst = GetCurrentProcess();
168 else
169 hDst = OpenProcess(PROCESS_DUP_HANDLE, 0, dwDstProcId);
171 if (hDst)
173 /* Get src process handle */
174 if (dwSrcProcId == dwMyProcId)
175 hSrc = GetCurrentProcess();
176 else
177 hSrc = OpenProcess(PROCESS_DUP_HANDLE, 0, dwSrcProcId);
179 if (hSrc)
181 /* Make handle available to dest process */
182 if (!DuplicateHandle(hDst, (HANDLE)hShared, hSrc, &hRet,
183 dwAccess, 0, dwOptions | DUPLICATE_SAME_ACCESS))
184 hRet = (HSHARED)NULL;
186 if (dwSrcProcId != dwMyProcId)
187 CloseHandle(hSrc);
190 if (dwDstProcId != dwMyProcId)
191 CloseHandle(hDst);
194 TRACE("Returning handle %p\n", (PVOID)hRet);
195 return hRet;
198 /*************************************************************************
199 * @ [SHLWAPI.7]
201 * Create a block of sharable memory and initialise it with data.
203 * PARAMS
204 * dwProcId [I] ID of process owning data
205 * lpvData [I] Pointer to data to write
206 * dwSize [I] Size of data
208 * RETURNS
209 * Success: A shared memory handle
210 * Failure: NULL
212 * NOTES
213 * Ordinals 7-11 provide a set of calls to create shared memory between a
214 * group of processes. The shared memory is treated opaquely in that its size
215 * is not exposed to clients who map it. This is accomplished by storing
216 * the size of the map as the first DWORD of mapped data, and then offsetting
217 * the view pointer returned by this size.
220 HSHARED WINAPI SHAllocShared(DWORD dwProcId, DWORD dwSize, LPCVOID lpvData)
222 HANDLE hMap;
223 LPVOID pMapped;
224 HSHARED hRet = (HSHARED)NULL;
226 TRACE("(%ld,%p,%ld)\n", dwProcId, lpvData, dwSize);
228 /* Create file mapping of the correct length */
229 hMap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, FILE_MAP_READ, 0,
230 dwSize + sizeof(dwSize), NULL);
231 if (!hMap)
232 return hRet;
234 /* Get a view in our process address space */
235 pMapped = MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
237 if (pMapped)
239 /* Write size of data, followed by the data, to the view */
240 *((DWORD*)pMapped) = dwSize;
241 if (dwSize)
242 memcpy((char *) pMapped + sizeof(dwSize), lpvData, dwSize);
244 /* Release view. All further views mapped will be opaque */
245 UnmapViewOfFile(pMapped);
246 hRet = SHLWAPI_DupSharedHandle((HSHARED)hMap, dwProcId,
247 GetCurrentProcessId(), FILE_MAP_ALL_ACCESS,
248 DUPLICATE_SAME_ACCESS);
251 CloseHandle(hMap);
252 return hRet;
255 /*************************************************************************
256 * @ [SHLWAPI.8]
258 * Get a pointer to a block of shared memory from a shared memory handle.
260 * PARAMS
261 * hShared [I] Shared memory handle
262 * dwProcId [I] ID of process owning hShared
264 * RETURNS
265 * Success: A pointer to the shared memory
266 * Failure: NULL
269 PVOID WINAPI SHLockShared(HSHARED hShared, DWORD dwProcId)
271 HSHARED hDup;
272 LPVOID pMapped;
274 TRACE("(%p %ld)\n", (PVOID)hShared, dwProcId);
276 /* Get handle to shared memory for current process */
277 hDup = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
278 FILE_MAP_ALL_ACCESS, 0);
279 /* Get View */
280 pMapped = MapViewOfFile((HANDLE)hDup, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
281 CloseHandle(hDup);
283 if (pMapped)
284 return (char *) pMapped + sizeof(DWORD); /* Hide size */
285 return NULL;
288 /*************************************************************************
289 * @ [SHLWAPI.9]
291 * Release a pointer to a block of shared memory.
293 * PARAMS
294 * lpView [I] Shared memory pointer
296 * RETURNS
297 * Success: TRUE
298 * Failure: FALSE
301 BOOL WINAPI SHUnlockShared(LPVOID lpView)
303 TRACE("(%p)\n", lpView);
304 return UnmapViewOfFile((char *) lpView - sizeof(DWORD)); /* Include size */
307 /*************************************************************************
308 * @ [SHLWAPI.10]
310 * Destroy a block of sharable memory.
312 * PARAMS
313 * hShared [I] Shared memory handle
314 * dwProcId [I] ID of process owning hShared
316 * RETURNS
317 * Success: TRUE
318 * Failure: FALSE
321 BOOL WINAPI SHFreeShared(HSHARED hShared, DWORD dwProcId)
323 HSHARED hClose;
325 TRACE("(%p %ld)\n", (PVOID)hShared, dwProcId);
327 /* Get a copy of the handle for our process, closing the source handle */
328 hClose = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
329 FILE_MAP_ALL_ACCESS,DUPLICATE_CLOSE_SOURCE);
330 /* Close local copy */
331 return CloseHandle((HANDLE)hClose);
334 /*************************************************************************
335 * @ [SHLWAPI.11]
337 * Copy a sharable memory handle from one process to another.
339 * PARAMS
340 * hShared [I] Shared memory handle to duplicate
341 * dwDstProcId [I] ID of the process wanting the duplicated handle
342 * dwSrcProcId [I] ID of the process owning hShared
343 * dwAccess [I] Desired DuplicateHandle() access
344 * dwOptions [I] Desired DuplicateHandle() options
346 * RETURNS
347 * Success: A handle suitable for use by the dwDstProcId process.
348 * Failure: A NULL handle.
351 HSHARED WINAPI SHMapHandle(HSHARED hShared, DWORD dwDstProcId, DWORD dwSrcProcId,
352 DWORD dwAccess, DWORD dwOptions)
354 HSHARED hRet;
356 hRet = SHLWAPI_DupSharedHandle(hShared, dwDstProcId, dwSrcProcId,
357 dwAccess, dwOptions);
358 return hRet;
361 /*************************************************************************
362 * @ [SHLWAPI.13]
364 * Create and register a clipboard enumerator for a web browser.
366 * PARAMS
367 * lpBC [I] Binding context
368 * lpUnknown [I] An object exposing the IWebBrowserApp interface
370 * RETURNS
371 * Success: S_OK.
372 * Failure: An HRESULT error code.
374 * NOTES
375 * The enumerator is stored as a property of the web browser. If it does not
376 * yet exist, it is created and set before being registered.
378 HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown)
380 static const WCHAR szProperty[] = { '{','D','0','F','C','A','4','2','0',
381 '-','D','3','F','5','-','1','1','C','F', '-','B','2','1','1','-','0',
382 '0','A','A','0','0','4','A','E','8','3','7','}','\0' };
383 IEnumFORMATETC* pIEnumFormatEtc = NULL;
384 VARIANTARG var;
385 HRESULT hRet;
386 IWebBrowserApp* pBrowser = NULL;
388 TRACE("(%p, %p)\n", lpBC, lpUnknown);
390 /* Get An IWebBrowserApp interface from lpUnknown */
391 hRet = IUnknown_QueryService(lpUnknown, &IID_IWebBrowserApp, &IID_IWebBrowserApp, (PVOID)&pBrowser);
392 if (FAILED(hRet) || !pBrowser)
393 return E_NOINTERFACE;
395 V_VT(&var) = VT_EMPTY;
397 /* The property we get is the browsers clipboard enumerator */
398 hRet = IWebBrowserApp_GetProperty(pBrowser, (BSTR)szProperty, &var);
399 if (FAILED(hRet))
400 return hRet;
402 if (V_VT(&var) == VT_EMPTY)
404 /* Iterate through accepted documents and RegisterClipBoardFormatA() them */
405 char szKeyBuff[128], szValueBuff[128];
406 DWORD dwKeySize, dwValueSize, dwRet = 0, dwCount = 0, dwNumValues, dwType;
407 FORMATETC* formatList, *format;
408 HKEY hDocs;
410 TRACE("Registering formats and creating IEnumFORMATETC instance\n");
412 if (!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\Current"
413 "Version\\Internet Settings\\Accepted Documents", &hDocs))
414 return E_FAIL;
416 /* Get count of values in key */
417 while (!dwRet)
419 dwKeySize = sizeof(szKeyBuff);
420 dwRet = RegEnumValueA(hDocs,dwCount,szKeyBuff,&dwKeySize,0,&dwType,0,0);
421 dwCount++;
424 dwNumValues = dwCount;
426 /* Note: dwCount = number of items + 1; The extra item is the end node */
427 format = formatList = HeapAlloc(GetProcessHeap(), 0, dwCount * sizeof(FORMATETC));
428 if (!formatList)
429 return E_OUTOFMEMORY;
431 if (dwNumValues > 1)
433 dwRet = 0;
434 dwCount = 0;
436 dwNumValues--;
438 /* Register clipboard formats for the values and populate format list */
439 while(!dwRet && dwCount < dwNumValues)
441 dwKeySize = sizeof(szKeyBuff);
442 dwValueSize = sizeof(szValueBuff);
443 dwRet = RegEnumValueA(hDocs, dwCount, szKeyBuff, &dwKeySize, 0, &dwType,
444 (PBYTE)szValueBuff, &dwValueSize);
445 if (!dwRet)
446 return E_FAIL;
448 format->cfFormat = RegisterClipboardFormatA(szValueBuff);
449 format->ptd = NULL;
450 format->dwAspect = 1;
451 format->lindex = 4;
452 format->tymed = -1;
454 format++;
455 dwCount++;
459 /* Terminate the (maybe empty) list, last entry has a cfFormat of 0 */
460 format->cfFormat = 0;
461 format->ptd = NULL;
462 format->dwAspect = 1;
463 format->lindex = 4;
464 format->tymed = -1;
466 /* Create a clipboard enumerator */
467 GET_FUNC(pCreateFormatEnumerator, urlmon, "CreateFormatEnumerator", E_FAIL);
468 hRet = pCreateFormatEnumerator(dwNumValues, formatList, &pIEnumFormatEtc);
470 if (FAILED(hRet) || !pIEnumFormatEtc)
471 return hRet;
473 /* Set our enumerator as the browsers property */
474 V_VT(&var) = VT_UNKNOWN;
475 V_UNKNOWN(&var) = (IUnknown*)pIEnumFormatEtc;
477 hRet = IWebBrowserApp_PutProperty(pBrowser, (BSTR)szProperty, var);
478 if (FAILED(hRet))
480 IEnumFORMATETC_Release(pIEnumFormatEtc);
481 goto RegisterDefaultAcceptHeaders_Exit;
485 if (V_VT(&var) == VT_UNKNOWN)
487 /* Our variant is holding the clipboard enumerator */
488 IUnknown* pIUnknown = V_UNKNOWN(&var);
489 IEnumFORMATETC* pClone = NULL;
491 TRACE("Retrieved IEnumFORMATETC property\n");
493 /* Get an IEnumFormatEtc interface from the variants value */
494 pIEnumFormatEtc = NULL;
495 hRet = IUnknown_QueryInterface(pIUnknown, &IID_IEnumFORMATETC,
496 (PVOID)&pIEnumFormatEtc);
497 if (!hRet && pIEnumFormatEtc)
499 /* Clone and register the enumerator */
500 hRet = IEnumFORMATETC_Clone(pIEnumFormatEtc, &pClone);
501 if (!hRet && pClone)
503 GET_FUNC(pRegisterFormatEnumerator, urlmon, "RegisterFormatEnumerator", E_FAIL);
504 pRegisterFormatEnumerator(lpBC, pClone, 0);
506 IEnumFORMATETC_Release(pClone);
509 /* Release the IEnumFormatEtc interface */
510 IEnumFORMATETC_Release(pIUnknown);
512 IUnknown_Release(V_UNKNOWN(&var));
515 RegisterDefaultAcceptHeaders_Exit:
516 IWebBrowserApp_Release(pBrowser);
517 return hRet;
520 /*************************************************************************
521 * @ [SHLWAPI.14]
523 * Get Explorers "AcceptLanguage" setting.
525 * PARAMS
526 * langbuf [O] Destination for language string
527 * buflen [I] Length of langbuf
529 * RETURNS
530 * Success: S_OK. langbuf is set to the language string found.
531 * Failure: E_FAIL, If any arguments are invalid, error occurred, or Explorer
532 * does not contain the setting.
534 HRESULT WINAPI GetAcceptLanguagesA(
535 LPSTR langbuf,
536 LPDWORD buflen)
538 CHAR *mystr;
539 DWORD mystrlen, mytype;
540 HKEY mykey;
541 LCID mylcid;
543 mystrlen = (*buflen > 6) ? *buflen : 6;
544 mystr = (CHAR*)HeapAlloc(GetProcessHeap(),
545 HEAP_ZERO_MEMORY, mystrlen);
546 RegOpenKeyA(HKEY_CURRENT_USER,
547 "Software\\Microsoft\\Internet Explorer\\International",
548 &mykey);
549 if (RegQueryValueExA(mykey, "AcceptLanguage",
550 0, &mytype, (PBYTE)mystr, &mystrlen)) {
551 /* Did not find value */
552 mylcid = GetUserDefaultLCID();
553 /* somehow the mylcid translates into "en-us"
554 * this is similar to "LOCALE_SABBREVLANGNAME"
555 * which could be gotten via GetLocaleInfo.
556 * The only problem is LOCALE_SABBREVLANGUAGE" is
557 * a 3 char string (first 2 are country code and third is
558 * letter for "sublanguage", which does not come close to
559 * "en-us"
561 lstrcpyA(mystr, "en-us");
562 mystrlen = lstrlenA(mystr);
564 else {
565 /* handle returned string */
566 FIXME("missing code\n");
568 if (mystrlen > *buflen)
569 lstrcpynA(langbuf, mystr, *buflen);
570 else {
571 lstrcpyA(langbuf, mystr);
572 *buflen = lstrlenA(langbuf);
574 RegCloseKey(mykey);
575 HeapFree(GetProcessHeap(), 0, mystr);
576 TRACE("language is %s\n", debugstr_a(langbuf));
577 return 0;
580 /*************************************************************************
581 * @ [SHLWAPI.15]
583 * Unicode version of GetAcceptLanguagesA.
585 HRESULT WINAPI GetAcceptLanguagesW(
586 LPWSTR langbuf,
587 LPDWORD buflen)
589 CHAR *mystr;
590 DWORD mystrlen, mytype;
591 HKEY mykey;
592 LCID mylcid;
594 mystrlen = (*buflen > 6) ? *buflen : 6;
595 mystr = (CHAR*)HeapAlloc(GetProcessHeap(),
596 HEAP_ZERO_MEMORY, mystrlen);
597 RegOpenKeyA(HKEY_CURRENT_USER,
598 "Software\\Microsoft\\Internet Explorer\\International",
599 &mykey);
600 if (RegQueryValueExA(mykey, "AcceptLanguage",
601 0, &mytype, (PBYTE)mystr, &mystrlen)) {
602 /* Did not find value */
603 mylcid = GetUserDefaultLCID();
604 /* somehow the mylcid translates into "en-us"
605 * this is similar to "LOCALE_SABBREVLANGNAME"
606 * which could be gotten via GetLocaleInfo.
607 * The only problem is LOCALE_SABBREVLANGUAGE" is
608 * a 3 char string (first 2 are country code and third is
609 * letter for "sublanguage", which does not come close to
610 * "en-us"
612 lstrcpyA(mystr, "en-us");
613 mystrlen = lstrlenA(mystr);
615 else {
616 /* handle returned string */
617 FIXME("missing code\n");
619 RegCloseKey(mykey);
620 *buflen = MultiByteToWideChar(0, 0, mystr, -1, langbuf, (*buflen)-1);
621 HeapFree(GetProcessHeap(), 0, mystr);
622 TRACE("language is %s\n", debugstr_w(langbuf));
623 return 0;
626 /*************************************************************************
627 * @ [SHLWAPI.23]
629 * Convert a GUID to a string.
631 * PARAMS
632 * guid [I] GUID to convert
633 * str [O] Destination for string
634 * cmax [I] Length of output buffer
636 * RETURNS
637 * The length of the string created.
639 INT WINAPI SHStringFromGUIDA(REFGUID guid, LPSTR lpszDest, INT cchMax)
641 char xguid[40];
642 INT iLen;
644 TRACE("(%s,%p,%d)\n", debugstr_guid(guid), lpszDest, cchMax);
646 sprintf(xguid, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
647 guid->Data1, guid->Data2, guid->Data3,
648 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
649 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
651 iLen = strlen(xguid) + 1;
653 if (iLen > cchMax)
654 return 0;
655 memcpy(lpszDest, xguid, iLen);
656 return iLen;
659 /*************************************************************************
660 * @ [SHLWAPI.24]
662 * Unicode version of SHStringFromGUIDA.
664 INT WINAPI SHStringFromGUIDW(REFGUID guid, LPWSTR lpszDest, INT cchMax)
666 char xguid[40];
667 INT iLen = SHStringFromGUIDA(guid, xguid, cchMax);
669 if (iLen)
670 MultiByteToWideChar(CP_ACP, 0, xguid, -1, lpszDest, cchMax);
671 return iLen;
674 /*************************************************************************
675 * @ [SHLWAPI.25]
677 * Determine if a Unicode character is alphabetic.
679 * PARAMS
680 * wc [I] Character to check.
682 * RETURNS
683 * TRUE, if wc is alphabetic,
684 * FALSE otherwise.
686 BOOL WINAPI IsCharAlphaWrapW(WCHAR wc)
688 return (get_char_typeW(wc) & C1_ALPHA) != 0;
691 /*************************************************************************
692 * @ [SHLWAPI.26]
694 * Determine if a Unicode character is upper-case.
696 * PARAMS
697 * wc [I] Character to check.
699 * RETURNS
700 * TRUE, if wc is upper-case,
701 * FALSE otherwise.
703 BOOL WINAPI IsCharUpperWrapW(WCHAR wc)
705 return (get_char_typeW(wc) & C1_UPPER) != 0;
708 /*************************************************************************
709 * @ [SHLWAPI.27]
711 * Determine if a Unicode character is lower-case.
713 * PARAMS
714 * wc [I] Character to check.
716 * RETURNS
717 * TRUE, if wc is lower-case,
718 * FALSE otherwise.
720 BOOL WINAPI IsCharLowerWrapW(WCHAR wc)
722 return (get_char_typeW(wc) & C1_LOWER) != 0;
725 /*************************************************************************
726 * @ [SHLWAPI.28]
728 * Determine if a Unicode character is alphabetic or a digit.
730 * PARAMS
731 * wc [I] Character to check.
733 * RETURNS
734 * TRUE, if wc is alphabetic or a digit,
735 * FALSE otherwise.
737 BOOL WINAPI IsCharAlphaNumericWrapW(WCHAR wc)
739 return (get_char_typeW(wc) & (C1_ALPHA|C1_DIGIT)) != 0;
742 /*************************************************************************
743 * @ [SHLWAPI.29]
745 * Determine if a Unicode character is a space.
747 * PARAMS
748 * wc [I] Character to check.
750 * RETURNS
751 * TRUE, if wc is a space,
752 * FALSE otherwise.
754 BOOL WINAPI IsCharSpaceW(WCHAR wc)
756 return (get_char_typeW(wc) & C1_SPACE) != 0;
759 /*************************************************************************
760 * @ [SHLWAPI.30]
762 * Determine if a Unicode character is a blank.
764 * PARAMS
765 * wc [I] Character to check.
767 * RETURNS
768 * TRUE, if wc is a blank,
769 * FALSE otherwise.
772 BOOL WINAPI IsCharBlankW(WCHAR wc)
774 return (get_char_typeW(wc) & C1_BLANK) != 0;
777 /*************************************************************************
778 * @ [SHLWAPI.31]
780 * Determine if a Unicode character is punctuation.
782 * PARAMS
783 * wc [I] Character to check.
785 * RETURNS
786 * TRUE, if wc is punctuation,
787 * FALSE otherwise.
789 BOOL WINAPI IsCharPunctW(WCHAR wc)
791 return (get_char_typeW(wc) & C1_PUNCT) != 0;
794 /*************************************************************************
795 * @ [SHLWAPI.32]
797 * Determine if a Unicode character is a control character.
799 * PARAMS
800 * wc [I] Character to check.
802 * RETURNS
803 * TRUE, if wc is a control character,
804 * FALSE otherwise.
806 BOOL WINAPI IsCharCntrlW(WCHAR wc)
808 return (get_char_typeW(wc) & C1_CNTRL) != 0;
811 /*************************************************************************
812 * @ [SHLWAPI.33]
814 * Determine if a Unicode character is a digit.
816 * PARAMS
817 * wc [I] Character to check.
819 * RETURNS
820 * TRUE, if wc is a digit,
821 * FALSE otherwise.
823 BOOL WINAPI IsCharDigitW(WCHAR wc)
825 return (get_char_typeW(wc) & C1_DIGIT) != 0;
828 /*************************************************************************
829 * @ [SHLWAPI.34]
831 * Determine if a Unicode character is a hex digit.
833 * PARAMS
834 * wc [I] Character to check.
836 * RETURNS
837 * TRUE, if wc is a hex digit,
838 * FALSE otherwise.
840 BOOL WINAPI IsCharXDigitW(WCHAR wc)
842 return (get_char_typeW(wc) & C1_XDIGIT) != 0;
845 /*************************************************************************
846 * @ [SHLWAPI.35]
849 BOOL WINAPI GetStringType3ExW(LPWSTR lpszStr, DWORD dwLen, LPVOID p3)
851 FIXME("(%s,0x%08lx,%p): stub\n", debugstr_w(lpszStr), dwLen, p3);
852 return TRUE;
855 /*************************************************************************
856 * @ [SHLWAPI.36]
858 * Insert a bitmap menu item at the bottom of a menu.
860 * PARAMS
861 * hMenu [I] Menu to insert into
862 * flags [I] Flags for insertion
863 * id [I] Menu ID of the item
864 * str [I] Menu text for the item
866 * RETURNS
867 * Success: TRUE, the item is inserted into the menu
868 * Failure: FALSE, if any parameter is invalid
870 BOOL WINAPI AppendMenuWrapW(HMENU hMenu, UINT flags, UINT id, LPCWSTR str)
872 TRACE("(%p,0x%08x,0x%08x,%s)\n",hMenu, flags, id, debugstr_w(str));
873 return InsertMenuW(hMenu, -1, flags | MF_BITMAP, id, str);
876 /*************************************************************************
877 * @ [SHLWAPI.74]
879 * Get the text from a given dialog item.
881 * PARAMS
882 * hWnd [I] Handle of dialog
883 * nItem [I] Index of item
884 * lpsDest [O] Buffer for receiving window text
885 * nDestLen [I] Length of buffer.
887 * RETURNS
888 * Success: The length of the returned text.
889 * Failure: 0.
891 INT WINAPI GetDlgItemTextWrapW(HWND hWnd, INT nItem, LPWSTR lpsDest,INT nDestLen)
893 HWND hItem = GetDlgItem(hWnd, nItem);
895 if (hItem)
896 return GetWindowTextW(hItem, lpsDest, nDestLen);
897 if (nDestLen)
898 *lpsDest = (WCHAR)'\0';
899 return 0;
902 /*************************************************************************
903 * @ [SHLWAPI.138]
905 * Set the text of a given dialog item.
907 * PARAMS
908 * hWnd [I] Handle of dialog
909 * iItem [I] Index of item
910 * lpszText [O] Text to set
912 * RETURNS
913 * Success: TRUE. The text of the dialog is set to lpszText.
914 * Failure: FALSE, Otherwise.
916 BOOL WINAPI SetDlgItemTextWrapW(HWND hWnd, INT iItem, LPCWSTR lpszText)
918 HWND hWndItem = GetDlgItem(hWnd, iItem);
919 if (hWndItem)
920 return SetWindowTextW(hWndItem, lpszText);
921 return FALSE;
924 /*************************************************************************
925 * @ [SHLWAPI.151]
927 * Compare two Ascii strings up to a given length.
929 * PARAMS
930 * lpszSrc [I] Source string
931 * lpszCmp [I] String to compare to lpszSrc
932 * len [I] Maximum length
934 * RETURNS
935 * A number greater than, less than or equal to 0 depending on whether
936 * lpszSrc is greater than, less than or equal to lpszCmp.
938 DWORD WINAPI StrCmpNCA(LPCSTR lpszSrc, LPCSTR lpszCmp, INT len)
940 return strncmp(lpszSrc, lpszCmp, len);
943 /*************************************************************************
944 * @ [SHLWAPI.152]
946 * Unicode version of StrCmpNCA.
948 DWORD WINAPI StrCmpNCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, INT len)
950 return strncmpW(lpszSrc, lpszCmp, len);
953 /*************************************************************************
954 * @ [SHLWAPI.153]
956 * Compare two Ascii strings up to a given length, ignoring case.
958 * PARAMS
959 * lpszSrc [I] Source string
960 * lpszCmp [I] String to compare to lpszSrc
961 * len [I] Maximum length
963 * RETURNS
964 * A number greater than, less than or equal to 0 depending on whether
965 * lpszSrc is greater than, less than or equal to lpszCmp.
967 DWORD WINAPI StrCmpNICA(LPCSTR lpszSrc, LPCSTR lpszCmp, DWORD len)
969 return strncasecmp(lpszSrc, lpszCmp, len);
972 /*************************************************************************
973 * @ [SHLWAPI.154]
975 * Unicode version of StrCmpNICA.
977 DWORD WINAPI StrCmpNICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, DWORD len)
979 return strncmpiW(lpszSrc, lpszCmp, len);
982 /*************************************************************************
983 * @ [SHLWAPI.155]
985 * Compare two Ascii strings.
987 * PARAMS
988 * lpszSrc [I] Source string
989 * lpszCmp [I] String to compare to lpszSrc
991 * RETURNS
992 * A number greater than, less than or equal to 0 depending on whether
993 * lpszSrc is greater than, less than or equal to lpszCmp.
995 DWORD WINAPI StrCmpCA(LPCSTR lpszSrc, LPCSTR lpszCmp)
997 return strcmp(lpszSrc, lpszCmp);
1000 /*************************************************************************
1001 * @ [SHLWAPI.156]
1003 * Unicode version of StrCmpCA.
1005 DWORD WINAPI StrCmpCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp)
1007 return strcmpW(lpszSrc, lpszCmp);
1010 /*************************************************************************
1011 * @ [SHLWAPI.157]
1013 * Compare two Ascii strings, ignoring case.
1015 * PARAMS
1016 * lpszSrc [I] Source string
1017 * lpszCmp [I] String to compare to lpszSrc
1019 * RETURNS
1020 * A number greater than, less than or equal to 0 depending on whether
1021 * lpszSrc is greater than, less than or equal to lpszCmp.
1023 DWORD WINAPI StrCmpICA(LPCSTR lpszSrc, LPCSTR lpszCmp)
1025 return strcasecmp(lpszSrc, lpszCmp);
1028 /*************************************************************************
1029 * @ [SHLWAPI.158]
1031 * Unicode version of StrCmpICA.
1033 DWORD WINAPI StrCmpICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp)
1035 return strcmpiW(lpszSrc, lpszCmp);
1038 /*************************************************************************
1039 * @ [SHLWAPI.160]
1041 * Get an identification string for the OS and explorer.
1043 * PARAMS
1044 * lpszDest [O] Destination for Id string
1045 * dwDestLen [I] Length of lpszDest
1047 * RETURNS
1048 * TRUE, If the string was created successfully
1049 * FALSE, Otherwise
1051 BOOL WINAPI SHAboutInfoA(LPSTR lpszDest, DWORD dwDestLen)
1053 WCHAR buff[2084];
1055 TRACE("(%p,%ld)\n", lpszDest, dwDestLen);
1057 if (lpszDest && SHAboutInfoW(buff, dwDestLen))
1059 WideCharToMultiByte(CP_ACP, 0, buff, -1, lpszDest, dwDestLen, NULL, NULL);
1060 return TRUE;
1062 return FALSE;
1065 /*************************************************************************
1066 * @ [SHLWAPI.161]
1068 * Unicode version of SHAboutInfoA.
1070 BOOL WINAPI SHAboutInfoW(LPWSTR lpszDest, DWORD dwDestLen)
1072 static const WCHAR szIEKey[] = { 'S','O','F','T','W','A','R','E','\\',
1073 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
1074 ' ','E','x','p','l','o','r','e','r','\0' };
1075 static const WCHAR szWinNtKey[] = { 'S','O','F','T','W','A','R','E','\\',
1076 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s',' ',
1077 'N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
1078 static const WCHAR szWinKey[] = { 'S','O','F','T','W','A','R','E','\\',
1079 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
1080 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
1081 static const WCHAR szRegKey[] = { 'S','O','F','T','W','A','R','E','\\',
1082 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
1083 ' ','E','x','p','l','o','r','e','r','\\',
1084 'R','e','g','i','s','t','r','a','t','i','o','n','\0' };
1085 static const WCHAR szVersion[] = { 'V','e','r','s','i','o','n','\0' };
1086 static const WCHAR szCustomized[] = { 'C','u','s','t','o','m','i','z','e','d',
1087 'V','e','r','s','i','o','n','\0' };
1088 static const WCHAR szOwner[] = { 'R','e','g','i','s','t','e','r','e','d',
1089 'O','w','n','e','r','\0' };
1090 static const WCHAR szOrg[] = { 'R','e','g','i','s','t','e','r','e','d',
1091 'O','r','g','a','n','i','z','a','t','i','o','n','\0' };
1092 static const WCHAR szProduct[] = { 'P','r','o','d','u','c','t','I','d','\0' };
1093 static const WCHAR szUpdate[] = { 'I','E','A','K',
1094 'U','p','d','a','t','e','U','r','l','\0' };
1095 static const WCHAR szHelp[] = { 'I','E','A','K',
1096 'H','e','l','p','S','t','r','i','n','g','\0' };
1097 WCHAR buff[2084];
1098 HKEY hReg;
1099 DWORD dwType, dwLen;
1101 TRACE("(%p,%ld)\n", lpszDest, dwDestLen);
1103 if (!lpszDest)
1104 return FALSE;
1106 *lpszDest = '\0';
1108 /* Try the NT key first, followed by 95/98 key */
1109 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinNtKey, 0, KEY_READ, &hReg) &&
1110 RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinKey, 0, KEY_READ, &hReg))
1111 return FALSE;
1113 /* OS Version */
1114 buff[0] = '\0';
1115 dwLen = 30;
1116 if (!SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey, szVersion, &dwType, buff, &dwLen))
1118 DWORD dwStrLen = strlenW(buff);
1119 dwLen = 30 - dwStrLen;
1120 SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey,
1121 szCustomized, &dwType, buff+dwStrLen, &dwLen);
1123 StrCatBuffW(lpszDest, buff, dwDestLen);
1125 /* ~Registered Owner */
1126 buff[0] = '~';
1127 dwLen = 256;
1128 if (SHGetValueW(hReg, szOwner, 0, &dwType, buff+1, &dwLen))
1129 buff[1] = '\0';
1130 StrCatBuffW(lpszDest, buff, dwDestLen);
1132 /* ~Registered Organization */
1133 dwLen = 256;
1134 if (SHGetValueW(hReg, szOrg, 0, &dwType, buff+1, &dwLen))
1135 buff[1] = '\0';
1136 StrCatBuffW(lpszDest, buff, dwDestLen);
1138 /* FIXME: Not sure where this number comes from */
1139 buff[0] = '~';
1140 buff[1] = '0';
1141 buff[2] = '\0';
1142 StrCatBuffW(lpszDest, buff, dwDestLen);
1144 /* ~Product Id */
1145 dwLen = 256;
1146 if (SHGetValueW(HKEY_LOCAL_MACHINE, szRegKey, szProduct, &dwType, buff+1, &dwLen))
1147 buff[1] = '\0';
1148 StrCatBuffW(lpszDest, buff, dwDestLen);
1150 /* ~IE Update Url */
1151 dwLen = 2048;
1152 if(SHGetValueW(HKEY_LOCAL_MACHINE, szWinKey, szUpdate, &dwType, buff+1, &dwLen))
1153 buff[1] = '\0';
1154 StrCatBuffW(lpszDest, buff, dwDestLen);
1156 /* ~IE Help String */
1157 dwLen = 256;
1158 if(SHGetValueW(hReg, szHelp, 0, &dwType, buff+1, &dwLen))
1159 buff[1] = '\0';
1160 StrCatBuffW(lpszDest, buff, dwDestLen);
1162 RegCloseKey(hReg);
1163 return TRUE;
1166 /*************************************************************************
1167 * @ [SHLWAPI.163]
1169 * Call IOleCommandTarget_QueryStatus() on an object.
1171 * PARAMS
1172 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1173 * pguidCmdGroup [I] GUID for the command group
1174 * cCmds [I]
1175 * prgCmds [O] Commands
1176 * pCmdText [O] Command text
1178 * RETURNS
1179 * Success: S_OK.
1180 * Failure: E_FAIL, if lpUnknown is NULL.
1181 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1182 * Otherwise, an error code from IOleCommandTarget_QueryStatus().
1184 HRESULT WINAPI IUnknown_QueryStatus(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
1185 ULONG cCmds, OLECMD *prgCmds, OLECMDTEXT* pCmdText)
1187 HRESULT hRet = E_FAIL;
1189 TRACE("(%p,%p,%ld,%p,%p)\n",lpUnknown, pguidCmdGroup, cCmds, prgCmds, pCmdText);
1191 if (lpUnknown)
1193 IOleCommandTarget* lpOle;
1195 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
1196 (void**)&lpOle);
1198 if (SUCCEEDED(hRet) && lpOle)
1200 hRet = IOleCommandTarget_QueryStatus(lpOle, pguidCmdGroup, cCmds,
1201 prgCmds, pCmdText);
1202 IOleCommandTarget_Release(lpOle);
1205 return hRet;
1208 /*************************************************************************
1209 * @ [SHLWAPI.164]
1211 * Call IOleCommandTarget_Exec() on an object.
1213 * PARAMS
1214 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1215 * pguidCmdGroup [I] GUID for the command group
1217 * RETURNS
1218 * Success: S_OK.
1219 * Failure: E_FAIL, if lpUnknown is NULL.
1220 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1221 * Otherwise, an error code from IOleCommandTarget_Exec().
1223 HRESULT WINAPI IUnknown_Exec(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
1224 DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
1225 VARIANT* pvaOut)
1227 HRESULT hRet = E_FAIL;
1229 TRACE("(%p,%p,%ld,%ld,%p,%p)\n",lpUnknown, pguidCmdGroup, nCmdID,
1230 nCmdexecopt, pvaIn, pvaOut);
1232 if (lpUnknown)
1234 IOleCommandTarget* lpOle;
1236 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
1237 (void**)&lpOle);
1238 if (SUCCEEDED(hRet) && lpOle)
1240 hRet = IOleCommandTarget_Exec(lpOle, pguidCmdGroup, nCmdID,
1241 nCmdexecopt, pvaIn, pvaOut);
1242 IOleCommandTarget_Release(lpOle);
1245 return hRet;
1248 /*************************************************************************
1249 * @ [SHLWAPI.165]
1251 * Retrieve, modify, and re-set a value from a window.
1253 * PARAMS
1254 * hWnd [I] Window to get value from
1255 * offset [I] Offset of value
1256 * wMask [I] Mask for uiFlags
1257 * wFlags [I] Bits to set in window value
1259 * RETURNS
1260 * The new value as it was set, or 0 if any parameter is invalid.
1262 * NOTES
1263 * Any bits set in uiMask are cleared from the value, then any bits set in
1264 * uiFlags are set in the value.
1266 LONG WINAPI SHSetWindowBits(HWND hwnd, INT offset, UINT wMask, UINT wFlags)
1268 LONG ret = GetWindowLongA(hwnd, offset);
1269 LONG newFlags = (wFlags & wMask) | (ret & ~wFlags);
1271 if (newFlags != ret)
1272 ret = SetWindowLongA(hwnd, offset, newFlags);
1273 return ret;
1276 /*************************************************************************
1277 * @ [SHLWAPI.167]
1279 * Change a window's parent.
1281 * PARAMS
1282 * hWnd [I] Window to change parent of
1283 * hWndParent [I] New parent window
1285 * RETURNS
1286 * The old parent of hWnd.
1288 * NOTES
1289 * If hWndParent is NULL (desktop), the window style is changed to WS_POPUP.
1290 * If hWndParent is NOT NULL then we set the WS_CHILD style.
1292 HWND WINAPI SHSetParentHwnd(HWND hWnd, HWND hWndParent)
1294 TRACE("%p, %p\n", hWnd, hWndParent);
1296 if(GetParent(hWnd) == hWndParent)
1297 return 0;
1299 if(hWndParent)
1300 SHSetWindowBits(hWnd, GWL_STYLE, WS_CHILD, WS_CHILD);
1301 else
1302 SHSetWindowBits(hWnd, GWL_STYLE, WS_POPUP, WS_POPUP);
1304 return SetParent(hWnd, hWndParent);
1307 /*************************************************************************
1308 * @ [SHLWAPI.168]
1310 * Locate and advise a connection point in an IConnectionPointContainer object.
1312 * PARAMS
1313 * lpUnkSink [I] Sink for the connection point advise call
1314 * riid [I] REFIID of connection point to advise
1315 * bAdviseOnly [I] TRUE = Advise only, FALSE = Unadvise first
1316 * lpUnknown [I] Object supporting the IConnectionPointContainer interface
1317 * lpCookie [O] Pointer to connection point cookie
1318 * lppCP [O] Destination for the IConnectionPoint found
1320 * RETURNS
1321 * Success: S_OK. If lppCP is non-NULL, it is filled with the IConnectionPoint
1322 * that was advised. The caller is responsable for releasing it.
1323 * Failure: E_FAIL, if any arguments are invalid.
1324 * E_NOINTERFACE, if lpUnknown isn't an IConnectionPointContainer,
1325 * Or an HRESULT error code if any call fails.
1327 HRESULT WINAPI ConnectToConnectionPoint(IUnknown* lpUnkSink, REFIID riid, BOOL bAdviseOnly,
1328 IUnknown* lpUnknown, LPDWORD lpCookie,
1329 IConnectionPoint **lppCP)
1331 HRESULT hRet;
1332 IConnectionPointContainer* lpContainer;
1333 IConnectionPoint *lpCP;
1335 if(!lpUnknown || (bAdviseOnly && !lpUnkSink))
1336 return E_FAIL;
1338 if(lppCP)
1339 *lppCP = NULL;
1341 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer,
1342 (void**)&lpContainer);
1343 if (SUCCEEDED(hRet))
1345 hRet = IConnectionPointContainer_FindConnectionPoint(lpContainer, riid, &lpCP);
1347 if (SUCCEEDED(hRet))
1349 if(!bAdviseOnly)
1350 hRet = IConnectionPoint_Unadvise(lpCP, *lpCookie);
1351 hRet = IConnectionPoint_Advise(lpCP, lpUnkSink, lpCookie);
1353 if (FAILED(hRet))
1354 *lpCookie = 0;
1356 if (lppCP && SUCCEEDED(hRet))
1357 *lppCP = lpCP; /* Caller keeps the interface */
1358 else
1359 IConnectionPoint_Release(lpCP); /* Release it */
1362 IUnknown_Release(lpContainer);
1364 return hRet;
1367 /*************************************************************************
1368 * @ [SHLWAPI.169]
1370 * Release an interface.
1372 * PARAMS
1373 * lpUnknown [I] Object to release
1375 * RETURNS
1376 * Nothing.
1378 DWORD WINAPI IUnknown_AtomicRelease(IUnknown ** lpUnknown)
1380 IUnknown *temp;
1382 TRACE("(%p)\n",lpUnknown);
1384 if(!lpUnknown || !*((LPDWORD)lpUnknown)) return 0;
1385 temp = *lpUnknown;
1386 *lpUnknown = NULL;
1388 TRACE("doing Release\n");
1390 return IUnknown_Release(temp);
1393 /*************************************************************************
1394 * @ [SHLWAPI.170]
1396 * Skip '//' if present in a string.
1398 * PARAMS
1399 * lpszSrc [I] String to check for '//'
1401 * RETURNS
1402 * Success: The next character after the '//' or the string if not present
1403 * Failure: NULL, if lpszStr is NULL.
1405 LPCSTR WINAPI PathSkipLeadingSlashesA(LPCSTR lpszSrc)
1407 if (lpszSrc && lpszSrc[0] == '/' && lpszSrc[1] == '/')
1408 lpszSrc += 2;
1409 return lpszSrc;
1412 /*************************************************************************
1413 * @ [SHLWAPI.171]
1415 * Check if two interfaces come from the same object.
1417 * PARAMS
1418 * lpInt1 [I] Interface to check against lpInt2.
1419 * lpInt2 [I] Interface to check against lpInt1.
1421 * RETURNS
1422 * TRUE, If the interfaces come from the same object.
1423 * FALSE Otherwise.
1425 BOOL WINAPI SHIsSameObject(IUnknown* lpInt1, IUnknown* lpInt2)
1427 LPVOID lpUnknown1, lpUnknown2;
1429 TRACE("%p %p\n", lpInt1, lpInt2);
1431 if (!lpInt1 || !lpInt2)
1432 return FALSE;
1434 if (lpInt1 == lpInt2)
1435 return TRUE;
1437 if (!SUCCEEDED(IUnknown_QueryInterface(lpInt1, &IID_IUnknown,
1438 (LPVOID *)&lpUnknown1)))
1439 return FALSE;
1441 if (!SUCCEEDED(IUnknown_QueryInterface(lpInt2, &IID_IUnknown,
1442 (LPVOID *)&lpUnknown2)))
1443 return FALSE;
1445 if (lpUnknown1 == lpUnknown2)
1446 return TRUE;
1448 return FALSE;
1451 /*************************************************************************
1452 * @ [SHLWAPI.172]
1454 * Get the window handle of an object.
1456 * PARAMS
1457 * lpUnknown [I] Object to get the window handle of
1458 * lphWnd [O] Destination for window handle
1460 * RETURNS
1461 * Success: S_OK. lphWnd contains the objects window handle.
1462 * Failure: An HRESULT error code.
1464 * NOTES
1465 * lpUnknown is expected to support one of the following interfaces:
1466 * IOleWindow(), IInternetSecurityMgrSite(), or IShellView().
1468 HRESULT WINAPI IUnknown_GetWindow(IUnknown *lpUnknown, HWND *lphWnd)
1470 /* FIXME: Wine has no header for this object */
1471 static const GUID IID_IInternetSecurityMgrSite = { 0x79eac9ed,
1472 0xbaf9, 0x11ce, { 0x8c, 0x82, 0x00, 0xaa, 0x00, 0x4b, 0xa9, 0x0b }};
1473 IUnknown *lpOle;
1474 HRESULT hRet = E_FAIL;
1476 TRACE("(%p,%p)\n", lpUnknown, lphWnd);
1478 if (!lpUnknown)
1479 return hRet;
1481 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleWindow, (void**)&lpOle);
1483 if (FAILED(hRet))
1485 hRet = IUnknown_QueryInterface(lpUnknown,&IID_IShellView, (void**)&lpOle);
1487 if (FAILED(hRet))
1489 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInternetSecurityMgrSite,
1490 (void**)&lpOle);
1494 if (SUCCEEDED(hRet))
1496 /* Lazyness here - Since GetWindow() is the first method for the above 3
1497 * interfaces, we use the same call for them all.
1499 hRet = IOleWindow_GetWindow((IOleWindow*)lpOle, lphWnd);
1500 IUnknown_Release(lpOle);
1501 if (lphWnd)
1502 TRACE("Returning HWND=%p\n", *lphWnd);
1505 return hRet;
1508 /*************************************************************************
1509 * @ [SHLWAPI.173]
1511 * Call a method on as as yet unidentified object.
1513 * PARAMS
1514 * pUnk [I] Object supporting the unidentified interface,
1515 * arg [I] Argument for the call on the object.
1517 * RETURNS
1518 * S_OK.
1520 HRESULT WINAPI IUnknown_SetOwner(IUnknown *pUnk, ULONG arg)
1522 static const GUID guid_173 = {
1523 0x5836fb00, 0x8187, 0x11cf, { 0xa1,0x2b,0x00,0xaa,0x00,0x4a,0xe8,0x37 }
1525 IMalloc *pUnk2;
1527 TRACE("(%p,%ld)\n", pUnk, arg);
1529 /* Note: arg may not be a ULONG and pUnk2 is for sure not an IMalloc -
1530 * We use this interface as its vtable entry is compatible with the
1531 * object in question.
1532 * FIXME: Find out what this object is and where it should be defined.
1534 if (pUnk &&
1535 SUCCEEDED(IUnknown_QueryInterface(pUnk, &guid_173, (void**)&pUnk2)))
1537 IMalloc_Alloc(pUnk2, arg); /* Faked call!! */
1538 IMalloc_Release(pUnk2);
1540 return S_OK;
1543 /*************************************************************************
1544 * @ [SHLWAPI.174]
1546 * Call either IObjectWithSite_SetSite() or IPersistMoniker_GetClassID() on
1547 * an interface.
1549 * RETURNS
1550 * Success: S_OK.
1551 * Failure: E_FAIL, if p1 is NULL.
1552 * E_NOINTERFACE If p1 does not support the IPersist interface,
1553 * Or an HRESULT error code.
1555 DWORD WINAPI IUnknown_SetSite(
1556 IUnknown *p1, /* [in] OLE object */
1557 LPVOID *p2) /* [out] ptr for call results */
1559 DWORD ret, aa;
1561 if (!p1) return E_FAIL;
1563 /* see if SetSite interface exists for IObjectWithSite object */
1564 ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id1, (LPVOID *)&p1);
1565 TRACE("first IU_QI ret=%08lx, p1=%p\n", ret, p1);
1566 if (ret) {
1568 /* see if GetClassId interface exists for IPersistMoniker object */
1569 ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id2, (LPVOID *)&aa);
1570 TRACE("second IU_QI ret=%08lx, aa=%08lx\n", ret, aa);
1571 if (ret) return ret;
1573 /* fake a GetClassId call */
1574 ret = IOleWindow_GetWindow((IOleWindow *)aa, (HWND*)p2);
1575 TRACE("second IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1576 *(LPDWORD)p2);
1577 IUnknown_Release((IUnknown *)aa);
1579 else {
1580 /* fake a SetSite call */
1581 ret = IOleWindow_GetWindow((IOleWindow *)p1, (HWND*)p2);
1582 TRACE("first IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1583 *(LPDWORD)p2);
1584 IUnknown_Release((IUnknown *)p1);
1586 return ret;
1589 /*************************************************************************
1590 * @ [SHLWAPI.175]
1592 * Call IPersist_GetClassID() on an object.
1594 * PARAMS
1595 * lpUnknown [I] Object supporting the IPersist interface
1596 * lpClassId [O] Destination for Class Id
1598 * RETURNS
1599 * Success: S_OK. lpClassId contains the Class Id requested.
1600 * Failure: E_FAIL, If lpUnknown is NULL,
1601 * E_NOINTERFACE If lpUnknown does not support IPersist,
1602 * Or an HRESULT error code.
1604 HRESULT WINAPI IUnknown_GetClassID(IUnknown *lpUnknown, CLSID* lpClassId)
1606 IPersist* lpPersist;
1607 HRESULT hRet = E_FAIL;
1609 TRACE("(%p,%p)\n", lpUnknown, debugstr_guid(lpClassId));
1611 if (lpUnknown)
1613 hRet = IUnknown_QueryInterface(lpUnknown,&IID_IPersist,(void**)&lpPersist);
1614 if (SUCCEEDED(hRet))
1616 IPersist_GetClassID(lpPersist, lpClassId);
1617 IPersist_Release(lpPersist);
1620 return hRet;
1623 /*************************************************************************
1624 * @ [SHLWAPI.176]
1626 * Retrieve a Service Interface from an object.
1628 * PARAMS
1629 * lpUnknown [I] Object to get an IServiceProvider interface from
1630 * sid [I] Service ID for IServiceProvider_QueryService() call
1631 * riid [I] Function requested for QueryService call
1632 * lppOut [O] Destination for the service interface pointer
1634 * RETURNS
1635 * Success: S_OK. lppOut contains an object providing the requested service
1636 * Failure: An HRESULT error code
1638 * NOTES
1639 * lpUnknown is expected to support the IServiceProvider interface.
1641 HRESULT WINAPI IUnknown_QueryService(IUnknown* lpUnknown, REFGUID sid, REFIID riid,
1642 LPVOID *lppOut)
1644 IServiceProvider* pService = NULL;
1645 HRESULT hRet;
1647 if (!lppOut)
1648 return E_FAIL;
1650 *lppOut = NULL;
1652 if (!lpUnknown)
1653 return E_FAIL;
1655 /* Get an IServiceProvider interface from the object */
1656 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IServiceProvider,
1657 (LPVOID*)&pService);
1659 if (!hRet && pService)
1661 TRACE("QueryInterface returned (IServiceProvider*)%p\n", pService);
1663 /* Get a Service interface from the object */
1664 hRet = IServiceProvider_QueryService(pService, sid, riid, lppOut);
1666 TRACE("(IServiceProvider*)%p returned (IUnknown*)%p\n", pService, *lppOut);
1668 /* Release the IServiceProvider interface */
1669 IUnknown_Release(pService);
1671 return hRet;
1674 /*************************************************************************
1675 * @ [SHLWAPI.177]
1677 * Loads a popup menu.
1679 * PARAMS
1680 * hInst [I] Instance handle
1681 * szName [I] Menu name
1683 * RETURNS
1684 * Success: TRUE.
1685 * Failure: FALSE.
1687 BOOL WINAPI SHLoadMenuPopup(HINSTANCE hInst, LPCWSTR szName)
1689 HMENU hMenu, hSubMenu;
1691 if ((hMenu = LoadMenuW(hInst, szName)))
1693 if ((hSubMenu = GetSubMenu(hMenu, 0)))
1694 RemoveMenu(hMenu, 0, MF_BYPOSITION);
1696 DestroyMenu(hMenu);
1697 return TRUE;
1699 return FALSE;
1702 typedef struct _enumWndData
1704 UINT uiMsgId;
1705 WPARAM wParam;
1706 LPARAM lParam;
1707 LRESULT (WINAPI *pfnPost)(HWND,UINT,WPARAM,LPARAM);
1708 } enumWndData;
1710 /* Callback for SHLWAPI_178 */
1711 static BOOL CALLBACK SHLWAPI_EnumChildProc(HWND hWnd, LPARAM lParam)
1713 enumWndData *data = (enumWndData *)lParam;
1715 TRACE("(%p,%p)\n", hWnd, data);
1716 data->pfnPost(hWnd, data->uiMsgId, data->wParam, data->lParam);
1717 return TRUE;
1720 /*************************************************************************
1721 * @ [SHLWAPI.178]
1723 * Send or post a message to every child of a window.
1725 * PARAMS
1726 * hWnd [I] Window whose children will get the messages
1727 * uiMsgId [I] Message Id
1728 * wParam [I] WPARAM of message
1729 * lParam [I] LPARAM of message
1730 * bSend [I] TRUE = Use SendMessageA(), FALSE = Use PostMessageA()
1732 * RETURNS
1733 * Nothing.
1735 * NOTES
1736 * The appropriate ASCII or Unicode function is called for the window.
1738 void WINAPI SHPropagateMessage(HWND hWnd, UINT uiMsgId, WPARAM wParam, LPARAM lParam, BOOL bSend)
1740 enumWndData data;
1742 TRACE("(%p,%u,%d,%ld,%d)\n", hWnd, uiMsgId, wParam, lParam, bSend);
1744 if(hWnd)
1746 data.uiMsgId = uiMsgId;
1747 data.wParam = wParam;
1748 data.lParam = lParam;
1750 if (bSend)
1751 data.pfnPost = IsWindowUnicode(hWnd) ? (void*)SendMessageW : (void*)SendMessageA;
1752 else
1753 data.pfnPost = IsWindowUnicode(hWnd) ? (void*)PostMessageW : (void*)PostMessageA;
1755 EnumChildWindows(hWnd, SHLWAPI_EnumChildProc, (LPARAM)&data);
1759 /*************************************************************************
1760 * @ [SHLWAPI.180]
1762 * Remove all sub-menus from a menu.
1764 * PARAMS
1765 * hMenu [I] Menu to remove sub-menus from
1767 * RETURNS
1768 * Success: 0. All sub-menus under hMenu are removed
1769 * Failure: -1, if any parameter is invalid
1771 DWORD WINAPI SHRemoveAllSubMenus(HMENU hMenu)
1773 int iItemCount = GetMenuItemCount(hMenu) - 1;
1774 while (iItemCount >= 0)
1776 HMENU hSubMenu = GetSubMenu(hMenu, iItemCount);
1777 if (hSubMenu)
1778 RemoveMenu(hMenu, iItemCount, MF_BYPOSITION);
1779 iItemCount--;
1781 return iItemCount;
1784 /*************************************************************************
1785 * @ [SHLWAPI.181]
1787 * Enable or disable a menu item.
1789 * PARAMS
1790 * hMenu [I] Menu holding menu item
1791 * uID [I] ID of menu item to enable/disable
1792 * bEnable [I] Whether to enable (TRUE) or disable (FALSE) the item.
1794 * RETURNS
1795 * The return code from EnableMenuItem.
1797 UINT WINAPI SHEnableMenuItem(HMENU hMenu, UINT wItemID, BOOL bEnable)
1799 return EnableMenuItem(hMenu, wItemID, bEnable ? MF_ENABLED : MF_GRAYED);
1802 /*************************************************************************
1803 * @ [SHLWAPI.182]
1805 * Check or uncheck a menu item.
1807 * PARAMS
1808 * hMenu [I] Menu holding menu item
1809 * uID [I] ID of menu item to check/uncheck
1810 * bCheck [I] Whether to check (TRUE) or uncheck (FALSE) the item.
1812 * RETURNS
1813 * The return code from CheckMenuItem.
1815 DWORD WINAPI SHCheckMenuItem(HMENU hMenu, UINT uID, BOOL bCheck)
1817 return CheckMenuItem(hMenu, uID, bCheck ? MF_CHECKED : MF_UNCHECKED);
1820 /*************************************************************************
1821 * @ [SHLWAPI.183]
1823 * Register a window class if it isn't already.
1825 * PARAMS
1826 * lpWndClass [I] Window class to register
1828 * RETURNS
1829 * The result of the RegisterClassA call.
1831 DWORD WINAPI SHRegisterClassA(WNDCLASSA *wndclass)
1833 WNDCLASSA wca;
1834 if (GetClassInfoA(wndclass->hInstance, wndclass->lpszClassName, &wca))
1835 return TRUE;
1836 return (DWORD)RegisterClassA(wndclass);
1839 /*************************************************************************
1840 * @ [SHLWAPI.187]
1842 * Call IPersistPropertyBag_Load() on an object.
1844 * PARAMS
1845 * lpUnknown [I] Object supporting the IPersistPropertyBag interface
1846 * lpPropBag [O] Destination for loaded IPropertyBag
1848 * RETURNS
1849 * Success: S_OK.
1850 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1852 DWORD WINAPI SHLoadFromPropertyBag(IUnknown *lpUnknown, IPropertyBag* lpPropBag)
1854 IPersistPropertyBag* lpPPBag;
1855 HRESULT hRet = E_FAIL;
1857 TRACE("(%p,%p)\n", lpUnknown, lpPropBag);
1859 if (lpUnknown)
1861 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IPersistPropertyBag,
1862 (void**)&lpPPBag);
1863 if (SUCCEEDED(hRet) && lpPPBag)
1865 hRet = IPersistPropertyBag_Load(lpPPBag, lpPropBag, NULL);
1866 IPersistPropertyBag_Release(lpPPBag);
1869 return hRet;
1872 /*************************************************************************
1873 * @ [SHLWAPI.189]
1875 * Call IOleControlSite_GetExtendedControl() on an object.
1877 * PARAMS
1878 * lpUnknown [I] Object supporting the IOleControlSite interface
1879 * lppDisp [O] Destination for resulting IDispatch.
1881 * RETURNS
1882 * Success: S_OK.
1883 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1885 DWORD WINAPI IUnknown_OnFocusOCS(IUnknown *lpUnknown, IDispatch** lppDisp)
1887 IOleControlSite* lpCSite;
1888 HRESULT hRet = E_FAIL;
1890 TRACE("(%p,%p)\n", lpUnknown, lppDisp);
1891 if (lpUnknown)
1893 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleControlSite,
1894 (void**)&lpCSite);
1895 if (SUCCEEDED(hRet) && lpCSite)
1897 hRet = IOleControlSite_GetExtendedControl(lpCSite, lppDisp);
1898 IOleControlSite_Release(lpCSite);
1901 return hRet;
1904 /*************************************************************************
1905 * @ [SHLWAPI.192]
1907 * Get a sub-menu from a menu item.
1909 * PARAMS
1910 * hMenu [I] Menu to get sub-menu from
1911 * uID [I] ID of menu item containing sub-menu
1913 * RETURNS
1914 * The sub-menu of the item, or a NULL handle if any parameters are invalid.
1916 HMENU WINAPI SHGetMenuFromID(HMENU hMenu, UINT uID)
1918 MENUITEMINFOA mi;
1920 TRACE("(%p,%uld)\n", hMenu, uID);
1922 mi.cbSize = sizeof(MENUITEMINFOA);
1923 mi.fMask = MIIM_SUBMENU;
1925 if (!GetMenuItemInfoA(hMenu, uID, 0, &mi))
1926 return (HMENU)NULL;
1928 return mi.hSubMenu;
1931 /*************************************************************************
1932 * @ [SHLWAPI.193]
1934 * Get the color depth of the primary display.
1936 * PARAMS
1937 * None.
1939 * RETURNS
1940 * The color depth of the primary display.
1942 DWORD WINAPI SHGetCurColorRes()
1944 HDC hdc;
1945 DWORD ret;
1947 TRACE("()\n");
1949 hdc = GetDC(0);
1950 ret = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
1951 ReleaseDC(0, hdc);
1952 return ret;
1955 /*************************************************************************
1956 * @ [SHLWAPI.194]
1958 * Wait for a message to arrive, with a timeout.
1960 * PARAMS
1961 * hand [I] Handle to query
1962 * dwTimeout [I] Timeout in ticks or INFINITE to never timeout
1964 * RETURNS
1965 * STATUS_TIMEOUT if no message is received before dwTimeout ticks passes.
1966 * Otherwise returns the value from MsgWaitForMultipleObjectsEx when a
1967 * message is available.
1969 DWORD WINAPI SHWaitForSendMessageThread(HANDLE hand, DWORD dwTimeout)
1971 DWORD dwEndTicks = GetTickCount() + dwTimeout;
1972 DWORD dwRet;
1974 while ((dwRet = MsgWaitForMultipleObjectsEx(1, &hand, dwTimeout, QS_SENDMESSAGE, 0)) == 1)
1976 MSG msg;
1978 PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE);
1980 if (dwTimeout != INFINITE)
1982 if ((int)(dwTimeout = dwEndTicks - GetTickCount()) <= 0)
1983 return WAIT_TIMEOUT;
1987 return dwRet;
1990 /*************************************************************************
1991 * @ [SHLWAPI.197]
1993 * Blank out a region of text by drawing the background only.
1995 * PARAMS
1996 * hDC [I] Device context to draw in
1997 * pRect [I] Area to draw in
1998 * cRef [I] Color to draw in
2000 * RETURNS
2001 * Nothing.
2003 DWORD WINAPI SHFillRectClr(HDC hDC, LPCRECT pRect, COLORREF cRef)
2005 COLORREF cOldColor = SetBkColor(hDC, cRef);
2006 ExtTextOutA(hDC, 0, 0, ETO_OPAQUE, pRect, 0, 0, 0);
2007 SetBkColor(hDC, cOldColor);
2008 return 0;
2011 /*************************************************************************
2012 * @ [SHLWAPI.198]
2014 * Return the value asociated with a key in a map.
2016 * PARAMS
2017 * lpKeys [I] A list of keys of length iLen
2018 * lpValues [I] A list of values associated with lpKeys, of length iLen
2019 * iLen [I] Length of both lpKeys and lpValues
2020 * iKey [I] The key value to look up in lpKeys
2022 * RETURNS
2023 * The value in lpValues associated with iKey, or -1 if iKey is not
2024 * found in lpKeys.
2026 * NOTES
2027 * - If two elements in the map share the same key, this function returns
2028 * the value closest to the start of the map
2029 * - The native version of this function crashes if lpKeys or lpValues is NULL.
2031 int WINAPI SHSearchMapInt(const int *lpKeys, const int *lpValues, int iLen, int iKey)
2033 if (lpKeys && lpValues)
2035 int i = 0;
2037 while (i < iLen)
2039 if (lpKeys[i] == iKey)
2040 return lpValues[i]; /* Found */
2041 i++;
2044 return -1; /* Not found */
2048 /*************************************************************************
2049 * @ [SHLWAPI.199]
2051 * Copy an interface pointer
2053 * PARAMS
2054 * lppDest [O] Destination for copy
2055 * lpUnknown [I] Source for copy
2057 * RETURNS
2058 * Nothing.
2060 VOID WINAPI IUnknown_Set(IUnknown **lppDest, IUnknown *lpUnknown)
2062 TRACE("(%p,%p)\n", lppDest, lpUnknown);
2064 if (lppDest)
2065 IUnknown_AtomicRelease(lppDest); /* Release existing interface */
2067 if (lpUnknown)
2069 /* Copy */
2070 IUnknown_AddRef(lpUnknown);
2071 *lppDest = lpUnknown;
2075 /*************************************************************************
2076 * @ [SHLWAPI.201]
2079 HRESULT WINAPI MayExecForward(IUnknown* lpUnknown, INT iUnk, REFGUID pguidCmdGroup,
2080 DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
2081 VARIANT* pvaOut)
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 /*************************************************************************
2089 * @ [SHLWAPI.202]
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 /*************************************************************************
2099 * @ [SHLWAPI.204]
2101 * Determine if a window is not a child of another window.
2103 * PARAMS
2104 * hParent [I] Suspected parent window
2105 * hChild [I] Suspected child window
2107 * RETURNS
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)
2116 return TRUE;
2117 else if(hParent == hChild)
2118 return FALSE;
2119 return !IsChild(hParent, hChild);
2122 /*************************************************************************
2123 * @ [SHLWAPI.208]
2125 * Some sort of memory management process.
2127 DWORD WINAPI FDSA_Initialize(
2128 DWORD a,
2129 DWORD b,
2130 LPVOID c,
2131 LPVOID d,
2132 DWORD e)
2134 FIXME("(0x%08lx 0x%08lx %p %p 0x%08lx) stub\n",
2135 a, b, c, d, e);
2136 return 1;
2139 /*************************************************************************
2140 * @ [SHLWAPI.209]
2142 * Some sort of memory management process.
2144 DWORD WINAPI FDSA_Destroy(
2145 LPVOID a)
2147 FIXME("(%p) stub\n",
2149 return 1;
2152 /*************************************************************************
2153 * @ [SHLWAPI.210]
2155 * Some sort of memory management process.
2157 DWORD WINAPI FDSA_InsertItem(
2158 LPVOID a,
2159 DWORD b,
2160 LPVOID c)
2162 FIXME("(%p 0x%08lx %p) stub\n",
2163 a, b, c);
2164 return 0;
2167 /*************************************************************************
2168 * @ [SHLWAPI.211]
2170 DWORD WINAPI FDSA_DeleteItem(
2171 LPVOID a,
2172 DWORD b)
2174 FIXME("(%p 0x%08lx) stub\n",
2175 a, b);
2176 return 1;
2179 typedef struct {
2180 REFIID refid;
2181 DWORD indx;
2182 } IFACE_INDEX_TBL;
2184 /*************************************************************************
2185 * @ [SHLWAPI.219]
2187 * Call IUnknown_QueryInterface() on a table of objects.
2189 * RETURNS
2190 * Success: S_OK.
2191 * Failure: E_POINTER or E_NOINTERFACE.
2193 HRESULT WINAPI QISearch(
2194 LPVOID w, /* [in] Table of interfaces */
2195 IFACE_INDEX_TBL *x, /* [in] Array of REFIIDs and indexes into the table */
2196 REFIID riid, /* [in] REFIID to get interface for */
2197 LPVOID *ppv) /* [out] Destination for interface pointer */
2199 HRESULT ret;
2200 IUnknown *a_vtbl;
2201 IFACE_INDEX_TBL *xmove;
2203 TRACE("(%p %p %s %p)\n", w,x,debugstr_guid(riid),ppv);
2204 if (ppv) {
2205 xmove = x;
2206 while (xmove->refid) {
2207 TRACE("trying (indx %ld) %s\n", xmove->indx, debugstr_guid(xmove->refid));
2208 if (IsEqualIID(riid, xmove->refid)) {
2209 a_vtbl = (IUnknown*)(xmove->indx + (LPBYTE)w);
2210 TRACE("matched, returning (%p)\n", a_vtbl);
2211 *ppv = (LPVOID)a_vtbl;
2212 IUnknown_AddRef(a_vtbl);
2213 return S_OK;
2215 xmove++;
2218 if (IsEqualIID(riid, &IID_IUnknown)) {
2219 a_vtbl = (IUnknown*)(x->indx + (LPBYTE)w);
2220 TRACE("returning first for IUnknown (%p)\n", a_vtbl);
2221 *ppv = (LPVOID)a_vtbl;
2222 IUnknown_AddRef(a_vtbl);
2223 return S_OK;
2225 *ppv = 0;
2226 ret = E_NOINTERFACE;
2227 } else
2228 ret = E_POINTER;
2230 TRACE("-- 0x%08lx\n", ret);
2231 return ret;
2234 /*************************************************************************
2235 * @ [SHLWAPI.221]
2237 * Remove the "PropDlgFont" property from a window.
2239 * PARAMS
2240 * hWnd [I] Window to remove the property from
2242 * RETURNS
2243 * A handle to the removed property, or NULL if it did not exist.
2245 HANDLE WINAPI SHRemoveDefaultDialogFont(HWND hWnd)
2247 HANDLE hProp;
2249 TRACE("(%p)\n", hWnd);
2251 hProp = GetPropA(hWnd, "PropDlgFont");
2253 if(hProp)
2255 DeleteObject(hProp);
2256 hProp = RemovePropA(hWnd, "PropDlgFont");
2258 return hProp;
2261 /*************************************************************************
2262 * @ [SHLWAPI.236]
2264 * Load the in-process server of a given GUID.
2266 * PARAMS
2267 * refiid [I] GUID of the server to load.
2269 * RETURNS
2270 * Success: A handle to the loaded server dll.
2271 * Failure: A NULL handle.
2273 HMODULE WINAPI SHPinDllOfCLSID(REFIID refiid)
2275 HKEY newkey;
2276 DWORD type, count;
2277 CHAR value[MAX_PATH], string[MAX_PATH];
2279 strcpy(string, "CLSID\\");
2280 SHStringFromGUIDA(refiid, string + 6, sizeof(string)/sizeof(char) - 6);
2281 strcat(string, "\\InProcServer32");
2283 count = MAX_PATH;
2284 RegOpenKeyExA(HKEY_CLASSES_ROOT, string, 0, 1, &newkey);
2285 RegQueryValueExA(newkey, 0, 0, &type, (PBYTE)value, &count);
2286 RegCloseKey(newkey);
2287 return LoadLibraryExA(value, 0, 0);
2290 /*************************************************************************
2291 * @ [SHLWAPI.237]
2293 * Unicode version of SHLWAPI_183.
2295 DWORD WINAPI SHRegisterClassW(WNDCLASSW * lpWndClass)
2297 WNDCLASSW WndClass;
2299 TRACE("(%p %s)\n",lpWndClass->hInstance, debugstr_w(lpWndClass->lpszClassName));
2301 if (GetClassInfoW(lpWndClass->hInstance, lpWndClass->lpszClassName, &WndClass))
2302 return TRUE;
2303 return RegisterClassW(lpWndClass);
2306 /*************************************************************************
2307 * @ [SHLWAPI.238]
2309 * Unregister a list of classes.
2311 * PARAMS
2312 * hInst [I] Application instance that registered the classes
2313 * lppClasses [I] List of class names
2314 * iCount [I] Number of names in lppClasses
2316 * RETURNS
2317 * Nothing.
2319 void WINAPI SHUnregisterClassesA(HINSTANCE hInst, LPCSTR *lppClasses, INT iCount)
2321 WNDCLASSA WndClass;
2323 TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);
2325 while (iCount > 0)
2327 if (GetClassInfoA(hInst, *lppClasses, &WndClass))
2328 UnregisterClassA(*lppClasses, hInst);
2329 lppClasses++;
2330 iCount--;
2334 /*************************************************************************
2335 * @ [SHLWAPI.239]
2337 * Unicode version of SHUnregisterClassesA.
2339 void WINAPI SHUnregisterClassesW(HINSTANCE hInst, LPCWSTR *lppClasses, INT iCount)
2341 WNDCLASSW WndClass;
2343 TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);
2345 while (iCount > 0)
2347 if (GetClassInfoW(hInst, *lppClasses, &WndClass))
2348 UnregisterClassW(*lppClasses, hInst);
2349 lppClasses++;
2350 iCount--;
2354 /*************************************************************************
2355 * @ [SHLWAPI.240]
2357 * Call The correct (Ascii/Unicode) default window procedure for a window.
2359 * PARAMS
2360 * hWnd [I] Window to call the default procedure for
2361 * uMessage [I] Message ID
2362 * wParam [I] WPARAM of message
2363 * lParam [I] LPARAM of message
2365 * RETURNS
2366 * The result of calling DefWindowProcA() or DefWindowProcW().
2368 LRESULT CALLBACK SHDefWindowProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
2370 if (IsWindowUnicode(hWnd))
2371 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
2372 return DefWindowProcA(hWnd, uMessage, wParam, lParam);
2375 /*************************************************************************
2376 * @ [SHLWAPI.257]
2378 * Create a worker window using CreateWindowExA().
2380 * PARAMS
2381 * wndProc [I] Window procedure
2382 * hWndParent [I] Parent window
2383 * dwExStyle [I] Extra style flags
2384 * dwStyle [I] Style flags
2385 * hMenu [I] Window menu
2386 * z [I] Unknown
2388 * RETURNS
2389 * Success: The window handle of the newly created window.
2390 * Failure: 0.
2392 HWND WINAPI SHCreateWorkerWindowA(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
2393 DWORD dwStyle, HMENU hMenu, LONG z)
2395 static const char* szClass = "WorkerA";
2396 WNDCLASSA wc;
2397 HWND hWnd;
2399 TRACE("(0x%08lx,%p,0x%08lx,0x%08lx,%p,0x%08lx)\n",
2400 wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2402 /* Create Window class */
2403 wc.style = 0;
2404 wc.lpfnWndProc = DefWindowProcA;
2405 wc.cbClsExtra = 0;
2406 wc.cbWndExtra = 4;
2407 wc.hInstance = shlwapi_hInstance;
2408 wc.hIcon = (HICON)0;
2409 wc.hCursor = LoadCursorA((HINSTANCE)0, (LPSTR)IDC_ARROW);
2410 wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
2411 wc.lpszMenuName = NULL;
2412 wc.lpszClassName = szClass;
2414 SHRegisterClassA(&wc); /* Register class */
2416 /* FIXME: Set extra bits in dwExStyle */
2418 hWnd = CreateWindowExA(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
2419 hWndParent, hMenu, shlwapi_hInstance, 0);
2420 if (hWnd)
2422 SetWindowLongA(hWnd, DWL_MSGRESULT, z);
2424 if (wndProc)
2425 SetWindowLongA(hWnd, GWL_WNDPROC, wndProc);
2427 return hWnd;
2430 typedef struct tagPOLICYDATA
2432 DWORD policy; /* flags value passed to SHRestricted */
2433 LPCWSTR appstr; /* application str such as "Explorer" */
2434 LPCWSTR keystr; /* name of the actual registry key / policy */
2435 } POLICYDATA, *LPPOLICYDATA;
2437 #define SHELL_NO_POLICY 0xffffffff
2439 /* default shell policy registry key */
2440 static WCHAR strRegistryPolicyW[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o',
2441 's','o','f','t','\\','W','i','n','d','o','w','s','\\',
2442 'C','u','r','r','e','n','t','V','e','r','s','i','o','n',
2443 '\\','P','o','l','i','c','i','e','s',0};
2445 /*************************************************************************
2446 * @ [SHLWAPI.271]
2448 * Retrieve a policy value from the registry.
2450 * PARAMS
2451 * lpSubKey [I] registry key name
2452 * lpSubName [I] subname of registry key
2453 * lpValue [I] value name of registry value
2455 * RETURNS
2456 * the value associated with the registry key or 0 if not found
2458 DWORD WINAPI SHGetRestriction(LPCWSTR lpSubKey, LPCWSTR lpSubName, LPCWSTR lpValue)
2460 DWORD retval, datsize = sizeof(retval);
2461 HKEY hKey;
2463 if (!lpSubKey)
2464 lpSubKey = (LPCWSTR)strRegistryPolicyW;
2466 retval = RegOpenKeyW(HKEY_LOCAL_MACHINE, lpSubKey, &hKey);
2467 if (retval != ERROR_SUCCESS)
2468 retval = RegOpenKeyW(HKEY_CURRENT_USER, lpSubKey, &hKey);
2469 if (retval != ERROR_SUCCESS)
2470 return 0;
2472 SHGetValueW(hKey, lpSubName, lpValue, NULL, (LPBYTE)&retval, &datsize);
2473 RegCloseKey(hKey);
2474 return retval;
2477 /*************************************************************************
2478 * @ [SHLWAPI.266]
2480 * Helper function to retrieve the possibly cached value for a specific policy
2482 * PARAMS
2483 * policy [I] The policy to look for
2484 * initial [I] Main registry key to open, if NULL use default
2485 * polTable [I] Table of known policies, 0 terminated
2486 * polArr [I] Cache array of policy values
2488 * RETURNS
2489 * The retrieved policy value or 0 if not successful
2491 * NOTES
2492 * This function is used by the native SHRestricted function to search for the
2493 * policy and cache it once retrieved. The current Wine implementation uses a
2494 * different POLICYDATA structure and implements a similar algorithme adapted to
2495 * that structure.
2497 DWORD WINAPI SHRestrictionLookup(
2498 DWORD policy,
2499 LPCWSTR initial,
2500 LPPOLICYDATA polTable,
2501 LPDWORD polArr)
2503 TRACE("(0x%08lx %s %p %p)\n", policy, debugstr_w(initial), polTable, polArr);
2505 if (!polTable || !polArr)
2506 return 0;
2508 for (;polTable->policy; polTable++, polArr++)
2510 if (policy == polTable->policy)
2512 /* we have a known policy */
2514 /* check if this policy has been cached */
2515 if (*polArr == SHELL_NO_POLICY)
2516 *polArr = SHGetRestriction(initial, polTable->appstr, polTable->keystr);
2517 return *polArr;
2520 /* we don't know this policy, return 0 */
2521 TRACE("unknown policy: (%08lx)\n", policy);
2522 return 0;
2525 /*************************************************************************
2526 * @ [SHLWAPI.267]
2528 * Get an interface from an object.
2530 * RETURNS
2531 * Success: S_OK. ppv contains the requested interface.
2532 * Failure: An HRESULT error code.
2534 * NOTES
2535 * This QueryInterface asks the inner object for a interface. In case
2536 * of aggregation this request would be forwarded by the inner to the
2537 * outer object. This function asks the inner object directly for the
2538 * interface circumventing the forwarding to the outer object.
2540 HRESULT WINAPI SHWeakQueryInterface(
2541 IUnknown * pUnk, /* [in] Outer object */
2542 IUnknown * pInner, /* [in] Inner object */
2543 IID * riid, /* [in] Interface GUID to query for */
2544 LPVOID* ppv) /* [out] Destination for queried interface */
2546 HRESULT hret = E_NOINTERFACE;
2547 TRACE("(pUnk=%p pInner=%p\n\tIID: %s %p)\n",pUnk,pInner,debugstr_guid(riid), ppv);
2549 *ppv = NULL;
2550 if(pUnk && pInner) {
2551 hret = IUnknown_QueryInterface(pInner, riid, (LPVOID*)ppv);
2552 if (SUCCEEDED(hret)) IUnknown_Release(pUnk);
2554 TRACE("-- 0x%08lx\n", hret);
2555 return hret;
2558 /*************************************************************************
2559 * @ [SHLWAPI.268]
2561 * Move a reference from one interface to another.
2563 * PARAMS
2564 * lpDest [O] Destination to receive the reference
2565 * lppUnknown [O] Source to give up the reference to lpDest
2567 * RETURNS
2568 * Nothing.
2570 VOID WINAPI SHWeakReleaseInterface(IUnknown *lpDest, IUnknown **lppUnknown)
2572 TRACE("(%p,%p)\n", lpDest, lppUnknown);
2574 if (*lppUnknown)
2576 /* Copy Reference*/
2577 IUnknown_AddRef(lpDest);
2578 IUnknown_AtomicRelease(lppUnknown); /* Release existing interface */
2582 /*************************************************************************
2583 * @ [SHLWAPI.269]
2585 * Convert an ASCII string of a CLSID into a CLSID.
2587 * PARAMS
2588 * idstr [I] String representing a CLSID in registry format
2589 * id [O] Destination for the converted CLSID
2591 * RETURNS
2592 * Success: TRUE. id contains the converted CLSID.
2593 * Failure: FALSE.
2595 BOOL WINAPI GUIDFromStringA(LPCSTR idstr, CLSID *id)
2597 WCHAR wClsid[40];
2598 MultiByteToWideChar(CP_ACP, 0, idstr, -1, wClsid, sizeof(wClsid)/sizeof(WCHAR));
2599 return SUCCEEDED(CLSIDFromStringWrap(wClsid, id));
2602 /*************************************************************************
2603 * @ [SHLWAPI.270]
2605 * Unicode version of GUIDFromStringA.
2607 BOOL WINAPI GUIDFromStringW(LPCWSTR idstr, CLSID *id)
2609 return SUCCEEDED(CLSIDFromStringWrap(idstr, id));
2612 /*************************************************************************
2613 * @ [SHLWAPI.276]
2615 * Determine if the browser is integrated into the shell, and set a registry
2616 * key accordingly.
2618 * PARAMS
2619 * None.
2621 * RETURNS
2622 * 1, If the browser is not integrated.
2623 * 2, If the browser is integrated.
2625 * NOTES
2626 * The key "HKLM\Software\Microsoft\Internet Explorer\IntegratedBrowser" is
2627 * either set to TRUE, or removed depending on whether the browser is deemed
2628 * to be integrated.
2630 DWORD WINAPI WhichPlatform()
2632 static LPCSTR szIntegratedBrowser = "IntegratedBrowser";
2633 static DWORD dwState = 0;
2634 HKEY hKey;
2635 DWORD dwRet, dwData, dwSize;
2637 if (dwState)
2638 return dwState;
2640 /* If shell32 exports DllGetVersion(), the browser is integrated */
2641 GET_FUNC(pDllGetVersion, shell32, "DllGetVersion", 1);
2642 dwState = pDllGetVersion ? 2 : 1;
2644 /* Set or delete the key accordinly */
2645 dwRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
2646 "Software\\Microsoft\\Internet Explorer", 0,
2647 KEY_ALL_ACCESS, &hKey);
2648 if (!dwRet)
2650 dwRet = RegQueryValueExA(hKey, szIntegratedBrowser, 0, 0,
2651 (LPBYTE)&dwData, &dwSize);
2653 if (!dwRet && dwState == 1)
2655 /* Value exists but browser is not integrated */
2656 RegDeleteValueA(hKey, szIntegratedBrowser);
2658 else if (dwRet && dwState == 2)
2660 /* Browser is integrated but value does not exist */
2661 dwData = TRUE;
2662 RegSetValueExA(hKey, szIntegratedBrowser, 0, REG_DWORD,
2663 (LPBYTE)&dwData, sizeof(dwData));
2665 RegCloseKey(hKey);
2667 return dwState;
2670 /*************************************************************************
2671 * @ [SHLWAPI.278]
2673 * Unicode version of SHCreateWorkerWindowA.
2675 HWND WINAPI SHCreateWorkerWindowW(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
2676 DWORD dwStyle, HMENU hMenu, LONG z)
2678 static const WCHAR szClass[] = { 'W', 'o', 'r', 'k', 'e', 'r', 'W', '\0' };
2679 WNDCLASSW wc;
2680 HWND hWnd;
2682 TRACE("(0x%08lx,%p,0x%08lx,0x%08lx,%p,0x%08lx)\n",
2683 wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2685 /* If our OS is natively ASCII, use the ASCII version */
2686 if (!(GetVersion() & 0x80000000)) /* NT */
2687 return SHCreateWorkerWindowA(wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2689 /* Create Window class */
2690 wc.style = 0;
2691 wc.lpfnWndProc = DefWindowProcW;
2692 wc.cbClsExtra = 0;
2693 wc.cbWndExtra = 4;
2694 wc.hInstance = shlwapi_hInstance;
2695 wc.hIcon = (HICON)0;
2696 wc.hCursor = LoadCursorA((HINSTANCE)0, (LPSTR)IDC_ARROW);
2697 wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
2698 wc.lpszMenuName = NULL;
2699 wc.lpszClassName = szClass;
2701 SHRegisterClassW(&wc); /* Register class */
2703 /* FIXME: Set extra bits in dwExStyle */
2705 hWnd = CreateWindowExW(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
2706 hWndParent, hMenu, shlwapi_hInstance, 0);
2707 if (hWnd)
2709 SetWindowLongA(hWnd, DWL_MSGRESULT, z);
2711 if (wndProc)
2712 SetWindowLongA(hWnd, GWL_WNDPROC, wndProc);
2714 return hWnd;
2717 /*************************************************************************
2718 * @ [SHLWAPI.279]
2720 * Get and show a context menu from a shell folder.
2722 * PARAMS
2723 * hWnd [I] Window displaying the shell folder
2724 * lpFolder [I] IShellFolder interface
2725 * lpApidl [I] Id for the particular folder desired
2727 * RETURNS
2728 * Success: S_OK.
2729 * Failure: An HRESULT error code indicating the error.
2731 HRESULT WINAPI SHInvokeDefaultCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl)
2733 return SHInvokeCommand(hWnd, lpFolder, lpApidl, FALSE);
2736 /*************************************************************************
2737 * @ [SHLWAPI.281]
2739 * _SHPackDispParamsV
2741 HRESULT WINAPI SHPackDispParamsV(LPVOID w, LPVOID x, LPVOID y, LPVOID z)
2743 FIXME("%p %p %p %p\n",w,x,y,z);
2744 return E_FAIL;
2747 /*************************************************************************
2748 * @ [SHLWAPI.282]
2750 * This function seems to be a forward to SHPackDispParamsV (whatever THAT
2751 * function does...).
2753 HRESULT WINAPI SHPackDispParams(LPVOID w, LPVOID x, LPVOID y, LPVOID z)
2755 FIXME("%p %p %p %p\n", w, x, y, z);
2756 return E_FAIL;
2759 /*************************************************************************
2760 * @ [SHLWAPI.284]
2762 * _IConnectionPoint_SimpleInvoke
2764 DWORD WINAPI IConnectionPoint_SimpleInvoke(
2765 LPVOID x,
2766 LPVOID y,
2767 LPVOID z)
2769 FIXME("(%p %p %p) stub\n",x,y,z);
2770 return 0;
2773 /*************************************************************************
2774 * @ [SHLWAPI.285]
2776 * Notify an IConnectionPoint object of changes.
2778 * PARAMS
2779 * lpCP [I] Object to notify
2780 * dispID [I]
2782 * RETURNS
2783 * Success: S_OK.
2784 * Failure: E_NOINTERFACE, if lpCP is NULL or does not support the
2785 * IConnectionPoint interface.
2787 HRESULT WINAPI IConnectionPoint_OnChanged(IConnectionPoint* lpCP, DISPID dispID)
2789 IEnumConnections *lpEnum;
2790 HRESULT hRet = E_NOINTERFACE;
2792 TRACE("(%p,0x%8lX)\n", lpCP, dispID);
2794 /* Get an enumerator for the connections */
2795 if (lpCP)
2796 hRet = IConnectionPoint_EnumConnections(lpCP, &lpEnum);
2798 if (SUCCEEDED(hRet))
2800 IPropertyNotifySink *lpSink;
2801 CONNECTDATA connData;
2802 ULONG ulFetched;
2804 /* Call OnChanged() for every notify sink in the connection point */
2805 while (IEnumConnections_Next(lpEnum, 1, &connData, &ulFetched) == S_OK)
2807 if (SUCCEEDED(IUnknown_QueryInterface(connData.pUnk, &IID_IPropertyNotifySink, (void**)&lpSink)) &&
2808 lpSink)
2810 IPropertyNotifySink_OnChanged(lpSink, dispID);
2811 IPropertyNotifySink_Release(lpSink);
2813 IUnknown_Release(connData.pUnk);
2816 IEnumConnections_Release(lpEnum);
2818 return hRet;
2821 /*************************************************************************
2822 * @ [SHLWAPI.287]
2824 * Notify an IConnectionPointContainer object of changes.
2826 * PARAMS
2827 * lpUnknown [I] Object to notify
2828 * dispID [I]
2830 * RETURNS
2831 * Success: S_OK.
2832 * Failure: E_NOINTERFACE, if lpUnknown is NULL or does not support the
2833 * IConnectionPointContainer interface.
2835 HRESULT WINAPI IUnknown_CPContainerOnChanged(IUnknown *lpUnknown, DISPID dispID)
2837 IConnectionPointContainer* lpCPC = NULL;
2838 HRESULT hRet = E_NOINTERFACE;
2840 TRACE("(%p,0x%8lX)\n", lpUnknown, dispID);
2842 if (lpUnknown)
2843 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer, (void**)&lpCPC);
2845 if (SUCCEEDED(hRet))
2847 IConnectionPoint* lpCP;
2849 hRet = IConnectionPointContainer_FindConnectionPoint(lpCPC, &IID_IPropertyNotifySink, &lpCP);
2850 IConnectionPointContainer_Release(lpCPC);
2852 hRet = IConnectionPoint_OnChanged(lpCP, dispID);
2853 IConnectionPoint_Release(lpCP);
2855 return hRet;
2858 /*************************************************************************
2859 * @ [SHLWAPI.289]
2861 * See PlaySoundW.
2863 BOOL WINAPI PlaySoundWrapW(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
2865 GET_FUNC(pPlaySoundW, winmm, "PlaySoundW", FALSE);
2866 return pPlaySoundW(pszSound, hmod, fdwSound);
2869 /*************************************************************************
2870 * @ [SHLWAPI.294]
2872 BOOL WINAPI SHGetIniStringW(LPSTR str1, LPSTR str2, LPSTR pStr, DWORD some_len, LPCSTR lpStr2)
2875 * str1: "I" "I" pushl esp+0x20
2876 * str2: "U" "I" pushl 0x77c93810
2877 * (is "I" and "U" "integer" and "unsigned" ??)
2879 * pStr: "" "" pushl eax
2880 * some_len: 0x824 0x104 pushl 0x824
2881 * lpStr2: "%l" "%l" pushl esp+0xc
2883 * shlwapi. StrCpyNW(lpStr2, irrelevant_var, 0x104);
2884 * LocalAlloc(0x00, some_len) -> irrelevant_var
2885 * LocalAlloc(0x40, irrelevant_len) -> pStr
2886 * shlwapi.294(str1, str2, pStr, some_len, lpStr2);
2887 * shlwapi.PathRemoveBlanksW(pStr);
2889 FIXME("('%s', '%s', '%s', %08lx, '%s'): stub!\n", str1, str2, pStr, some_len, lpStr2);
2890 return TRUE;
2893 /*************************************************************************
2894 * @ [SHLWAPI.295]
2896 * Called by ICQ2000b install via SHDOCVW:
2897 * str1: "InternetShortcut"
2898 * x: some unknown pointer
2899 * str2: "http://free.aol.com/tryaolfree/index.adp?139269"
2900 * str3: "C:\\WINDOWS\\Desktop.new2\\Free AOL & Unlimited Internet.url"
2902 * In short: this one maybe creates a desktop link :-)
2904 BOOL WINAPI SHSetIniStringW(LPWSTR str1, LPVOID x, LPWSTR str2, LPWSTR str3)
2906 FIXME("('%s', %p, '%s', '%s'), stub.\n", debugstr_w(str1), x, debugstr_w(str2), debugstr_w(str3));
2907 return TRUE;
2910 /*************************************************************************
2911 * @ [SHLWAPI.299]
2913 * See COMCTL32_417.
2915 BOOL WINAPI ExtTextOutWrapW(HDC hdc, INT x, INT y, UINT flags, const RECT *lprect,
2916 LPCWSTR str, UINT count, const INT *lpDx)
2918 GET_FUNC(pCOMCTL32_417, comctl32, (LPCSTR)417, FALSE);
2919 return pCOMCTL32_417(hdc, x, y, flags, lprect, str, count, lpDx);
2922 /*************************************************************************
2923 * @ [SHLWAPI.313]
2925 * See SHGetFileInfoW.
2927 DWORD WINAPI SHGetFileInfoWrapW(LPCWSTR path, DWORD dwFileAttributes,
2928 SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
2930 GET_FUNC(pSHGetFileInfoW, shell32, "SHGetFileInfoW", 0);
2931 return pSHGetFileInfoW(path, dwFileAttributes, psfi, sizeofpsfi, flags);
2934 /*************************************************************************
2935 * @ [SHLWAPI.318]
2937 * See DragQueryFileW.
2939 UINT WINAPI DragQueryFileWrapW(HDROP hDrop, UINT lFile, LPWSTR lpszFile, UINT lLength)
2941 GET_FUNC(pDragQueryFileW, shell32, "DragQueryFileW", 0);
2942 return pDragQueryFileW(hDrop, lFile, lpszFile, lLength);
2945 /*************************************************************************
2946 * @ [SHLWAPI.333]
2948 * See SHBrowseForFolderW.
2950 LPITEMIDLIST WINAPI SHBrowseForFolderWrapW(LPBROWSEINFOW lpBi)
2952 GET_FUNC(pSHBrowseForFolderW, shell32, "SHBrowseForFolderW", NULL);
2953 return pSHBrowseForFolderW(lpBi);
2956 /*************************************************************************
2957 * @ [SHLWAPI.334]
2959 * See SHGetPathFromIDListW.
2961 BOOL WINAPI SHGetPathFromIDListWrapW(LPCITEMIDLIST pidl,LPWSTR pszPath)
2963 GET_FUNC(pSHGetPathFromIDListW, shell32, "SHGetPathFromIDListW", 0);
2964 return pSHGetPathFromIDListW(pidl, pszPath);
2967 /*************************************************************************
2968 * @ [SHLWAPI.335]
2970 * See ShellExecuteExW.
2972 BOOL WINAPI ShellExecuteExWrapW(LPSHELLEXECUTEINFOW lpExecInfo)
2974 GET_FUNC(pShellExecuteExW, shell32, "ShellExecuteExW", FALSE);
2975 return pShellExecuteExW(lpExecInfo);
2978 /*************************************************************************
2979 * @ [SHLWAPI.336]
2981 * See SHFileOperationW.
2983 HICON WINAPI SHFileOperationWrapW(LPSHFILEOPSTRUCTW lpFileOp)
2985 GET_FUNC(pSHFileOperationW, shell32, "SHFileOperationW", 0);
2986 return pSHFileOperationW(lpFileOp);
2989 /*************************************************************************
2990 * @ [SHLWAPI.337]
2992 * See ExtractIconExW.
2994 UINT WINAPI ExtractIconExWrapW(LPCWSTR lpszFile, INT nIconIndex, HICON *phiconLarge,
2995 HICON *phiconSmall, UINT nIcons)
2997 GET_FUNC(pExtractIconExW, shell32, "ExtractIconExW", 0);
2998 return pExtractIconExW(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
3001 /*************************************************************************
3002 * @ [SHLWAPI.342]
3005 LONG WINAPI SHInterlockedCompareExchange( PLONG dest, LONG xchg, LONG compare)
3007 return InterlockedCompareExchange(dest, xchg, compare);
3010 /*************************************************************************
3011 * @ [SHLWAPI.346]
3013 DWORD WINAPI SHUnicodeToUnicode(
3014 LPCWSTR src,
3015 LPWSTR dest,
3016 int len)
3018 FIXME("(%s %p 0x%08x)stub\n",debugstr_w(src),dest,len);
3019 lstrcpynW(dest, src, len);
3020 return lstrlenW(dest)+1;
3023 /*************************************************************************
3024 * @ [SHLWAPI.350]
3026 * See GetFileVersionInfoSizeW.
3028 DWORD WINAPI GetFileVersionInfoSizeWrapW(
3029 LPWSTR x,
3030 LPVOID y)
3032 DWORD ret;
3034 GET_FUNC(pGetFileVersionInfoSizeW, version, "GetFileVersionInfoSizeW", 0);
3035 ret = pGetFileVersionInfoSizeW(x, y);
3036 return 0x208 + ret;
3039 /*************************************************************************
3040 * @ [SHLWAPI.351]
3042 * See GetFileVersionInfoW.
3044 BOOL WINAPI GetFileVersionInfoWrapW(
3045 LPWSTR w, /* [in] path to dll */
3046 DWORD x, /* [in] parm 2 to GetFileVersionInfoA */
3047 DWORD y, /* [in] return value from SHLWAPI_350() - assume length */
3048 LPVOID z) /* [in/out] buffer (+0x208 sent to GetFileVersionInfoA()) */
3050 GET_FUNC(pGetFileVersionInfoW, version, "GetFileVersionInfoW", 0);
3051 return pGetFileVersionInfoW(w, x, y-0x208, (char*)z+0x208);
3054 /*************************************************************************
3055 * @ [SHLWAPI.352]
3057 * See VerQueryValueW.
3059 WORD WINAPI VerQueryValueWrapW(
3060 LPVOID w, /* [in] Buffer from SHLWAPI_351() */
3061 LPWSTR x, /* [in] Value to retrieve - converted and passed to VerQueryValueA() as #2 */
3062 LPVOID y, /* [out] Ver buffer - passed to VerQueryValueA as #3 */
3063 UINT* z) /* [in] Ver length - passed to VerQueryValueA as #4 */
3065 GET_FUNC(pVerQueryValueW, version, "VerQueryValueW", 0);
3066 return pVerQueryValueW((char*)w+0x208, x, y, z);
3069 #define IsIface(type) SUCCEEDED((hRet = IUnknown_QueryInterface(lpUnknown, &IID_##type, (void**)&lpObj)))
3070 #define IShellBrowser_EnableModeless IShellBrowser_EnableModelessSB
3071 #define EnableModeless(type) type##_EnableModeless((type*)lpObj, bModeless)
3073 /*************************************************************************
3074 * @ [SHLWAPI.355]
3076 * Change the modality of a shell object.
3078 * PARAMS
3079 * lpUnknown [I] Object to make modeless
3080 * bModeless [I] TRUE=Make modeless, FALSE=Make modal
3082 * RETURNS
3083 * Success: S_OK. The modality lpUnknown is changed.
3084 * Failure: An HRESULT error code indicating the error.
3086 * NOTES
3087 * lpUnknown must support the IOleInPlaceFrame interface, the
3088 * IInternetSecurityMgrSite interface, the IShellBrowser interface
3089 * or the IDocHostUIHandler interface, or this call fails.
3091 HRESULT WINAPI IUnknown_EnableModeless(IUnknown *lpUnknown, BOOL bModeless)
3093 IUnknown *lpObj;
3094 HRESULT hRet;
3096 TRACE("(%p,%d)\n", lpUnknown, bModeless);
3098 if (!lpUnknown)
3099 return E_FAIL;
3101 if (IsIface(IOleInPlaceFrame))
3102 EnableModeless(IOleInPlaceFrame);
3103 else if (IsIface(IShellBrowser))
3104 EnableModeless(IShellBrowser);
3105 #if 0
3106 /* FIXME: Wine has no headers for these objects yet */
3107 else if (IsIface(IInternetSecurityMgrSite))
3108 EnableModeless(IInternetSecurityMgrSite);
3109 else if (IsIface(IDocHostUIHandler))
3110 EnableModeless(IDocHostUIHandler);
3111 #endif
3112 else
3113 return hRet;
3115 IUnknown_Release(lpObj);
3116 return S_OK;
3119 /*************************************************************************
3120 * @ [SHLWAPI.357]
3122 * See SHGetNewLinkInfoW.
3124 BOOL WINAPI SHGetNewLinkInfoWrapW(LPCWSTR pszLinkTo, LPCWSTR pszDir, LPWSTR pszName,
3125 BOOL *pfMustCopy, UINT uFlags)
3127 GET_FUNC(pSHGetNewLinkInfoW, shell32, "SHGetNewLinkInfoW", FALSE);
3128 return pSHGetNewLinkInfoW(pszLinkTo, pszDir, pszName, pfMustCopy, uFlags);
3131 /*************************************************************************
3132 * @ [SHLWAPI.358]
3134 * See SHDefExtractIconW.
3136 UINT WINAPI SHDefExtractIconWrapW(LPCWSTR pszIconFile, int iIndex, UINT uFlags, HICON* phiconLarge,
3137 HICON* phiconSmall, UINT nIconSize)
3139 GET_FUNC(pSHDefExtractIconW, shell32, "SHDefExtractIconW", 0);
3140 return pSHDefExtractIconW(pszIconFile, iIndex, uFlags, phiconLarge, phiconSmall, nIconSize);
3143 /*************************************************************************
3144 * @ [SHLWAPI.363]
3146 * Get and show a context menu from a shell folder.
3148 * PARAMS
3149 * hWnd [I] Window displaying the shell folder
3150 * lpFolder [I] IShellFolder interface
3151 * lpApidl [I] Id for the particular folder desired
3152 * bInvokeDefault [I] Whether to invoke the default menu item
3154 * RETURNS
3155 * Success: S_OK. If bInvokeDefault is TRUE, the default menu action was
3156 * executed.
3157 * Failure: An HRESULT error code indicating the error.
3159 HRESULT WINAPI SHInvokeCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl, BOOL bInvokeDefault)
3161 IContextMenu *iContext;
3162 HRESULT hRet = E_FAIL;
3164 TRACE("(%p,%p,%p,%d)\n", hWnd, lpFolder, lpApidl, bInvokeDefault);
3166 if (!lpFolder)
3167 return hRet;
3169 /* Get the context menu from the shell folder */
3170 hRet = IShellFolder_GetUIObjectOf(lpFolder, hWnd, 1, &lpApidl,
3171 &IID_IContextMenu, 0, (void**)&iContext);
3172 if (SUCCEEDED(hRet))
3174 HMENU hMenu;
3175 if ((hMenu = CreatePopupMenu()))
3177 HRESULT hQuery;
3178 DWORD dwDefaultId = 0;
3180 /* Add the context menu entries to the popup */
3181 hQuery = IContextMenu_QueryContextMenu(iContext, hMenu, 0, 1, 0x7FFF,
3182 bInvokeDefault ? CMF_NORMAL : CMF_DEFAULTONLY);
3184 if (SUCCEEDED(hQuery))
3186 if (bInvokeDefault &&
3187 (dwDefaultId = GetMenuDefaultItem(hMenu, 0, 0)) != 0xFFFFFFFF)
3189 CMINVOKECOMMANDINFO cmIci;
3190 /* Invoke the default item */
3191 memset(&cmIci,0,sizeof(cmIci));
3192 cmIci.cbSize = sizeof(cmIci);
3193 cmIci.fMask = CMIC_MASK_ASYNCOK;
3194 cmIci.hwnd = hWnd;
3195 cmIci.lpVerb = MAKEINTRESOURCEA(dwDefaultId);
3196 cmIci.nShow = SW_SCROLLCHILDREN;
3198 hRet = IContextMenu_InvokeCommand(iContext, &cmIci);
3201 DestroyMenu(hMenu);
3203 IContextMenu_Release(iContext);
3205 return hRet;
3208 /*************************************************************************
3209 * @ [SHLWAPI.370]
3211 * See ExtractIconW.
3213 HICON WINAPI ExtractIconWrapW(HINSTANCE hInstance, LPCWSTR lpszExeFileName,
3214 UINT nIconIndex)
3216 GET_FUNC(pExtractIconW, shell32, "ExtractIconW", NULL);
3217 return pExtractIconW(hInstance, lpszExeFileName, nIconIndex);
3220 /*************************************************************************
3221 * @ [SHLWAPI.376]
3223 LANGID WINAPI MLGetUILanguage()
3225 FIXME("() stub\n");
3226 /* FIXME: This should be a forward in the .spec file to the win2k function
3227 * kernel32.GetUserDefaultUILanguage, however that function isn't there yet.
3229 return GetUserDefaultLangID();
3232 /*************************************************************************
3233 * @ [SHLWAPI.377]
3235 * Load a library from the directory of a particular process.
3237 * PARAMS
3238 * new_mod [I] Library name
3239 * inst_hwnd [I] Module whose directory is to be used
3240 * dwFlags [I] Flags controlling the load
3242 * RETURNS
3243 * Success: A handle to the loaded module
3244 * Failure: A NULL handle.
3246 HMODULE WINAPI MLLoadLibraryA(LPCSTR new_mod, HMODULE inst_hwnd, DWORD dwFlags)
3248 /* FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for
3249 * each call here.
3250 * FIXME: Native shows calls to:
3251 * SHRegGetUSValue for "Software\Microsoft\Internet Explorer\International"
3252 * CheckVersion
3253 * RegOpenKeyExA for "HKLM\Software\Microsoft\Internet Explorer"
3254 * RegQueryValueExA for "LPKInstalled"
3255 * RegCloseKey
3256 * RegOpenKeyExA for "HKCU\Software\Microsoft\Internet Explorer\International"
3257 * RegQueryValueExA for "ResourceLocale"
3258 * RegCloseKey
3259 * RegOpenKeyExA for "HKLM\Software\Microsoft\Active Setup\Installed Components\{guid}"
3260 * RegQueryValueExA for "Locale"
3261 * RegCloseKey
3262 * and then tests the Locale ("en" for me).
3263 * code below
3264 * after the code then a DPA_Create (first time) and DPA_InsertPtr are done.
3266 CHAR mod_path[2*MAX_PATH];
3267 LPSTR ptr;
3269 FIXME("(%s,%p,0x%08lx) semi-stub!\n", debugstr_a(new_mod), inst_hwnd, dwFlags);
3270 GetModuleFileNameA(inst_hwnd, mod_path, 2*MAX_PATH);
3271 ptr = strrchr(mod_path, '\\');
3272 if (ptr) {
3273 strcpy(ptr+1, new_mod);
3274 TRACE("loading %s\n", debugstr_a(mod_path));
3275 return LoadLibraryA(mod_path);
3277 return NULL;
3280 /*************************************************************************
3281 * @ [SHLWAPI.378]
3283 * Unicode version of MLLoadLibraryA.
3285 HMODULE WINAPI MLLoadLibraryW(LPCWSTR new_mod, HMODULE inst_hwnd, DWORD dwFlags)
3287 WCHAR mod_path[2*MAX_PATH];
3288 LPWSTR ptr;
3290 FIXME("(%s,%p,0x%08lx) semi-stub!\n", debugstr_w(new_mod), inst_hwnd, dwFlags);
3291 GetModuleFileNameW(inst_hwnd, mod_path, 2*MAX_PATH);
3292 ptr = strrchrW(mod_path, '\\');
3293 if (ptr) {
3294 strcpyW(ptr+1, new_mod);
3295 TRACE("loading %s\n", debugstr_w(mod_path));
3296 return LoadLibraryW(mod_path);
3298 return NULL;
3301 /*************************************************************************
3302 * ColorAdjustLuma [SHLWAPI.@]
3304 * Adjust the luminosity of a color
3306 * PARAMS
3307 * cRGB [I] RGB value to convert
3308 * dwLuma [I] Luma adjustment
3309 * bUnknown [I] Unknown
3311 * RETURNS
3312 * The adjusted RGB color.
3314 COLORREF WINAPI ColorAdjustLuma(COLORREF cRGB, int dwLuma, BOOL bUnknown)
3316 TRACE("(0x%8lx,%d,%d)\n", cRGB, dwLuma, bUnknown);
3318 if (dwLuma)
3320 WORD wH, wL, wS;
3322 ColorRGBToHLS(cRGB, &wH, &wL, &wS);
3324 FIXME("Ignoring luma adjustment\n");
3326 /* FIXME: The ajdustment is not linear */
3328 cRGB = ColorHLSToRGB(wH, wL, wS);
3330 return cRGB;
3333 /*************************************************************************
3334 * @ [SHLWAPI.389]
3336 * See GetSaveFileNameW.
3338 BOOL WINAPI GetSaveFileNameWrapW(LPOPENFILENAMEW ofn)
3340 GET_FUNC(pGetSaveFileNameW, comdlg32, "GetSaveFileNameW", FALSE);
3341 return pGetSaveFileNameW(ofn);
3344 /*************************************************************************
3345 * @ [SHLWAPI.390]
3347 * See WNetRestoreConnectionW.
3349 DWORD WINAPI WNetRestoreConnectionWrapW(HWND hwndOwner, LPWSTR lpszDevice)
3351 GET_FUNC(pWNetRestoreConnectionW, mpr, "WNetRestoreConnectionW", 0);
3352 return pWNetRestoreConnectionW(hwndOwner, lpszDevice);
3355 /*************************************************************************
3356 * @ [SHLWAPI.391]
3358 * See WNetGetLastErrorW.
3360 DWORD WINAPI WNetGetLastErrorWrapW(LPDWORD lpError, LPWSTR lpErrorBuf, DWORD nErrorBufSize,
3361 LPWSTR lpNameBuf, DWORD nNameBufSize)
3363 GET_FUNC(pWNetGetLastErrorW, mpr, "WNetGetLastErrorW", 0);
3364 return pWNetGetLastErrorW(lpError, lpErrorBuf, nErrorBufSize, lpNameBuf, nNameBufSize);
3367 /*************************************************************************
3368 * @ [SHLWAPI.401]
3370 * See PageSetupDlgW.
3372 BOOL WINAPI PageSetupDlgWrapW(LPPAGESETUPDLGW pagedlg)
3374 GET_FUNC(pPageSetupDlgW, comdlg32, "PageSetupDlgW", FALSE);
3375 return pPageSetupDlgW(pagedlg);
3378 /*************************************************************************
3379 * @ [SHLWAPI.402]
3381 * See PrintDlgW.
3383 BOOL WINAPI PrintDlgWrapW(LPPRINTDLGW printdlg)
3385 GET_FUNC(pPrintDlgW, comdlg32, "PrintDlgW", FALSE);
3386 return pPrintDlgW(printdlg);
3389 /*************************************************************************
3390 * @ [SHLWAPI.403]
3392 * See GetOpenFileNameW.
3394 BOOL WINAPI GetOpenFileNameWrapW(LPOPENFILENAMEW ofn)
3396 GET_FUNC(pGetOpenFileNameW, comdlg32, "GetOpenFileNameW", FALSE);
3397 return pGetOpenFileNameW(ofn);
3400 /* INTERNAL: Map from HLS color space to RGB */
3401 static WORD WINAPI ConvertHue(int wHue, WORD wMid1, WORD wMid2)
3403 wHue = wHue > 240 ? wHue - 240 : wHue < 0 ? wHue + 240 : wHue;
3405 if (wHue > 160)
3406 return wMid1;
3407 else if (wHue > 120)
3408 wHue = 160 - wHue;
3409 else if (wHue > 40)
3410 return wMid2;
3412 return ((wHue * (wMid2 - wMid1) + 20) / 40) + wMid1;
3415 /* Convert to RGB and scale into RGB range (0..255) */
3416 #define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240
3418 /*************************************************************************
3419 * ColorHLSToRGB [SHLWAPI.@]
3421 * Convert from hls color space into an rgb COLORREF.
3423 * PARAMS
3424 * wHue [I] Hue amount
3425 * wLuminosity [I] Luminosity amount
3426 * wSaturation [I] Saturation amount
3428 * RETURNS
3429 * A COLORREF representing the converted color.
3431 * NOTES
3432 * Input hls values are constrained to the range (0..240).
3434 COLORREF WINAPI ColorHLSToRGB(WORD wHue, WORD wLuminosity, WORD wSaturation)
3436 WORD wRed;
3438 if (wSaturation)
3440 WORD wGreen, wBlue, wMid1, wMid2;
3442 if (wLuminosity > 120)
3443 wMid2 = wSaturation + wLuminosity - (wSaturation * wLuminosity + 120) / 240;
3444 else
3445 wMid2 = ((wSaturation + 240) * wLuminosity + 120) / 240;
3447 wMid1 = wLuminosity * 2 - wMid2;
3449 wRed = GET_RGB(wHue + 80);
3450 wGreen = GET_RGB(wHue);
3451 wBlue = GET_RGB(wHue - 80);
3453 return RGB(wRed, wGreen, wBlue);
3456 wRed = wLuminosity * 255 / 240;
3457 return RGB(wRed, wRed, wRed);
3460 /*************************************************************************
3461 * @ [SHLWAPI.413]
3463 * Get the current docking status of the system.
3465 * PARAMS
3466 * dwFlags [I] DOCKINFO_ flags from "winbase.h", unused
3468 * RETURNS
3469 * One of DOCKINFO_UNDOCKED, DOCKINFO_UNDOCKED, or 0 if the system is not
3470 * a notebook.
3472 DWORD WINAPI SHGetMachineInfo(DWORD dwFlags)
3474 HW_PROFILE_INFOA hwInfo;
3476 TRACE("(0x%08lx)\n", dwFlags);
3478 GetCurrentHwProfileA(&hwInfo);
3479 switch (hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED))
3481 case DOCKINFO_DOCKED:
3482 case DOCKINFO_UNDOCKED:
3483 return hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED);
3484 default:
3485 return 0;
3489 /*************************************************************************
3490 * @ [SHLWAPI.418]
3492 * Function seems to do FreeLibrary plus other things.
3494 * FIXME native shows the following calls:
3495 * RtlEnterCriticalSection
3496 * LocalFree
3497 * GetProcAddress(Comctl32??, 150L)
3498 * DPA_DeletePtr
3499 * RtlLeaveCriticalSection
3500 * followed by the FreeLibrary.
3501 * The above code may be related to .377 above.
3503 BOOL WINAPI MLFreeLibrary(HMODULE hModule)
3505 FIXME("(%p) semi-stub\n", hModule);
3506 return FreeLibrary(hModule);
3509 /*************************************************************************
3510 * @ [SHLWAPI.429]
3511 * FIXME I have no idea what this function does or what its arguments are.
3513 BOOL WINAPI MLIsMLHInstance(HINSTANCE hInst)
3515 FIXME("(%p) stub\n", hInst);
3516 return FALSE;
3520 /*************************************************************************
3521 * @ [SHLWAPI.430]
3523 DWORD WINAPI MLSetMLHInstance(HINSTANCE hInst, HANDLE hHeap)
3525 FIXME("(%p,%p) stub\n", hInst, hHeap);
3526 return E_FAIL; /* This is what is used if shlwapi not loaded */
3529 /*************************************************************************
3530 * @ [SHLWAPI.431]
3532 DWORD WINAPI MLClearMLHInstance(DWORD x)
3534 FIXME("(0x%08lx)stub\n", x);
3535 return 0xabba1247;
3538 /*************************************************************************
3539 * @ [SHLWAPI.436]
3541 * Convert an Unicode string CLSID into a CLSID.
3543 * PARAMS
3544 * idstr [I] string containing a CLSID in text form
3545 * id [O] CLSID extracted from the string
3547 * RETURNS
3548 * S_OK on success or E_INVALIDARG on failure
3550 * NOTES
3551 * This is really CLSIDFromString() which is exported by ole32.dll,
3552 * however the native shlwapi.dll does *not* import ole32. Nor does
3553 * ole32.dll import this ordinal from shlwapi. Therefore we must conclude
3554 * that MS duplicated the code for CLSIDFromString(), and yes they did, only
3555 * it returns an E_INVALIDARG error code on failure.
3556 * This is a duplicate (with changes for Unicode) of CLSIDFromString16()
3557 * in "dlls/ole32/compobj.c".
3559 HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR idstr, CLSID *id)
3561 LPCWSTR s = idstr;
3562 BYTE *p;
3563 INT i;
3564 WCHAR table[256];
3566 if (!s) {
3567 memset(id, 0, sizeof(CLSID));
3568 return S_OK;
3570 else { /* validate the CLSID string */
3572 if (strlenW(s) != 38)
3573 return E_INVALIDARG;
3575 if ((s[0]!=L'{') || (s[9]!=L'-') || (s[14]!=L'-') || (s[19]!=L'-') || (s[24]!=L'-') || (s[37]!=L'}'))
3576 return E_INVALIDARG;
3578 for (i=1; i<37; i++)
3580 if ((i == 9)||(i == 14)||(i == 19)||(i == 24))
3581 continue;
3582 if (!(((s[i] >= L'0') && (s[i] <= L'9')) ||
3583 ((s[i] >= L'a') && (s[i] <= L'f')) ||
3584 ((s[i] >= L'A') && (s[i] <= L'F')))
3586 return E_INVALIDARG;
3590 TRACE("%s -> %p\n", debugstr_w(s), id);
3592 /* quick lookup table */
3593 memset(table, 0, 256*sizeof(WCHAR));
3595 for (i = 0; i < 10; i++) {
3596 table['0' + i] = i;
3598 for (i = 0; i < 6; i++) {
3599 table['A' + i] = i+10;
3600 table['a' + i] = i+10;
3603 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
3605 p = (BYTE *) id;
3607 s++; /* skip leading brace */
3608 for (i = 0; i < 4; i++) {
3609 p[3 - i] = table[*s]<<4 | table[*(s+1)];
3610 s += 2;
3612 p += 4;
3613 s++; /* skip - */
3615 for (i = 0; i < 2; i++) {
3616 p[1-i] = table[*s]<<4 | table[*(s+1)];
3617 s += 2;
3619 p += 2;
3620 s++; /* skip - */
3622 for (i = 0; i < 2; i++) {
3623 p[1-i] = table[*s]<<4 | table[*(s+1)];
3624 s += 2;
3626 p += 2;
3627 s++; /* skip - */
3629 /* these are just sequential bytes */
3630 for (i = 0; i < 2; i++) {
3631 *p++ = table[*s]<<4 | table[*(s+1)];
3632 s += 2;
3634 s++; /* skip - */
3636 for (i = 0; i < 6; i++) {
3637 *p++ = table[*s]<<4 | table[*(s+1)];
3638 s += 2;
3641 return S_OK;
3644 /*************************************************************************
3645 * @ [SHLWAPI.437]
3647 * Determine if the OS supports a given feature.
3649 * PARAMS
3650 * dwFeature [I] Feature requested (undocumented)
3652 * RETURNS
3653 * TRUE If the feature is available.
3654 * FALSE If the feature is not available.
3656 DWORD WINAPI IsOS(DWORD feature)
3658 FIXME("(0x%08lx) stub\n", feature);
3659 if (feature == 4)
3660 return TRUE;
3661 return FALSE;
3664 /*************************************************************************
3665 * ColorRGBToHLS [SHLWAPI.@]
3667 * Convert an rgb COLORREF into the hls color space.
3669 * PARAMS
3670 * cRGB [I] Source rgb value
3671 * pwHue [O] Destination for converted hue
3672 * pwLuminance [O] Destination for converted luminance
3673 * pwSaturation [O] Destination for converted saturation
3675 * RETURNS
3676 * Nothing. pwHue, pwLuminance and pwSaturation are set to the converted
3677 * values.
3679 * NOTES
3680 * Output HLS values are constrained to the range (0..240).
3681 * For Achromatic conversions, Hue is set to 160.
3683 VOID WINAPI ColorRGBToHLS(COLORREF cRGB, LPWORD pwHue,
3684 LPWORD pwLuminance, LPWORD pwSaturation)
3686 int wR, wG, wB, wMax, wMin, wHue, wLuminosity, wSaturation;
3688 TRACE("(%08lx,%p,%p,%p)\n", cRGB, pwHue, pwLuminance, pwSaturation);
3690 wR = GetRValue(cRGB);
3691 wG = GetGValue(cRGB);
3692 wB = GetBValue(cRGB);
3694 wMax = max(wR, max(wG, wB));
3695 wMin = min(wR, min(wG, wB));
3697 /* Luminosity */
3698 wLuminosity = ((wMax + wMin) * 240 + 255) / 510;
3700 if (wMax == wMin)
3702 /* Achromatic case */
3703 wSaturation = 0;
3704 /* Hue is now unrepresentable, but this is what native returns... */
3705 wHue = 160;
3707 else
3709 /* Chromatic case */
3710 int wDelta = wMax - wMin, wRNorm, wGNorm, wBNorm;
3712 /* Saturation */
3713 if (wLuminosity <= 120)
3714 wSaturation = ((wMax + wMin)/2 + wDelta * 240) / (wMax + wMin);
3715 else
3716 wSaturation = ((510 - wMax - wMin)/2 + wDelta * 240) / (510 - wMax - wMin);
3718 /* Hue */
3719 wRNorm = (wDelta/2 + wMax * 40 - wR * 40) / wDelta;
3720 wGNorm = (wDelta/2 + wMax * 40 - wG * 40) / wDelta;
3721 wBNorm = (wDelta/2 + wMax * 40 - wB * 40) / wDelta;
3723 if (wR == wMax)
3724 wHue = wBNorm - wGNorm;
3725 else if (wG == wMax)
3726 wHue = 80 + wRNorm - wBNorm;
3727 else
3728 wHue = 160 + wGNorm - wRNorm;
3729 if (wHue < 0)
3730 wHue += 240;
3731 else if (wHue > 240)
3732 wHue -= 240;
3734 if (pwHue)
3735 *pwHue = wHue;
3736 if (pwLuminance)
3737 *pwLuminance = wLuminosity;
3738 if (pwSaturation)
3739 *pwSaturation = wSaturation;
3742 /*************************************************************************
3743 * SHCreateShellPalette [SHLWAPI.@]
3745 HPALETTE WINAPI SHCreateShellPalette(HDC hdc)
3747 FIXME("stub\n");
3748 return CreateHalftonePalette(hdc);
3751 /*************************************************************************
3752 * SHGetInverseCMAP (SHLWAPI.@)
3754 * Get an inverse color map table.
3756 * PARAMS
3757 * lpCmap [O] Destination for color map
3758 * dwSize [I] Size of memory pointed to by lpCmap
3760 * RETURNS
3761 * Success: S_OK.
3762 * Failure: E_POINTER, If lpCmap is invalid.
3763 * E_INVALIDARG, If dwFlags is invalid
3764 * E_OUTOFMEMORY, If there is no memory available
3766 * NOTES
3767 * dwSize may only be CMAP_PTR_SIZE (4) or CMAP_SIZE (8192).
3768 * If dwSize = CMAP_PTR_SIZE, *lpCmap is set to the address of this DLL's
3769 * internal CMap.
3770 * If dwSize = CMAP_SIZE, lpCmap is filled with a copy of the data from
3771 * this DLL's internal CMap.
3773 HRESULT WINAPI SHGetInverseCMAP(LPDWORD dest, DWORD dwSize)
3775 if (dwSize == 4) {
3776 FIXME(" - returning bogus address for SHGetInverseCMAP\n");
3777 *dest = (DWORD)0xabba1249;
3778 return 0;
3780 FIXME("(%p, %#lx) stub\n", dest, dwSize);
3781 return 0;
3784 /*************************************************************************
3785 * SHIsLowMemoryMachine [SHLWAPI.@]
3787 * Determine if the current computer has low memory.
3789 * PARAMS
3790 * x [I] FIXME
3792 * RETURNS
3793 * TRUE if the users machine has 16 Megabytes of memory or less,
3794 * FALSE otherwise.
3796 BOOL WINAPI SHIsLowMemoryMachine (DWORD x)
3798 FIXME("(0x%08lx) stub\n", x);
3799 return FALSE;
3802 /*************************************************************************
3803 * GetMenuPosFromID [SHLWAPI.@]
3805 * Return the position of a menu item from its Id.
3807 * PARAMS
3808 * hMenu [I] Menu containing the item
3809 * wID [I] Id of the menu item
3811 * RETURNS
3812 * Success: The index of the menu item in hMenu.
3813 * Failure: -1, If the item is not found.
3815 INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID)
3817 MENUITEMINFOA mi;
3818 INT nCount = GetMenuItemCount(hMenu), nIter = 0;
3820 while (nIter < nCount)
3822 mi.wID = 0;
3823 if (!GetMenuItemInfoA(hMenu, nIter, TRUE, &mi) && mi.wID == wID)
3824 return nIter;
3825 nIter++;
3827 return -1;
3830 /*************************************************************************
3831 * @ [SHLWAPI.179]
3833 * Same as SHLWAPI.GetMenuPosFromID
3835 DWORD WINAPI SHMenuIndexFromID(HMENU hMenu, UINT uID)
3837 return GetMenuPosFromID(hMenu, uID);
3841 /*************************************************************************
3842 * @ [SHLWAPI.448]
3844 VOID WINAPI FixSlashesAndColonW(LPWSTR lpwstr)
3846 while (*lpwstr)
3848 if (*lpwstr == '/')
3849 *lpwstr = '\\';
3850 lpwstr++;
3855 /*************************************************************************
3856 * @ [SHLWAPI.461]
3858 DWORD WINAPI SHGetAppCompatFlags()
3860 FIXME("stub\n");
3861 return 0;
3865 /*************************************************************************
3866 * @ [SHLWAPI.549]
3868 HRESULT WINAPI SHCoCreateInstanceAC(REFCLSID rclsid, LPUNKNOWN pUnkOuter,
3869 DWORD dwClsContext, REFIID iid, LPVOID *ppv)
3871 return CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, ppv);
3874 /*************************************************************************
3875 * SHSkipJunction [SHLWAPI.@]
3877 * Determine if a bind context can be bound to an object
3879 * PARAMS
3880 * pbc [I] Bind context to check
3881 * pclsid [I] CLSID of object to be bound to
3883 * RETURNS
3884 * TRUE: If it is safe to bind
3885 * FALSE: If pbc is invalid or binding would not be safe
3888 BOOL WINAPI SHSkipJunction(IBindCtx *pbc, const CLSID *pclsid)
3890 static WCHAR szSkipBinding[] = { 'S','k','i','p',' ',
3891 'B','i','n','d','i','n','g',' ','C','L','S','I','D','\0' };
3892 BOOL bRet = FALSE;
3894 if (pbc)
3896 IUnknown* lpUnk;
3898 if (SUCCEEDED(IBindCtx_GetObjectParam(pbc, szSkipBinding, &lpUnk)))
3900 CLSID clsid;
3902 if (SUCCEEDED(IUnknown_GetClassID(lpUnk, &clsid)) &&
3903 IsEqualGUID(pclsid, &clsid))
3904 bRet = TRUE;
3906 IUnknown_Release(lpUnk);
3909 return bRet;
3912 /***********************************************************************
3913 * SHGetShellKey (SHLWAPI.@)
3915 DWORD WINAPI SHGetShellKey(DWORD a, DWORD b, DWORD c)
3917 FIXME("(%lx, %lx, %lx): stub\n", a, b, c);
3918 return 0x50;
3921 /***********************************************************************
3922 * SHQueueUserWorkItem (SHLWAPI.@)
3924 HRESULT WINAPI SHQueueUserWorkItem(DWORD a, DWORD b, DWORD c, DWORD d, DWORD e, DWORD f, DWORD g)
3926 FIXME("(%lx, %lx, %lx, %lx, %lx, %lx, %lx): stub\n", a, b, c, d, e, f, g);
3927 return E_FAIL;
3930 /***********************************************************************
3931 * IUnknown_OnFocusChangeIS (SHLWAPI.@)
3933 DWORD WINAPI IUnknown_OnFocusChangeIS(IUnknown * pUnk, IUnknown * pFocusObject, BOOL bChange)
3935 FIXME("(%p, %p, %s)\n", pUnk, pFocusObject, bChange ? "TRUE" : "FALSE");
3938 IInputObjectSite * pIOS = NULL;
3939 if (SUCCEEDED(IUnknown_QueryInterface(pUnk, &IID_IInputObjectSite, (void **)&pIOS))
3940 IInputObjectSite_OnFocusChangeIS(pIOS, pFocusObject, bChange);
3943 return 0;
3946 /***********************************************************************
3947 * SHGetValueW (SHLWAPI.@)
3949 HRESULT WINAPI SKGetValueW(DWORD a, LPWSTR b, LPWSTR c, DWORD d, DWORD e, DWORD f)
3951 FIXME("(%lx, %s, %s, %lx, %lx, %lx): stub\n", a, debugstr_w(b), debugstr_w(c), d, e, f);
3952 return E_FAIL;