Remove stdlib.h inclusion if winsock.h is included.
[wine/dcerpc.git] / dlls / shlwapi / ordinal.c
blob6c61d550d923cab9f55b2c5f62b7da3383d89952
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 COBJMACROS
32 #define NONAMELESSUNION
33 #define NONAMELESSSTRUCT
35 #include "windef.h"
36 #include "winbase.h"
37 #include "winuser.h"
38 #include "winnls.h"
39 #include "objbase.h"
40 #include "docobj.h"
41 #include "exdisp.h"
42 #include "shlguid.h"
43 #include "wingdi.h"
44 #include "shlobj.h"
45 #include "shellapi.h"
46 #include "commdlg.h"
47 #include "wine/unicode.h"
48 #include "winreg.h"
49 #include "wine/debug.h"
50 #include "shlwapi.h"
53 WINE_DEFAULT_DEBUG_CHANNEL(shell);
55 /* Get a function pointer from a DLL handle */
56 #define GET_FUNC(func, module, name, fail) \
57 do { \
58 if (!func) { \
59 if (!SHLWAPI_h##module && !(SHLWAPI_h##module = LoadLibraryA(#module ".dll"))) return fail; \
60 func = (fn##func)GetProcAddress(SHLWAPI_h##module, name); \
61 if (!func) return fail; \
62 } \
63 } while (0)
65 /* DLL handles for late bound calls */
66 extern HINSTANCE shlwapi_hInstance;
67 extern HMODULE SHLWAPI_hshell32;
68 extern HMODULE SHLWAPI_hwinmm;
69 extern HMODULE SHLWAPI_hcomdlg32;
70 extern HMODULE SHLWAPI_hcomctl32;
71 extern HMODULE SHLWAPI_hmpr;
72 extern HMODULE SHLWAPI_hurlmon;
73 extern HMODULE SHLWAPI_hversion;
75 extern DWORD SHLWAPI_ThreadRef_index;
77 /* following is GUID for IObjectWithSite::SetSite -- see _174 */
78 static DWORD id1[4] = {0xfc4801a3, 0x11cf2ba9, 0xaa0029a2, 0x52733d00};
79 /* following is GUID for IPersistMoniker::GetClassID -- see _174 */
80 static DWORD id2[4] = {0x79eac9ee, 0x11cebaf9, 0xaa00828c, 0x0ba94b00};
82 /* Function pointers for GET_FUNC macro; these need to be global because of gcc bug */
83 typedef LPITEMIDLIST (WINAPI *fnpSHBrowseForFolderW)(LPBROWSEINFOW);
84 static fnpSHBrowseForFolderW pSHBrowseForFolderW;
85 typedef BOOL (WINAPI *fnpPlaySoundW)(LPCWSTR, HMODULE, DWORD);
86 static fnpPlaySoundW pPlaySoundW;
87 typedef DWORD (WINAPI *fnpSHGetFileInfoW)(LPCWSTR,DWORD,SHFILEINFOW*,UINT,UINT);
88 static fnpSHGetFileInfoW pSHGetFileInfoW;
89 typedef UINT (WINAPI *fnpDragQueryFileW)(HDROP, UINT, LPWSTR, UINT);
90 static fnpDragQueryFileW pDragQueryFileW;
91 typedef BOOL (WINAPI *fnpSHGetPathFromIDListW)(LPCITEMIDLIST, LPWSTR);
92 static fnpSHGetPathFromIDListW pSHGetPathFromIDListW;
93 typedef BOOL (WINAPI *fnpShellExecuteExW)(LPSHELLEXECUTEINFOW);
94 static fnpShellExecuteExW pShellExecuteExW;
95 typedef HICON (WINAPI *fnpSHFileOperationW)(LPSHFILEOPSTRUCTW);
96 static fnpSHFileOperationW pSHFileOperationW;
97 typedef UINT (WINAPI *fnpExtractIconExW)(LPCWSTR, INT,HICON *,HICON *, UINT);
98 static fnpExtractIconExW pExtractIconExW;
99 typedef BOOL (WINAPI *fnpSHGetNewLinkInfoW)(LPCWSTR, LPCWSTR, LPCWSTR, BOOL*, UINT);
100 static fnpSHGetNewLinkInfoW pSHGetNewLinkInfoW;
101 typedef HRESULT (WINAPI *fnpSHDefExtractIconW)(LPCWSTR, int, UINT, HICON*, HICON*, UINT);
102 static fnpSHDefExtractIconW pSHDefExtractIconW;
103 typedef HICON (WINAPI *fnpExtractIconW)(HINSTANCE, LPCWSTR, UINT);
104 static fnpExtractIconW pExtractIconW;
105 typedef BOOL (WINAPI *fnpGetSaveFileNameW)(LPOPENFILENAMEW);
106 static fnpGetSaveFileNameW pGetSaveFileNameW;
107 typedef DWORD (WINAPI *fnpWNetRestoreConnectionW)(HWND, LPWSTR);
108 static fnpWNetRestoreConnectionW pWNetRestoreConnectionW;
109 typedef DWORD (WINAPI *fnpWNetGetLastErrorW)(LPDWORD, LPWSTR, DWORD, LPWSTR, DWORD);
110 static fnpWNetGetLastErrorW pWNetGetLastErrorW;
111 typedef BOOL (WINAPI *fnpPageSetupDlgW)(LPPAGESETUPDLGW);
112 static fnpPageSetupDlgW pPageSetupDlgW;
113 typedef BOOL (WINAPI *fnpPrintDlgW)(LPPRINTDLGW);
114 static fnpPrintDlgW pPrintDlgW;
115 typedef BOOL (WINAPI *fnpGetOpenFileNameW)(LPOPENFILENAMEW);
116 static fnpGetOpenFileNameW pGetOpenFileNameW;
117 typedef DWORD (WINAPI *fnpGetFileVersionInfoSizeW)(LPCWSTR,LPDWORD);
118 static fnpGetFileVersionInfoSizeW pGetFileVersionInfoSizeW;
119 typedef BOOL (WINAPI *fnpGetFileVersionInfoW)(LPCWSTR,DWORD,DWORD,LPVOID);
120 static fnpGetFileVersionInfoW pGetFileVersionInfoW;
121 typedef WORD (WINAPI *fnpVerQueryValueW)(LPVOID,LPCWSTR,LPVOID*,UINT*);
122 static fnpVerQueryValueW pVerQueryValueW;
123 typedef BOOL (WINAPI *fnpCOMCTL32_417)(HDC,INT,INT,UINT,const RECT*,LPCWSTR,UINT,const INT*);
124 static fnpCOMCTL32_417 pCOMCTL32_417;
125 typedef HRESULT (WINAPI *fnpDllGetVersion)(DLLVERSIONINFO*);
126 static fnpDllGetVersion pDllGetVersion;
127 typedef HRESULT (WINAPI *fnpCreateFormatEnumerator)(UINT,FORMATETC*,IEnumFORMATETC**);
128 static fnpCreateFormatEnumerator pCreateFormatEnumerator;
129 typedef HRESULT (WINAPI *fnpRegisterFormatEnumerator)(LPBC,IEnumFORMATETC*,DWORD);
130 static fnpRegisterFormatEnumerator pRegisterFormatEnumerator;
132 HRESULT WINAPI IUnknown_QueryService(IUnknown*,REFGUID,REFIID,LPVOID*);
133 HRESULT WINAPI SHInvokeCommand(HWND,IShellFolder*,LPCITEMIDLIST,BOOL);
134 HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR,CLSID*);
135 BOOL WINAPI SHAboutInfoW(LPWSTR,DWORD);
138 NOTES: Most functions exported by ordinal seem to be superflous.
139 The reason for these functions to be there is to provide a wrapper
140 for unicode functions to provide these functions on systems without
141 unicode functions eg. win95/win98. Since we have such functions we just
142 call these. If running Wine with native DLL's, some late bound calls may
143 fail. However, it is better to implement the functions in the forward DLL
144 and recommend the builtin rather than reimplementing the calls here!
147 /*************************************************************************
148 * SHLWAPI_DupSharedHandle
150 * Internal implemetation of SHLWAPI_11.
152 static
153 HANDLE WINAPI SHLWAPI_DupSharedHandle(HANDLE hShared, DWORD dwDstProcId,
154 DWORD dwSrcProcId, DWORD dwAccess,
155 DWORD dwOptions)
157 HANDLE hDst, hSrc;
158 DWORD dwMyProcId = GetCurrentProcessId();
159 HANDLE hRet = NULL;
161 TRACE("(%p,%ld,%ld,%08lx,%08lx)\n", hShared, dwDstProcId, dwSrcProcId,
162 dwAccess, dwOptions);
164 /* Get dest process handle */
165 if (dwDstProcId == dwMyProcId)
166 hDst = GetCurrentProcess();
167 else
168 hDst = OpenProcess(PROCESS_DUP_HANDLE, 0, dwDstProcId);
170 if (hDst)
172 /* Get src process handle */
173 if (dwSrcProcId == dwMyProcId)
174 hSrc = GetCurrentProcess();
175 else
176 hSrc = OpenProcess(PROCESS_DUP_HANDLE, 0, dwSrcProcId);
178 if (hSrc)
180 /* Make handle available to dest process */
181 if (!DuplicateHandle(hDst, hShared, hSrc, &hRet,
182 dwAccess, 0, dwOptions | DUPLICATE_SAME_ACCESS))
183 hRet = NULL;
185 if (dwSrcProcId != dwMyProcId)
186 CloseHandle(hSrc);
189 if (dwDstProcId != dwMyProcId)
190 CloseHandle(hDst);
193 TRACE("Returning handle %p\n", hRet);
194 return hRet;
197 /*************************************************************************
198 * @ [SHLWAPI.7]
200 * Create a block of sharable memory and initialise it with data.
202 * PARAMS
203 * lpvData [I] Pointer to data to write
204 * dwSize [I] Size of data
205 * dwProcId [I] ID of process owning data
207 * RETURNS
208 * Success: A shared memory handle
209 * Failure: NULL
211 * NOTES
212 * Ordinals 7-11 provide a set of calls to create shared memory between a
213 * group of processes. The shared memory is treated opaquely in that its size
214 * is not exposed to clients who map it. This is accomplished by storing
215 * the size of the map as the first DWORD of mapped data, and then offsetting
216 * the view pointer returned by this size.
219 HANDLE WINAPI SHAllocShared(LPCVOID lpvData, DWORD dwSize, DWORD dwProcId)
221 HANDLE hMap;
222 LPVOID pMapped;
223 HANDLE hRet = NULL;
225 TRACE("(%p,%ld,%ld)\n", lpvData, dwSize, dwProcId);
227 /* Create file mapping of the correct length */
228 hMap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, FILE_MAP_READ, 0,
229 dwSize + sizeof(dwSize), NULL);
230 if (!hMap)
231 return hRet;
233 /* Get a view in our process address space */
234 pMapped = MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
236 if (pMapped)
238 /* Write size of data, followed by the data, to the view */
239 *((DWORD*)pMapped) = dwSize;
240 if (lpvData)
241 memcpy((char *) pMapped + sizeof(dwSize), lpvData, dwSize);
243 /* Release view. All further views mapped will be opaque */
244 UnmapViewOfFile(pMapped);
245 hRet = SHLWAPI_DupSharedHandle(hMap, dwProcId,
246 GetCurrentProcessId(), FILE_MAP_ALL_ACCESS,
247 DUPLICATE_SAME_ACCESS);
250 CloseHandle(hMap);
251 return hRet;
254 /*************************************************************************
255 * @ [SHLWAPI.8]
257 * Get a pointer to a block of shared memory from a shared memory handle.
259 * PARAMS
260 * hShared [I] Shared memory handle
261 * dwProcId [I] ID of process owning hShared
263 * RETURNS
264 * Success: A pointer to the shared memory
265 * Failure: NULL
268 PVOID WINAPI SHLockShared(HANDLE hShared, DWORD dwProcId)
270 HANDLE hDup;
271 LPVOID pMapped;
273 TRACE("(%p %ld)\n", hShared, dwProcId);
275 /* Get handle to shared memory for current process */
276 hDup = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
277 FILE_MAP_ALL_ACCESS, 0);
278 /* Get View */
279 pMapped = MapViewOfFile(hDup, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
280 CloseHandle(hDup);
282 if (pMapped)
283 return (char *) pMapped + sizeof(DWORD); /* Hide size */
284 return NULL;
287 /*************************************************************************
288 * @ [SHLWAPI.9]
290 * Release a pointer to a block of shared memory.
292 * PARAMS
293 * lpView [I] Shared memory pointer
295 * RETURNS
296 * Success: TRUE
297 * Failure: FALSE
300 BOOL WINAPI SHUnlockShared(LPVOID lpView)
302 TRACE("(%p)\n", lpView);
303 return UnmapViewOfFile((char *) lpView - sizeof(DWORD)); /* Include size */
306 /*************************************************************************
307 * @ [SHLWAPI.10]
309 * Destroy a block of sharable memory.
311 * PARAMS
312 * hShared [I] Shared memory handle
313 * dwProcId [I] ID of process owning hShared
315 * RETURNS
316 * Success: TRUE
317 * Failure: FALSE
320 BOOL WINAPI SHFreeShared(HANDLE hShared, DWORD dwProcId)
322 HANDLE hClose;
324 TRACE("(%p %ld)\n", hShared, dwProcId);
326 /* Get a copy of the handle for our process, closing the source handle */
327 hClose = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
328 FILE_MAP_ALL_ACCESS,DUPLICATE_CLOSE_SOURCE);
329 /* Close local copy */
330 return CloseHandle(hClose);
333 /*************************************************************************
334 * @ [SHLWAPI.11]
336 * Copy a sharable memory handle from one process to another.
338 * PARAMS
339 * hShared [I] Shared memory handle to duplicate
340 * dwDstProcId [I] ID of the process wanting the duplicated handle
341 * dwSrcProcId [I] ID of the process owning hShared
342 * dwAccess [I] Desired DuplicateHandle() access
343 * dwOptions [I] Desired DuplicateHandle() options
345 * RETURNS
346 * Success: A handle suitable for use by the dwDstProcId process.
347 * Failure: A NULL handle.
350 HANDLE WINAPI SHMapHandle(HANDLE hShared, DWORD dwDstProcId, DWORD dwSrcProcId,
351 DWORD dwAccess, DWORD dwOptions)
353 HANDLE hRet;
355 hRet = SHLWAPI_DupSharedHandle(hShared, dwDstProcId, dwSrcProcId,
356 dwAccess, dwOptions);
357 return hRet;
360 /*************************************************************************
361 * @ [SHLWAPI.13]
363 * Create and register a clipboard enumerator for a web browser.
365 * PARAMS
366 * lpBC [I] Binding context
367 * lpUnknown [I] An object exposing the IWebBrowserApp interface
369 * RETURNS
370 * Success: S_OK.
371 * Failure: An HRESULT error code.
373 * NOTES
374 * The enumerator is stored as a property of the web browser. If it does not
375 * yet exist, it is created and set before being registered.
377 HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown)
379 static const WCHAR szProperty[] = { '{','D','0','F','C','A','4','2','0',
380 '-','D','3','F','5','-','1','1','C','F', '-','B','2','1','1','-','0',
381 '0','A','A','0','0','4','A','E','8','3','7','}','\0' };
382 IEnumFORMATETC* pIEnumFormatEtc = NULL;
383 VARIANTARG var;
384 HRESULT hRet;
385 IWebBrowserApp* pBrowser = NULL;
387 TRACE("(%p, %p)\n", lpBC, lpUnknown);
389 /* Get An IWebBrowserApp interface from lpUnknown */
390 hRet = IUnknown_QueryService(lpUnknown, &IID_IWebBrowserApp, &IID_IWebBrowserApp, (PVOID)&pBrowser);
391 if (FAILED(hRet) || !pBrowser)
392 return E_NOINTERFACE;
394 V_VT(&var) = VT_EMPTY;
396 /* The property we get is the browsers clipboard enumerator */
397 hRet = IWebBrowserApp_GetProperty(pBrowser, (BSTR)szProperty, &var);
398 if (FAILED(hRet))
399 return hRet;
401 if (V_VT(&var) == VT_EMPTY)
403 /* Iterate through accepted documents and RegisterClipBoardFormatA() them */
404 char szKeyBuff[128], szValueBuff[128];
405 DWORD dwKeySize, dwValueSize, dwRet = 0, dwCount = 0, dwNumValues, dwType;
406 FORMATETC* formatList, *format;
407 HKEY hDocs;
409 TRACE("Registering formats and creating IEnumFORMATETC instance\n");
411 if (!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\Current"
412 "Version\\Internet Settings\\Accepted Documents", &hDocs))
413 return E_FAIL;
415 /* Get count of values in key */
416 while (!dwRet)
418 dwKeySize = sizeof(szKeyBuff);
419 dwRet = RegEnumValueA(hDocs,dwCount,szKeyBuff,&dwKeySize,0,&dwType,0,0);
420 dwCount++;
423 dwNumValues = dwCount;
425 /* Note: dwCount = number of items + 1; The extra item is the end node */
426 format = formatList = HeapAlloc(GetProcessHeap(), 0, dwCount * sizeof(FORMATETC));
427 if (!formatList)
428 return E_OUTOFMEMORY;
430 if (dwNumValues > 1)
432 dwRet = 0;
433 dwCount = 0;
435 dwNumValues--;
437 /* Register clipboard formats for the values and populate format list */
438 while(!dwRet && dwCount < dwNumValues)
440 dwKeySize = sizeof(szKeyBuff);
441 dwValueSize = sizeof(szValueBuff);
442 dwRet = RegEnumValueA(hDocs, dwCount, szKeyBuff, &dwKeySize, 0, &dwType,
443 (PBYTE)szValueBuff, &dwValueSize);
444 if (!dwRet)
445 return E_FAIL;
447 format->cfFormat = RegisterClipboardFormatA(szValueBuff);
448 format->ptd = NULL;
449 format->dwAspect = 1;
450 format->lindex = 4;
451 format->tymed = -1;
453 format++;
454 dwCount++;
458 /* Terminate the (maybe empty) list, last entry has a cfFormat of 0 */
459 format->cfFormat = 0;
460 format->ptd = NULL;
461 format->dwAspect = 1;
462 format->lindex = 4;
463 format->tymed = -1;
465 /* Create a clipboard enumerator */
466 GET_FUNC(pCreateFormatEnumerator, urlmon, "CreateFormatEnumerator", E_FAIL);
467 hRet = pCreateFormatEnumerator(dwNumValues, formatList, &pIEnumFormatEtc);
469 if (FAILED(hRet) || !pIEnumFormatEtc)
470 return hRet;
472 /* Set our enumerator as the browsers property */
473 V_VT(&var) = VT_UNKNOWN;
474 V_UNKNOWN(&var) = (IUnknown*)pIEnumFormatEtc;
476 hRet = IWebBrowserApp_PutProperty(pBrowser, (BSTR)szProperty, var);
477 if (FAILED(hRet))
479 IEnumFORMATETC_Release(pIEnumFormatEtc);
480 goto RegisterDefaultAcceptHeaders_Exit;
484 if (V_VT(&var) == VT_UNKNOWN)
486 /* Our variant is holding the clipboard enumerator */
487 IUnknown* pIUnknown = V_UNKNOWN(&var);
488 IEnumFORMATETC* pClone = NULL;
490 TRACE("Retrieved IEnumFORMATETC property\n");
492 /* Get an IEnumFormatEtc interface from the variants value */
493 pIEnumFormatEtc = NULL;
494 hRet = IUnknown_QueryInterface(pIUnknown, &IID_IEnumFORMATETC,
495 (PVOID)&pIEnumFormatEtc);
496 if (!hRet && pIEnumFormatEtc)
498 /* Clone and register the enumerator */
499 hRet = IEnumFORMATETC_Clone(pIEnumFormatEtc, &pClone);
500 if (!hRet && pClone)
502 GET_FUNC(pRegisterFormatEnumerator, urlmon, "RegisterFormatEnumerator", E_FAIL);
503 pRegisterFormatEnumerator(lpBC, pClone, 0);
505 IEnumFORMATETC_Release(pClone);
508 /* Release the IEnumFormatEtc interface */
509 IEnumFORMATETC_Release(pIUnknown);
511 IUnknown_Release(V_UNKNOWN(&var));
514 RegisterDefaultAcceptHeaders_Exit:
515 IWebBrowserApp_Release(pBrowser);
516 return hRet;
519 /*************************************************************************
520 * @ [SHLWAPI.15]
522 * Get Explorers "AcceptLanguage" setting.
524 * PARAMS
525 * langbuf [O] Destination for language string
526 * buflen [I] Length of langbuf
527 * [0] Success: used 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.
533 * E_INVALIDARG, If the buffer is not big enough
535 HRESULT WINAPI GetAcceptLanguagesW( LPWSTR langbuf, LPDWORD buflen)
537 static const WCHAR szkeyW[] = {
538 'S','o','f','t','w','a','r','e','\\',
539 'M','i','c','r','o','s','o','f','t','\\',
540 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
541 'I','n','t','e','r','n','a','t','i','o','n','a','l',0};
542 static const WCHAR valueW[] = {
543 'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0};
544 static const WCHAR enusW[] = {'e','n','-','u','s',0};
545 DWORD mystrlen, mytype;
546 HKEY mykey;
547 HRESULT retval;
548 LCID mylcid;
549 WCHAR *mystr;
551 if(!langbuf || !buflen || !*buflen)
552 return E_FAIL;
554 mystrlen = (*buflen > 20) ? *buflen : 20 ;
555 mystr = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * mystrlen);
556 RegOpenKeyW(HKEY_CURRENT_USER, szkeyW, &mykey);
557 if(RegQueryValueExW(mykey, valueW, 0, &mytype, (PBYTE)mystr, &mystrlen)) {
558 /* Did not find value */
559 mylcid = GetUserDefaultLCID();
560 /* somehow the mylcid translates into "en-us"
561 * this is similar to "LOCALE_SABBREVLANGNAME"
562 * which could be gotten via GetLocaleInfo.
563 * The only problem is LOCALE_SABBREVLANGUAGE" is
564 * a 3 char string (first 2 are country code and third is
565 * letter for "sublanguage", which does not come close to
566 * "en-us"
568 lstrcpyW(mystr, enusW);
569 mystrlen = lstrlenW(mystr);
570 } else {
571 /* handle returned string */
572 FIXME("missing code\n");
574 memcpy( langbuf, mystr, min(*buflen,strlenW(mystr)+1)*sizeof(WCHAR) );
576 if(*buflen > strlenW(mystr)) {
577 *buflen = strlenW(mystr);
578 retval = S_OK;
579 } else {
580 *buflen = 0;
581 retval = E_INVALIDARG;
582 SetLastError(ERROR_INSUFFICIENT_BUFFER);
584 RegCloseKey(mykey);
585 HeapFree(GetProcessHeap(), 0, mystr);
586 return retval;
589 /*************************************************************************
590 * @ [SHLWAPI.14]
592 * Ascii version of GetAcceptLanguagesW.
594 HRESULT WINAPI GetAcceptLanguagesA( LPSTR langbuf, LPDWORD buflen)
596 WCHAR *langbufW;
597 DWORD buflenW, convlen;
598 HRESULT retval;
600 if(!langbuf || !buflen || !*buflen) return E_FAIL;
602 buflenW = *buflen;
603 langbufW = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * buflenW);
604 retval = GetAcceptLanguagesW(langbufW, &buflenW);
606 /* FIXME: this is wrong, the string may not be null-terminated */
607 convlen = WideCharToMultiByte(CP_ACP, 0, langbufW, -1, langbuf,
608 *buflen, NULL, NULL);
609 *buflen = buflenW ? convlen : 0;
611 HeapFree(GetProcessHeap(), 0, langbufW);
612 return retval;
615 /*************************************************************************
616 * @ [SHLWAPI.23]
618 * Convert a GUID to a string.
620 * PARAMS
621 * guid [I] GUID to convert
622 * lpszDest [O] Destination for string
623 * cchMax [I] Length of output buffer
625 * RETURNS
626 * The length of the string created.
628 INT WINAPI SHStringFromGUIDA(REFGUID guid, LPSTR lpszDest, INT cchMax)
630 char xguid[40];
631 INT iLen;
633 TRACE("(%s,%p,%d)\n", debugstr_guid(guid), lpszDest, cchMax);
635 sprintf(xguid, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
636 guid->Data1, guid->Data2, guid->Data3,
637 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
638 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
640 iLen = strlen(xguid) + 1;
642 if (iLen > cchMax)
643 return 0;
644 memcpy(lpszDest, xguid, iLen);
645 return iLen;
648 /*************************************************************************
649 * @ [SHLWAPI.24]
651 * Convert a GUID to a string.
653 * PARAMS
654 * guid [I] GUID to convert
655 * str [O] Destination for string
656 * cmax [I] Length of output buffer
658 * RETURNS
659 * The length of the string created.
661 INT WINAPI SHStringFromGUIDW(REFGUID guid, LPWSTR lpszDest, INT cchMax)
663 WCHAR xguid[40];
664 INT iLen;
665 static const WCHAR wszFormat[] = {'{','%','0','8','l','X','-','%','0','4','X','-','%','0','4','X','-',
666 '%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','%','0','2','X','%','0','2',
667 'X','%','0','2','X','%','0','2','X','}',0};
669 TRACE("(%s,%p,%d)\n", debugstr_guid(guid), lpszDest, cchMax);
671 sprintfW(xguid, wszFormat, guid->Data1, guid->Data2, guid->Data3,
672 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
673 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
675 iLen = strlenW(xguid) + 1;
677 if (iLen > cchMax)
678 return 0;
679 memcpy(lpszDest, xguid, iLen*sizeof(WCHAR));
680 return iLen;
683 /*************************************************************************
684 * @ [SHLWAPI.29]
686 * Determine if a Unicode character is a space.
688 * PARAMS
689 * wc [I] Character to check.
691 * RETURNS
692 * TRUE, if wc is a space,
693 * FALSE otherwise.
695 BOOL WINAPI IsCharSpaceW(WCHAR wc)
697 WORD CharType;
699 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_SPACE);
702 /*************************************************************************
703 * @ [SHLWAPI.30]
705 * Determine if a Unicode character is a blank.
707 * PARAMS
708 * wc [I] Character to check.
710 * RETURNS
711 * TRUE, if wc is a blank,
712 * FALSE otherwise.
715 BOOL WINAPI IsCharBlankW(WCHAR wc)
717 WORD CharType;
719 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_BLANK);
722 /*************************************************************************
723 * @ [SHLWAPI.31]
725 * Determine if a Unicode character is punctuation.
727 * PARAMS
728 * wc [I] Character to check.
730 * RETURNS
731 * TRUE, if wc is punctuation,
732 * FALSE otherwise.
734 BOOL WINAPI IsCharPunctW(WCHAR wc)
736 WORD CharType;
738 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_PUNCT);
741 /*************************************************************************
742 * @ [SHLWAPI.32]
744 * Determine if a Unicode character is a control character.
746 * PARAMS
747 * wc [I] Character to check.
749 * RETURNS
750 * TRUE, if wc is a control character,
751 * FALSE otherwise.
753 BOOL WINAPI IsCharCntrlW(WCHAR wc)
755 WORD CharType;
757 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_CNTRL);
760 /*************************************************************************
761 * @ [SHLWAPI.33]
763 * Determine if a Unicode character is a digit.
765 * PARAMS
766 * wc [I] Character to check.
768 * RETURNS
769 * TRUE, if wc is a digit,
770 * FALSE otherwise.
772 BOOL WINAPI IsCharDigitW(WCHAR wc)
774 WORD CharType;
776 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_DIGIT);
779 /*************************************************************************
780 * @ [SHLWAPI.34]
782 * Determine if a Unicode character is a hex digit.
784 * PARAMS
785 * wc [I] Character to check.
787 * RETURNS
788 * TRUE, if wc is a hex digit,
789 * FALSE otherwise.
791 BOOL WINAPI IsCharXDigitW(WCHAR wc)
793 WORD CharType;
795 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_XDIGIT);
798 /*************************************************************************
799 * @ [SHLWAPI.35]
802 BOOL WINAPI GetStringType3ExW(LPWSTR lpszStr, DWORD dwLen, LPVOID p3)
804 FIXME("(%s,0x%08lx,%p): stub\n", debugstr_w(lpszStr), dwLen, p3);
805 return TRUE;
808 /*************************************************************************
809 * @ [SHLWAPI.36]
811 * Insert a bitmap menu item at the bottom of a menu.
813 * PARAMS
814 * hMenu [I] Menu to insert into
815 * flags [I] Flags for insertion
816 * id [I] Menu ID of the item
817 * str [I] Menu text for the item
819 * RETURNS
820 * Success: TRUE, the item is inserted into the menu
821 * Failure: FALSE, if any parameter is invalid
823 BOOL WINAPI AppendMenuWrapW(HMENU hMenu, UINT flags, UINT id, LPCWSTR str)
825 TRACE("(%p,0x%08x,0x%08x,%s)\n",hMenu, flags, id, debugstr_w(str));
826 return InsertMenuW(hMenu, -1, flags | MF_BITMAP, id, str);
829 /*************************************************************************
830 * @ [SHLWAPI.74]
832 * Get the text from a given dialog item.
834 * PARAMS
835 * hWnd [I] Handle of dialog
836 * nItem [I] Index of item
837 * lpsDest [O] Buffer for receiving window text
838 * nDestLen [I] Length of buffer.
840 * RETURNS
841 * Success: The length of the returned text.
842 * Failure: 0.
844 INT WINAPI GetDlgItemTextWrapW(HWND hWnd, INT nItem, LPWSTR lpsDest,INT nDestLen)
846 HWND hItem = GetDlgItem(hWnd, nItem);
848 if (hItem)
849 return GetWindowTextW(hItem, lpsDest, nDestLen);
850 if (nDestLen)
851 *lpsDest = (WCHAR)'\0';
852 return 0;
855 /*************************************************************************
856 * @ [SHLWAPI.138]
858 * Set the text of a given dialog item.
860 * PARAMS
861 * hWnd [I] Handle of dialog
862 * iItem [I] Index of item
863 * lpszText [O] Text to set
865 * RETURNS
866 * Success: TRUE. The text of the dialog is set to lpszText.
867 * Failure: FALSE, Otherwise.
869 BOOL WINAPI SetDlgItemTextWrapW(HWND hWnd, INT iItem, LPCWSTR lpszText)
871 HWND hWndItem = GetDlgItem(hWnd, iItem);
872 if (hWndItem)
873 return SetWindowTextW(hWndItem, lpszText);
874 return FALSE;
877 /*************************************************************************
878 * @ [SHLWAPI.151]
880 * Compare two Ascii strings up to a given length.
882 * PARAMS
883 * lpszSrc [I] Source string
884 * lpszCmp [I] String to compare to lpszSrc
885 * len [I] Maximum length
887 * RETURNS
888 * A number greater than, less than or equal to 0 depending on whether
889 * lpszSrc is greater than, less than or equal to lpszCmp.
891 DWORD WINAPI StrCmpNCA(LPCSTR lpszSrc, LPCSTR lpszCmp, INT len)
893 return strncmp(lpszSrc, lpszCmp, len);
896 /*************************************************************************
897 * @ [SHLWAPI.152]
899 * Unicode version of StrCmpNCA.
901 DWORD WINAPI StrCmpNCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, INT len)
903 return strncmpW(lpszSrc, lpszCmp, len);
906 /*************************************************************************
907 * @ [SHLWAPI.153]
909 * Compare two Ascii strings up to a given length, ignoring case.
911 * PARAMS
912 * lpszSrc [I] Source string
913 * lpszCmp [I] String to compare to lpszSrc
914 * len [I] Maximum length
916 * RETURNS
917 * A number greater than, less than or equal to 0 depending on whether
918 * lpszSrc is greater than, less than or equal to lpszCmp.
920 DWORD WINAPI StrCmpNICA(LPCSTR lpszSrc, LPCSTR lpszCmp, DWORD len)
922 return strncasecmp(lpszSrc, lpszCmp, len);
925 /*************************************************************************
926 * @ [SHLWAPI.154]
928 * Unicode version of StrCmpNICA.
930 DWORD WINAPI StrCmpNICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, DWORD len)
932 return strncmpiW(lpszSrc, lpszCmp, len);
935 /*************************************************************************
936 * @ [SHLWAPI.155]
938 * Compare two Ascii strings.
940 * PARAMS
941 * lpszSrc [I] Source string
942 * lpszCmp [I] String to compare to lpszSrc
944 * RETURNS
945 * A number greater than, less than or equal to 0 depending on whether
946 * lpszSrc is greater than, less than or equal to lpszCmp.
948 DWORD WINAPI StrCmpCA(LPCSTR lpszSrc, LPCSTR lpszCmp)
950 return strcmp(lpszSrc, lpszCmp);
953 /*************************************************************************
954 * @ [SHLWAPI.156]
956 * Unicode version of StrCmpCA.
958 DWORD WINAPI StrCmpCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp)
960 return strcmpW(lpszSrc, lpszCmp);
963 /*************************************************************************
964 * @ [SHLWAPI.157]
966 * Compare two Ascii strings, ignoring case.
968 * PARAMS
969 * lpszSrc [I] Source string
970 * lpszCmp [I] String to compare to lpszSrc
972 * RETURNS
973 * A number greater than, less than or equal to 0 depending on whether
974 * lpszSrc is greater than, less than or equal to lpszCmp.
976 DWORD WINAPI StrCmpICA(LPCSTR lpszSrc, LPCSTR lpszCmp)
978 return strcasecmp(lpszSrc, lpszCmp);
981 /*************************************************************************
982 * @ [SHLWAPI.158]
984 * Unicode version of StrCmpICA.
986 DWORD WINAPI StrCmpICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp)
988 return strcmpiW(lpszSrc, lpszCmp);
991 /*************************************************************************
992 * @ [SHLWAPI.160]
994 * Get an identification string for the OS and explorer.
996 * PARAMS
997 * lpszDest [O] Destination for Id string
998 * dwDestLen [I] Length of lpszDest
1000 * RETURNS
1001 * TRUE, If the string was created successfully
1002 * FALSE, Otherwise
1004 BOOL WINAPI SHAboutInfoA(LPSTR lpszDest, DWORD dwDestLen)
1006 WCHAR buff[2084];
1008 TRACE("(%p,%ld)\n", lpszDest, dwDestLen);
1010 if (lpszDest && SHAboutInfoW(buff, dwDestLen))
1012 WideCharToMultiByte(CP_ACP, 0, buff, -1, lpszDest, dwDestLen, NULL, NULL);
1013 return TRUE;
1015 return FALSE;
1018 /*************************************************************************
1019 * @ [SHLWAPI.161]
1021 * Unicode version of SHAboutInfoA.
1023 BOOL WINAPI SHAboutInfoW(LPWSTR lpszDest, DWORD dwDestLen)
1025 static const WCHAR szIEKey[] = { 'S','O','F','T','W','A','R','E','\\',
1026 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
1027 ' ','E','x','p','l','o','r','e','r','\0' };
1028 static const WCHAR szWinNtKey[] = { 'S','O','F','T','W','A','R','E','\\',
1029 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s',' ',
1030 'N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
1031 static const WCHAR szWinKey[] = { 'S','O','F','T','W','A','R','E','\\',
1032 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
1033 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
1034 static const WCHAR szRegKey[] = { 'S','O','F','T','W','A','R','E','\\',
1035 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
1036 ' ','E','x','p','l','o','r','e','r','\\',
1037 'R','e','g','i','s','t','r','a','t','i','o','n','\0' };
1038 static const WCHAR szVersion[] = { 'V','e','r','s','i','o','n','\0' };
1039 static const WCHAR szCustomized[] = { 'C','u','s','t','o','m','i','z','e','d',
1040 'V','e','r','s','i','o','n','\0' };
1041 static const WCHAR szOwner[] = { 'R','e','g','i','s','t','e','r','e','d',
1042 'O','w','n','e','r','\0' };
1043 static const WCHAR szOrg[] = { 'R','e','g','i','s','t','e','r','e','d',
1044 'O','r','g','a','n','i','z','a','t','i','o','n','\0' };
1045 static const WCHAR szProduct[] = { 'P','r','o','d','u','c','t','I','d','\0' };
1046 static const WCHAR szUpdate[] = { 'I','E','A','K',
1047 'U','p','d','a','t','e','U','r','l','\0' };
1048 static const WCHAR szHelp[] = { 'I','E','A','K',
1049 'H','e','l','p','S','t','r','i','n','g','\0' };
1050 WCHAR buff[2084];
1051 HKEY hReg;
1052 DWORD dwType, dwLen;
1054 TRACE("(%p,%ld)\n", lpszDest, dwDestLen);
1056 if (!lpszDest)
1057 return FALSE;
1059 *lpszDest = '\0';
1061 /* Try the NT key first, followed by 95/98 key */
1062 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinNtKey, 0, KEY_READ, &hReg) &&
1063 RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinKey, 0, KEY_READ, &hReg))
1064 return FALSE;
1066 /* OS Version */
1067 buff[0] = '\0';
1068 dwLen = 30;
1069 if (!SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey, szVersion, &dwType, buff, &dwLen))
1071 DWORD dwStrLen = strlenW(buff);
1072 dwLen = 30 - dwStrLen;
1073 SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey,
1074 szCustomized, &dwType, buff+dwStrLen, &dwLen);
1076 StrCatBuffW(lpszDest, buff, dwDestLen);
1078 /* ~Registered Owner */
1079 buff[0] = '~';
1080 dwLen = 256;
1081 if (SHGetValueW(hReg, szOwner, 0, &dwType, buff+1, &dwLen))
1082 buff[1] = '\0';
1083 StrCatBuffW(lpszDest, buff, dwDestLen);
1085 /* ~Registered Organization */
1086 dwLen = 256;
1087 if (SHGetValueW(hReg, szOrg, 0, &dwType, buff+1, &dwLen))
1088 buff[1] = '\0';
1089 StrCatBuffW(lpszDest, buff, dwDestLen);
1091 /* FIXME: Not sure where this number comes from */
1092 buff[0] = '~';
1093 buff[1] = '0';
1094 buff[2] = '\0';
1095 StrCatBuffW(lpszDest, buff, dwDestLen);
1097 /* ~Product Id */
1098 dwLen = 256;
1099 if (SHGetValueW(HKEY_LOCAL_MACHINE, szRegKey, szProduct, &dwType, buff+1, &dwLen))
1100 buff[1] = '\0';
1101 StrCatBuffW(lpszDest, buff, dwDestLen);
1103 /* ~IE Update Url */
1104 dwLen = 2048;
1105 if(SHGetValueW(HKEY_LOCAL_MACHINE, szWinKey, szUpdate, &dwType, buff+1, &dwLen))
1106 buff[1] = '\0';
1107 StrCatBuffW(lpszDest, buff, dwDestLen);
1109 /* ~IE Help String */
1110 dwLen = 256;
1111 if(SHGetValueW(hReg, szHelp, 0, &dwType, buff+1, &dwLen))
1112 buff[1] = '\0';
1113 StrCatBuffW(lpszDest, buff, dwDestLen);
1115 RegCloseKey(hReg);
1116 return TRUE;
1119 /*************************************************************************
1120 * @ [SHLWAPI.163]
1122 * Call IOleCommandTarget_QueryStatus() on an object.
1124 * PARAMS
1125 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1126 * pguidCmdGroup [I] GUID for the command group
1127 * cCmds [I]
1128 * prgCmds [O] Commands
1129 * pCmdText [O] Command text
1131 * RETURNS
1132 * Success: S_OK.
1133 * Failure: E_FAIL, if lpUnknown is NULL.
1134 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1135 * Otherwise, an error code from IOleCommandTarget_QueryStatus().
1137 HRESULT WINAPI IUnknown_QueryStatus(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
1138 ULONG cCmds, OLECMD *prgCmds, OLECMDTEXT* pCmdText)
1140 HRESULT hRet = E_FAIL;
1142 TRACE("(%p,%p,%ld,%p,%p)\n",lpUnknown, pguidCmdGroup, cCmds, prgCmds, pCmdText);
1144 if (lpUnknown)
1146 IOleCommandTarget* lpOle;
1148 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
1149 (void**)&lpOle);
1151 if (SUCCEEDED(hRet) && lpOle)
1153 hRet = IOleCommandTarget_QueryStatus(lpOle, pguidCmdGroup, cCmds,
1154 prgCmds, pCmdText);
1155 IOleCommandTarget_Release(lpOle);
1158 return hRet;
1161 /*************************************************************************
1162 * @ [SHLWAPI.164]
1164 * Call IOleCommandTarget_Exec() on an object.
1166 * PARAMS
1167 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1168 * pguidCmdGroup [I] GUID for the command group
1170 * RETURNS
1171 * Success: S_OK.
1172 * Failure: E_FAIL, if lpUnknown is NULL.
1173 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1174 * Otherwise, an error code from IOleCommandTarget_Exec().
1176 HRESULT WINAPI IUnknown_Exec(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
1177 DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
1178 VARIANT* pvaOut)
1180 HRESULT hRet = E_FAIL;
1182 TRACE("(%p,%p,%ld,%ld,%p,%p)\n",lpUnknown, pguidCmdGroup, nCmdID,
1183 nCmdexecopt, pvaIn, pvaOut);
1185 if (lpUnknown)
1187 IOleCommandTarget* lpOle;
1189 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
1190 (void**)&lpOle);
1191 if (SUCCEEDED(hRet) && lpOle)
1193 hRet = IOleCommandTarget_Exec(lpOle, pguidCmdGroup, nCmdID,
1194 nCmdexecopt, pvaIn, pvaOut);
1195 IOleCommandTarget_Release(lpOle);
1198 return hRet;
1201 /*************************************************************************
1202 * @ [SHLWAPI.165]
1204 * Retrieve, modify, and re-set a value from a window.
1206 * PARAMS
1207 * hWnd [I] Window to get value from
1208 * offset [I] Offset of value
1209 * wMask [I] Mask for uiFlags
1210 * wFlags [I] Bits to set in window value
1212 * RETURNS
1213 * The new value as it was set, or 0 if any parameter is invalid.
1215 * NOTES
1216 * Any bits set in uiMask are cleared from the value, then any bits set in
1217 * uiFlags are set in the value.
1219 LONG WINAPI SHSetWindowBits(HWND hwnd, INT offset, UINT wMask, UINT wFlags)
1221 LONG ret = GetWindowLongA(hwnd, offset);
1222 LONG newFlags = (wFlags & wMask) | (ret & ~wFlags);
1224 if (newFlags != ret)
1225 ret = SetWindowLongA(hwnd, offset, newFlags);
1226 return ret;
1229 /*************************************************************************
1230 * @ [SHLWAPI.167]
1232 * Change a window's parent.
1234 * PARAMS
1235 * hWnd [I] Window to change parent of
1236 * hWndParent [I] New parent window
1238 * RETURNS
1239 * The old parent of hWnd.
1241 * NOTES
1242 * If hWndParent is NULL (desktop), the window style is changed to WS_POPUP.
1243 * If hWndParent is NOT NULL then we set the WS_CHILD style.
1245 HWND WINAPI SHSetParentHwnd(HWND hWnd, HWND hWndParent)
1247 TRACE("%p, %p\n", hWnd, hWndParent);
1249 if(GetParent(hWnd) == hWndParent)
1250 return 0;
1252 if(hWndParent)
1253 SHSetWindowBits(hWnd, GWL_STYLE, WS_CHILD, WS_CHILD);
1254 else
1255 SHSetWindowBits(hWnd, GWL_STYLE, WS_POPUP, WS_POPUP);
1257 return SetParent(hWnd, hWndParent);
1260 /*************************************************************************
1261 * @ [SHLWAPI.168]
1263 * Locate and advise a connection point in an IConnectionPointContainer object.
1265 * PARAMS
1266 * lpUnkSink [I] Sink for the connection point advise call
1267 * riid [I] REFIID of connection point to advise
1268 * bAdviseOnly [I] TRUE = Advise only, FALSE = Unadvise first
1269 * lpUnknown [I] Object supporting the IConnectionPointContainer interface
1270 * lpCookie [O] Pointer to connection point cookie
1271 * lppCP [O] Destination for the IConnectionPoint found
1273 * RETURNS
1274 * Success: S_OK. If lppCP is non-NULL, it is filled with the IConnectionPoint
1275 * that was advised. The caller is responsable for releasing it.
1276 * Failure: E_FAIL, if any arguments are invalid.
1277 * E_NOINTERFACE, if lpUnknown isn't an IConnectionPointContainer,
1278 * Or an HRESULT error code if any call fails.
1280 HRESULT WINAPI ConnectToConnectionPoint(IUnknown* lpUnkSink, REFIID riid, BOOL bAdviseOnly,
1281 IUnknown* lpUnknown, LPDWORD lpCookie,
1282 IConnectionPoint **lppCP)
1284 HRESULT hRet;
1285 IConnectionPointContainer* lpContainer;
1286 IConnectionPoint *lpCP;
1288 if(!lpUnknown || (bAdviseOnly && !lpUnkSink))
1289 return E_FAIL;
1291 if(lppCP)
1292 *lppCP = NULL;
1294 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer,
1295 (void**)&lpContainer);
1296 if (SUCCEEDED(hRet))
1298 hRet = IConnectionPointContainer_FindConnectionPoint(lpContainer, riid, &lpCP);
1300 if (SUCCEEDED(hRet))
1302 if(!bAdviseOnly)
1303 hRet = IConnectionPoint_Unadvise(lpCP, *lpCookie);
1304 hRet = IConnectionPoint_Advise(lpCP, lpUnkSink, lpCookie);
1306 if (FAILED(hRet))
1307 *lpCookie = 0;
1309 if (lppCP && SUCCEEDED(hRet))
1310 *lppCP = lpCP; /* Caller keeps the interface */
1311 else
1312 IConnectionPoint_Release(lpCP); /* Release it */
1315 IUnknown_Release(lpContainer);
1317 return hRet;
1320 /*************************************************************************
1321 * @ [SHLWAPI.169]
1323 * Release an interface.
1325 * PARAMS
1326 * lpUnknown [I] Object to release
1328 * RETURNS
1329 * Nothing.
1331 DWORD WINAPI IUnknown_AtomicRelease(IUnknown ** lpUnknown)
1333 IUnknown *temp;
1335 TRACE("(%p)\n",lpUnknown);
1337 if(!lpUnknown || !*((LPDWORD)lpUnknown)) return 0;
1338 temp = *lpUnknown;
1339 *lpUnknown = NULL;
1341 TRACE("doing Release\n");
1343 return IUnknown_Release(temp);
1346 /*************************************************************************
1347 * @ [SHLWAPI.170]
1349 * Skip '//' if present in a string.
1351 * PARAMS
1352 * lpszSrc [I] String to check for '//'
1354 * RETURNS
1355 * Success: The next character after the '//' or the string if not present
1356 * Failure: NULL, if lpszStr is NULL.
1358 LPCSTR WINAPI PathSkipLeadingSlashesA(LPCSTR lpszSrc)
1360 if (lpszSrc && lpszSrc[0] == '/' && lpszSrc[1] == '/')
1361 lpszSrc += 2;
1362 return lpszSrc;
1365 /*************************************************************************
1366 * @ [SHLWAPI.171]
1368 * Check if two interfaces come from the same object.
1370 * PARAMS
1371 * lpInt1 [I] Interface to check against lpInt2.
1372 * lpInt2 [I] Interface to check against lpInt1.
1374 * RETURNS
1375 * TRUE, If the interfaces come from the same object.
1376 * FALSE Otherwise.
1378 BOOL WINAPI SHIsSameObject(IUnknown* lpInt1, IUnknown* lpInt2)
1380 LPVOID lpUnknown1, lpUnknown2;
1382 TRACE("%p %p\n", lpInt1, lpInt2);
1384 if (!lpInt1 || !lpInt2)
1385 return FALSE;
1387 if (lpInt1 == lpInt2)
1388 return TRUE;
1390 if (!SUCCEEDED(IUnknown_QueryInterface(lpInt1, &IID_IUnknown,
1391 (LPVOID *)&lpUnknown1)))
1392 return FALSE;
1394 if (!SUCCEEDED(IUnknown_QueryInterface(lpInt2, &IID_IUnknown,
1395 (LPVOID *)&lpUnknown2)))
1396 return FALSE;
1398 if (lpUnknown1 == lpUnknown2)
1399 return TRUE;
1401 return FALSE;
1404 /*************************************************************************
1405 * @ [SHLWAPI.172]
1407 * Get the window handle of an object.
1409 * PARAMS
1410 * lpUnknown [I] Object to get the window handle of
1411 * lphWnd [O] Destination for window handle
1413 * RETURNS
1414 * Success: S_OK. lphWnd contains the objects window handle.
1415 * Failure: An HRESULT error code.
1417 * NOTES
1418 * lpUnknown is expected to support one of the following interfaces:
1419 * IOleWindow(), IInternetSecurityMgrSite(), or IShellView().
1421 HRESULT WINAPI IUnknown_GetWindow(IUnknown *lpUnknown, HWND *lphWnd)
1423 /* FIXME: Wine has no header for this object */
1424 static const GUID IID_IInternetSecurityMgrSite = { 0x79eac9ed,
1425 0xbaf9, 0x11ce, { 0x8c, 0x82, 0x00, 0xaa, 0x00, 0x4b, 0xa9, 0x0b }};
1426 IUnknown *lpOle;
1427 HRESULT hRet = E_FAIL;
1429 TRACE("(%p,%p)\n", lpUnknown, lphWnd);
1431 if (!lpUnknown)
1432 return hRet;
1434 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleWindow, (void**)&lpOle);
1436 if (FAILED(hRet))
1438 hRet = IUnknown_QueryInterface(lpUnknown,&IID_IShellView, (void**)&lpOle);
1440 if (FAILED(hRet))
1442 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInternetSecurityMgrSite,
1443 (void**)&lpOle);
1447 if (SUCCEEDED(hRet))
1449 /* Lazyness here - Since GetWindow() is the first method for the above 3
1450 * interfaces, we use the same call for them all.
1452 hRet = IOleWindow_GetWindow((IOleWindow*)lpOle, lphWnd);
1453 IUnknown_Release(lpOle);
1454 if (lphWnd)
1455 TRACE("Returning HWND=%p\n", *lphWnd);
1458 return hRet;
1461 /*************************************************************************
1462 * @ [SHLWAPI.173]
1464 * Call a method on as as yet unidentified object.
1466 * PARAMS
1467 * pUnk [I] Object supporting the unidentified interface,
1468 * arg [I] Argument for the call on the object.
1470 * RETURNS
1471 * S_OK.
1473 HRESULT WINAPI IUnknown_SetOwner(IUnknown *pUnk, ULONG arg)
1475 static const GUID guid_173 = {
1476 0x5836fb00, 0x8187, 0x11cf, { 0xa1,0x2b,0x00,0xaa,0x00,0x4a,0xe8,0x37 }
1478 IMalloc *pUnk2;
1480 TRACE("(%p,%ld)\n", pUnk, arg);
1482 /* Note: arg may not be a ULONG and pUnk2 is for sure not an IMalloc -
1483 * We use this interface as its vtable entry is compatible with the
1484 * object in question.
1485 * FIXME: Find out what this object is and where it should be defined.
1487 if (pUnk &&
1488 SUCCEEDED(IUnknown_QueryInterface(pUnk, &guid_173, (void**)&pUnk2)))
1490 IMalloc_Alloc(pUnk2, arg); /* Faked call!! */
1491 IMalloc_Release(pUnk2);
1493 return S_OK;
1496 /*************************************************************************
1497 * @ [SHLWAPI.174]
1499 * Call either IObjectWithSite_SetSite() or IPersistMoniker_GetClassID() on
1500 * an interface.
1502 * RETURNS
1503 * Success: S_OK.
1504 * Failure: E_FAIL, if p1 is NULL.
1505 * E_NOINTERFACE If p1 does not support the IPersist interface,
1506 * Or an HRESULT error code.
1508 DWORD WINAPI IUnknown_SetSite(
1509 IUnknown *p1, /* [in] OLE object */
1510 LPVOID *p2) /* [out] ptr for call results */
1512 DWORD ret, aa;
1514 if (!p1) return E_FAIL;
1516 /* see if SetSite interface exists for IObjectWithSite object */
1517 ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id1, (LPVOID *)&p1);
1518 TRACE("first IU_QI ret=%08lx, p1=%p\n", ret, p1);
1519 if (ret) {
1521 /* see if GetClassId interface exists for IPersistMoniker object */
1522 ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id2, (LPVOID *)&aa);
1523 TRACE("second IU_QI ret=%08lx, aa=%08lx\n", ret, aa);
1524 if (ret) return ret;
1526 /* fake a GetClassId call */
1527 ret = IOleWindow_GetWindow((IOleWindow *)aa, (HWND*)p2);
1528 TRACE("second IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1529 *(LPDWORD)p2);
1530 IUnknown_Release((IUnknown *)aa);
1532 else {
1533 /* fake a SetSite call */
1534 ret = IOleWindow_GetWindow((IOleWindow *)p1, (HWND*)p2);
1535 TRACE("first IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1536 *(LPDWORD)p2);
1537 IUnknown_Release((IUnknown *)p1);
1539 return ret;
1542 /*************************************************************************
1543 * @ [SHLWAPI.175]
1545 * Call IPersist_GetClassID() on an object.
1547 * PARAMS
1548 * lpUnknown [I] Object supporting the IPersist interface
1549 * lpClassId [O] Destination for Class Id
1551 * RETURNS
1552 * Success: S_OK. lpClassId contains the Class Id requested.
1553 * Failure: E_FAIL, If lpUnknown is NULL,
1554 * E_NOINTERFACE If lpUnknown does not support IPersist,
1555 * Or an HRESULT error code.
1557 HRESULT WINAPI IUnknown_GetClassID(IUnknown *lpUnknown, CLSID* lpClassId)
1559 IPersist* lpPersist;
1560 HRESULT hRet = E_FAIL;
1562 TRACE("(%p,%p)\n", lpUnknown, debugstr_guid(lpClassId));
1564 if (lpUnknown)
1566 hRet = IUnknown_QueryInterface(lpUnknown,&IID_IPersist,(void**)&lpPersist);
1567 if (SUCCEEDED(hRet))
1569 IPersist_GetClassID(lpPersist, lpClassId);
1570 IPersist_Release(lpPersist);
1573 return hRet;
1576 /*************************************************************************
1577 * @ [SHLWAPI.176]
1579 * Retrieve a Service Interface from an object.
1581 * PARAMS
1582 * lpUnknown [I] Object to get an IServiceProvider interface from
1583 * sid [I] Service ID for IServiceProvider_QueryService() call
1584 * riid [I] Function requested for QueryService call
1585 * lppOut [O] Destination for the service interface pointer
1587 * RETURNS
1588 * Success: S_OK. lppOut contains an object providing the requested service
1589 * Failure: An HRESULT error code
1591 * NOTES
1592 * lpUnknown is expected to support the IServiceProvider interface.
1594 HRESULT WINAPI IUnknown_QueryService(IUnknown* lpUnknown, REFGUID sid, REFIID riid,
1595 LPVOID *lppOut)
1597 IServiceProvider* pService = NULL;
1598 HRESULT hRet;
1600 if (!lppOut)
1601 return E_FAIL;
1603 *lppOut = NULL;
1605 if (!lpUnknown)
1606 return E_FAIL;
1608 /* Get an IServiceProvider interface from the object */
1609 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IServiceProvider,
1610 (LPVOID*)&pService);
1612 if (!hRet && pService)
1614 TRACE("QueryInterface returned (IServiceProvider*)%p\n", pService);
1616 /* Get a Service interface from the object */
1617 hRet = IServiceProvider_QueryService(pService, sid, riid, lppOut);
1619 TRACE("(IServiceProvider*)%p returned (IUnknown*)%p\n", pService, *lppOut);
1621 /* Release the IServiceProvider interface */
1622 IUnknown_Release(pService);
1624 return hRet;
1627 /*************************************************************************
1628 * @ [SHLWAPI.177]
1630 * Loads a popup menu.
1632 * PARAMS
1633 * hInst [I] Instance handle
1634 * szName [I] Menu name
1636 * RETURNS
1637 * Success: TRUE.
1638 * Failure: FALSE.
1640 BOOL WINAPI SHLoadMenuPopup(HINSTANCE hInst, LPCWSTR szName)
1642 HMENU hMenu, hSubMenu;
1644 if ((hMenu = LoadMenuW(hInst, szName)))
1646 if ((hSubMenu = GetSubMenu(hMenu, 0)))
1647 RemoveMenu(hMenu, 0, MF_BYPOSITION);
1649 DestroyMenu(hMenu);
1650 return TRUE;
1652 return FALSE;
1655 typedef struct _enumWndData
1657 UINT uiMsgId;
1658 WPARAM wParam;
1659 LPARAM lParam;
1660 LRESULT (WINAPI *pfnPost)(HWND,UINT,WPARAM,LPARAM);
1661 } enumWndData;
1663 /* Callback for SHLWAPI_178 */
1664 static BOOL CALLBACK SHLWAPI_EnumChildProc(HWND hWnd, LPARAM lParam)
1666 enumWndData *data = (enumWndData *)lParam;
1668 TRACE("(%p,%p)\n", hWnd, data);
1669 data->pfnPost(hWnd, data->uiMsgId, data->wParam, data->lParam);
1670 return TRUE;
1673 /*************************************************************************
1674 * @ [SHLWAPI.178]
1676 * Send or post a message to every child of a window.
1678 * PARAMS
1679 * hWnd [I] Window whose children will get the messages
1680 * uiMsgId [I] Message Id
1681 * wParam [I] WPARAM of message
1682 * lParam [I] LPARAM of message
1683 * bSend [I] TRUE = Use SendMessageA(), FALSE = Use PostMessageA()
1685 * RETURNS
1686 * Nothing.
1688 * NOTES
1689 * The appropriate ASCII or Unicode function is called for the window.
1691 void WINAPI SHPropagateMessage(HWND hWnd, UINT uiMsgId, WPARAM wParam, LPARAM lParam, BOOL bSend)
1693 enumWndData data;
1695 TRACE("(%p,%u,%d,%ld,%d)\n", hWnd, uiMsgId, wParam, lParam, bSend);
1697 if(hWnd)
1699 data.uiMsgId = uiMsgId;
1700 data.wParam = wParam;
1701 data.lParam = lParam;
1703 if (bSend)
1704 data.pfnPost = IsWindowUnicode(hWnd) ? (void*)SendMessageW : (void*)SendMessageA;
1705 else
1706 data.pfnPost = IsWindowUnicode(hWnd) ? (void*)PostMessageW : (void*)PostMessageA;
1708 EnumChildWindows(hWnd, SHLWAPI_EnumChildProc, (LPARAM)&data);
1712 /*************************************************************************
1713 * @ [SHLWAPI.180]
1715 * Remove all sub-menus from a menu.
1717 * PARAMS
1718 * hMenu [I] Menu to remove sub-menus from
1720 * RETURNS
1721 * Success: 0. All sub-menus under hMenu are removed
1722 * Failure: -1, if any parameter is invalid
1724 DWORD WINAPI SHRemoveAllSubMenus(HMENU hMenu)
1726 int iItemCount = GetMenuItemCount(hMenu) - 1;
1727 while (iItemCount >= 0)
1729 HMENU hSubMenu = GetSubMenu(hMenu, iItemCount);
1730 if (hSubMenu)
1731 RemoveMenu(hMenu, iItemCount, MF_BYPOSITION);
1732 iItemCount--;
1734 return iItemCount;
1737 /*************************************************************************
1738 * @ [SHLWAPI.181]
1740 * Enable or disable a menu item.
1742 * PARAMS
1743 * hMenu [I] Menu holding menu item
1744 * uID [I] ID of menu item to enable/disable
1745 * bEnable [I] Whether to enable (TRUE) or disable (FALSE) the item.
1747 * RETURNS
1748 * The return code from EnableMenuItem.
1750 UINT WINAPI SHEnableMenuItem(HMENU hMenu, UINT wItemID, BOOL bEnable)
1752 return EnableMenuItem(hMenu, wItemID, bEnable ? MF_ENABLED : MF_GRAYED);
1755 /*************************************************************************
1756 * @ [SHLWAPI.182]
1758 * Check or uncheck a menu item.
1760 * PARAMS
1761 * hMenu [I] Menu holding menu item
1762 * uID [I] ID of menu item to check/uncheck
1763 * bCheck [I] Whether to check (TRUE) or uncheck (FALSE) the item.
1765 * RETURNS
1766 * The return code from CheckMenuItem.
1768 DWORD WINAPI SHCheckMenuItem(HMENU hMenu, UINT uID, BOOL bCheck)
1770 return CheckMenuItem(hMenu, uID, bCheck ? MF_CHECKED : MF_UNCHECKED);
1773 /*************************************************************************
1774 * @ [SHLWAPI.183]
1776 * Register a window class if it isn't already.
1778 * PARAMS
1779 * lpWndClass [I] Window class to register
1781 * RETURNS
1782 * The result of the RegisterClassA call.
1784 DWORD WINAPI SHRegisterClassA(WNDCLASSA *wndclass)
1786 WNDCLASSA wca;
1787 if (GetClassInfoA(wndclass->hInstance, wndclass->lpszClassName, &wca))
1788 return TRUE;
1789 return (DWORD)RegisterClassA(wndclass);
1792 /*************************************************************************
1793 * @ [SHLWAPI.186]
1795 BOOL WINAPI SHSimulateDrop(IDropTarget *pDrop, IDataObject *pDataObj,
1796 DWORD grfKeyState, PPOINTL lpPt, DWORD* pdwEffect)
1798 DWORD dwEffect = DROPEFFECT_LINK | DROPEFFECT_MOVE | DROPEFFECT_COPY;
1799 POINTL pt = { 0, 0 };
1801 if (!lpPt)
1802 lpPt = &pt;
1804 if (!pdwEffect)
1805 pdwEffect = &dwEffect;
1807 IDropTarget_DragEnter(pDrop, pDataObj, grfKeyState, *lpPt, pdwEffect);
1809 if (*pdwEffect)
1810 return IDropTarget_Drop(pDrop, pDataObj, grfKeyState, *lpPt, pdwEffect);
1812 IDropTarget_DragLeave(pDrop);
1813 return TRUE;
1816 /*************************************************************************
1817 * @ [SHLWAPI.187]
1819 * Call IPersistPropertyBag_Load() on an object.
1821 * PARAMS
1822 * lpUnknown [I] Object supporting the IPersistPropertyBag interface
1823 * lpPropBag [O] Destination for loaded IPropertyBag
1825 * RETURNS
1826 * Success: S_OK.
1827 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1829 DWORD WINAPI SHLoadFromPropertyBag(IUnknown *lpUnknown, IPropertyBag* lpPropBag)
1831 IPersistPropertyBag* lpPPBag;
1832 HRESULT hRet = E_FAIL;
1834 TRACE("(%p,%p)\n", lpUnknown, lpPropBag);
1836 if (lpUnknown)
1838 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IPersistPropertyBag,
1839 (void**)&lpPPBag);
1840 if (SUCCEEDED(hRet) && lpPPBag)
1842 hRet = IPersistPropertyBag_Load(lpPPBag, lpPropBag, NULL);
1843 IPersistPropertyBag_Release(lpPPBag);
1846 return hRet;
1849 /*************************************************************************
1850 * @ [SHLWAPI.188]
1852 * Call IOleControlSite_TranslateAccelerator() on an object.
1854 * PARAMS
1855 * lpUnknown [I] Object supporting the IOleControlSite interface.
1856 * lpMsg [I] Key message to be processed.
1857 * dwModifiers [I] Flags containing the state of the modifier keys.
1859 * RETURNS
1860 * Success: S_OK.
1861 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
1863 HRESULT WINAPI IUnknown_TranslateAcceleratorOCS(IUnknown *lpUnknown, LPMSG lpMsg, DWORD dwModifiers)
1865 IOleControlSite* lpCSite = NULL;
1866 HRESULT hRet = E_INVALIDARG;
1868 TRACE("(%p,%p,0x%08lx)\n", lpUnknown, lpMsg, dwModifiers);
1869 if (lpUnknown)
1871 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleControlSite,
1872 (void**)&lpCSite);
1873 if (SUCCEEDED(hRet) && lpCSite)
1875 hRet = IOleControlSite_TranslateAccelerator(lpCSite, lpMsg, dwModifiers);
1876 IOleControlSite_Release(lpCSite);
1879 return hRet;
1883 /*************************************************************************
1884 * @ [SHLWAPI.189]
1886 * Call IOleControlSite_GetExtendedControl() on an object.
1888 * PARAMS
1889 * lpUnknown [I] Object supporting the IOleControlSite interface.
1890 * lppDisp [O] Destination for resulting IDispatch.
1892 * RETURNS
1893 * Success: S_OK.
1894 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1896 DWORD WINAPI IUnknown_OnFocusOCS(IUnknown *lpUnknown, IDispatch** lppDisp)
1898 IOleControlSite* lpCSite = NULL;
1899 HRESULT hRet = E_FAIL;
1901 TRACE("(%p,%p)\n", lpUnknown, lppDisp);
1902 if (lpUnknown)
1904 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleControlSite,
1905 (void**)&lpCSite);
1906 if (SUCCEEDED(hRet) && lpCSite)
1908 hRet = IOleControlSite_GetExtendedControl(lpCSite, lppDisp);
1909 IOleControlSite_Release(lpCSite);
1912 return hRet;
1915 /*************************************************************************
1916 * @ [SHLWAPI.190]
1918 HRESULT WINAPI IUnknown_HandleIRestrict(LPUNKNOWN lpUnknown, PVOID lpArg1,
1919 PVOID lpArg2, PVOID lpArg3, PVOID lpArg4)
1921 /* FIXME: {D12F26B2-D90A-11D0-830D-00AA005B4383} - What object does this represent? */
1922 static const DWORD service_id[] = { 0xd12f26b2, 0x11d0d90a, 0xaa000d83, 0x83435b00 };
1923 /* FIXME: {D12F26B1-D90A-11D0-830D-00AA005B4383} - Also Unknown/undocumented */
1924 static const DWORD function_id[] = { 0xd12f26b1, 0x11d0d90a, 0xaa000d83, 0x83435b00 };
1925 HRESULT hRet = E_INVALIDARG;
1926 LPUNKNOWN lpUnkInner = NULL; /* FIXME: Real type is unknown */
1928 TRACE("(%p,%p,%p,%p,%p)\n", lpUnknown, lpArg1, lpArg2, lpArg3, lpArg4);
1930 if (lpUnknown && lpArg4)
1932 hRet = IUnknown_QueryService(lpUnknown, (REFGUID)service_id,
1933 (REFGUID)function_id, (void**)&lpUnkInner);
1935 if (SUCCEEDED(hRet) && lpUnkInner)
1937 /* FIXME: The type of service object requested is unknown, however
1938 * testing shows that its first method is called with 4 parameters.
1939 * Fake this by using IParseDisplayName_ParseDisplayName since the
1940 * signature and position in the vtable matches our unknown object type.
1942 hRet = IParseDisplayName_ParseDisplayName((LPPARSEDISPLAYNAME)lpUnkInner,
1943 lpArg1, lpArg2, lpArg3, lpArg4);
1944 IUnknown_Release(lpUnkInner);
1947 return hRet;
1950 /*************************************************************************
1951 * @ [SHLWAPI.192]
1953 * Get a sub-menu from a menu item.
1955 * PARAMS
1956 * hMenu [I] Menu to get sub-menu from
1957 * uID [I] ID of menu item containing sub-menu
1959 * RETURNS
1960 * The sub-menu of the item, or a NULL handle if any parameters are invalid.
1962 HMENU WINAPI SHGetMenuFromID(HMENU hMenu, UINT uID)
1964 MENUITEMINFOA mi;
1966 TRACE("(%p,%uld)\n", hMenu, uID);
1968 mi.cbSize = sizeof(MENUITEMINFOA);
1969 mi.fMask = MIIM_SUBMENU;
1971 if (!GetMenuItemInfoA(hMenu, uID, 0, &mi))
1972 return NULL;
1974 return mi.hSubMenu;
1977 /*************************************************************************
1978 * @ [SHLWAPI.193]
1980 * Get the color depth of the primary display.
1982 * PARAMS
1983 * None.
1985 * RETURNS
1986 * The color depth of the primary display.
1988 DWORD WINAPI SHGetCurColorRes()
1990 HDC hdc;
1991 DWORD ret;
1993 TRACE("()\n");
1995 hdc = GetDC(0);
1996 ret = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
1997 ReleaseDC(0, hdc);
1998 return ret;
2001 /*************************************************************************
2002 * @ [SHLWAPI.194]
2004 * Wait for a message to arrive, with a timeout.
2006 * PARAMS
2007 * hand [I] Handle to query
2008 * dwTimeout [I] Timeout in ticks or INFINITE to never timeout
2010 * RETURNS
2011 * STATUS_TIMEOUT if no message is received before dwTimeout ticks passes.
2012 * Otherwise returns the value from MsgWaitForMultipleObjectsEx when a
2013 * message is available.
2015 DWORD WINAPI SHWaitForSendMessageThread(HANDLE hand, DWORD dwTimeout)
2017 DWORD dwEndTicks = GetTickCount() + dwTimeout;
2018 DWORD dwRet;
2020 while ((dwRet = MsgWaitForMultipleObjectsEx(1, &hand, dwTimeout, QS_SENDMESSAGE, 0)) == 1)
2022 MSG msg;
2024 PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE);
2026 if (dwTimeout != INFINITE)
2028 if ((int)(dwTimeout = dwEndTicks - GetTickCount()) <= 0)
2029 return WAIT_TIMEOUT;
2033 return dwRet;
2036 /*************************************************************************
2037 * @ [SHLWAPI.195]
2039 * Determine if a shell folder can be expanded.
2041 * PARAMS
2042 * lpFolder [I] Parent folder containing the object to test.
2043 * pidl [I] Id of the object to test.
2045 * RETURNS
2046 * Success: S_OK, if the object is expandable, S_FALSE otherwise.
2047 * Failure: E_INVALIDARG, if any argument is invalid.
2049 * NOTES
2050 * If the object to be tested does not expose the IQueryInfo() interface it
2051 * will not be identified as an expandable folder.
2053 HRESULT WINAPI SHIsExpandableFolder(LPSHELLFOLDER lpFolder, LPCITEMIDLIST pidl)
2055 HRESULT hRet = E_INVALIDARG;
2056 IQueryInfo *lpInfo;
2058 if (lpFolder && pidl)
2060 hRet = IShellFolder_GetUIObjectOf(lpFolder, NULL, 1, &pidl, &IID_IQueryInfo,
2061 NULL, (void**)&lpInfo);
2062 if (FAILED(hRet))
2063 hRet = S_FALSE; /* Doesn't expose IQueryInfo */
2064 else
2066 DWORD dwFlags = 0;
2068 /* MSDN states of IQueryInfo_GetInfoFlags() that "This method is not
2069 * currently used". Really? You wouldn't be holding out on me would you?
2071 hRet = IQueryInfo_GetInfoFlags(lpInfo, &dwFlags);
2073 if (SUCCEEDED(hRet))
2075 /* 0x2 is an undocumented flag apparently indicating expandability */
2076 hRet = dwFlags & 0x2 ? S_OK : S_FALSE;
2079 IQueryInfo_Release(lpInfo);
2082 return hRet;
2085 /*************************************************************************
2086 * @ [SHLWAPI.197]
2088 * Blank out a region of text by drawing the background only.
2090 * PARAMS
2091 * hDC [I] Device context to draw in
2092 * pRect [I] Area to draw in
2093 * cRef [I] Color to draw in
2095 * RETURNS
2096 * Nothing.
2098 DWORD WINAPI SHFillRectClr(HDC hDC, LPCRECT pRect, COLORREF cRef)
2100 COLORREF cOldColor = SetBkColor(hDC, cRef);
2101 ExtTextOutA(hDC, 0, 0, ETO_OPAQUE, pRect, 0, 0, 0);
2102 SetBkColor(hDC, cOldColor);
2103 return 0;
2106 /*************************************************************************
2107 * @ [SHLWAPI.198]
2109 * Return the value asociated with a key in a map.
2111 * PARAMS
2112 * lpKeys [I] A list of keys of length iLen
2113 * lpValues [I] A list of values associated with lpKeys, of length iLen
2114 * iLen [I] Length of both lpKeys and lpValues
2115 * iKey [I] The key value to look up in lpKeys
2117 * RETURNS
2118 * The value in lpValues associated with iKey, or -1 if iKey is not
2119 * found in lpKeys.
2121 * NOTES
2122 * - If two elements in the map share the same key, this function returns
2123 * the value closest to the start of the map
2124 * - The native version of this function crashes if lpKeys or lpValues is NULL.
2126 int WINAPI SHSearchMapInt(const int *lpKeys, const int *lpValues, int iLen, int iKey)
2128 if (lpKeys && lpValues)
2130 int i = 0;
2132 while (i < iLen)
2134 if (lpKeys[i] == iKey)
2135 return lpValues[i]; /* Found */
2136 i++;
2139 return -1; /* Not found */
2143 /*************************************************************************
2144 * @ [SHLWAPI.199]
2146 * Copy an interface pointer
2148 * PARAMS
2149 * lppDest [O] Destination for copy
2150 * lpUnknown [I] Source for copy
2152 * RETURNS
2153 * Nothing.
2155 VOID WINAPI IUnknown_Set(IUnknown **lppDest, IUnknown *lpUnknown)
2157 TRACE("(%p,%p)\n", lppDest, lpUnknown);
2159 if (lppDest)
2160 IUnknown_AtomicRelease(lppDest); /* Release existing interface */
2162 if (lpUnknown)
2164 /* Copy */
2165 IUnknown_AddRef(lpUnknown);
2166 *lppDest = lpUnknown;
2170 /*************************************************************************
2171 * @ [SHLWAPI.200]
2174 HRESULT WINAPI MayQSForward(IUnknown* lpUnknown, PVOID lpReserved,
2175 REFGUID riidCmdGrp, ULONG cCmds,
2176 OLECMD *prgCmds, OLECMDTEXT* pCmdText)
2178 FIXME("(%p,%p,%p,%ld,%p,%p) - stub\n",
2179 lpUnknown, lpReserved, riidCmdGrp, cCmds, prgCmds, pCmdText);
2181 /* FIXME: Calls IsQSForward & IUnknown_QueryStatus */
2182 return DRAGDROP_E_NOTREGISTERED;
2185 /*************************************************************************
2186 * @ [SHLWAPI.201]
2189 HRESULT WINAPI MayExecForward(IUnknown* lpUnknown, INT iUnk, REFGUID pguidCmdGroup,
2190 DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
2191 VARIANT* pvaOut)
2193 FIXME("(%p,%d,%p,%ld,%ld,%p,%p) - stub!\n", lpUnknown, iUnk, pguidCmdGroup,
2194 nCmdID, nCmdexecopt, pvaIn, pvaOut);
2195 return DRAGDROP_E_NOTREGISTERED;
2198 /*************************************************************************
2199 * @ [SHLWAPI.202]
2202 HRESULT WINAPI IsQSForward(REFGUID pguidCmdGroup,ULONG cCmds, OLECMD *prgCmds)
2204 FIXME("(%p,%ld,%p) - stub!\n", pguidCmdGroup, cCmds, prgCmds);
2205 return DRAGDROP_E_NOTREGISTERED;
2208 /*************************************************************************
2209 * @ [SHLWAPI.204]
2211 * Determine if a window is not a child of another window.
2213 * PARAMS
2214 * hParent [I] Suspected parent window
2215 * hChild [I] Suspected child window
2217 * RETURNS
2218 * TRUE: If hChild is a child window of hParent
2219 * FALSE: If hChild is not a child window of hParent, or they are equal
2221 BOOL WINAPI SHIsChildOrSelf(HWND hParent, HWND hChild)
2223 TRACE("(%p,%p)\n", hParent, hChild);
2225 if (!hParent || !hChild)
2226 return TRUE;
2227 else if(hParent == hChild)
2228 return FALSE;
2229 return !IsChild(hParent, hChild);
2232 /*************************************************************************
2233 * @ [SHLWAPI.208]
2235 * Some sort of memory management process.
2237 DWORD WINAPI FDSA_Initialize(
2238 DWORD a,
2239 DWORD b,
2240 LPVOID c,
2241 LPVOID d,
2242 DWORD e)
2244 FIXME("(0x%08lx 0x%08lx %p %p 0x%08lx) stub\n",
2245 a, b, c, d, e);
2246 return 1;
2249 /*************************************************************************
2250 * @ [SHLWAPI.209]
2252 * Some sort of memory management process.
2254 DWORD WINAPI FDSA_Destroy(
2255 LPVOID a)
2257 FIXME("(%p) stub\n",
2259 return 1;
2262 /*************************************************************************
2263 * @ [SHLWAPI.210]
2265 * Some sort of memory management process.
2267 DWORD WINAPI FDSA_InsertItem(
2268 LPVOID a,
2269 DWORD b,
2270 LPVOID c)
2272 FIXME("(%p 0x%08lx %p) stub\n",
2273 a, b, c);
2274 return 0;
2277 /*************************************************************************
2278 * @ [SHLWAPI.211]
2280 DWORD WINAPI FDSA_DeleteItem(
2281 LPVOID a,
2282 DWORD b)
2284 FIXME("(%p 0x%08lx) stub\n",
2285 a, b);
2286 return 1;
2289 typedef struct {
2290 REFIID refid;
2291 DWORD indx;
2292 } IFACE_INDEX_TBL;
2294 /*************************************************************************
2295 * @ [SHLWAPI.219]
2297 * Call IUnknown_QueryInterface() on a table of objects.
2299 * RETURNS
2300 * Success: S_OK.
2301 * Failure: E_POINTER or E_NOINTERFACE.
2303 HRESULT WINAPI QISearch(
2304 LPVOID w, /* [in] Table of interfaces */
2305 IFACE_INDEX_TBL *x, /* [in] Array of REFIIDs and indexes into the table */
2306 REFIID riid, /* [in] REFIID to get interface for */
2307 LPVOID *ppv) /* [out] Destination for interface pointer */
2309 HRESULT ret;
2310 IUnknown *a_vtbl;
2311 IFACE_INDEX_TBL *xmove;
2313 TRACE("(%p %p %s %p)\n", w,x,debugstr_guid(riid),ppv);
2314 if (ppv) {
2315 xmove = x;
2316 while (xmove->refid) {
2317 TRACE("trying (indx %ld) %s\n", xmove->indx, debugstr_guid(xmove->refid));
2318 if (IsEqualIID(riid, xmove->refid)) {
2319 a_vtbl = (IUnknown*)(xmove->indx + (LPBYTE)w);
2320 TRACE("matched, returning (%p)\n", a_vtbl);
2321 *ppv = (LPVOID)a_vtbl;
2322 IUnknown_AddRef(a_vtbl);
2323 return S_OK;
2325 xmove++;
2328 if (IsEqualIID(riid, &IID_IUnknown)) {
2329 a_vtbl = (IUnknown*)(x->indx + (LPBYTE)w);
2330 TRACE("returning first for IUnknown (%p)\n", a_vtbl);
2331 *ppv = (LPVOID)a_vtbl;
2332 IUnknown_AddRef(a_vtbl);
2333 return S_OK;
2335 *ppv = 0;
2336 ret = E_NOINTERFACE;
2337 } else
2338 ret = E_POINTER;
2340 TRACE("-- 0x%08lx\n", ret);
2341 return ret;
2344 /*************************************************************************
2345 * @ [SHLWAPI.221]
2347 * Remove the "PropDlgFont" property from a window.
2349 * PARAMS
2350 * hWnd [I] Window to remove the property from
2352 * RETURNS
2353 * A handle to the removed property, or NULL if it did not exist.
2355 HANDLE WINAPI SHRemoveDefaultDialogFont(HWND hWnd)
2357 HANDLE hProp;
2359 TRACE("(%p)\n", hWnd);
2361 hProp = GetPropA(hWnd, "PropDlgFont");
2363 if(hProp)
2365 DeleteObject(hProp);
2366 hProp = RemovePropA(hWnd, "PropDlgFont");
2368 return hProp;
2371 /*************************************************************************
2372 * @ [SHLWAPI.236]
2374 * Load the in-process server of a given GUID.
2376 * PARAMS
2377 * refiid [I] GUID of the server to load.
2379 * RETURNS
2380 * Success: A handle to the loaded server dll.
2381 * Failure: A NULL handle.
2383 HMODULE WINAPI SHPinDllOfCLSID(REFIID refiid)
2385 HKEY newkey;
2386 DWORD type, count;
2387 CHAR value[MAX_PATH], string[MAX_PATH];
2389 strcpy(string, "CLSID\\");
2390 SHStringFromGUIDA(refiid, string + 6, sizeof(string)/sizeof(char) - 6);
2391 strcat(string, "\\InProcServer32");
2393 count = MAX_PATH;
2394 RegOpenKeyExA(HKEY_CLASSES_ROOT, string, 0, 1, &newkey);
2395 RegQueryValueExA(newkey, 0, 0, &type, (PBYTE)value, &count);
2396 RegCloseKey(newkey);
2397 return LoadLibraryExA(value, 0, 0);
2400 /*************************************************************************
2401 * @ [SHLWAPI.237]
2403 * Unicode version of SHLWAPI_183.
2405 DWORD WINAPI SHRegisterClassW(WNDCLASSW * lpWndClass)
2407 WNDCLASSW WndClass;
2409 TRACE("(%p %s)\n",lpWndClass->hInstance, debugstr_w(lpWndClass->lpszClassName));
2411 if (GetClassInfoW(lpWndClass->hInstance, lpWndClass->lpszClassName, &WndClass))
2412 return TRUE;
2413 return RegisterClassW(lpWndClass);
2416 /*************************************************************************
2417 * @ [SHLWAPI.238]
2419 * Unregister a list of classes.
2421 * PARAMS
2422 * hInst [I] Application instance that registered the classes
2423 * lppClasses [I] List of class names
2424 * iCount [I] Number of names in lppClasses
2426 * RETURNS
2427 * Nothing.
2429 void WINAPI SHUnregisterClassesA(HINSTANCE hInst, LPCSTR *lppClasses, INT iCount)
2431 WNDCLASSA WndClass;
2433 TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);
2435 while (iCount > 0)
2437 if (GetClassInfoA(hInst, *lppClasses, &WndClass))
2438 UnregisterClassA(*lppClasses, hInst);
2439 lppClasses++;
2440 iCount--;
2444 /*************************************************************************
2445 * @ [SHLWAPI.239]
2447 * Unicode version of SHUnregisterClassesA.
2449 void WINAPI SHUnregisterClassesW(HINSTANCE hInst, LPCWSTR *lppClasses, INT iCount)
2451 WNDCLASSW WndClass;
2453 TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);
2455 while (iCount > 0)
2457 if (GetClassInfoW(hInst, *lppClasses, &WndClass))
2458 UnregisterClassW(*lppClasses, hInst);
2459 lppClasses++;
2460 iCount--;
2464 /*************************************************************************
2465 * @ [SHLWAPI.240]
2467 * Call The correct (Ascii/Unicode) default window procedure for a window.
2469 * PARAMS
2470 * hWnd [I] Window to call the default procedure for
2471 * uMessage [I] Message ID
2472 * wParam [I] WPARAM of message
2473 * lParam [I] LPARAM of message
2475 * RETURNS
2476 * The result of calling DefWindowProcA() or DefWindowProcW().
2478 LRESULT CALLBACK SHDefWindowProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
2480 if (IsWindowUnicode(hWnd))
2481 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
2482 return DefWindowProcA(hWnd, uMessage, wParam, lParam);
2485 /*************************************************************************
2486 * @ [SHLWAPI.256]
2488 HRESULT WINAPI IUnknown_GetSite(LPUNKNOWN lpUnknown, REFIID iid, PVOID *lppSite)
2490 HRESULT hRet = E_INVALIDARG;
2491 LPOBJECTWITHSITE lpSite = NULL;
2493 TRACE("(%p,%s,%p)\n", lpUnknown, debugstr_guid(iid), lppSite);
2495 if (lpUnknown && iid && lppSite)
2497 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IObjectWithSite,
2498 (void**)&lpSite);
2499 if (SUCCEEDED(hRet) && lpSite)
2501 hRet = IObjectWithSite_GetSite(lpSite, iid, lppSite);
2502 IObjectWithSite_Release(lpSite);
2505 return hRet;
2508 /*************************************************************************
2509 * @ [SHLWAPI.257]
2511 * Create a worker window using CreateWindowExA().
2513 * PARAMS
2514 * wndProc [I] Window procedure
2515 * hWndParent [I] Parent window
2516 * dwExStyle [I] Extra style flags
2517 * dwStyle [I] Style flags
2518 * hMenu [I] Window menu
2519 * z [I] Unknown
2521 * RETURNS
2522 * Success: The window handle of the newly created window.
2523 * Failure: 0.
2525 HWND WINAPI SHCreateWorkerWindowA(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
2526 DWORD dwStyle, HMENU hMenu, LONG z)
2528 static const char* szClass = "WorkerA";
2529 WNDCLASSA wc;
2530 HWND hWnd;
2532 TRACE("(0x%08lx,%p,0x%08lx,0x%08lx,%p,0x%08lx)\n",
2533 wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2535 /* Create Window class */
2536 wc.style = 0;
2537 wc.lpfnWndProc = DefWindowProcA;
2538 wc.cbClsExtra = 0;
2539 wc.cbWndExtra = 4;
2540 wc.hInstance = shlwapi_hInstance;
2541 wc.hIcon = NULL;
2542 wc.hCursor = LoadCursorA(NULL, (LPSTR)IDC_ARROW);
2543 wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
2544 wc.lpszMenuName = NULL;
2545 wc.lpszClassName = szClass;
2547 SHRegisterClassA(&wc); /* Register class */
2549 /* FIXME: Set extra bits in dwExStyle */
2551 hWnd = CreateWindowExA(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
2552 hWndParent, hMenu, shlwapi_hInstance, 0);
2553 if (hWnd)
2555 SetWindowLongPtrW(hWnd, DWLP_MSGRESULT, z);
2557 if (wndProc)
2558 SetWindowLongPtrA(hWnd, GWLP_WNDPROC, wndProc);
2560 return hWnd;
2563 typedef struct tagPOLICYDATA
2565 DWORD policy; /* flags value passed to SHRestricted */
2566 LPCWSTR appstr; /* application str such as "Explorer" */
2567 LPCWSTR keystr; /* name of the actual registry key / policy */
2568 } POLICYDATA, *LPPOLICYDATA;
2570 #define SHELL_NO_POLICY 0xffffffff
2572 /* default shell policy registry key */
2573 static const WCHAR strRegistryPolicyW[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o',
2574 's','o','f','t','\\','W','i','n','d','o','w','s','\\',
2575 'C','u','r','r','e','n','t','V','e','r','s','i','o','n',
2576 '\\','P','o','l','i','c','i','e','s',0};
2578 /*************************************************************************
2579 * @ [SHLWAPI.271]
2581 * Retrieve a policy value from the registry.
2583 * PARAMS
2584 * lpSubKey [I] registry key name
2585 * lpSubName [I] subname of registry key
2586 * lpValue [I] value name of registry value
2588 * RETURNS
2589 * the value associated with the registry key or 0 if not found
2591 DWORD WINAPI SHGetRestriction(LPCWSTR lpSubKey, LPCWSTR lpSubName, LPCWSTR lpValue)
2593 DWORD retval, datsize = sizeof(retval);
2594 HKEY hKey;
2596 if (!lpSubKey)
2597 lpSubKey = strRegistryPolicyW;
2599 retval = RegOpenKeyW(HKEY_LOCAL_MACHINE, lpSubKey, &hKey);
2600 if (retval != ERROR_SUCCESS)
2601 retval = RegOpenKeyW(HKEY_CURRENT_USER, lpSubKey, &hKey);
2602 if (retval != ERROR_SUCCESS)
2603 return 0;
2605 SHGetValueW(hKey, lpSubName, lpValue, NULL, (LPBYTE)&retval, &datsize);
2606 RegCloseKey(hKey);
2607 return retval;
2610 /*************************************************************************
2611 * @ [SHLWAPI.266]
2613 * Helper function to retrieve the possibly cached value for a specific policy
2615 * PARAMS
2616 * policy [I] The policy to look for
2617 * initial [I] Main registry key to open, if NULL use default
2618 * polTable [I] Table of known policies, 0 terminated
2619 * polArr [I] Cache array of policy values
2621 * RETURNS
2622 * The retrieved policy value or 0 if not successful
2624 * NOTES
2625 * This function is used by the native SHRestricted function to search for the
2626 * policy and cache it once retrieved. The current Wine implementation uses a
2627 * different POLICYDATA structure and implements a similar algorithme adapted to
2628 * that structure.
2630 DWORD WINAPI SHRestrictionLookup(
2631 DWORD policy,
2632 LPCWSTR initial,
2633 LPPOLICYDATA polTable,
2634 LPDWORD polArr)
2636 TRACE("(0x%08lx %s %p %p)\n", policy, debugstr_w(initial), polTable, polArr);
2638 if (!polTable || !polArr)
2639 return 0;
2641 for (;polTable->policy; polTable++, polArr++)
2643 if (policy == polTable->policy)
2645 /* we have a known policy */
2647 /* check if this policy has been cached */
2648 if (*polArr == SHELL_NO_POLICY)
2649 *polArr = SHGetRestriction(initial, polTable->appstr, polTable->keystr);
2650 return *polArr;
2653 /* we don't know this policy, return 0 */
2654 TRACE("unknown policy: (%08lx)\n", policy);
2655 return 0;
2658 /*************************************************************************
2659 * @ [SHLWAPI.267]
2661 * Get an interface from an object.
2663 * RETURNS
2664 * Success: S_OK. ppv contains the requested interface.
2665 * Failure: An HRESULT error code.
2667 * NOTES
2668 * This QueryInterface asks the inner object for an interface. In case
2669 * of aggregation this request would be forwarded by the inner to the
2670 * outer object. This function asks the inner object directly for the
2671 * interface circumventing the forwarding to the outer object.
2673 HRESULT WINAPI SHWeakQueryInterface(
2674 IUnknown * pUnk, /* [in] Outer object */
2675 IUnknown * pInner, /* [in] Inner object */
2676 IID * riid, /* [in] Interface GUID to query for */
2677 LPVOID* ppv) /* [out] Destination for queried interface */
2679 HRESULT hret = E_NOINTERFACE;
2680 TRACE("(pUnk=%p pInner=%p\n\tIID: %s %p)\n",pUnk,pInner,debugstr_guid(riid), ppv);
2682 *ppv = NULL;
2683 if(pUnk && pInner) {
2684 hret = IUnknown_QueryInterface(pInner, riid, (LPVOID*)ppv);
2685 if (SUCCEEDED(hret)) IUnknown_Release(pUnk);
2687 TRACE("-- 0x%08lx\n", hret);
2688 return hret;
2691 /*************************************************************************
2692 * @ [SHLWAPI.268]
2694 * Move a reference from one interface to another.
2696 * PARAMS
2697 * lpDest [O] Destination to receive the reference
2698 * lppUnknown [O] Source to give up the reference to lpDest
2700 * RETURNS
2701 * Nothing.
2703 VOID WINAPI SHWeakReleaseInterface(IUnknown *lpDest, IUnknown **lppUnknown)
2705 TRACE("(%p,%p)\n", lpDest, lppUnknown);
2707 if (*lppUnknown)
2709 /* Copy Reference*/
2710 IUnknown_AddRef(lpDest);
2711 IUnknown_AtomicRelease(lppUnknown); /* Release existing interface */
2715 /*************************************************************************
2716 * @ [SHLWAPI.269]
2718 * Convert an ASCII string of a CLSID into a CLSID.
2720 * PARAMS
2721 * idstr [I] String representing a CLSID in registry format
2722 * id [O] Destination for the converted CLSID
2724 * RETURNS
2725 * Success: TRUE. id contains the converted CLSID.
2726 * Failure: FALSE.
2728 BOOL WINAPI GUIDFromStringA(LPCSTR idstr, CLSID *id)
2730 WCHAR wClsid[40];
2731 MultiByteToWideChar(CP_ACP, 0, idstr, -1, wClsid, sizeof(wClsid)/sizeof(WCHAR));
2732 return SUCCEEDED(CLSIDFromStringWrap(wClsid, id));
2735 /*************************************************************************
2736 * @ [SHLWAPI.270]
2738 * Unicode version of GUIDFromStringA.
2740 BOOL WINAPI GUIDFromStringW(LPCWSTR idstr, CLSID *id)
2742 return SUCCEEDED(CLSIDFromStringWrap(idstr, id));
2745 /*************************************************************************
2746 * @ [SHLWAPI.276]
2748 * Determine if the browser is integrated into the shell, and set a registry
2749 * key accordingly.
2751 * PARAMS
2752 * None.
2754 * RETURNS
2755 * 1, If the browser is not integrated.
2756 * 2, If the browser is integrated.
2758 * NOTES
2759 * The key "HKLM\Software\Microsoft\Internet Explorer\IntegratedBrowser" is
2760 * either set to TRUE, or removed depending on whether the browser is deemed
2761 * to be integrated.
2763 DWORD WINAPI WhichPlatform()
2765 static LPCSTR szIntegratedBrowser = "IntegratedBrowser";
2766 static DWORD dwState = 0;
2767 HKEY hKey;
2768 DWORD dwRet, dwData, dwSize;
2770 if (dwState)
2771 return dwState;
2773 /* If shell32 exports DllGetVersion(), the browser is integrated */
2774 GET_FUNC(pDllGetVersion, shell32, "DllGetVersion", 1);
2775 dwState = pDllGetVersion ? 2 : 1;
2777 /* Set or delete the key accordingly */
2778 dwRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
2779 "Software\\Microsoft\\Internet Explorer", 0,
2780 KEY_ALL_ACCESS, &hKey);
2781 if (!dwRet)
2783 dwRet = RegQueryValueExA(hKey, szIntegratedBrowser, 0, 0,
2784 (LPBYTE)&dwData, &dwSize);
2786 if (!dwRet && dwState == 1)
2788 /* Value exists but browser is not integrated */
2789 RegDeleteValueA(hKey, szIntegratedBrowser);
2791 else if (dwRet && dwState == 2)
2793 /* Browser is integrated but value does not exist */
2794 dwData = TRUE;
2795 RegSetValueExA(hKey, szIntegratedBrowser, 0, REG_DWORD,
2796 (LPBYTE)&dwData, sizeof(dwData));
2798 RegCloseKey(hKey);
2800 return dwState;
2803 /*************************************************************************
2804 * @ [SHLWAPI.278]
2806 * Unicode version of SHCreateWorkerWindowA.
2808 HWND WINAPI SHCreateWorkerWindowW(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
2809 DWORD dwStyle, HMENU hMenu, LONG z)
2811 static const WCHAR szClass[] = { 'W', 'o', 'r', 'k', 'e', 'r', 'W', '\0' };
2812 WNDCLASSW wc;
2813 HWND hWnd;
2815 TRACE("(0x%08lx,%p,0x%08lx,0x%08lx,%p,0x%08lx)\n",
2816 wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2818 /* If our OS is natively ASCII, use the ASCII version */
2819 if (!(GetVersion() & 0x80000000)) /* NT */
2820 return SHCreateWorkerWindowA(wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2822 /* Create Window class */
2823 wc.style = 0;
2824 wc.lpfnWndProc = DefWindowProcW;
2825 wc.cbClsExtra = 0;
2826 wc.cbWndExtra = 4;
2827 wc.hInstance = shlwapi_hInstance;
2828 wc.hIcon = NULL;
2829 wc.hCursor = LoadCursorW(NULL, (LPWSTR)IDC_ARROW);
2830 wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
2831 wc.lpszMenuName = NULL;
2832 wc.lpszClassName = szClass;
2834 SHRegisterClassW(&wc); /* Register class */
2836 /* FIXME: Set extra bits in dwExStyle */
2838 hWnd = CreateWindowExW(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
2839 hWndParent, hMenu, shlwapi_hInstance, 0);
2840 if (hWnd)
2842 SetWindowLongPtrW(hWnd, DWLP_MSGRESULT, z);
2844 if (wndProc)
2845 SetWindowLongPtrW(hWnd, GWLP_WNDPROC, wndProc);
2847 return hWnd;
2850 /*************************************************************************
2851 * @ [SHLWAPI.279]
2853 * Get and show a context menu from a shell folder.
2855 * PARAMS
2856 * hWnd [I] Window displaying the shell folder
2857 * lpFolder [I] IShellFolder interface
2858 * lpApidl [I] Id for the particular folder desired
2860 * RETURNS
2861 * Success: S_OK.
2862 * Failure: An HRESULT error code indicating the error.
2864 HRESULT WINAPI SHInvokeDefaultCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl)
2866 return SHInvokeCommand(hWnd, lpFolder, lpApidl, FALSE);
2869 /*************************************************************************
2870 * @ [SHLWAPI.281]
2872 * _SHPackDispParamsV
2874 HRESULT WINAPI SHPackDispParamsV(LPVOID w, LPVOID x, LPVOID y, LPVOID z)
2876 FIXME("%p %p %p %p\n",w,x,y,z);
2877 return E_FAIL;
2880 /*************************************************************************
2881 * @ [SHLWAPI.282]
2883 * This function seems to be a forward to SHPackDispParamsV (whatever THAT
2884 * function does...).
2886 HRESULT WINAPI SHPackDispParams(LPVOID w, LPVOID x, LPVOID y, LPVOID z)
2888 FIXME("%p %p %p %p\n", w, x, y, z);
2889 return E_FAIL;
2892 /*************************************************************************
2893 * @ [SHLWAPI.284]
2895 * _IConnectionPoint_SimpleInvoke
2897 DWORD WINAPI IConnectionPoint_SimpleInvoke(
2898 LPVOID x,
2899 LPVOID y,
2900 LPVOID z)
2902 FIXME("(%p %p %p) stub\n",x,y,z);
2903 return 0;
2906 /*************************************************************************
2907 * @ [SHLWAPI.285]
2909 * Notify an IConnectionPoint object of changes.
2911 * PARAMS
2912 * lpCP [I] Object to notify
2913 * dispID [I]
2915 * RETURNS
2916 * Success: S_OK.
2917 * Failure: E_NOINTERFACE, if lpCP is NULL or does not support the
2918 * IConnectionPoint interface.
2920 HRESULT WINAPI IConnectionPoint_OnChanged(IConnectionPoint* lpCP, DISPID dispID)
2922 IEnumConnections *lpEnum;
2923 HRESULT hRet = E_NOINTERFACE;
2925 TRACE("(%p,0x%8lX)\n", lpCP, dispID);
2927 /* Get an enumerator for the connections */
2928 if (lpCP)
2929 hRet = IConnectionPoint_EnumConnections(lpCP, &lpEnum);
2931 if (SUCCEEDED(hRet))
2933 IPropertyNotifySink *lpSink;
2934 CONNECTDATA connData;
2935 ULONG ulFetched;
2937 /* Call OnChanged() for every notify sink in the connection point */
2938 while (IEnumConnections_Next(lpEnum, 1, &connData, &ulFetched) == S_OK)
2940 if (SUCCEEDED(IUnknown_QueryInterface(connData.pUnk, &IID_IPropertyNotifySink, (void**)&lpSink)) &&
2941 lpSink)
2943 IPropertyNotifySink_OnChanged(lpSink, dispID);
2944 IPropertyNotifySink_Release(lpSink);
2946 IUnknown_Release(connData.pUnk);
2949 IEnumConnections_Release(lpEnum);
2951 return hRet;
2954 /*************************************************************************
2955 * @ [SHLWAPI.287]
2957 * Notify an IConnectionPointContainer object of changes.
2959 * PARAMS
2960 * lpUnknown [I] Object to notify
2961 * dispID [I]
2963 * RETURNS
2964 * Success: S_OK.
2965 * Failure: E_NOINTERFACE, if lpUnknown is NULL or does not support the
2966 * IConnectionPointContainer interface.
2968 HRESULT WINAPI IUnknown_CPContainerOnChanged(IUnknown *lpUnknown, DISPID dispID)
2970 IConnectionPointContainer* lpCPC = NULL;
2971 HRESULT hRet = E_NOINTERFACE;
2973 TRACE("(%p,0x%8lX)\n", lpUnknown, dispID);
2975 if (lpUnknown)
2976 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer, (void**)&lpCPC);
2978 if (SUCCEEDED(hRet))
2980 IConnectionPoint* lpCP;
2982 hRet = IConnectionPointContainer_FindConnectionPoint(lpCPC, &IID_IPropertyNotifySink, &lpCP);
2983 IConnectionPointContainer_Release(lpCPC);
2985 hRet = IConnectionPoint_OnChanged(lpCP, dispID);
2986 IConnectionPoint_Release(lpCP);
2988 return hRet;
2991 /*************************************************************************
2992 * @ [SHLWAPI.289]
2994 * See PlaySoundW.
2996 BOOL WINAPI PlaySoundWrapW(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
2998 GET_FUNC(pPlaySoundW, winmm, "PlaySoundW", FALSE);
2999 return pPlaySoundW(pszSound, hmod, fdwSound);
3002 /*************************************************************************
3003 * @ [SHLWAPI.294]
3005 BOOL WINAPI SHGetIniStringW(LPSTR str1, LPSTR str2, LPSTR pStr, DWORD some_len, LPCSTR lpStr2)
3008 * str1: "I" "I" pushl esp+0x20
3009 * str2: "U" "I" pushl 0x77c93810
3010 * (is "I" and "U" "integer" and "unsigned" ??)
3012 * pStr: "" "" pushl eax
3013 * some_len: 0x824 0x104 pushl 0x824
3014 * lpStr2: "%l" "%l" pushl esp+0xc
3016 * shlwapi. StrCpyNW(lpStr2, irrelevant_var, 0x104);
3017 * LocalAlloc(0x00, some_len) -> irrelevant_var
3018 * LocalAlloc(0x40, irrelevant_len) -> pStr
3019 * shlwapi.294(str1, str2, pStr, some_len, lpStr2);
3020 * shlwapi.PathRemoveBlanksW(pStr);
3022 FIXME("('%s', '%s', '%s', %08lx, '%s'): stub!\n", str1, str2, pStr, some_len, lpStr2);
3023 return TRUE;
3026 /*************************************************************************
3027 * @ [SHLWAPI.295]
3029 * Called by ICQ2000b install via SHDOCVW:
3030 * str1: "InternetShortcut"
3031 * x: some unknown pointer
3032 * str2: "http://free.aol.com/tryaolfree/index.adp?139269"
3033 * str3: "C:\\WINDOWS\\Desktop.new2\\Free AOL & Unlimited Internet.url"
3035 * In short: this one maybe creates a desktop link :-)
3037 BOOL WINAPI SHSetIniStringW(LPWSTR str1, LPVOID x, LPWSTR str2, LPWSTR str3)
3039 FIXME("('%s', %p, '%s', '%s'), stub.\n", debugstr_w(str1), x, debugstr_w(str2), debugstr_w(str3));
3040 return TRUE;
3043 /*************************************************************************
3044 * @ [SHLWAPI.299]
3046 * See COMCTL32_417.
3048 BOOL WINAPI ExtTextOutWrapW(HDC hdc, INT x, INT y, UINT flags, const RECT *lprect,
3049 LPCWSTR str, UINT count, const INT *lpDx)
3051 GET_FUNC(pCOMCTL32_417, comctl32, (LPCSTR)417, FALSE);
3052 return pCOMCTL32_417(hdc, x, y, flags, lprect, str, count, lpDx);
3055 /*************************************************************************
3056 * @ [SHLWAPI.313]
3058 * See SHGetFileInfoW.
3060 DWORD WINAPI SHGetFileInfoWrapW(LPCWSTR path, DWORD dwFileAttributes,
3061 SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
3063 GET_FUNC(pSHGetFileInfoW, shell32, "SHGetFileInfoW", 0);
3064 return pSHGetFileInfoW(path, dwFileAttributes, psfi, sizeofpsfi, flags);
3067 /*************************************************************************
3068 * @ [SHLWAPI.318]
3070 * See DragQueryFileW.
3072 UINT WINAPI DragQueryFileWrapW(HDROP hDrop, UINT lFile, LPWSTR lpszFile, UINT lLength)
3074 GET_FUNC(pDragQueryFileW, shell32, "DragQueryFileW", 0);
3075 return pDragQueryFileW(hDrop, lFile, lpszFile, lLength);
3078 /*************************************************************************
3079 * @ [SHLWAPI.333]
3081 * See SHBrowseForFolderW.
3083 LPITEMIDLIST WINAPI SHBrowseForFolderWrapW(LPBROWSEINFOW lpBi)
3085 GET_FUNC(pSHBrowseForFolderW, shell32, "SHBrowseForFolderW", NULL);
3086 return pSHBrowseForFolderW(lpBi);
3089 /*************************************************************************
3090 * @ [SHLWAPI.334]
3092 * See SHGetPathFromIDListW.
3094 BOOL WINAPI SHGetPathFromIDListWrapW(LPCITEMIDLIST pidl,LPWSTR pszPath)
3096 GET_FUNC(pSHGetPathFromIDListW, shell32, "SHGetPathFromIDListW", 0);
3097 return pSHGetPathFromIDListW(pidl, pszPath);
3100 /*************************************************************************
3101 * @ [SHLWAPI.335]
3103 * See ShellExecuteExW.
3105 BOOL WINAPI ShellExecuteExWrapW(LPSHELLEXECUTEINFOW lpExecInfo)
3107 GET_FUNC(pShellExecuteExW, shell32, "ShellExecuteExW", FALSE);
3108 return pShellExecuteExW(lpExecInfo);
3111 /*************************************************************************
3112 * @ [SHLWAPI.336]
3114 * See SHFileOperationW.
3116 HICON WINAPI SHFileOperationWrapW(LPSHFILEOPSTRUCTW lpFileOp)
3118 GET_FUNC(pSHFileOperationW, shell32, "SHFileOperationW", 0);
3119 return pSHFileOperationW(lpFileOp);
3122 /*************************************************************************
3123 * @ [SHLWAPI.337]
3125 * See ExtractIconExW.
3127 UINT WINAPI ExtractIconExWrapW(LPCWSTR lpszFile, INT nIconIndex, HICON *phiconLarge,
3128 HICON *phiconSmall, UINT nIcons)
3130 GET_FUNC(pExtractIconExW, shell32, "ExtractIconExW", 0);
3131 return pExtractIconExW(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
3134 /*************************************************************************
3135 * @ [SHLWAPI.342]
3138 LONG WINAPI SHInterlockedCompareExchange( PLONG dest, LONG xchg, LONG compare)
3140 return InterlockedCompareExchange(dest, xchg, compare);
3143 /*************************************************************************
3144 * @ [SHLWAPI.350]
3146 * See GetFileVersionInfoSizeW.
3148 DWORD WINAPI GetFileVersionInfoSizeWrapW(
3149 LPWSTR x,
3150 LPVOID y)
3152 DWORD ret;
3154 GET_FUNC(pGetFileVersionInfoSizeW, version, "GetFileVersionInfoSizeW", 0);
3155 ret = pGetFileVersionInfoSizeW(x, y);
3156 return 0x208 + ret;
3159 /*************************************************************************
3160 * @ [SHLWAPI.351]
3162 * See GetFileVersionInfoW.
3164 BOOL WINAPI GetFileVersionInfoWrapW(
3165 LPWSTR w, /* [in] path to dll */
3166 DWORD x, /* [in] parm 2 to GetFileVersionInfoA */
3167 DWORD y, /* [in] return value from SHLWAPI_350() - assume length */
3168 LPVOID z) /* [in/out] buffer (+0x208 sent to GetFileVersionInfoA()) */
3170 GET_FUNC(pGetFileVersionInfoW, version, "GetFileVersionInfoW", 0);
3171 return pGetFileVersionInfoW(w, x, y-0x208, (char*)z+0x208);
3174 /*************************************************************************
3175 * @ [SHLWAPI.352]
3177 * See VerQueryValueW.
3179 WORD WINAPI VerQueryValueWrapW(
3180 LPVOID w, /* [in] Buffer from SHLWAPI_351() */
3181 LPWSTR x, /* [in] Value to retrieve - converted and passed to VerQueryValueA() as #2 */
3182 LPVOID y, /* [out] Ver buffer - passed to VerQueryValueA as #3 */
3183 UINT* z) /* [in] Ver length - passed to VerQueryValueA as #4 */
3185 GET_FUNC(pVerQueryValueW, version, "VerQueryValueW", 0);
3186 return pVerQueryValueW((char*)w+0x208, x, y, z);
3189 #define IsIface(type) SUCCEEDED((hRet = IUnknown_QueryInterface(lpUnknown, &IID_##type, (void**)&lpObj)))
3190 #define IShellBrowser_EnableModeless IShellBrowser_EnableModelessSB
3191 #define EnableModeless(type) type##_EnableModeless((type*)lpObj, bModeless)
3193 /*************************************************************************
3194 * @ [SHLWAPI.355]
3196 * Change the modality of a shell object.
3198 * PARAMS
3199 * lpUnknown [I] Object to make modeless
3200 * bModeless [I] TRUE=Make modeless, FALSE=Make modal
3202 * RETURNS
3203 * Success: S_OK. The modality lpUnknown is changed.
3204 * Failure: An HRESULT error code indicating the error.
3206 * NOTES
3207 * lpUnknown must support the IOleInPlaceFrame interface, the
3208 * IInternetSecurityMgrSite interface, the IShellBrowser interface
3209 * the IDocHostUIHandler interface, or the IOleInPlaceActiveObject interface,
3210 * or this call will fail.
3212 HRESULT WINAPI IUnknown_EnableModeless(IUnknown *lpUnknown, BOOL bModeless)
3214 IUnknown *lpObj;
3215 HRESULT hRet;
3217 TRACE("(%p,%d)\n", lpUnknown, bModeless);
3219 if (!lpUnknown)
3220 return E_FAIL;
3222 if (IsIface(IOleInPlaceActiveObject))
3223 EnableModeless(IOleInPlaceActiveObject);
3224 else if (IsIface(IOleInPlaceFrame))
3225 EnableModeless(IOleInPlaceFrame);
3226 else if (IsIface(IShellBrowser))
3227 EnableModeless(IShellBrowser);
3228 #if 0
3229 /* FIXME: Wine has no headers for these objects yet */
3230 else if (IsIface(IInternetSecurityMgrSite))
3231 EnableModeless(IInternetSecurityMgrSite);
3232 else if (IsIface(IDocHostUIHandler))
3233 EnableModeless(IDocHostUIHandler);
3234 #endif
3235 else
3236 return hRet;
3238 IUnknown_Release(lpObj);
3239 return S_OK;
3242 /*************************************************************************
3243 * @ [SHLWAPI.357]
3245 * See SHGetNewLinkInfoW.
3247 BOOL WINAPI SHGetNewLinkInfoWrapW(LPCWSTR pszLinkTo, LPCWSTR pszDir, LPWSTR pszName,
3248 BOOL *pfMustCopy, UINT uFlags)
3250 GET_FUNC(pSHGetNewLinkInfoW, shell32, "SHGetNewLinkInfoW", FALSE);
3251 return pSHGetNewLinkInfoW(pszLinkTo, pszDir, pszName, pfMustCopy, uFlags);
3254 /*************************************************************************
3255 * @ [SHLWAPI.358]
3257 * See SHDefExtractIconW.
3259 UINT WINAPI SHDefExtractIconWrapW(LPCWSTR pszIconFile, int iIndex, UINT uFlags, HICON* phiconLarge,
3260 HICON* phiconSmall, UINT nIconSize)
3262 GET_FUNC(pSHDefExtractIconW, shell32, "SHDefExtractIconW", 0);
3263 return pSHDefExtractIconW(pszIconFile, iIndex, uFlags, phiconLarge, phiconSmall, nIconSize);
3266 /*************************************************************************
3267 * @ [SHLWAPI.363]
3269 * Get and show a context menu from a shell folder.
3271 * PARAMS
3272 * hWnd [I] Window displaying the shell folder
3273 * lpFolder [I] IShellFolder interface
3274 * lpApidl [I] Id for the particular folder desired
3275 * bInvokeDefault [I] Whether to invoke the default menu item
3277 * RETURNS
3278 * Success: S_OK. If bInvokeDefault is TRUE, the default menu action was
3279 * executed.
3280 * Failure: An HRESULT error code indicating the error.
3282 HRESULT WINAPI SHInvokeCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl, BOOL bInvokeDefault)
3284 IContextMenu *iContext;
3285 HRESULT hRet = E_FAIL;
3287 TRACE("(%p,%p,%p,%d)\n", hWnd, lpFolder, lpApidl, bInvokeDefault);
3289 if (!lpFolder)
3290 return hRet;
3292 /* Get the context menu from the shell folder */
3293 hRet = IShellFolder_GetUIObjectOf(lpFolder, hWnd, 1, &lpApidl,
3294 &IID_IContextMenu, 0, (void**)&iContext);
3295 if (SUCCEEDED(hRet))
3297 HMENU hMenu;
3298 if ((hMenu = CreatePopupMenu()))
3300 HRESULT hQuery;
3301 DWORD dwDefaultId = 0;
3303 /* Add the context menu entries to the popup */
3304 hQuery = IContextMenu_QueryContextMenu(iContext, hMenu, 0, 1, 0x7FFF,
3305 bInvokeDefault ? CMF_NORMAL : CMF_DEFAULTONLY);
3307 if (SUCCEEDED(hQuery))
3309 if (bInvokeDefault &&
3310 (dwDefaultId = GetMenuDefaultItem(hMenu, 0, 0)) != 0xFFFFFFFF)
3312 CMINVOKECOMMANDINFO cmIci;
3313 /* Invoke the default item */
3314 memset(&cmIci,0,sizeof(cmIci));
3315 cmIci.cbSize = sizeof(cmIci);
3316 cmIci.fMask = CMIC_MASK_ASYNCOK;
3317 cmIci.hwnd = hWnd;
3318 cmIci.lpVerb = MAKEINTRESOURCEA(dwDefaultId);
3319 cmIci.nShow = SW_SCROLLCHILDREN;
3321 hRet = IContextMenu_InvokeCommand(iContext, &cmIci);
3324 DestroyMenu(hMenu);
3326 IContextMenu_Release(iContext);
3328 return hRet;
3331 /*************************************************************************
3332 * @ [SHLWAPI.370]
3334 * See ExtractIconW.
3336 HICON WINAPI ExtractIconWrapW(HINSTANCE hInstance, LPCWSTR lpszExeFileName,
3337 UINT nIconIndex)
3339 GET_FUNC(pExtractIconW, shell32, "ExtractIconW", NULL);
3340 return pExtractIconW(hInstance, lpszExeFileName, nIconIndex);
3343 /*************************************************************************
3344 * @ [SHLWAPI.376]
3346 LANGID WINAPI MLGetUILanguage()
3348 FIXME("() stub\n");
3349 /* FIXME: This should be a forward in the .spec file to the win2k function
3350 * kernel32.GetUserDefaultUILanguage, however that function isn't there yet.
3352 return GetUserDefaultLangID();
3355 /*************************************************************************
3356 * @ [SHLWAPI.377]
3358 * Load a library from the directory of a particular process.
3360 * PARAMS
3361 * new_mod [I] Library name
3362 * inst_hwnd [I] Module whose directory is to be used
3363 * dwFlags [I] Flags controlling the load
3365 * RETURNS
3366 * Success: A handle to the loaded module
3367 * Failure: A NULL handle.
3369 HMODULE WINAPI MLLoadLibraryA(LPCSTR new_mod, HMODULE inst_hwnd, DWORD dwFlags)
3371 /* FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for
3372 * each call here.
3373 * FIXME: Native shows calls to:
3374 * SHRegGetUSValue for "Software\Microsoft\Internet Explorer\International"
3375 * CheckVersion
3376 * RegOpenKeyExA for "HKLM\Software\Microsoft\Internet Explorer"
3377 * RegQueryValueExA for "LPKInstalled"
3378 * RegCloseKey
3379 * RegOpenKeyExA for "HKCU\Software\Microsoft\Internet Explorer\International"
3380 * RegQueryValueExA for "ResourceLocale"
3381 * RegCloseKey
3382 * RegOpenKeyExA for "HKLM\Software\Microsoft\Active Setup\Installed Components\{guid}"
3383 * RegQueryValueExA for "Locale"
3384 * RegCloseKey
3385 * and then tests the Locale ("en" for me).
3386 * code below
3387 * after the code then a DPA_Create (first time) and DPA_InsertPtr are done.
3389 CHAR mod_path[2*MAX_PATH];
3390 LPSTR ptr;
3391 DWORD len;
3393 FIXME("(%s,%p,0x%08lx) semi-stub!\n", debugstr_a(new_mod), inst_hwnd, dwFlags);
3394 len = GetModuleFileNameA(inst_hwnd, mod_path, sizeof(mod_path));
3395 if (!len || len >= sizeof(mod_path)) return NULL;
3397 ptr = strrchr(mod_path, '\\');
3398 if (ptr) {
3399 strcpy(ptr+1, new_mod);
3400 TRACE("loading %s\n", debugstr_a(mod_path));
3401 return LoadLibraryA(mod_path);
3403 return NULL;
3406 /*************************************************************************
3407 * @ [SHLWAPI.378]
3409 * Unicode version of MLLoadLibraryA.
3411 HMODULE WINAPI MLLoadLibraryW(LPCWSTR new_mod, HMODULE inst_hwnd, DWORD dwFlags)
3413 WCHAR mod_path[2*MAX_PATH];
3414 LPWSTR ptr;
3415 DWORD len;
3417 FIXME("(%s,%p,0x%08lx) semi-stub!\n", debugstr_w(new_mod), inst_hwnd, dwFlags);
3418 len = GetModuleFileNameW(inst_hwnd, mod_path, sizeof(mod_path) / sizeof(WCHAR));
3419 if (!len || len >= sizeof(mod_path) / sizeof(WCHAR)) return NULL;
3421 ptr = strrchrW(mod_path, '\\');
3422 if (ptr) {
3423 strcpyW(ptr+1, new_mod);
3424 TRACE("loading %s\n", debugstr_w(mod_path));
3425 return LoadLibraryW(mod_path);
3427 return NULL;
3430 /*************************************************************************
3431 * ColorAdjustLuma [SHLWAPI.@]
3433 * Adjust the luminosity of a color
3435 * PARAMS
3436 * cRGB [I] RGB value to convert
3437 * dwLuma [I] Luma adjustment
3438 * bUnknown [I] Unknown
3440 * RETURNS
3441 * The adjusted RGB color.
3443 COLORREF WINAPI ColorAdjustLuma(COLORREF cRGB, int dwLuma, BOOL bUnknown)
3445 TRACE("(0x%8lx,%d,%d)\n", cRGB, dwLuma, bUnknown);
3447 if (dwLuma)
3449 WORD wH, wL, wS;
3451 ColorRGBToHLS(cRGB, &wH, &wL, &wS);
3453 FIXME("Ignoring luma adjustment\n");
3455 /* FIXME: The ajdustment is not linear */
3457 cRGB = ColorHLSToRGB(wH, wL, wS);
3459 return cRGB;
3462 /*************************************************************************
3463 * @ [SHLWAPI.389]
3465 * See GetSaveFileNameW.
3467 BOOL WINAPI GetSaveFileNameWrapW(LPOPENFILENAMEW ofn)
3469 GET_FUNC(pGetSaveFileNameW, comdlg32, "GetSaveFileNameW", FALSE);
3470 return pGetSaveFileNameW(ofn);
3473 /*************************************************************************
3474 * @ [SHLWAPI.390]
3476 * See WNetRestoreConnectionW.
3478 DWORD WINAPI WNetRestoreConnectionWrapW(HWND hwndOwner, LPWSTR lpszDevice)
3480 GET_FUNC(pWNetRestoreConnectionW, mpr, "WNetRestoreConnectionW", 0);
3481 return pWNetRestoreConnectionW(hwndOwner, lpszDevice);
3484 /*************************************************************************
3485 * @ [SHLWAPI.391]
3487 * See WNetGetLastErrorW.
3489 DWORD WINAPI WNetGetLastErrorWrapW(LPDWORD lpError, LPWSTR lpErrorBuf, DWORD nErrorBufSize,
3490 LPWSTR lpNameBuf, DWORD nNameBufSize)
3492 GET_FUNC(pWNetGetLastErrorW, mpr, "WNetGetLastErrorW", 0);
3493 return pWNetGetLastErrorW(lpError, lpErrorBuf, nErrorBufSize, lpNameBuf, nNameBufSize);
3496 /*************************************************************************
3497 * @ [SHLWAPI.401]
3499 * See PageSetupDlgW.
3501 BOOL WINAPI PageSetupDlgWrapW(LPPAGESETUPDLGW pagedlg)
3503 GET_FUNC(pPageSetupDlgW, comdlg32, "PageSetupDlgW", FALSE);
3504 return pPageSetupDlgW(pagedlg);
3507 /*************************************************************************
3508 * @ [SHLWAPI.402]
3510 * See PrintDlgW.
3512 BOOL WINAPI PrintDlgWrapW(LPPRINTDLGW printdlg)
3514 GET_FUNC(pPrintDlgW, comdlg32, "PrintDlgW", FALSE);
3515 return pPrintDlgW(printdlg);
3518 /*************************************************************************
3519 * @ [SHLWAPI.403]
3521 * See GetOpenFileNameW.
3523 BOOL WINAPI GetOpenFileNameWrapW(LPOPENFILENAMEW ofn)
3525 GET_FUNC(pGetOpenFileNameW, comdlg32, "GetOpenFileNameW", FALSE);
3526 return pGetOpenFileNameW(ofn);
3529 /* INTERNAL: Map from HLS color space to RGB */
3530 static WORD WINAPI ConvertHue(int wHue, WORD wMid1, WORD wMid2)
3532 wHue = wHue > 240 ? wHue - 240 : wHue < 0 ? wHue + 240 : wHue;
3534 if (wHue > 160)
3535 return wMid1;
3536 else if (wHue > 120)
3537 wHue = 160 - wHue;
3538 else if (wHue > 40)
3539 return wMid2;
3541 return ((wHue * (wMid2 - wMid1) + 20) / 40) + wMid1;
3544 /* Convert to RGB and scale into RGB range (0..255) */
3545 #define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240
3547 /*************************************************************************
3548 * ColorHLSToRGB [SHLWAPI.@]
3550 * Convert from hls color space into an rgb COLORREF.
3552 * PARAMS
3553 * wHue [I] Hue amount
3554 * wLuminosity [I] Luminosity amount
3555 * wSaturation [I] Saturation amount
3557 * RETURNS
3558 * A COLORREF representing the converted color.
3560 * NOTES
3561 * Input hls values are constrained to the range (0..240).
3563 COLORREF WINAPI ColorHLSToRGB(WORD wHue, WORD wLuminosity, WORD wSaturation)
3565 WORD wRed;
3567 if (wSaturation)
3569 WORD wGreen, wBlue, wMid1, wMid2;
3571 if (wLuminosity > 120)
3572 wMid2 = wSaturation + wLuminosity - (wSaturation * wLuminosity + 120) / 240;
3573 else
3574 wMid2 = ((wSaturation + 240) * wLuminosity + 120) / 240;
3576 wMid1 = wLuminosity * 2 - wMid2;
3578 wRed = GET_RGB(wHue + 80);
3579 wGreen = GET_RGB(wHue);
3580 wBlue = GET_RGB(wHue - 80);
3582 return RGB(wRed, wGreen, wBlue);
3585 wRed = wLuminosity * 255 / 240;
3586 return RGB(wRed, wRed, wRed);
3589 /*************************************************************************
3590 * @ [SHLWAPI.413]
3592 * Get the current docking status of the system.
3594 * PARAMS
3595 * dwFlags [I] DOCKINFO_ flags from "winbase.h", unused
3597 * RETURNS
3598 * One of DOCKINFO_UNDOCKED, DOCKINFO_UNDOCKED, or 0 if the system is not
3599 * a notebook.
3601 DWORD WINAPI SHGetMachineInfo(DWORD dwFlags)
3603 HW_PROFILE_INFOA hwInfo;
3605 TRACE("(0x%08lx)\n", dwFlags);
3607 GetCurrentHwProfileA(&hwInfo);
3608 switch (hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED))
3610 case DOCKINFO_DOCKED:
3611 case DOCKINFO_UNDOCKED:
3612 return hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED);
3613 default:
3614 return 0;
3618 /*************************************************************************
3619 * @ [SHLWAPI.418]
3621 * Function seems to do FreeLibrary plus other things.
3623 * FIXME native shows the following calls:
3624 * RtlEnterCriticalSection
3625 * LocalFree
3626 * GetProcAddress(Comctl32??, 150L)
3627 * DPA_DeletePtr
3628 * RtlLeaveCriticalSection
3629 * followed by the FreeLibrary.
3630 * The above code may be related to .377 above.
3632 BOOL WINAPI MLFreeLibrary(HMODULE hModule)
3634 FIXME("(%p) semi-stub\n", hModule);
3635 return FreeLibrary(hModule);
3638 /*************************************************************************
3639 * @ [SHLWAPI.419]
3641 BOOL WINAPI SHFlushSFCacheWrap(void) {
3642 FIXME(": stub\n");
3643 return TRUE;
3646 /*************************************************************************
3647 * @ [SHLWAPI.429]
3648 * FIXME I have no idea what this function does or what its arguments are.
3650 BOOL WINAPI MLIsMLHInstance(HINSTANCE hInst)
3652 FIXME("(%p) stub\n", hInst);
3653 return FALSE;
3657 /*************************************************************************
3658 * @ [SHLWAPI.430]
3660 DWORD WINAPI MLSetMLHInstance(HINSTANCE hInst, HANDLE hHeap)
3662 FIXME("(%p,%p) stub\n", hInst, hHeap);
3663 return E_FAIL; /* This is what is used if shlwapi not loaded */
3666 /*************************************************************************
3667 * @ [SHLWAPI.431]
3669 DWORD WINAPI MLClearMLHInstance(DWORD x)
3671 FIXME("(0x%08lx)stub\n", x);
3672 return 0xabba1247;
3675 /*************************************************************************
3676 * @ [SHLWAPI.436]
3678 * Convert an Unicode string CLSID into a CLSID.
3680 * PARAMS
3681 * idstr [I] string containing a CLSID in text form
3682 * id [O] CLSID extracted from the string
3684 * RETURNS
3685 * S_OK on success or E_INVALIDARG on failure
3687 * NOTES
3688 * This is really CLSIDFromString() which is exported by ole32.dll,
3689 * however the native shlwapi.dll does *not* import ole32. Nor does
3690 * ole32.dll import this ordinal from shlwapi. Therefore we must conclude
3691 * that MS duplicated the code for CLSIDFromString(), and yes they did, only
3692 * it returns an E_INVALIDARG error code on failure.
3693 * This is a duplicate (with changes for Unicode) of CLSIDFromString16()
3694 * in "dlls/ole32/compobj.c".
3696 HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR idstr, CLSID *id)
3698 LPCWSTR s = idstr;
3699 BYTE *p;
3700 INT i;
3701 WCHAR table[256];
3703 if (!s) {
3704 memset(id, 0, sizeof(CLSID));
3705 return S_OK;
3707 else { /* validate the CLSID string */
3709 if (strlenW(s) != 38)
3710 return E_INVALIDARG;
3712 if ((s[0]!=L'{') || (s[9]!=L'-') || (s[14]!=L'-') || (s[19]!=L'-') || (s[24]!=L'-') || (s[37]!=L'}'))
3713 return E_INVALIDARG;
3715 for (i=1; i<37; i++)
3717 if ((i == 9)||(i == 14)||(i == 19)||(i == 24))
3718 continue;
3719 if (!(((s[i] >= L'0') && (s[i] <= L'9')) ||
3720 ((s[i] >= L'a') && (s[i] <= L'f')) ||
3721 ((s[i] >= L'A') && (s[i] <= L'F')))
3723 return E_INVALIDARG;
3727 TRACE("%s -> %p\n", debugstr_w(s), id);
3729 /* quick lookup table */
3730 memset(table, 0, 256*sizeof(WCHAR));
3732 for (i = 0; i < 10; i++) {
3733 table['0' + i] = i;
3735 for (i = 0; i < 6; i++) {
3736 table['A' + i] = i+10;
3737 table['a' + i] = i+10;
3740 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
3742 p = (BYTE *) id;
3744 s++; /* skip leading brace */
3745 for (i = 0; i < 4; i++) {
3746 p[3 - i] = table[*s]<<4 | table[*(s+1)];
3747 s += 2;
3749 p += 4;
3750 s++; /* skip - */
3752 for (i = 0; i < 2; i++) {
3753 p[1-i] = table[*s]<<4 | table[*(s+1)];
3754 s += 2;
3756 p += 2;
3757 s++; /* skip - */
3759 for (i = 0; i < 2; i++) {
3760 p[1-i] = table[*s]<<4 | table[*(s+1)];
3761 s += 2;
3763 p += 2;
3764 s++; /* skip - */
3766 /* these are just sequential bytes */
3767 for (i = 0; i < 2; i++) {
3768 *p++ = table[*s]<<4 | table[*(s+1)];
3769 s += 2;
3771 s++; /* skip - */
3773 for (i = 0; i < 6; i++) {
3774 *p++ = table[*s]<<4 | table[*(s+1)];
3775 s += 2;
3778 return S_OK;
3781 /*************************************************************************
3782 * @ [SHLWAPI.437]
3784 * Determine if the OS supports a given feature.
3786 * PARAMS
3787 * dwFeature [I] Feature requested (undocumented)
3789 * RETURNS
3790 * TRUE If the feature is available.
3791 * FALSE If the feature is not available.
3793 BOOL WINAPI IsOS(DWORD feature)
3795 OSVERSIONINFOA osvi;
3796 DWORD platform, majorv, minorv;
3798 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
3799 if(!GetVersionExA(&osvi)) {
3800 ERR("GetVersionEx failed");
3801 return FALSE;
3804 majorv = osvi.dwMajorVersion;
3805 minorv = osvi.dwMinorVersion;
3806 platform = osvi.dwPlatformId;
3808 #define ISOS_RETURN(x) \
3809 TRACE("(0x%lx) ret=%d\n",feature,(x)); \
3810 return (x);
3812 switch(feature) {
3813 case OS_WIN32SORGREATER:
3814 ISOS_RETURN(platform == VER_PLATFORM_WIN32s
3815 || platform == VER_PLATFORM_WIN32_WINDOWS)
3816 case OS_NT:
3817 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3818 case OS_WIN95ORGREATER:
3819 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS)
3820 case OS_NT4ORGREATER:
3821 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 4)
3822 case OS_WIN2000ORGREATER_ALT:
3823 case OS_WIN2000ORGREATER:
3824 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5)
3825 case OS_WIN98ORGREATER:
3826 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv >= 10)
3827 case OS_WIN98_GOLD:
3828 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv == 10)
3829 case OS_WIN2000PRO:
3830 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5)
3831 case OS_WIN2000SERVER:
3832 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3833 case OS_WIN2000ADVSERVER:
3834 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3835 case OS_WIN2000DATACENTER:
3836 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3837 case OS_WIN2000TERMINAL:
3838 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3839 case OS_EMBEDDED:
3840 FIXME("(OS_EMBEDDED) What should we return here?\n");
3841 return FALSE;
3842 case OS_TERMINALCLIENT:
3843 FIXME("(OS_TERMINALCLIENT) What should we return here?\n");
3844 return FALSE;
3845 case OS_TERMINALREMOTEADMIN:
3846 FIXME("(OS_TERMINALREMOTEADMIN) What should we return here?\n");
3847 return FALSE;
3848 case OS_WIN95_GOLD:
3849 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv == 0)
3850 case OS_MEORGREATER:
3851 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv >= 90)
3852 case OS_XPORGREATER:
3853 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5 && minorv >= 1)
3854 case OS_HOME:
3855 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5 && minorv >= 1)
3856 case OS_PROFESSIONAL:
3857 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3858 case OS_DATACENTER:
3859 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3860 case OS_ADVSERVER:
3861 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5)
3862 case OS_SERVER:
3863 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3864 case OS_TERMINALSERVER:
3865 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3866 case OS_PERSONALTERMINALSERVER:
3867 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && minorv >= 1 && majorv >= 5)
3868 case OS_FASTUSERSWITCHING:
3869 FIXME("(OS_FASTUSERSWITCHING) What should we return here?\n");
3870 return TRUE;
3871 case OS_WELCOMELOGONUI:
3872 FIXME("(OS_WELCOMELOGONUI) What should we return here?\n");
3873 return FALSE;
3874 case OS_DOMAINMEMBER:
3875 FIXME("(OS_DOMAINMEMBER) What should we return here?\n");
3876 return TRUE;
3877 case OS_ANYSERVER:
3878 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3879 case OS_WOW6432:
3880 FIXME("(OS_WOW6432) Should we check this?\n");
3881 return FALSE;
3882 case OS_WEBSERVER:
3883 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3884 case OS_SMALLBUSINESSSERVER:
3885 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3886 case OS_TABLETPC:
3887 FIXME("(OS_TABLEPC) What should we return here?\n");
3888 return FALSE;
3889 case OS_SERVERADMINUI:
3890 FIXME("(OS_SERVERADMINUI) What should we return here?\n");
3891 return FALSE;
3892 case OS_MEDIACENTER:
3893 FIXME("(OS_MEDIACENTER) What should we return here?\n");
3894 return FALSE;
3895 case OS_APPLIANCE:
3896 FIXME("(OS_APPLIANCE) What should we return here?\n");
3897 return FALSE;
3900 #undef ISOS_RETURN
3902 WARN("(0x%lx) unknown parameter\n",feature);
3904 return FALSE;
3907 /*************************************************************************
3908 * @ [SHLWAPI.478]
3910 * Call IInputObject_TranslateAcceleratorIO() on an object.
3912 * PARAMS
3913 * lpUnknown [I] Object supporting the IInputObject interface.
3914 * lpMsg [I] Key message to be processed.
3916 * RETURNS
3917 * Success: S_OK.
3918 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
3920 HRESULT WINAPI IUnknown_TranslateAcceleratorIO(IUnknown *lpUnknown, LPMSG lpMsg)
3922 IInputObject* lpInput = NULL;
3923 HRESULT hRet = E_INVALIDARG;
3925 TRACE("(%p,%p)\n", lpUnknown, lpMsg);
3926 if (lpUnknown)
3928 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInputObject,
3929 (void**)&lpInput);
3930 if (SUCCEEDED(hRet) && lpInput)
3932 hRet = IInputObject_TranslateAcceleratorIO(lpInput, lpMsg);
3933 IInputObject_Release(lpInput);
3936 return hRet;
3939 /*************************************************************************
3940 * @ [SHLWAPI.481]
3942 * Call IInputObject_HasFocusIO() on an object.
3944 * PARAMS
3945 * lpUnknown [I] Object supporting the IInputObject interface.
3947 * RETURNS
3948 * Success: S_OK, if lpUnknown is an IInputObject object and has the focus,
3949 * or S_FALSE otherwise.
3950 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
3952 HRESULT WINAPI IUnknown_HasFocusIO(IUnknown *lpUnknown)
3954 IInputObject* lpInput = NULL;
3955 HRESULT hRet = E_INVALIDARG;
3957 TRACE("(%p)\n", lpUnknown);
3958 if (lpUnknown)
3960 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInputObject,
3961 (void**)&lpInput);
3962 if (SUCCEEDED(hRet) && lpInput)
3964 hRet = IInputObject_HasFocusIO(lpInput);
3965 IInputObject_Release(lpInput);
3968 return hRet;
3971 /*************************************************************************
3972 * ColorRGBToHLS [SHLWAPI.@]
3974 * Convert an rgb COLORREF into the hls color space.
3976 * PARAMS
3977 * cRGB [I] Source rgb value
3978 * pwHue [O] Destination for converted hue
3979 * pwLuminance [O] Destination for converted luminance
3980 * pwSaturation [O] Destination for converted saturation
3982 * RETURNS
3983 * Nothing. pwHue, pwLuminance and pwSaturation are set to the converted
3984 * values.
3986 * NOTES
3987 * Output HLS values are constrained to the range (0..240).
3988 * For Achromatic conversions, Hue is set to 160.
3990 VOID WINAPI ColorRGBToHLS(COLORREF cRGB, LPWORD pwHue,
3991 LPWORD pwLuminance, LPWORD pwSaturation)
3993 int wR, wG, wB, wMax, wMin, wHue, wLuminosity, wSaturation;
3995 TRACE("(%08lx,%p,%p,%p)\n", cRGB, pwHue, pwLuminance, pwSaturation);
3997 wR = GetRValue(cRGB);
3998 wG = GetGValue(cRGB);
3999 wB = GetBValue(cRGB);
4001 wMax = max(wR, max(wG, wB));
4002 wMin = min(wR, min(wG, wB));
4004 /* Luminosity */
4005 wLuminosity = ((wMax + wMin) * 240 + 255) / 510;
4007 if (wMax == wMin)
4009 /* Achromatic case */
4010 wSaturation = 0;
4011 /* Hue is now unrepresentable, but this is what native returns... */
4012 wHue = 160;
4014 else
4016 /* Chromatic case */
4017 int wDelta = wMax - wMin, wRNorm, wGNorm, wBNorm;
4019 /* Saturation */
4020 if (wLuminosity <= 120)
4021 wSaturation = ((wMax + wMin)/2 + wDelta * 240) / (wMax + wMin);
4022 else
4023 wSaturation = ((510 - wMax - wMin)/2 + wDelta * 240) / (510 - wMax - wMin);
4025 /* Hue */
4026 wRNorm = (wDelta/2 + wMax * 40 - wR * 40) / wDelta;
4027 wGNorm = (wDelta/2 + wMax * 40 - wG * 40) / wDelta;
4028 wBNorm = (wDelta/2 + wMax * 40 - wB * 40) / wDelta;
4030 if (wR == wMax)
4031 wHue = wBNorm - wGNorm;
4032 else if (wG == wMax)
4033 wHue = 80 + wRNorm - wBNorm;
4034 else
4035 wHue = 160 + wGNorm - wRNorm;
4036 if (wHue < 0)
4037 wHue += 240;
4038 else if (wHue > 240)
4039 wHue -= 240;
4041 if (pwHue)
4042 *pwHue = wHue;
4043 if (pwLuminance)
4044 *pwLuminance = wLuminosity;
4045 if (pwSaturation)
4046 *pwSaturation = wSaturation;
4049 /*************************************************************************
4050 * SHCreateShellPalette [SHLWAPI.@]
4052 HPALETTE WINAPI SHCreateShellPalette(HDC hdc)
4054 FIXME("stub\n");
4055 return CreateHalftonePalette(hdc);
4058 /*************************************************************************
4059 * SHGetInverseCMAP (SHLWAPI.@)
4061 * Get an inverse color map table.
4063 * PARAMS
4064 * lpCmap [O] Destination for color map
4065 * dwSize [I] Size of memory pointed to by lpCmap
4067 * RETURNS
4068 * Success: S_OK.
4069 * Failure: E_POINTER, If lpCmap is invalid.
4070 * E_INVALIDARG, If dwFlags is invalid
4071 * E_OUTOFMEMORY, If there is no memory available
4073 * NOTES
4074 * dwSize may only be CMAP_PTR_SIZE (4) or CMAP_SIZE (8192).
4075 * If dwSize = CMAP_PTR_SIZE, *lpCmap is set to the address of this DLL's
4076 * internal CMap.
4077 * If dwSize = CMAP_SIZE, lpCmap is filled with a copy of the data from
4078 * this DLL's internal CMap.
4080 HRESULT WINAPI SHGetInverseCMAP(LPDWORD dest, DWORD dwSize)
4082 if (dwSize == 4) {
4083 FIXME(" - returning bogus address for SHGetInverseCMAP\n");
4084 *dest = (DWORD)0xabba1249;
4085 return 0;
4087 FIXME("(%p, %#lx) stub\n", dest, dwSize);
4088 return 0;
4091 /*************************************************************************
4092 * SHIsLowMemoryMachine [SHLWAPI.@]
4094 * Determine if the current computer has low memory.
4096 * PARAMS
4097 * x [I] FIXME
4099 * RETURNS
4100 * TRUE if the users machine has 16 Megabytes of memory or less,
4101 * FALSE otherwise.
4103 BOOL WINAPI SHIsLowMemoryMachine (DWORD x)
4105 FIXME("(0x%08lx) stub\n", x);
4106 return FALSE;
4109 /*************************************************************************
4110 * GetMenuPosFromID [SHLWAPI.@]
4112 * Return the position of a menu item from its Id.
4114 * PARAMS
4115 * hMenu [I] Menu containing the item
4116 * wID [I] Id of the menu item
4118 * RETURNS
4119 * Success: The index of the menu item in hMenu.
4120 * Failure: -1, If the item is not found.
4122 INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID)
4124 MENUITEMINFOA mi;
4125 INT nCount = GetMenuItemCount(hMenu), nIter = 0;
4127 while (nIter < nCount)
4129 mi.wID = 0;
4130 if (!GetMenuItemInfoA(hMenu, nIter, TRUE, &mi) && mi.wID == wID)
4131 return nIter;
4132 nIter++;
4134 return -1;
4137 /*************************************************************************
4138 * @ [SHLWAPI.179]
4140 * Same as SHLWAPI.GetMenuPosFromID
4142 DWORD WINAPI SHMenuIndexFromID(HMENU hMenu, UINT uID)
4144 return GetMenuPosFromID(hMenu, uID);
4148 /*************************************************************************
4149 * @ [SHLWAPI.448]
4151 VOID WINAPI FixSlashesAndColonW(LPWSTR lpwstr)
4153 while (*lpwstr)
4155 if (*lpwstr == '/')
4156 *lpwstr = '\\';
4157 lpwstr++;
4162 /*************************************************************************
4163 * @ [SHLWAPI.461]
4165 DWORD WINAPI SHGetAppCompatFlags(DWORD dwUnknown)
4167 FIXME("(0x%08lx) stub\n", dwUnknown);
4168 return 0;
4172 /*************************************************************************
4173 * @ [SHLWAPI.549]
4175 HRESULT WINAPI SHCoCreateInstanceAC(REFCLSID rclsid, LPUNKNOWN pUnkOuter,
4176 DWORD dwClsContext, REFIID iid, LPVOID *ppv)
4178 return CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, ppv);
4181 /*************************************************************************
4182 * SHSkipJunction [SHLWAPI.@]
4184 * Determine if a bind context can be bound to an object
4186 * PARAMS
4187 * pbc [I] Bind context to check
4188 * pclsid [I] CLSID of object to be bound to
4190 * RETURNS
4191 * TRUE: If it is safe to bind
4192 * FALSE: If pbc is invalid or binding would not be safe
4195 BOOL WINAPI SHSkipJunction(IBindCtx *pbc, const CLSID *pclsid)
4197 static const WCHAR szSkipBinding[] = { 'S','k','i','p',' ',
4198 'B','i','n','d','i','n','g',' ','C','L','S','I','D','\0' };
4199 BOOL bRet = FALSE;
4201 if (pbc)
4203 IUnknown* lpUnk;
4205 if (SUCCEEDED(IBindCtx_GetObjectParam(pbc, (LPOLESTR)szSkipBinding, &lpUnk)))
4207 CLSID clsid;
4209 if (SUCCEEDED(IUnknown_GetClassID(lpUnk, &clsid)) &&
4210 IsEqualGUID(pclsid, &clsid))
4211 bRet = TRUE;
4213 IUnknown_Release(lpUnk);
4216 return bRet;
4219 /***********************************************************************
4220 * SHGetShellKey (SHLWAPI.@)
4222 DWORD WINAPI SHGetShellKey(DWORD a, DWORD b, DWORD c)
4224 FIXME("(%lx, %lx, %lx): stub\n", a, b, c);
4225 return 0x50;
4228 /***********************************************************************
4229 * SHQueueUserWorkItem (SHLWAPI.@)
4231 HRESULT WINAPI SHQueueUserWorkItem(DWORD a, DWORD b, DWORD c, DWORD d, DWORD e, DWORD f, DWORD g)
4233 FIXME("(%lx, %lx, %lx, %lx, %lx, %lx, %lx): stub\n", a, b, c, d, e, f, g);
4234 return E_FAIL;
4237 /***********************************************************************
4238 * IUnknown_OnFocusChangeIS (SHLWAPI.@)
4240 HRESULT WINAPI IUnknown_OnFocusChangeIS(LPUNKNOWN lpUnknown, LPUNKNOWN pFocusObject, BOOL bFocus)
4242 IInputObjectSite *pIOS = NULL;
4243 HRESULT hRet = E_INVALIDARG;
4245 TRACE("(%p, %p, %s)\n", lpUnknown, pFocusObject, bFocus ? "TRUE" : "FALSE");
4247 if (lpUnknown)
4249 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInputObjectSite,
4250 (void **)&pIOS);
4251 if (SUCCEEDED(hRet) && pIOS)
4253 hRet = IInputObjectSite_OnFocusChangeIS(pIOS, pFocusObject, bFocus);
4254 IInputObjectSite_Release(pIOS);
4257 return hRet;
4260 /***********************************************************************
4261 * SHGetValueW (SHLWAPI.@)
4263 HRESULT WINAPI SKGetValueW(DWORD a, LPWSTR b, LPWSTR c, DWORD d, DWORD e, DWORD f)
4265 FIXME("(%lx, %s, %s, %lx, %lx, %lx): stub\n", a, debugstr_w(b), debugstr_w(c), d, e, f);
4266 return E_FAIL;
4269 typedef HRESULT (WINAPI *DllGetVersion_func)(DLLVERSIONINFO *);
4271 /***********************************************************************
4272 * GetUIVersion (SHLWAPI.452)
4274 DWORD WINAPI GetUIVersion(void)
4276 static DWORD version;
4278 if (!version)
4280 DllGetVersion_func pDllGetVersion;
4281 HMODULE dll = LoadLibraryA("shell32.dll");
4282 if (!dll) return 0;
4284 pDllGetVersion = (DllGetVersion_func)GetProcAddress(dll, "DllGetVersion");
4285 if (pDllGetVersion)
4287 DLLVERSIONINFO dvi;
4288 dvi.cbSize = sizeof(DLLVERSIONINFO);
4289 if (pDllGetVersion(&dvi) == S_OK) version = dvi.dwMajorVersion;
4291 FreeLibrary( dll );
4292 if (!version) version = 3; /* old shell dlls don't have DllGetVersion */
4294 return version;