push b5232b2081a0e20e4bf07d6ded424d0101e4a589
[wine/hacks.git] / dlls / shlwapi / ordinal.c
blobb1cb585a6170992ab1bea831eccae3a677eb13cb
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "config.h"
24 #include "wine/port.h"
26 #include <stdarg.h>
27 #include <stdio.h>
28 #include <string.h>
30 #define COBJMACROS
31 #define NONAMELESSUNION
32 #define NONAMELESSSTRUCT
34 #include "windef.h"
35 #include "winbase.h"
36 #include "winreg.h"
37 #include "wingdi.h"
38 #include "winuser.h"
39 #include "winver.h"
40 #include "winnetwk.h"
41 #include "mmsystem.h"
42 #include "objbase.h"
43 #include "exdisp.h"
44 #include "shlobj.h"
45 #include "shlwapi.h"
46 #include "shellapi.h"
47 #include "commdlg.h"
48 #include "wine/unicode.h"
49 #include "wine/debug.h"
52 WINE_DEFAULT_DEBUG_CHANNEL(shell);
54 /* DLL handles for late bound calls */
55 extern HINSTANCE shlwapi_hInstance;
56 extern DWORD SHLWAPI_ThreadRef_index;
58 HRESULT WINAPI IUnknown_QueryService(IUnknown*,REFGUID,REFIID,LPVOID*);
59 HRESULT WINAPI SHInvokeCommand(HWND,IShellFolder*,LPCITEMIDLIST,BOOL);
60 BOOL WINAPI SHAboutInfoW(LPWSTR,DWORD);
63 NOTES: Most functions exported by ordinal seem to be superflous.
64 The reason for these functions to be there is to provide a wrapper
65 for unicode functions to provide these functions on systems without
66 unicode functions eg. win95/win98. Since we have such functions we just
67 call these. If running Wine with native DLLs, some late bound calls may
68 fail. However, it is better to implement the functions in the forward DLL
69 and recommend the builtin rather than reimplementing the calls here!
72 /*************************************************************************
73 * SHLWAPI_DupSharedHandle
75 * Internal implemetation of SHLWAPI_11.
77 static
78 HANDLE WINAPI SHLWAPI_DupSharedHandle(HANDLE hShared, DWORD dwDstProcId,
79 DWORD dwSrcProcId, DWORD dwAccess,
80 DWORD dwOptions)
82 HANDLE hDst, hSrc;
83 DWORD dwMyProcId = GetCurrentProcessId();
84 HANDLE hRet = NULL;
86 TRACE("(%p,%d,%d,%08x,%08x)\n", hShared, dwDstProcId, dwSrcProcId,
87 dwAccess, dwOptions);
89 /* Get dest process handle */
90 if (dwDstProcId == dwMyProcId)
91 hDst = GetCurrentProcess();
92 else
93 hDst = OpenProcess(PROCESS_DUP_HANDLE, 0, dwDstProcId);
95 if (hDst)
97 /* Get src process handle */
98 if (dwSrcProcId == dwMyProcId)
99 hSrc = GetCurrentProcess();
100 else
101 hSrc = OpenProcess(PROCESS_DUP_HANDLE, 0, dwSrcProcId);
103 if (hSrc)
105 /* Make handle available to dest process */
106 if (!DuplicateHandle(hDst, hShared, hSrc, &hRet,
107 dwAccess, 0, dwOptions | DUPLICATE_SAME_ACCESS))
108 hRet = NULL;
110 if (dwSrcProcId != dwMyProcId)
111 CloseHandle(hSrc);
114 if (dwDstProcId != dwMyProcId)
115 CloseHandle(hDst);
118 TRACE("Returning handle %p\n", hRet);
119 return hRet;
122 /*************************************************************************
123 * @ [SHLWAPI.7]
125 * Create a block of sharable memory and initialise it with data.
127 * PARAMS
128 * lpvData [I] Pointer to data to write
129 * dwSize [I] Size of data
130 * dwProcId [I] ID of process owning data
132 * RETURNS
133 * Success: A shared memory handle
134 * Failure: NULL
136 * NOTES
137 * Ordinals 7-11 provide a set of calls to create shared memory between a
138 * group of processes. The shared memory is treated opaquely in that its size
139 * is not exposed to clients who map it. This is accomplished by storing
140 * the size of the map as the first DWORD of mapped data, and then offsetting
141 * the view pointer returned by this size.
144 HANDLE WINAPI SHAllocShared(LPCVOID lpvData, DWORD dwSize, DWORD dwProcId)
146 HANDLE hMap;
147 LPVOID pMapped;
148 HANDLE hRet = NULL;
150 TRACE("(%p,%d,%d)\n", lpvData, dwSize, dwProcId);
152 /* Create file mapping of the correct length */
153 hMap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, FILE_MAP_READ, 0,
154 dwSize + sizeof(dwSize), NULL);
155 if (!hMap)
156 return hRet;
158 /* Get a view in our process address space */
159 pMapped = MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
161 if (pMapped)
163 /* Write size of data, followed by the data, to the view */
164 *((DWORD*)pMapped) = dwSize;
165 if (lpvData)
166 memcpy((char *) pMapped + sizeof(dwSize), lpvData, dwSize);
168 /* Release view. All further views mapped will be opaque */
169 UnmapViewOfFile(pMapped);
170 hRet = SHLWAPI_DupSharedHandle(hMap, dwProcId,
171 GetCurrentProcessId(), FILE_MAP_ALL_ACCESS,
172 DUPLICATE_SAME_ACCESS);
175 CloseHandle(hMap);
176 return hRet;
179 /*************************************************************************
180 * @ [SHLWAPI.8]
182 * Get a pointer to a block of shared memory from a shared memory handle.
184 * PARAMS
185 * hShared [I] Shared memory handle
186 * dwProcId [I] ID of process owning hShared
188 * RETURNS
189 * Success: A pointer to the shared memory
190 * Failure: NULL
193 PVOID WINAPI SHLockShared(HANDLE hShared, DWORD dwProcId)
195 HANDLE hDup;
196 LPVOID pMapped;
198 TRACE("(%p %d)\n", hShared, dwProcId);
200 /* Get handle to shared memory for current process */
201 hDup = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
202 FILE_MAP_ALL_ACCESS, 0);
203 /* Get View */
204 pMapped = MapViewOfFile(hDup, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
205 CloseHandle(hDup);
207 if (pMapped)
208 return (char *) pMapped + sizeof(DWORD); /* Hide size */
209 return NULL;
212 /*************************************************************************
213 * @ [SHLWAPI.9]
215 * Release a pointer to a block of shared memory.
217 * PARAMS
218 * lpView [I] Shared memory pointer
220 * RETURNS
221 * Success: TRUE
222 * Failure: FALSE
225 BOOL WINAPI SHUnlockShared(LPVOID lpView)
227 TRACE("(%p)\n", lpView);
228 return UnmapViewOfFile((char *) lpView - sizeof(DWORD)); /* Include size */
231 /*************************************************************************
232 * @ [SHLWAPI.10]
234 * Destroy a block of sharable memory.
236 * PARAMS
237 * hShared [I] Shared memory handle
238 * dwProcId [I] ID of process owning hShared
240 * RETURNS
241 * Success: TRUE
242 * Failure: FALSE
245 BOOL WINAPI SHFreeShared(HANDLE hShared, DWORD dwProcId)
247 HANDLE hClose;
249 TRACE("(%p %d)\n", hShared, dwProcId);
251 /* Get a copy of the handle for our process, closing the source handle */
252 hClose = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
253 FILE_MAP_ALL_ACCESS,DUPLICATE_CLOSE_SOURCE);
254 /* Close local copy */
255 return CloseHandle(hClose);
258 /*************************************************************************
259 * @ [SHLWAPI.11]
261 * Copy a sharable memory handle from one process to another.
263 * PARAMS
264 * hShared [I] Shared memory handle to duplicate
265 * dwDstProcId [I] ID of the process wanting the duplicated handle
266 * dwSrcProcId [I] ID of the process owning hShared
267 * dwAccess [I] Desired DuplicateHandle() access
268 * dwOptions [I] Desired DuplicateHandle() options
270 * RETURNS
271 * Success: A handle suitable for use by the dwDstProcId process.
272 * Failure: A NULL handle.
275 HANDLE WINAPI SHMapHandle(HANDLE hShared, DWORD dwDstProcId, DWORD dwSrcProcId,
276 DWORD dwAccess, DWORD dwOptions)
278 HANDLE hRet;
280 hRet = SHLWAPI_DupSharedHandle(hShared, dwDstProcId, dwSrcProcId,
281 dwAccess, dwOptions);
282 return hRet;
285 /*************************************************************************
286 * @ [SHLWAPI.13]
288 * Create and register a clipboard enumerator for a web browser.
290 * PARAMS
291 * lpBC [I] Binding context
292 * lpUnknown [I] An object exposing the IWebBrowserApp interface
294 * RETURNS
295 * Success: S_OK.
296 * Failure: An HRESULT error code.
298 * NOTES
299 * The enumerator is stored as a property of the web browser. If it does not
300 * yet exist, it is created and set before being registered.
302 HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown)
304 static const WCHAR szProperty[] = { '{','D','0','F','C','A','4','2','0',
305 '-','D','3','F','5','-','1','1','C','F', '-','B','2','1','1','-','0',
306 '0','A','A','0','0','4','A','E','8','3','7','}','\0' };
307 BSTR property;
308 IEnumFORMATETC* pIEnumFormatEtc = NULL;
309 VARIANTARG var;
310 HRESULT hRet;
311 IWebBrowserApp* pBrowser = NULL;
313 TRACE("(%p, %p)\n", lpBC, lpUnknown);
315 /* Get An IWebBrowserApp interface from lpUnknown */
316 hRet = IUnknown_QueryService(lpUnknown, &IID_IWebBrowserApp, &IID_IWebBrowserApp, (PVOID)&pBrowser);
317 if (FAILED(hRet) || !pBrowser)
318 return E_NOINTERFACE;
320 V_VT(&var) = VT_EMPTY;
322 /* The property we get is the browsers clipboard enumerator */
323 property = SysAllocString(szProperty);
324 hRet = IWebBrowserApp_GetProperty(pBrowser, property, &var);
325 SysFreeString(property);
326 if (FAILED(hRet))
327 return hRet;
329 if (V_VT(&var) == VT_EMPTY)
331 /* Iterate through accepted documents and RegisterClipBoardFormatA() them */
332 char szKeyBuff[128], szValueBuff[128];
333 DWORD dwKeySize, dwValueSize, dwRet = 0, dwCount = 0, dwNumValues, dwType;
334 FORMATETC* formatList, *format;
335 HKEY hDocs;
337 TRACE("Registering formats and creating IEnumFORMATETC instance\n");
339 if (!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\Current"
340 "Version\\Internet Settings\\Accepted Documents", &hDocs))
341 return E_FAIL;
343 /* Get count of values in key */
344 while (!dwRet)
346 dwKeySize = sizeof(szKeyBuff);
347 dwRet = RegEnumValueA(hDocs,dwCount,szKeyBuff,&dwKeySize,0,&dwType,0,0);
348 dwCount++;
351 dwNumValues = dwCount;
353 /* Note: dwCount = number of items + 1; The extra item is the end node */
354 format = formatList = HeapAlloc(GetProcessHeap(), 0, dwCount * sizeof(FORMATETC));
355 if (!formatList)
356 return E_OUTOFMEMORY;
358 if (dwNumValues > 1)
360 dwRet = 0;
361 dwCount = 0;
363 dwNumValues--;
365 /* Register clipboard formats for the values and populate format list */
366 while(!dwRet && dwCount < dwNumValues)
368 dwKeySize = sizeof(szKeyBuff);
369 dwValueSize = sizeof(szValueBuff);
370 dwRet = RegEnumValueA(hDocs, dwCount, szKeyBuff, &dwKeySize, 0, &dwType,
371 (PBYTE)szValueBuff, &dwValueSize);
372 if (!dwRet)
373 return E_FAIL;
375 format->cfFormat = RegisterClipboardFormatA(szValueBuff);
376 format->ptd = NULL;
377 format->dwAspect = 1;
378 format->lindex = 4;
379 format->tymed = -1;
381 format++;
382 dwCount++;
386 /* Terminate the (maybe empty) list, last entry has a cfFormat of 0 */
387 format->cfFormat = 0;
388 format->ptd = NULL;
389 format->dwAspect = 1;
390 format->lindex = 4;
391 format->tymed = -1;
393 /* Create a clipboard enumerator */
394 hRet = CreateFormatEnumerator(dwNumValues, formatList, &pIEnumFormatEtc);
396 if (FAILED(hRet) || !pIEnumFormatEtc)
397 return hRet;
399 /* Set our enumerator as the browsers property */
400 V_VT(&var) = VT_UNKNOWN;
401 V_UNKNOWN(&var) = (IUnknown*)pIEnumFormatEtc;
403 hRet = IWebBrowserApp_PutProperty(pBrowser, (BSTR)szProperty, var);
404 if (FAILED(hRet))
406 IEnumFORMATETC_Release(pIEnumFormatEtc);
407 goto RegisterDefaultAcceptHeaders_Exit;
411 if (V_VT(&var) == VT_UNKNOWN)
413 /* Our variant is holding the clipboard enumerator */
414 IUnknown* pIUnknown = V_UNKNOWN(&var);
415 IEnumFORMATETC* pClone = NULL;
417 TRACE("Retrieved IEnumFORMATETC property\n");
419 /* Get an IEnumFormatEtc interface from the variants value */
420 pIEnumFormatEtc = NULL;
421 hRet = IUnknown_QueryInterface(pIUnknown, &IID_IEnumFORMATETC,
422 (PVOID)&pIEnumFormatEtc);
423 if (!hRet && pIEnumFormatEtc)
425 /* Clone and register the enumerator */
426 hRet = IEnumFORMATETC_Clone(pIEnumFormatEtc, &pClone);
427 if (!hRet && pClone)
429 RegisterFormatEnumerator(lpBC, pClone, 0);
431 IEnumFORMATETC_Release(pClone);
434 /* Release the IEnumFormatEtc interface */
435 IEnumFORMATETC_Release(pIUnknown);
437 IUnknown_Release(V_UNKNOWN(&var));
440 RegisterDefaultAcceptHeaders_Exit:
441 IWebBrowserApp_Release(pBrowser);
442 return hRet;
445 /*************************************************************************
446 * @ [SHLWAPI.15]
448 * Get Explorers "AcceptLanguage" setting.
450 * PARAMS
451 * langbuf [O] Destination for language string
452 * buflen [I] Length of langbuf
453 * [0] Success: used length of langbuf
455 * RETURNS
456 * Success: S_OK. langbuf is set to the language string found.
457 * Failure: E_FAIL, If any arguments are invalid, error occurred, or Explorer
458 * does not contain the setting.
459 * E_INVALIDARG, If the buffer is not big enough
461 HRESULT WINAPI GetAcceptLanguagesW( LPWSTR langbuf, LPDWORD buflen)
463 static const WCHAR szkeyW[] = {
464 'S','o','f','t','w','a','r','e','\\',
465 'M','i','c','r','o','s','o','f','t','\\',
466 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
467 'I','n','t','e','r','n','a','t','i','o','n','a','l',0};
468 static const WCHAR valueW[] = {
469 'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0};
470 static const WCHAR enusW[] = {'e','n','-','u','s',0};
471 DWORD mystrlen, mytype;
472 HKEY mykey;
473 HRESULT retval;
474 LCID mylcid;
475 WCHAR *mystr;
477 if(!langbuf || !buflen || !*buflen)
478 return E_FAIL;
480 mystrlen = (*buflen > 20) ? *buflen : 20 ;
481 mystr = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * mystrlen);
482 RegOpenKeyW(HKEY_CURRENT_USER, szkeyW, &mykey);
483 if(RegQueryValueExW(mykey, valueW, 0, &mytype, (PBYTE)mystr, &mystrlen)) {
484 /* Did not find value */
485 mylcid = GetUserDefaultLCID();
486 /* somehow the mylcid translates into "en-us"
487 * this is similar to "LOCALE_SABBREVLANGNAME"
488 * which could be gotten via GetLocaleInfo.
489 * The only problem is LOCALE_SABBREVLANGUAGE" is
490 * a 3 char string (first 2 are country code and third is
491 * letter for "sublanguage", which does not come close to
492 * "en-us"
494 lstrcpyW(mystr, enusW);
495 mystrlen = lstrlenW(mystr);
496 } else {
497 /* handle returned string */
498 FIXME("missing code\n");
500 memcpy( langbuf, mystr, min(*buflen,strlenW(mystr)+1)*sizeof(WCHAR) );
502 if(*buflen > strlenW(mystr)) {
503 *buflen = strlenW(mystr);
504 retval = S_OK;
505 } else {
506 *buflen = 0;
507 retval = E_INVALIDARG;
508 SetLastError(ERROR_INSUFFICIENT_BUFFER);
510 RegCloseKey(mykey);
511 HeapFree(GetProcessHeap(), 0, mystr);
512 return retval;
515 /*************************************************************************
516 * @ [SHLWAPI.14]
518 * Ascii version of GetAcceptLanguagesW.
520 HRESULT WINAPI GetAcceptLanguagesA( LPSTR langbuf, LPDWORD buflen)
522 WCHAR *langbufW;
523 DWORD buflenW, convlen;
524 HRESULT retval;
526 if(!langbuf || !buflen || !*buflen) return E_FAIL;
528 buflenW = *buflen;
529 langbufW = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * buflenW);
530 retval = GetAcceptLanguagesW(langbufW, &buflenW);
532 /* FIXME: this is wrong, the string may not be null-terminated */
533 convlen = WideCharToMultiByte(CP_ACP, 0, langbufW, -1, langbuf,
534 *buflen, NULL, NULL);
535 *buflen = buflenW ? convlen : 0;
537 HeapFree(GetProcessHeap(), 0, langbufW);
538 return retval;
541 /*************************************************************************
542 * @ [SHLWAPI.23]
544 * Convert a GUID to a string.
546 * PARAMS
547 * guid [I] GUID to convert
548 * lpszDest [O] Destination for string
549 * cchMax [I] Length of output buffer
551 * RETURNS
552 * The length of the string created.
554 INT WINAPI SHStringFromGUIDA(REFGUID guid, LPSTR lpszDest, INT cchMax)
556 char xguid[40];
557 INT iLen;
559 TRACE("(%s,%p,%d)\n", debugstr_guid(guid), lpszDest, cchMax);
561 sprintf(xguid, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
562 guid->Data1, guid->Data2, guid->Data3,
563 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
564 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
566 iLen = strlen(xguid) + 1;
568 if (iLen > cchMax)
569 return 0;
570 memcpy(lpszDest, xguid, iLen);
571 return iLen;
574 /*************************************************************************
575 * @ [SHLWAPI.24]
577 * Convert a GUID to a string.
579 * PARAMS
580 * guid [I] GUID to convert
581 * str [O] Destination for string
582 * cmax [I] Length of output buffer
584 * RETURNS
585 * The length of the string created.
587 INT WINAPI SHStringFromGUIDW(REFGUID guid, LPWSTR lpszDest, INT cchMax)
589 WCHAR xguid[40];
590 INT iLen;
591 static const WCHAR wszFormat[] = {'{','%','0','8','l','X','-','%','0','4','X','-','%','0','4','X','-',
592 '%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','%','0','2','X','%','0','2',
593 'X','%','0','2','X','%','0','2','X','}',0};
595 TRACE("(%s,%p,%d)\n", debugstr_guid(guid), lpszDest, cchMax);
597 sprintfW(xguid, wszFormat, guid->Data1, guid->Data2, guid->Data3,
598 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
599 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
601 iLen = strlenW(xguid) + 1;
603 if (iLen > cchMax)
604 return 0;
605 memcpy(lpszDest, xguid, iLen*sizeof(WCHAR));
606 return iLen;
609 /*************************************************************************
610 * @ [SHLWAPI.29]
612 * Determine if a Unicode character is a space.
614 * PARAMS
615 * wc [I] Character to check.
617 * RETURNS
618 * TRUE, if wc is a space,
619 * FALSE otherwise.
621 BOOL WINAPI IsCharSpaceW(WCHAR wc)
623 WORD CharType;
625 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_SPACE);
628 /*************************************************************************
629 * @ [SHLWAPI.30]
631 * Determine if a Unicode character is a blank.
633 * PARAMS
634 * wc [I] Character to check.
636 * RETURNS
637 * TRUE, if wc is a blank,
638 * FALSE otherwise.
641 BOOL WINAPI IsCharBlankW(WCHAR wc)
643 WORD CharType;
645 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_BLANK);
648 /*************************************************************************
649 * @ [SHLWAPI.31]
651 * Determine if a Unicode character is punctuation.
653 * PARAMS
654 * wc [I] Character to check.
656 * RETURNS
657 * TRUE, if wc is punctuation,
658 * FALSE otherwise.
660 BOOL WINAPI IsCharPunctW(WCHAR wc)
662 WORD CharType;
664 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_PUNCT);
667 /*************************************************************************
668 * @ [SHLWAPI.32]
670 * Determine if a Unicode character is a control character.
672 * PARAMS
673 * wc [I] Character to check.
675 * RETURNS
676 * TRUE, if wc is a control character,
677 * FALSE otherwise.
679 BOOL WINAPI IsCharCntrlW(WCHAR wc)
681 WORD CharType;
683 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_CNTRL);
686 /*************************************************************************
687 * @ [SHLWAPI.33]
689 * Determine if a Unicode character is a digit.
691 * PARAMS
692 * wc [I] Character to check.
694 * RETURNS
695 * TRUE, if wc is a digit,
696 * FALSE otherwise.
698 BOOL WINAPI IsCharDigitW(WCHAR wc)
700 WORD CharType;
702 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_DIGIT);
705 /*************************************************************************
706 * @ [SHLWAPI.34]
708 * Determine if a Unicode character is a hex digit.
710 * PARAMS
711 * wc [I] Character to check.
713 * RETURNS
714 * TRUE, if wc is a hex digit,
715 * FALSE otherwise.
717 BOOL WINAPI IsCharXDigitW(WCHAR wc)
719 WORD CharType;
721 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_XDIGIT);
724 /*************************************************************************
725 * @ [SHLWAPI.35]
728 BOOL WINAPI GetStringType3ExW(LPWSTR lpszStr, DWORD dwLen, LPVOID p3)
730 FIXME("(%s,0x%08x,%p): stub\n", debugstr_w(lpszStr), dwLen, p3);
731 return TRUE;
734 /*************************************************************************
735 * @ [SHLWAPI.36]
737 * Insert a bitmap menu item at the bottom of a menu.
739 * PARAMS
740 * hMenu [I] Menu to insert into
741 * flags [I] Flags for insertion
742 * id [I] Menu ID of the item
743 * str [I] Menu text for the item
745 * RETURNS
746 * Success: TRUE, the item is inserted into the menu
747 * Failure: FALSE, if any parameter is invalid
749 BOOL WINAPI AppendMenuWrapW(HMENU hMenu, UINT flags, UINT id, LPCWSTR str)
751 TRACE("(%p,0x%08x,0x%08x,%s)\n",hMenu, flags, id, debugstr_w(str));
752 return InsertMenuW(hMenu, -1, flags | MF_BITMAP, id, str);
755 /*************************************************************************
756 * @ [SHLWAPI.138]
758 * Set the text of a given dialog item.
760 * PARAMS
761 * hWnd [I] Handle of dialog
762 * iItem [I] Index of item
763 * lpszText [O] Text to set
765 * RETURNS
766 * Success: TRUE. The text of the dialog is set to lpszText.
767 * Failure: FALSE, Otherwise.
769 BOOL WINAPI SetDlgItemTextWrapW(HWND hWnd, INT iItem, LPCWSTR lpszText)
771 HWND hWndItem = GetDlgItem(hWnd, iItem);
772 if (hWndItem)
773 return SetWindowTextW(hWndItem, lpszText);
774 return FALSE;
777 /*************************************************************************
778 * @ [SHLWAPI.151]
780 * Compare two Ascii strings up to a given length.
782 * PARAMS
783 * lpszSrc [I] Source string
784 * lpszCmp [I] String to compare to lpszSrc
785 * len [I] Maximum length
787 * RETURNS
788 * A number greater than, less than or equal to 0 depending on whether
789 * lpszSrc is greater than, less than or equal to lpszCmp.
791 DWORD WINAPI StrCmpNCA(LPCSTR lpszSrc, LPCSTR lpszCmp, INT len)
793 return strncmp(lpszSrc, lpszCmp, len);
796 /*************************************************************************
797 * @ [SHLWAPI.152]
799 * Unicode version of StrCmpNCA.
801 DWORD WINAPI StrCmpNCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, INT len)
803 return strncmpW(lpszSrc, lpszCmp, len);
806 /*************************************************************************
807 * @ [SHLWAPI.153]
809 * Compare two Ascii strings up to a given length, ignoring case.
811 * PARAMS
812 * lpszSrc [I] Source string
813 * lpszCmp [I] String to compare to lpszSrc
814 * len [I] Maximum length
816 * RETURNS
817 * A number greater than, less than or equal to 0 depending on whether
818 * lpszSrc is greater than, less than or equal to lpszCmp.
820 DWORD WINAPI StrCmpNICA(LPCSTR lpszSrc, LPCSTR lpszCmp, DWORD len)
822 return strncasecmp(lpszSrc, lpszCmp, len);
825 /*************************************************************************
826 * @ [SHLWAPI.154]
828 * Unicode version of StrCmpNICA.
830 DWORD WINAPI StrCmpNICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, DWORD len)
832 return strncmpiW(lpszSrc, lpszCmp, len);
835 /*************************************************************************
836 * @ [SHLWAPI.155]
838 * Compare two Ascii strings.
840 * PARAMS
841 * lpszSrc [I] Source string
842 * lpszCmp [I] String to compare to lpszSrc
844 * RETURNS
845 * A number greater than, less than or equal to 0 depending on whether
846 * lpszSrc is greater than, less than or equal to lpszCmp.
848 DWORD WINAPI StrCmpCA(LPCSTR lpszSrc, LPCSTR lpszCmp)
850 return strcmp(lpszSrc, lpszCmp);
853 /*************************************************************************
854 * @ [SHLWAPI.156]
856 * Unicode version of StrCmpCA.
858 DWORD WINAPI StrCmpCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp)
860 return strcmpW(lpszSrc, lpszCmp);
863 /*************************************************************************
864 * @ [SHLWAPI.157]
866 * Compare two Ascii strings, ignoring case.
868 * PARAMS
869 * lpszSrc [I] Source string
870 * lpszCmp [I] String to compare to lpszSrc
872 * RETURNS
873 * A number greater than, less than or equal to 0 depending on whether
874 * lpszSrc is greater than, less than or equal to lpszCmp.
876 DWORD WINAPI StrCmpICA(LPCSTR lpszSrc, LPCSTR lpszCmp)
878 return strcasecmp(lpszSrc, lpszCmp);
881 /*************************************************************************
882 * @ [SHLWAPI.158]
884 * Unicode version of StrCmpICA.
886 DWORD WINAPI StrCmpICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp)
888 return strcmpiW(lpszSrc, lpszCmp);
891 /*************************************************************************
892 * @ [SHLWAPI.160]
894 * Get an identification string for the OS and explorer.
896 * PARAMS
897 * lpszDest [O] Destination for Id string
898 * dwDestLen [I] Length of lpszDest
900 * RETURNS
901 * TRUE, If the string was created successfully
902 * FALSE, Otherwise
904 BOOL WINAPI SHAboutInfoA(LPSTR lpszDest, DWORD dwDestLen)
906 WCHAR buff[2084];
908 TRACE("(%p,%d)\n", lpszDest, dwDestLen);
910 if (lpszDest && SHAboutInfoW(buff, dwDestLen))
912 WideCharToMultiByte(CP_ACP, 0, buff, -1, lpszDest, dwDestLen, NULL, NULL);
913 return TRUE;
915 return FALSE;
918 /*************************************************************************
919 * @ [SHLWAPI.161]
921 * Unicode version of SHAboutInfoA.
923 BOOL WINAPI SHAboutInfoW(LPWSTR lpszDest, DWORD dwDestLen)
925 static const WCHAR szIEKey[] = { 'S','O','F','T','W','A','R','E','\\',
926 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
927 ' ','E','x','p','l','o','r','e','r','\0' };
928 static const WCHAR szWinNtKey[] = { 'S','O','F','T','W','A','R','E','\\',
929 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s',' ',
930 'N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
931 static const WCHAR szWinKey[] = { 'S','O','F','T','W','A','R','E','\\',
932 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
933 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
934 static const WCHAR szRegKey[] = { 'S','O','F','T','W','A','R','E','\\',
935 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
936 ' ','E','x','p','l','o','r','e','r','\\',
937 'R','e','g','i','s','t','r','a','t','i','o','n','\0' };
938 static const WCHAR szVersion[] = { 'V','e','r','s','i','o','n','\0' };
939 static const WCHAR szCustomized[] = { 'C','u','s','t','o','m','i','z','e','d',
940 'V','e','r','s','i','o','n','\0' };
941 static const WCHAR szOwner[] = { 'R','e','g','i','s','t','e','r','e','d',
942 'O','w','n','e','r','\0' };
943 static const WCHAR szOrg[] = { 'R','e','g','i','s','t','e','r','e','d',
944 'O','r','g','a','n','i','z','a','t','i','o','n','\0' };
945 static const WCHAR szProduct[] = { 'P','r','o','d','u','c','t','I','d','\0' };
946 static const WCHAR szUpdate[] = { 'I','E','A','K',
947 'U','p','d','a','t','e','U','r','l','\0' };
948 static const WCHAR szHelp[] = { 'I','E','A','K',
949 'H','e','l','p','S','t','r','i','n','g','\0' };
950 WCHAR buff[2084];
951 HKEY hReg;
952 DWORD dwType, dwLen;
954 TRACE("(%p,%d)\n", lpszDest, dwDestLen);
956 if (!lpszDest)
957 return FALSE;
959 *lpszDest = '\0';
961 /* Try the NT key first, followed by 95/98 key */
962 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinNtKey, 0, KEY_READ, &hReg) &&
963 RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinKey, 0, KEY_READ, &hReg))
964 return FALSE;
966 /* OS Version */
967 buff[0] = '\0';
968 dwLen = 30;
969 if (!SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey, szVersion, &dwType, buff, &dwLen))
971 DWORD dwStrLen = strlenW(buff);
972 dwLen = 30 - dwStrLen;
973 SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey,
974 szCustomized, &dwType, buff+dwStrLen, &dwLen);
976 StrCatBuffW(lpszDest, buff, dwDestLen);
978 /* ~Registered Owner */
979 buff[0] = '~';
980 dwLen = 256;
981 if (SHGetValueW(hReg, szOwner, 0, &dwType, buff+1, &dwLen))
982 buff[1] = '\0';
983 StrCatBuffW(lpszDest, buff, dwDestLen);
985 /* ~Registered Organization */
986 dwLen = 256;
987 if (SHGetValueW(hReg, szOrg, 0, &dwType, buff+1, &dwLen))
988 buff[1] = '\0';
989 StrCatBuffW(lpszDest, buff, dwDestLen);
991 /* FIXME: Not sure where this number comes from */
992 buff[0] = '~';
993 buff[1] = '0';
994 buff[2] = '\0';
995 StrCatBuffW(lpszDest, buff, dwDestLen);
997 /* ~Product Id */
998 dwLen = 256;
999 if (SHGetValueW(HKEY_LOCAL_MACHINE, szRegKey, szProduct, &dwType, buff+1, &dwLen))
1000 buff[1] = '\0';
1001 StrCatBuffW(lpszDest, buff, dwDestLen);
1003 /* ~IE Update Url */
1004 dwLen = 2048;
1005 if(SHGetValueW(HKEY_LOCAL_MACHINE, szWinKey, szUpdate, &dwType, buff+1, &dwLen))
1006 buff[1] = '\0';
1007 StrCatBuffW(lpszDest, buff, dwDestLen);
1009 /* ~IE Help String */
1010 dwLen = 256;
1011 if(SHGetValueW(hReg, szHelp, 0, &dwType, buff+1, &dwLen))
1012 buff[1] = '\0';
1013 StrCatBuffW(lpszDest, buff, dwDestLen);
1015 RegCloseKey(hReg);
1016 return TRUE;
1019 /*************************************************************************
1020 * @ [SHLWAPI.163]
1022 * Call IOleCommandTarget_QueryStatus() on an object.
1024 * PARAMS
1025 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1026 * pguidCmdGroup [I] GUID for the command group
1027 * cCmds [I]
1028 * prgCmds [O] Commands
1029 * pCmdText [O] Command text
1031 * RETURNS
1032 * Success: S_OK.
1033 * Failure: E_FAIL, if lpUnknown is NULL.
1034 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1035 * Otherwise, an error code from IOleCommandTarget_QueryStatus().
1037 HRESULT WINAPI IUnknown_QueryStatus(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
1038 ULONG cCmds, OLECMD *prgCmds, OLECMDTEXT* pCmdText)
1040 HRESULT hRet = E_FAIL;
1042 TRACE("(%p,%p,%d,%p,%p)\n",lpUnknown, pguidCmdGroup, cCmds, prgCmds, pCmdText);
1044 if (lpUnknown)
1046 IOleCommandTarget* lpOle;
1048 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
1049 (void**)&lpOle);
1051 if (SUCCEEDED(hRet) && lpOle)
1053 hRet = IOleCommandTarget_QueryStatus(lpOle, pguidCmdGroup, cCmds,
1054 prgCmds, pCmdText);
1055 IOleCommandTarget_Release(lpOle);
1058 return hRet;
1061 /*************************************************************************
1062 * @ [SHLWAPI.164]
1064 * Call IOleCommandTarget_Exec() on an object.
1066 * PARAMS
1067 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1068 * pguidCmdGroup [I] GUID for the command group
1070 * RETURNS
1071 * Success: S_OK.
1072 * Failure: E_FAIL, if lpUnknown is NULL.
1073 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1074 * Otherwise, an error code from IOleCommandTarget_Exec().
1076 HRESULT WINAPI IUnknown_Exec(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
1077 DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
1078 VARIANT* pvaOut)
1080 HRESULT hRet = E_FAIL;
1082 TRACE("(%p,%p,%d,%d,%p,%p)\n",lpUnknown, pguidCmdGroup, nCmdID,
1083 nCmdexecopt, pvaIn, pvaOut);
1085 if (lpUnknown)
1087 IOleCommandTarget* lpOle;
1089 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
1090 (void**)&lpOle);
1091 if (SUCCEEDED(hRet) && lpOle)
1093 hRet = IOleCommandTarget_Exec(lpOle, pguidCmdGroup, nCmdID,
1094 nCmdexecopt, pvaIn, pvaOut);
1095 IOleCommandTarget_Release(lpOle);
1098 return hRet;
1101 /*************************************************************************
1102 * @ [SHLWAPI.165]
1104 * Retrieve, modify, and re-set a value from a window.
1106 * PARAMS
1107 * hWnd [I] Window to get value from
1108 * offset [I] Offset of value
1109 * wMask [I] Mask for uiFlags
1110 * wFlags [I] Bits to set in window value
1112 * RETURNS
1113 * The new value as it was set, or 0 if any parameter is invalid.
1115 * NOTES
1116 * Any bits set in uiMask are cleared from the value, then any bits set in
1117 * uiFlags are set in the value.
1119 LONG WINAPI SHSetWindowBits(HWND hwnd, INT offset, UINT wMask, UINT wFlags)
1121 LONG ret = GetWindowLongA(hwnd, offset);
1122 LONG newFlags = (wFlags & wMask) | (ret & ~wFlags);
1124 if (newFlags != ret)
1125 ret = SetWindowLongA(hwnd, offset, newFlags);
1126 return ret;
1129 /*************************************************************************
1130 * @ [SHLWAPI.167]
1132 * Change a window's parent.
1134 * PARAMS
1135 * hWnd [I] Window to change parent of
1136 * hWndParent [I] New parent window
1138 * RETURNS
1139 * The old parent of hWnd.
1141 * NOTES
1142 * If hWndParent is NULL (desktop), the window style is changed to WS_POPUP.
1143 * If hWndParent is NOT NULL then we set the WS_CHILD style.
1145 HWND WINAPI SHSetParentHwnd(HWND hWnd, HWND hWndParent)
1147 TRACE("%p, %p\n", hWnd, hWndParent);
1149 if(GetParent(hWnd) == hWndParent)
1150 return 0;
1152 if(hWndParent)
1153 SHSetWindowBits(hWnd, GWL_STYLE, WS_CHILD, WS_CHILD);
1154 else
1155 SHSetWindowBits(hWnd, GWL_STYLE, WS_POPUP, WS_POPUP);
1157 return SetParent(hWnd, hWndParent);
1160 /*************************************************************************
1161 * @ [SHLWAPI.168]
1163 * Locate and advise a connection point in an IConnectionPointContainer object.
1165 * PARAMS
1166 * lpUnkSink [I] Sink for the connection point advise call
1167 * riid [I] REFIID of connection point to advise
1168 * bAdviseOnly [I] TRUE = Advise only, FALSE = Unadvise first
1169 * lpUnknown [I] Object supporting the IConnectionPointContainer interface
1170 * lpCookie [O] Pointer to connection point cookie
1171 * lppCP [O] Destination for the IConnectionPoint found
1173 * RETURNS
1174 * Success: S_OK. If lppCP is non-NULL, it is filled with the IConnectionPoint
1175 * that was advised. The caller is responsible for releasing it.
1176 * Failure: E_FAIL, if any arguments are invalid.
1177 * E_NOINTERFACE, if lpUnknown isn't an IConnectionPointContainer,
1178 * Or an HRESULT error code if any call fails.
1180 HRESULT WINAPI ConnectToConnectionPoint(IUnknown* lpUnkSink, REFIID riid, BOOL bAdviseOnly,
1181 IUnknown* lpUnknown, LPDWORD lpCookie,
1182 IConnectionPoint **lppCP)
1184 HRESULT hRet;
1185 IConnectionPointContainer* lpContainer;
1186 IConnectionPoint *lpCP;
1188 if(!lpUnknown || (bAdviseOnly && !lpUnkSink))
1189 return E_FAIL;
1191 if(lppCP)
1192 *lppCP = NULL;
1194 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer,
1195 (void**)&lpContainer);
1196 if (SUCCEEDED(hRet))
1198 hRet = IConnectionPointContainer_FindConnectionPoint(lpContainer, riid, &lpCP);
1200 if (SUCCEEDED(hRet))
1202 if(!bAdviseOnly)
1203 hRet = IConnectionPoint_Unadvise(lpCP, *lpCookie);
1204 hRet = IConnectionPoint_Advise(lpCP, lpUnkSink, lpCookie);
1206 if (FAILED(hRet))
1207 *lpCookie = 0;
1209 if (lppCP && SUCCEEDED(hRet))
1210 *lppCP = lpCP; /* Caller keeps the interface */
1211 else
1212 IConnectionPoint_Release(lpCP); /* Release it */
1215 IUnknown_Release(lpContainer);
1217 return hRet;
1220 /*************************************************************************
1221 * @ [SHLWAPI.169]
1223 * Release an interface.
1225 * PARAMS
1226 * lpUnknown [I] Object to release
1228 * RETURNS
1229 * Nothing.
1231 DWORD WINAPI IUnknown_AtomicRelease(IUnknown ** lpUnknown)
1233 IUnknown *temp;
1235 TRACE("(%p)\n",lpUnknown);
1237 if(!lpUnknown || !*((LPDWORD)lpUnknown)) return 0;
1238 temp = *lpUnknown;
1239 *lpUnknown = NULL;
1241 TRACE("doing Release\n");
1243 return IUnknown_Release(temp);
1246 /*************************************************************************
1247 * @ [SHLWAPI.170]
1249 * Skip '//' if present in a string.
1251 * PARAMS
1252 * lpszSrc [I] String to check for '//'
1254 * RETURNS
1255 * Success: The next character after the '//' or the string if not present
1256 * Failure: NULL, if lpszStr is NULL.
1258 LPCSTR WINAPI PathSkipLeadingSlashesA(LPCSTR lpszSrc)
1260 if (lpszSrc && lpszSrc[0] == '/' && lpszSrc[1] == '/')
1261 lpszSrc += 2;
1262 return lpszSrc;
1265 /*************************************************************************
1266 * @ [SHLWAPI.171]
1268 * Check if two interfaces come from the same object.
1270 * PARAMS
1271 * lpInt1 [I] Interface to check against lpInt2.
1272 * lpInt2 [I] Interface to check against lpInt1.
1274 * RETURNS
1275 * TRUE, If the interfaces come from the same object.
1276 * FALSE Otherwise.
1278 BOOL WINAPI SHIsSameObject(IUnknown* lpInt1, IUnknown* lpInt2)
1280 LPVOID lpUnknown1, lpUnknown2;
1282 TRACE("%p %p\n", lpInt1, lpInt2);
1284 if (!lpInt1 || !lpInt2)
1285 return FALSE;
1287 if (lpInt1 == lpInt2)
1288 return TRUE;
1290 if (!SUCCEEDED(IUnknown_QueryInterface(lpInt1, &IID_IUnknown,
1291 (LPVOID *)&lpUnknown1)))
1292 return FALSE;
1294 if (!SUCCEEDED(IUnknown_QueryInterface(lpInt2, &IID_IUnknown,
1295 (LPVOID *)&lpUnknown2)))
1296 return FALSE;
1298 if (lpUnknown1 == lpUnknown2)
1299 return TRUE;
1301 return FALSE;
1304 /*************************************************************************
1305 * @ [SHLWAPI.172]
1307 * Get the window handle of an object.
1309 * PARAMS
1310 * lpUnknown [I] Object to get the window handle of
1311 * lphWnd [O] Destination for window handle
1313 * RETURNS
1314 * Success: S_OK. lphWnd contains the objects window handle.
1315 * Failure: An HRESULT error code.
1317 * NOTES
1318 * lpUnknown is expected to support one of the following interfaces:
1319 * IOleWindow(), IInternetSecurityMgrSite(), or IShellView().
1321 HRESULT WINAPI IUnknown_GetWindow(IUnknown *lpUnknown, HWND *lphWnd)
1323 /* FIXME: Wine has no header for this object */
1324 static const GUID IID_IInternetSecurityMgrSite = { 0x79eac9ed,
1325 0xbaf9, 0x11ce, { 0x8c, 0x82, 0x00, 0xaa, 0x00, 0x4b, 0xa9, 0x0b }};
1326 IUnknown *lpOle;
1327 HRESULT hRet = E_FAIL;
1329 TRACE("(%p,%p)\n", lpUnknown, lphWnd);
1331 if (!lpUnknown)
1332 return hRet;
1334 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleWindow, (void**)&lpOle);
1336 if (FAILED(hRet))
1338 hRet = IUnknown_QueryInterface(lpUnknown,&IID_IShellView, (void**)&lpOle);
1340 if (FAILED(hRet))
1342 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInternetSecurityMgrSite,
1343 (void**)&lpOle);
1347 if (SUCCEEDED(hRet))
1349 /* Lazyness here - Since GetWindow() is the first method for the above 3
1350 * interfaces, we use the same call for them all.
1352 hRet = IOleWindow_GetWindow((IOleWindow*)lpOle, lphWnd);
1353 IUnknown_Release(lpOle);
1354 if (lphWnd)
1355 TRACE("Returning HWND=%p\n", *lphWnd);
1358 return hRet;
1361 /*************************************************************************
1362 * @ [SHLWAPI.173]
1364 * Call a method on as as yet unidentified object.
1366 * PARAMS
1367 * pUnk [I] Object supporting the unidentified interface,
1368 * arg [I] Argument for the call on the object.
1370 * RETURNS
1371 * S_OK.
1373 HRESULT WINAPI IUnknown_SetOwner(IUnknown *pUnk, ULONG arg)
1375 static const GUID guid_173 = {
1376 0x5836fb00, 0x8187, 0x11cf, { 0xa1,0x2b,0x00,0xaa,0x00,0x4a,0xe8,0x37 }
1378 IMalloc *pUnk2;
1380 TRACE("(%p,%d)\n", pUnk, arg);
1382 /* Note: arg may not be a ULONG and pUnk2 is for sure not an IMalloc -
1383 * We use this interface as its vtable entry is compatible with the
1384 * object in question.
1385 * FIXME: Find out what this object is and where it should be defined.
1387 if (pUnk &&
1388 SUCCEEDED(IUnknown_QueryInterface(pUnk, &guid_173, (void**)&pUnk2)))
1390 IMalloc_Alloc(pUnk2, arg); /* Faked call!! */
1391 IMalloc_Release(pUnk2);
1393 return S_OK;
1396 /*************************************************************************
1397 * @ [SHLWAPI.174]
1399 * Call either IObjectWithSite_SetSite() or IInternetSecurityManager_SetSecuritySite() on
1400 * an object.
1403 HRESULT WINAPI IUnknown_SetSite(
1404 IUnknown *obj, /* [in] OLE object */
1405 IUnknown *site) /* [in] Site interface */
1407 HRESULT hr;
1408 IObjectWithSite *iobjwithsite;
1409 IInternetSecurityManager *isecmgr;
1411 if (!obj) return E_FAIL;
1413 hr = IUnknown_QueryInterface(obj, &IID_IObjectWithSite, (LPVOID *)&iobjwithsite);
1414 TRACE("IID_IObjectWithSite QI ret=%08x, %p\n", hr, iobjwithsite);
1415 if (SUCCEEDED(hr))
1417 hr = IObjectWithSite_SetSite(iobjwithsite, site);
1418 TRACE("done IObjectWithSite_SetSite ret=%08x\n", hr);
1419 IUnknown_Release(iobjwithsite);
1421 else
1423 hr = IUnknown_QueryInterface(obj, &IID_IInternetSecurityManager, (LPVOID *)&isecmgr);
1424 TRACE("IID_IInternetSecurityManager QI ret=%08x, %p\n", hr, isecmgr);
1425 if (FAILED(hr)) return hr;
1427 hr = IInternetSecurityManager_SetSecuritySite(isecmgr, (IInternetSecurityMgrSite *)site);
1428 TRACE("done IInternetSecurityManager_SetSecuritySite ret=%08x\n", hr);
1429 IUnknown_Release(isecmgr);
1431 return hr;
1434 /*************************************************************************
1435 * @ [SHLWAPI.175]
1437 * Call IPersist_GetClassID() on an object.
1439 * PARAMS
1440 * lpUnknown [I] Object supporting the IPersist interface
1441 * lpClassId [O] Destination for Class Id
1443 * RETURNS
1444 * Success: S_OK. lpClassId contains the Class Id requested.
1445 * Failure: E_FAIL, If lpUnknown is NULL,
1446 * E_NOINTERFACE If lpUnknown does not support IPersist,
1447 * Or an HRESULT error code.
1449 HRESULT WINAPI IUnknown_GetClassID(IUnknown *lpUnknown, CLSID* lpClassId)
1451 IPersist* lpPersist;
1452 HRESULT hRet = E_FAIL;
1454 TRACE("(%p,%p)\n", lpUnknown, debugstr_guid(lpClassId));
1456 if (lpUnknown)
1458 hRet = IUnknown_QueryInterface(lpUnknown,&IID_IPersist,(void**)&lpPersist);
1459 if (SUCCEEDED(hRet))
1461 IPersist_GetClassID(lpPersist, lpClassId);
1462 IPersist_Release(lpPersist);
1465 return hRet;
1468 /*************************************************************************
1469 * @ [SHLWAPI.176]
1471 * Retrieve a Service Interface from an object.
1473 * PARAMS
1474 * lpUnknown [I] Object to get an IServiceProvider interface from
1475 * sid [I] Service ID for IServiceProvider_QueryService() call
1476 * riid [I] Function requested for QueryService call
1477 * lppOut [O] Destination for the service interface pointer
1479 * RETURNS
1480 * Success: S_OK. lppOut contains an object providing the requested service
1481 * Failure: An HRESULT error code
1483 * NOTES
1484 * lpUnknown is expected to support the IServiceProvider interface.
1486 HRESULT WINAPI IUnknown_QueryService(IUnknown* lpUnknown, REFGUID sid, REFIID riid,
1487 LPVOID *lppOut)
1489 IServiceProvider* pService = NULL;
1490 HRESULT hRet;
1492 if (!lppOut)
1493 return E_FAIL;
1495 *lppOut = NULL;
1497 if (!lpUnknown)
1498 return E_FAIL;
1500 /* Get an IServiceProvider interface from the object */
1501 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IServiceProvider,
1502 (LPVOID*)&pService);
1504 if (!hRet && pService)
1506 TRACE("QueryInterface returned (IServiceProvider*)%p\n", pService);
1508 /* Get a Service interface from the object */
1509 hRet = IServiceProvider_QueryService(pService, sid, riid, lppOut);
1511 TRACE("(IServiceProvider*)%p returned (IUnknown*)%p\n", pService, *lppOut);
1513 /* Release the IServiceProvider interface */
1514 IUnknown_Release(pService);
1516 return hRet;
1519 /*************************************************************************
1520 * @ [SHLWAPI.177]
1522 * Loads a popup menu.
1524 * PARAMS
1525 * hInst [I] Instance handle
1526 * szName [I] Menu name
1528 * RETURNS
1529 * Success: TRUE.
1530 * Failure: FALSE.
1532 BOOL WINAPI SHLoadMenuPopup(HINSTANCE hInst, LPCWSTR szName)
1534 HMENU hMenu, hSubMenu;
1536 if ((hMenu = LoadMenuW(hInst, szName)))
1538 if ((hSubMenu = GetSubMenu(hMenu, 0)))
1539 RemoveMenu(hMenu, 0, MF_BYPOSITION);
1541 DestroyMenu(hMenu);
1542 return TRUE;
1544 return FALSE;
1547 typedef struct _enumWndData
1549 UINT uiMsgId;
1550 WPARAM wParam;
1551 LPARAM lParam;
1552 LRESULT (WINAPI *pfnPost)(HWND,UINT,WPARAM,LPARAM);
1553 } enumWndData;
1555 /* Callback for SHLWAPI_178 */
1556 static BOOL CALLBACK SHLWAPI_EnumChildProc(HWND hWnd, LPARAM lParam)
1558 enumWndData *data = (enumWndData *)lParam;
1560 TRACE("(%p,%p)\n", hWnd, data);
1561 data->pfnPost(hWnd, data->uiMsgId, data->wParam, data->lParam);
1562 return TRUE;
1565 /*************************************************************************
1566 * @ [SHLWAPI.178]
1568 * Send or post a message to every child of a window.
1570 * PARAMS
1571 * hWnd [I] Window whose children will get the messages
1572 * uiMsgId [I] Message Id
1573 * wParam [I] WPARAM of message
1574 * lParam [I] LPARAM of message
1575 * bSend [I] TRUE = Use SendMessageA(), FALSE = Use PostMessageA()
1577 * RETURNS
1578 * Nothing.
1580 * NOTES
1581 * The appropriate ASCII or Unicode function is called for the window.
1583 void WINAPI SHPropagateMessage(HWND hWnd, UINT uiMsgId, WPARAM wParam, LPARAM lParam, BOOL bSend)
1585 enumWndData data;
1587 TRACE("(%p,%u,%ld,%ld,%d)\n", hWnd, uiMsgId, wParam, lParam, bSend);
1589 if(hWnd)
1591 data.uiMsgId = uiMsgId;
1592 data.wParam = wParam;
1593 data.lParam = lParam;
1595 if (bSend)
1596 data.pfnPost = IsWindowUnicode(hWnd) ? (void*)SendMessageW : (void*)SendMessageA;
1597 else
1598 data.pfnPost = IsWindowUnicode(hWnd) ? (void*)PostMessageW : (void*)PostMessageA;
1600 EnumChildWindows(hWnd, SHLWAPI_EnumChildProc, (LPARAM)&data);
1604 /*************************************************************************
1605 * @ [SHLWAPI.180]
1607 * Remove all sub-menus from a menu.
1609 * PARAMS
1610 * hMenu [I] Menu to remove sub-menus from
1612 * RETURNS
1613 * Success: 0. All sub-menus under hMenu are removed
1614 * Failure: -1, if any parameter is invalid
1616 DWORD WINAPI SHRemoveAllSubMenus(HMENU hMenu)
1618 int iItemCount = GetMenuItemCount(hMenu) - 1;
1619 while (iItemCount >= 0)
1621 HMENU hSubMenu = GetSubMenu(hMenu, iItemCount);
1622 if (hSubMenu)
1623 RemoveMenu(hMenu, iItemCount, MF_BYPOSITION);
1624 iItemCount--;
1626 return iItemCount;
1629 /*************************************************************************
1630 * @ [SHLWAPI.181]
1632 * Enable or disable a menu item.
1634 * PARAMS
1635 * hMenu [I] Menu holding menu item
1636 * uID [I] ID of menu item to enable/disable
1637 * bEnable [I] Whether to enable (TRUE) or disable (FALSE) the item.
1639 * RETURNS
1640 * The return code from EnableMenuItem.
1642 UINT WINAPI SHEnableMenuItem(HMENU hMenu, UINT wItemID, BOOL bEnable)
1644 return EnableMenuItem(hMenu, wItemID, bEnable ? MF_ENABLED : MF_GRAYED);
1647 /*************************************************************************
1648 * @ [SHLWAPI.182]
1650 * Check or uncheck a menu item.
1652 * PARAMS
1653 * hMenu [I] Menu holding menu item
1654 * uID [I] ID of menu item to check/uncheck
1655 * bCheck [I] Whether to check (TRUE) or uncheck (FALSE) the item.
1657 * RETURNS
1658 * The return code from CheckMenuItem.
1660 DWORD WINAPI SHCheckMenuItem(HMENU hMenu, UINT uID, BOOL bCheck)
1662 return CheckMenuItem(hMenu, uID, bCheck ? MF_CHECKED : MF_UNCHECKED);
1665 /*************************************************************************
1666 * @ [SHLWAPI.183]
1668 * Register a window class if it isn't already.
1670 * PARAMS
1671 * lpWndClass [I] Window class to register
1673 * RETURNS
1674 * The result of the RegisterClassA call.
1676 DWORD WINAPI SHRegisterClassA(WNDCLASSA *wndclass)
1678 WNDCLASSA wca;
1679 if (GetClassInfoA(wndclass->hInstance, wndclass->lpszClassName, &wca))
1680 return TRUE;
1681 return (DWORD)RegisterClassA(wndclass);
1684 /*************************************************************************
1685 * @ [SHLWAPI.186]
1687 BOOL WINAPI SHSimulateDrop(IDropTarget *pDrop, IDataObject *pDataObj,
1688 DWORD grfKeyState, PPOINTL lpPt, DWORD* pdwEffect)
1690 DWORD dwEffect = DROPEFFECT_LINK | DROPEFFECT_MOVE | DROPEFFECT_COPY;
1691 POINTL pt = { 0, 0 };
1693 if (!lpPt)
1694 lpPt = &pt;
1696 if (!pdwEffect)
1697 pdwEffect = &dwEffect;
1699 IDropTarget_DragEnter(pDrop, pDataObj, grfKeyState, *lpPt, pdwEffect);
1701 if (*pdwEffect)
1702 return IDropTarget_Drop(pDrop, pDataObj, grfKeyState, *lpPt, pdwEffect);
1704 IDropTarget_DragLeave(pDrop);
1705 return TRUE;
1708 /*************************************************************************
1709 * @ [SHLWAPI.187]
1711 * Call IPersistPropertyBag_Load() on an object.
1713 * PARAMS
1714 * lpUnknown [I] Object supporting the IPersistPropertyBag interface
1715 * lpPropBag [O] Destination for loaded IPropertyBag
1717 * RETURNS
1718 * Success: S_OK.
1719 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1721 DWORD WINAPI SHLoadFromPropertyBag(IUnknown *lpUnknown, IPropertyBag* lpPropBag)
1723 IPersistPropertyBag* lpPPBag;
1724 HRESULT hRet = E_FAIL;
1726 TRACE("(%p,%p)\n", lpUnknown, lpPropBag);
1728 if (lpUnknown)
1730 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IPersistPropertyBag,
1731 (void**)&lpPPBag);
1732 if (SUCCEEDED(hRet) && lpPPBag)
1734 hRet = IPersistPropertyBag_Load(lpPPBag, lpPropBag, NULL);
1735 IPersistPropertyBag_Release(lpPPBag);
1738 return hRet;
1741 /*************************************************************************
1742 * @ [SHLWAPI.188]
1744 * Call IOleControlSite_TranslateAccelerator() on an object.
1746 * PARAMS
1747 * lpUnknown [I] Object supporting the IOleControlSite interface.
1748 * lpMsg [I] Key message to be processed.
1749 * dwModifiers [I] Flags containing the state of the modifier keys.
1751 * RETURNS
1752 * Success: S_OK.
1753 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
1755 HRESULT WINAPI IUnknown_TranslateAcceleratorOCS(IUnknown *lpUnknown, LPMSG lpMsg, DWORD dwModifiers)
1757 IOleControlSite* lpCSite = NULL;
1758 HRESULT hRet = E_INVALIDARG;
1760 TRACE("(%p,%p,0x%08x)\n", lpUnknown, lpMsg, dwModifiers);
1761 if (lpUnknown)
1763 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleControlSite,
1764 (void**)&lpCSite);
1765 if (SUCCEEDED(hRet) && lpCSite)
1767 hRet = IOleControlSite_TranslateAccelerator(lpCSite, lpMsg, dwModifiers);
1768 IOleControlSite_Release(lpCSite);
1771 return hRet;
1775 /*************************************************************************
1776 * @ [SHLWAPI.189]
1778 * Call IOleControlSite_OnFocus() on an object.
1780 * PARAMS
1781 * lpUnknown [I] Object supporting the IOleControlSite interface.
1782 * fGotFocus [I] Whether focus was gained (TRUE) or lost (FALSE).
1784 * RETURNS
1785 * Success: S_OK.
1786 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1788 HRESULT WINAPI IUnknown_OnFocusOCS(IUnknown *lpUnknown, BOOL fGotFocus)
1790 IOleControlSite* lpCSite = NULL;
1791 HRESULT hRet = E_FAIL;
1793 TRACE("(%p,%s)\n", lpUnknown, fGotFocus ? "TRUE" : "FALSE");
1794 if (lpUnknown)
1796 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleControlSite,
1797 (void**)&lpCSite);
1798 if (SUCCEEDED(hRet) && lpCSite)
1800 hRet = IOleControlSite_OnFocus(lpCSite, fGotFocus);
1801 IOleControlSite_Release(lpCSite);
1804 return hRet;
1807 /*************************************************************************
1808 * @ [SHLWAPI.190]
1810 HRESULT WINAPI IUnknown_HandleIRestrict(LPUNKNOWN lpUnknown, PVOID lpArg1,
1811 PVOID lpArg2, PVOID lpArg3, PVOID lpArg4)
1813 /* FIXME: {D12F26B2-D90A-11D0-830D-00AA005B4383} - What object does this represent? */
1814 static const DWORD service_id[] = { 0xd12f26b2, 0x11d0d90a, 0xaa000d83, 0x83435b00 };
1815 /* FIXME: {D12F26B1-D90A-11D0-830D-00AA005B4383} - Also Unknown/undocumented */
1816 static const DWORD function_id[] = { 0xd12f26b1, 0x11d0d90a, 0xaa000d83, 0x83435b00 };
1817 HRESULT hRet = E_INVALIDARG;
1818 LPUNKNOWN lpUnkInner = NULL; /* FIXME: Real type is unknown */
1820 TRACE("(%p,%p,%p,%p,%p)\n", lpUnknown, lpArg1, lpArg2, lpArg3, lpArg4);
1822 if (lpUnknown && lpArg4)
1824 hRet = IUnknown_QueryService(lpUnknown, (REFGUID)service_id,
1825 (REFGUID)function_id, (void**)&lpUnkInner);
1827 if (SUCCEEDED(hRet) && lpUnkInner)
1829 /* FIXME: The type of service object requested is unknown, however
1830 * testing shows that its first method is called with 4 parameters.
1831 * Fake this by using IParseDisplayName_ParseDisplayName since the
1832 * signature and position in the vtable matches our unknown object type.
1834 hRet = IParseDisplayName_ParseDisplayName((LPPARSEDISPLAYNAME)lpUnkInner,
1835 lpArg1, lpArg2, lpArg3, lpArg4);
1836 IUnknown_Release(lpUnkInner);
1839 return hRet;
1842 /*************************************************************************
1843 * @ [SHLWAPI.192]
1845 * Get a sub-menu from a menu item.
1847 * PARAMS
1848 * hMenu [I] Menu to get sub-menu from
1849 * uID [I] ID of menu item containing sub-menu
1851 * RETURNS
1852 * The sub-menu of the item, or a NULL handle if any parameters are invalid.
1854 HMENU WINAPI SHGetMenuFromID(HMENU hMenu, UINT uID)
1856 MENUITEMINFOW mi;
1858 TRACE("(%p,%u)\n", hMenu, uID);
1860 mi.cbSize = sizeof(mi);
1861 mi.fMask = MIIM_SUBMENU;
1863 if (!GetMenuItemInfoW(hMenu, uID, FALSE, &mi))
1864 return NULL;
1866 return mi.hSubMenu;
1869 /*************************************************************************
1870 * @ [SHLWAPI.193]
1872 * Get the color depth of the primary display.
1874 * PARAMS
1875 * None.
1877 * RETURNS
1878 * The color depth of the primary display.
1880 DWORD WINAPI SHGetCurColorRes(void)
1882 HDC hdc;
1883 DWORD ret;
1885 TRACE("()\n");
1887 hdc = GetDC(0);
1888 ret = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
1889 ReleaseDC(0, hdc);
1890 return ret;
1893 /*************************************************************************
1894 * @ [SHLWAPI.194]
1896 * Wait for a message to arrive, with a timeout.
1898 * PARAMS
1899 * hand [I] Handle to query
1900 * dwTimeout [I] Timeout in ticks or INFINITE to never timeout
1902 * RETURNS
1903 * STATUS_TIMEOUT if no message is received before dwTimeout ticks passes.
1904 * Otherwise returns the value from MsgWaitForMultipleObjectsEx when a
1905 * message is available.
1907 DWORD WINAPI SHWaitForSendMessageThread(HANDLE hand, DWORD dwTimeout)
1909 DWORD dwEndTicks = GetTickCount() + dwTimeout;
1910 DWORD dwRet;
1912 while ((dwRet = MsgWaitForMultipleObjectsEx(1, &hand, dwTimeout, QS_SENDMESSAGE, 0)) == 1)
1914 MSG msg;
1916 PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE);
1918 if (dwTimeout != INFINITE)
1920 if ((int)(dwTimeout = dwEndTicks - GetTickCount()) <= 0)
1921 return WAIT_TIMEOUT;
1925 return dwRet;
1928 /*************************************************************************
1929 * @ [SHLWAPI.195]
1931 * Determine if a shell folder can be expanded.
1933 * PARAMS
1934 * lpFolder [I] Parent folder containing the object to test.
1935 * pidl [I] Id of the object to test.
1937 * RETURNS
1938 * Success: S_OK, if the object is expandable, S_FALSE otherwise.
1939 * Failure: E_INVALIDARG, if any argument is invalid.
1941 * NOTES
1942 * If the object to be tested does not expose the IQueryInfo() interface it
1943 * will not be identified as an expandable folder.
1945 HRESULT WINAPI SHIsExpandableFolder(LPSHELLFOLDER lpFolder, LPCITEMIDLIST pidl)
1947 HRESULT hRet = E_INVALIDARG;
1948 IQueryInfo *lpInfo;
1950 if (lpFolder && pidl)
1952 hRet = IShellFolder_GetUIObjectOf(lpFolder, NULL, 1, &pidl, &IID_IQueryInfo,
1953 NULL, (void**)&lpInfo);
1954 if (FAILED(hRet))
1955 hRet = S_FALSE; /* Doesn't expose IQueryInfo */
1956 else
1958 DWORD dwFlags = 0;
1960 /* MSDN states of IQueryInfo_GetInfoFlags() that "This method is not
1961 * currently used". Really? You wouldn't be holding out on me would you?
1963 hRet = IQueryInfo_GetInfoFlags(lpInfo, &dwFlags);
1965 if (SUCCEEDED(hRet))
1967 /* 0x2 is an undocumented flag apparently indicating expandability */
1968 hRet = dwFlags & 0x2 ? S_OK : S_FALSE;
1971 IQueryInfo_Release(lpInfo);
1974 return hRet;
1977 /*************************************************************************
1978 * @ [SHLWAPI.197]
1980 * Blank out a region of text by drawing the background only.
1982 * PARAMS
1983 * hDC [I] Device context to draw in
1984 * pRect [I] Area to draw in
1985 * cRef [I] Color to draw in
1987 * RETURNS
1988 * Nothing.
1990 DWORD WINAPI SHFillRectClr(HDC hDC, LPCRECT pRect, COLORREF cRef)
1992 COLORREF cOldColor = SetBkColor(hDC, cRef);
1993 ExtTextOutA(hDC, 0, 0, ETO_OPAQUE, pRect, 0, 0, 0);
1994 SetBkColor(hDC, cOldColor);
1995 return 0;
1998 /*************************************************************************
1999 * @ [SHLWAPI.198]
2001 * Return the value asociated with a key in a map.
2003 * PARAMS
2004 * lpKeys [I] A list of keys of length iLen
2005 * lpValues [I] A list of values associated with lpKeys, of length iLen
2006 * iLen [I] Length of both lpKeys and lpValues
2007 * iKey [I] The key value to look up in lpKeys
2009 * RETURNS
2010 * The value in lpValues associated with iKey, or -1 if iKey is not
2011 * found in lpKeys.
2013 * NOTES
2014 * - If two elements in the map share the same key, this function returns
2015 * the value closest to the start of the map
2016 * - The native version of this function crashes if lpKeys or lpValues is NULL.
2018 int WINAPI SHSearchMapInt(const int *lpKeys, const int *lpValues, int iLen, int iKey)
2020 if (lpKeys && lpValues)
2022 int i = 0;
2024 while (i < iLen)
2026 if (lpKeys[i] == iKey)
2027 return lpValues[i]; /* Found */
2028 i++;
2031 return -1; /* Not found */
2035 /*************************************************************************
2036 * @ [SHLWAPI.199]
2038 * Copy an interface pointer
2040 * PARAMS
2041 * lppDest [O] Destination for copy
2042 * lpUnknown [I] Source for copy
2044 * RETURNS
2045 * Nothing.
2047 VOID WINAPI IUnknown_Set(IUnknown **lppDest, IUnknown *lpUnknown)
2049 TRACE("(%p,%p)\n", lppDest, lpUnknown);
2051 if (lppDest)
2052 IUnknown_AtomicRelease(lppDest); /* Release existing interface */
2054 if (lpUnknown)
2056 /* Copy */
2057 IUnknown_AddRef(lpUnknown);
2058 *lppDest = lpUnknown;
2062 /*************************************************************************
2063 * @ [SHLWAPI.200]
2066 HRESULT WINAPI MayQSForward(IUnknown* lpUnknown, PVOID lpReserved,
2067 REFGUID riidCmdGrp, ULONG cCmds,
2068 OLECMD *prgCmds, OLECMDTEXT* pCmdText)
2070 FIXME("(%p,%p,%p,%d,%p,%p) - stub\n",
2071 lpUnknown, lpReserved, riidCmdGrp, cCmds, prgCmds, pCmdText);
2073 /* FIXME: Calls IsQSForward & IUnknown_QueryStatus */
2074 return DRAGDROP_E_NOTREGISTERED;
2077 /*************************************************************************
2078 * @ [SHLWAPI.201]
2081 HRESULT WINAPI MayExecForward(IUnknown* lpUnknown, INT iUnk, REFGUID pguidCmdGroup,
2082 DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
2083 VARIANT* pvaOut)
2085 FIXME("(%p,%d,%p,%d,%d,%p,%p) - stub!\n", lpUnknown, iUnk, pguidCmdGroup,
2086 nCmdID, nCmdexecopt, pvaIn, pvaOut);
2087 return DRAGDROP_E_NOTREGISTERED;
2090 /*************************************************************************
2091 * @ [SHLWAPI.202]
2094 HRESULT WINAPI IsQSForward(REFGUID pguidCmdGroup,ULONG cCmds, OLECMD *prgCmds)
2096 FIXME("(%p,%d,%p) - stub!\n", pguidCmdGroup, cCmds, prgCmds);
2097 return DRAGDROP_E_NOTREGISTERED;
2100 /*************************************************************************
2101 * @ [SHLWAPI.204]
2103 * Determine if a window is not a child of another window.
2105 * PARAMS
2106 * hParent [I] Suspected parent window
2107 * hChild [I] Suspected child window
2109 * RETURNS
2110 * TRUE: If hChild is a child window of hParent
2111 * FALSE: If hChild is not a child window of hParent, or they are equal
2113 BOOL WINAPI SHIsChildOrSelf(HWND hParent, HWND hChild)
2115 TRACE("(%p,%p)\n", hParent, hChild);
2117 if (!hParent || !hChild)
2118 return TRUE;
2119 else if(hParent == hChild)
2120 return FALSE;
2121 return !IsChild(hParent, hChild);
2124 /*************************************************************************
2125 * FDSA functions. Manage a dynamic array of fixed size memory blocks.
2128 typedef struct
2130 DWORD num_items; /* Number of elements inserted */
2131 void *mem; /* Ptr to array */
2132 DWORD blocks_alloced; /* Number of elements allocated */
2133 BYTE inc; /* Number of elements to grow by when we need to expand */
2134 BYTE block_size; /* Size in bytes of an element */
2135 BYTE flags; /* Flags */
2136 } FDSA_info;
2138 #define FDSA_FLAG_INTERNAL_ALLOC 0x01 /* When set we have allocated mem internally */
2140 /*************************************************************************
2141 * @ [SHLWAPI.208]
2143 * Initialize an FDSA arrary.
2145 BOOL WINAPI FDSA_Initialize(DWORD block_size, DWORD inc, FDSA_info *info, void *mem,
2146 DWORD init_blocks)
2148 TRACE("(0x%08x 0x%08x %p %p 0x%08x)\n", block_size, inc, info, mem, init_blocks);
2150 if(inc == 0)
2151 inc = 1;
2153 if(mem)
2154 memset(mem, 0, block_size * init_blocks);
2156 info->num_items = 0;
2157 info->inc = inc;
2158 info->mem = mem;
2159 info->blocks_alloced = init_blocks;
2160 info->block_size = block_size;
2161 info->flags = 0;
2163 return TRUE;
2166 /*************************************************************************
2167 * @ [SHLWAPI.209]
2169 * Destroy an FDSA array
2171 BOOL WINAPI FDSA_Destroy(FDSA_info *info)
2173 TRACE("(%p)\n", info);
2175 if(info->flags & FDSA_FLAG_INTERNAL_ALLOC)
2177 HeapFree(GetProcessHeap(), 0, info->mem);
2178 return FALSE;
2181 return TRUE;
2184 /*************************************************************************
2185 * @ [SHLWAPI.210]
2187 * Insert element into an FDSA array
2189 DWORD WINAPI FDSA_InsertItem(FDSA_info *info, DWORD where, const void *block)
2191 TRACE("(%p 0x%08x %p)\n", info, where, block);
2192 if(where > info->num_items)
2193 where = info->num_items;
2195 if(info->num_items >= info->blocks_alloced)
2197 DWORD size = (info->blocks_alloced + info->inc) * info->block_size;
2198 if(info->flags & 0x1)
2199 info->mem = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->mem, size);
2200 else
2202 void *old_mem = info->mem;
2203 info->mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
2204 memcpy(info->mem, old_mem, info->blocks_alloced * info->block_size);
2206 info->blocks_alloced += info->inc;
2207 info->flags |= 0x1;
2210 if(where < info->num_items)
2212 memmove((char*)info->mem + (where + 1) * info->block_size,
2213 (char*)info->mem + where * info->block_size,
2214 (info->num_items - where) * info->block_size);
2216 memcpy((char*)info->mem + where * info->block_size, block, info->block_size);
2218 info->num_items++;
2219 return where;
2222 /*************************************************************************
2223 * @ [SHLWAPI.211]
2225 * Delete an element from an FDSA array.
2227 BOOL WINAPI FDSA_DeleteItem(FDSA_info *info, DWORD where)
2229 TRACE("(%p 0x%08x)\n", info, where);
2231 if(where >= info->num_items)
2232 return FALSE;
2234 if(where < info->num_items - 1)
2236 memmove((char*)info->mem + where * info->block_size,
2237 (char*)info->mem + (where + 1) * info->block_size,
2238 (info->num_items - where - 1) * info->block_size);
2240 memset((char*)info->mem + (info->num_items - 1) * info->block_size,
2241 0, info->block_size);
2242 info->num_items--;
2243 return TRUE;
2247 typedef struct {
2248 REFIID refid;
2249 DWORD indx;
2250 } IFACE_INDEX_TBL;
2252 /*************************************************************************
2253 * @ [SHLWAPI.219]
2255 * Call IUnknown_QueryInterface() on a table of objects.
2257 * RETURNS
2258 * Success: S_OK.
2259 * Failure: E_POINTER or E_NOINTERFACE.
2261 HRESULT WINAPI QISearch(
2262 LPVOID w, /* [in] Table of interfaces */
2263 IFACE_INDEX_TBL *x, /* [in] Array of REFIIDs and indexes into the table */
2264 REFIID riid, /* [in] REFIID to get interface for */
2265 LPVOID *ppv) /* [out] Destination for interface pointer */
2267 HRESULT ret;
2268 IUnknown *a_vtbl;
2269 IFACE_INDEX_TBL *xmove;
2271 TRACE("(%p %p %s %p)\n", w,x,debugstr_guid(riid),ppv);
2272 if (ppv) {
2273 xmove = x;
2274 while (xmove->refid) {
2275 TRACE("trying (indx %d) %s\n", xmove->indx, debugstr_guid(xmove->refid));
2276 if (IsEqualIID(riid, xmove->refid)) {
2277 a_vtbl = (IUnknown*)(xmove->indx + (LPBYTE)w);
2278 TRACE("matched, returning (%p)\n", a_vtbl);
2279 *ppv = (LPVOID)a_vtbl;
2280 IUnknown_AddRef(a_vtbl);
2281 return S_OK;
2283 xmove++;
2286 if (IsEqualIID(riid, &IID_IUnknown)) {
2287 a_vtbl = (IUnknown*)(x->indx + (LPBYTE)w);
2288 TRACE("returning first for IUnknown (%p)\n", a_vtbl);
2289 *ppv = (LPVOID)a_vtbl;
2290 IUnknown_AddRef(a_vtbl);
2291 return S_OK;
2293 *ppv = 0;
2294 ret = E_NOINTERFACE;
2295 } else
2296 ret = E_POINTER;
2298 TRACE("-- 0x%08x\n", ret);
2299 return ret;
2302 /*************************************************************************
2303 * @ [SHLWAPI.221]
2305 * Remove the "PropDlgFont" property from a window.
2307 * PARAMS
2308 * hWnd [I] Window to remove the property from
2310 * RETURNS
2311 * A handle to the removed property, or NULL if it did not exist.
2313 HANDLE WINAPI SHRemoveDefaultDialogFont(HWND hWnd)
2315 HANDLE hProp;
2317 TRACE("(%p)\n", hWnd);
2319 hProp = GetPropA(hWnd, "PropDlgFont");
2321 if(hProp)
2323 DeleteObject(hProp);
2324 hProp = RemovePropA(hWnd, "PropDlgFont");
2326 return hProp;
2329 /*************************************************************************
2330 * @ [SHLWAPI.236]
2332 * Load the in-process server of a given GUID.
2334 * PARAMS
2335 * refiid [I] GUID of the server to load.
2337 * RETURNS
2338 * Success: A handle to the loaded server dll.
2339 * Failure: A NULL handle.
2341 HMODULE WINAPI SHPinDllOfCLSID(REFIID refiid)
2343 HKEY newkey;
2344 DWORD type, count;
2345 CHAR value[MAX_PATH], string[MAX_PATH];
2347 strcpy(string, "CLSID\\");
2348 SHStringFromGUIDA(refiid, string + 6, sizeof(string)/sizeof(char) - 6);
2349 strcat(string, "\\InProcServer32");
2351 count = MAX_PATH;
2352 RegOpenKeyExA(HKEY_CLASSES_ROOT, string, 0, 1, &newkey);
2353 RegQueryValueExA(newkey, 0, 0, &type, (PBYTE)value, &count);
2354 RegCloseKey(newkey);
2355 return LoadLibraryExA(value, 0, 0);
2358 /*************************************************************************
2359 * @ [SHLWAPI.237]
2361 * Unicode version of SHLWAPI_183.
2363 DWORD WINAPI SHRegisterClassW(WNDCLASSW * lpWndClass)
2365 WNDCLASSW WndClass;
2367 TRACE("(%p %s)\n",lpWndClass->hInstance, debugstr_w(lpWndClass->lpszClassName));
2369 if (GetClassInfoW(lpWndClass->hInstance, lpWndClass->lpszClassName, &WndClass))
2370 return TRUE;
2371 return RegisterClassW(lpWndClass);
2374 /*************************************************************************
2375 * @ [SHLWAPI.238]
2377 * Unregister a list of classes.
2379 * PARAMS
2380 * hInst [I] Application instance that registered the classes
2381 * lppClasses [I] List of class names
2382 * iCount [I] Number of names in lppClasses
2384 * RETURNS
2385 * Nothing.
2387 void WINAPI SHUnregisterClassesA(HINSTANCE hInst, LPCSTR *lppClasses, INT iCount)
2389 WNDCLASSA WndClass;
2391 TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);
2393 while (iCount > 0)
2395 if (GetClassInfoA(hInst, *lppClasses, &WndClass))
2396 UnregisterClassA(*lppClasses, hInst);
2397 lppClasses++;
2398 iCount--;
2402 /*************************************************************************
2403 * @ [SHLWAPI.239]
2405 * Unicode version of SHUnregisterClassesA.
2407 void WINAPI SHUnregisterClassesW(HINSTANCE hInst, LPCWSTR *lppClasses, INT iCount)
2409 WNDCLASSW WndClass;
2411 TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);
2413 while (iCount > 0)
2415 if (GetClassInfoW(hInst, *lppClasses, &WndClass))
2416 UnregisterClassW(*lppClasses, hInst);
2417 lppClasses++;
2418 iCount--;
2422 /*************************************************************************
2423 * @ [SHLWAPI.240]
2425 * Call The correct (Ascii/Unicode) default window procedure for a window.
2427 * PARAMS
2428 * hWnd [I] Window to call the default procedure for
2429 * uMessage [I] Message ID
2430 * wParam [I] WPARAM of message
2431 * lParam [I] LPARAM of message
2433 * RETURNS
2434 * The result of calling DefWindowProcA() or DefWindowProcW().
2436 LRESULT CALLBACK SHDefWindowProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
2438 if (IsWindowUnicode(hWnd))
2439 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
2440 return DefWindowProcA(hWnd, uMessage, wParam, lParam);
2443 /*************************************************************************
2444 * @ [SHLWAPI.256]
2446 HRESULT WINAPI IUnknown_GetSite(LPUNKNOWN lpUnknown, REFIID iid, PVOID *lppSite)
2448 HRESULT hRet = E_INVALIDARG;
2449 LPOBJECTWITHSITE lpSite = NULL;
2451 TRACE("(%p,%s,%p)\n", lpUnknown, debugstr_guid(iid), lppSite);
2453 if (lpUnknown && iid && lppSite)
2455 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IObjectWithSite,
2456 (void**)&lpSite);
2457 if (SUCCEEDED(hRet) && lpSite)
2459 hRet = IObjectWithSite_GetSite(lpSite, iid, lppSite);
2460 IObjectWithSite_Release(lpSite);
2463 return hRet;
2466 /*************************************************************************
2467 * @ [SHLWAPI.257]
2469 * Create a worker window using CreateWindowExA().
2471 * PARAMS
2472 * wndProc [I] Window procedure
2473 * hWndParent [I] Parent window
2474 * dwExStyle [I] Extra style flags
2475 * dwStyle [I] Style flags
2476 * hMenu [I] Window menu
2477 * z [I] Unknown
2479 * RETURNS
2480 * Success: The window handle of the newly created window.
2481 * Failure: 0.
2483 HWND WINAPI SHCreateWorkerWindowA(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
2484 DWORD dwStyle, HMENU hMenu, LONG z)
2486 static const char szClass[] = "WorkerA";
2487 WNDCLASSA wc;
2488 HWND hWnd;
2490 TRACE("(0x%08x,%p,0x%08x,0x%08x,%p,0x%08x)\n",
2491 wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2493 /* Create Window class */
2494 wc.style = 0;
2495 wc.lpfnWndProc = DefWindowProcA;
2496 wc.cbClsExtra = 0;
2497 wc.cbWndExtra = 4;
2498 wc.hInstance = shlwapi_hInstance;
2499 wc.hIcon = NULL;
2500 wc.hCursor = LoadCursorA(NULL, (LPSTR)IDC_ARROW);
2501 wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
2502 wc.lpszMenuName = NULL;
2503 wc.lpszClassName = szClass;
2505 SHRegisterClassA(&wc); /* Register class */
2507 /* FIXME: Set extra bits in dwExStyle */
2509 hWnd = CreateWindowExA(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
2510 hWndParent, hMenu, shlwapi_hInstance, 0);
2511 if (hWnd)
2513 SetWindowLongPtrW(hWnd, DWLP_MSGRESULT, z);
2515 if (wndProc)
2516 SetWindowLongPtrA(hWnd, GWLP_WNDPROC, wndProc);
2518 return hWnd;
2521 typedef struct tagPOLICYDATA
2523 DWORD policy; /* flags value passed to SHRestricted */
2524 LPCWSTR appstr; /* application str such as "Explorer" */
2525 LPCWSTR keystr; /* name of the actual registry key / policy */
2526 } POLICYDATA, *LPPOLICYDATA;
2528 #define SHELL_NO_POLICY 0xffffffff
2530 /* default shell policy registry key */
2531 static const WCHAR strRegistryPolicyW[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o',
2532 's','o','f','t','\\','W','i','n','d','o','w','s','\\',
2533 'C','u','r','r','e','n','t','V','e','r','s','i','o','n',
2534 '\\','P','o','l','i','c','i','e','s',0};
2536 /*************************************************************************
2537 * @ [SHLWAPI.271]
2539 * Retrieve a policy value from the registry.
2541 * PARAMS
2542 * lpSubKey [I] registry key name
2543 * lpSubName [I] subname of registry key
2544 * lpValue [I] value name of registry value
2546 * RETURNS
2547 * the value associated with the registry key or 0 if not found
2549 DWORD WINAPI SHGetRestriction(LPCWSTR lpSubKey, LPCWSTR lpSubName, LPCWSTR lpValue)
2551 DWORD retval, datsize = sizeof(retval);
2552 HKEY hKey;
2554 if (!lpSubKey)
2555 lpSubKey = strRegistryPolicyW;
2557 retval = RegOpenKeyW(HKEY_LOCAL_MACHINE, lpSubKey, &hKey);
2558 if (retval != ERROR_SUCCESS)
2559 retval = RegOpenKeyW(HKEY_CURRENT_USER, lpSubKey, &hKey);
2560 if (retval != ERROR_SUCCESS)
2561 return 0;
2563 SHGetValueW(hKey, lpSubName, lpValue, NULL, (LPBYTE)&retval, &datsize);
2564 RegCloseKey(hKey);
2565 return retval;
2568 /*************************************************************************
2569 * @ [SHLWAPI.266]
2571 * Helper function to retrieve the possibly cached value for a specific policy
2573 * PARAMS
2574 * policy [I] The policy to look for
2575 * initial [I] Main registry key to open, if NULL use default
2576 * polTable [I] Table of known policies, 0 terminated
2577 * polArr [I] Cache array of policy values
2579 * RETURNS
2580 * The retrieved policy value or 0 if not successful
2582 * NOTES
2583 * This function is used by the native SHRestricted function to search for the
2584 * policy and cache it once retrieved. The current Wine implementation uses a
2585 * different POLICYDATA structure and implements a similar algorithme adapted to
2586 * that structure.
2588 DWORD WINAPI SHRestrictionLookup(
2589 DWORD policy,
2590 LPCWSTR initial,
2591 LPPOLICYDATA polTable,
2592 LPDWORD polArr)
2594 TRACE("(0x%08x %s %p %p)\n", policy, debugstr_w(initial), polTable, polArr);
2596 if (!polTable || !polArr)
2597 return 0;
2599 for (;polTable->policy; polTable++, polArr++)
2601 if (policy == polTable->policy)
2603 /* we have a known policy */
2605 /* check if this policy has been cached */
2606 if (*polArr == SHELL_NO_POLICY)
2607 *polArr = SHGetRestriction(initial, polTable->appstr, polTable->keystr);
2608 return *polArr;
2611 /* we don't know this policy, return 0 */
2612 TRACE("unknown policy: (%08x)\n", policy);
2613 return 0;
2616 /*************************************************************************
2617 * @ [SHLWAPI.267]
2619 * Get an interface from an object.
2621 * RETURNS
2622 * Success: S_OK. ppv contains the requested interface.
2623 * Failure: An HRESULT error code.
2625 * NOTES
2626 * This QueryInterface asks the inner object for an interface. In case
2627 * of aggregation this request would be forwarded by the inner to the
2628 * outer object. This function asks the inner object directly for the
2629 * interface circumventing the forwarding to the outer object.
2631 HRESULT WINAPI SHWeakQueryInterface(
2632 IUnknown * pUnk, /* [in] Outer object */
2633 IUnknown * pInner, /* [in] Inner object */
2634 IID * riid, /* [in] Interface GUID to query for */
2635 LPVOID* ppv) /* [out] Destination for queried interface */
2637 HRESULT hret = E_NOINTERFACE;
2638 TRACE("(pUnk=%p pInner=%p\n\tIID: %s %p)\n",pUnk,pInner,debugstr_guid(riid), ppv);
2640 *ppv = NULL;
2641 if(pUnk && pInner) {
2642 hret = IUnknown_QueryInterface(pInner, riid, (LPVOID*)ppv);
2643 if (SUCCEEDED(hret)) IUnknown_Release(pUnk);
2645 TRACE("-- 0x%08x\n", hret);
2646 return hret;
2649 /*************************************************************************
2650 * @ [SHLWAPI.268]
2652 * Move a reference from one interface to another.
2654 * PARAMS
2655 * lpDest [O] Destination to receive the reference
2656 * lppUnknown [O] Source to give up the reference to lpDest
2658 * RETURNS
2659 * Nothing.
2661 VOID WINAPI SHWeakReleaseInterface(IUnknown *lpDest, IUnknown **lppUnknown)
2663 TRACE("(%p,%p)\n", lpDest, lppUnknown);
2665 if (*lppUnknown)
2667 /* Copy Reference*/
2668 IUnknown_AddRef(lpDest);
2669 IUnknown_AtomicRelease(lppUnknown); /* Release existing interface */
2673 /*************************************************************************
2674 * @ [SHLWAPI.269]
2676 * Convert an ASCII string of a CLSID into a CLSID.
2678 * PARAMS
2679 * idstr [I] String representing a CLSID in registry format
2680 * id [O] Destination for the converted CLSID
2682 * RETURNS
2683 * Success: TRUE. id contains the converted CLSID.
2684 * Failure: FALSE.
2686 BOOL WINAPI GUIDFromStringA(LPCSTR idstr, CLSID *id)
2688 WCHAR wClsid[40];
2689 MultiByteToWideChar(CP_ACP, 0, idstr, -1, wClsid, sizeof(wClsid)/sizeof(WCHAR));
2690 return SUCCEEDED(CLSIDFromString(wClsid, id));
2693 /*************************************************************************
2694 * @ [SHLWAPI.270]
2696 * Unicode version of GUIDFromStringA.
2698 BOOL WINAPI GUIDFromStringW(LPCWSTR idstr, CLSID *id)
2700 return SUCCEEDED(CLSIDFromString((LPOLESTR)idstr, id));
2703 /*************************************************************************
2704 * @ [SHLWAPI.276]
2706 * Determine if the browser is integrated into the shell, and set a registry
2707 * key accordingly.
2709 * PARAMS
2710 * None.
2712 * RETURNS
2713 * 1, If the browser is not integrated.
2714 * 2, If the browser is integrated.
2716 * NOTES
2717 * The key "HKLM\Software\Microsoft\Internet Explorer\IntegratedBrowser" is
2718 * either set to TRUE, or removed depending on whether the browser is deemed
2719 * to be integrated.
2721 DWORD WINAPI WhichPlatform(void)
2723 static const char szIntegratedBrowser[] = "IntegratedBrowser";
2724 static DWORD dwState = 0;
2725 HKEY hKey;
2726 DWORD dwRet, dwData, dwSize;
2727 HMODULE hshell32;
2729 if (dwState)
2730 return dwState;
2732 /* If shell32 exports DllGetVersion(), the browser is integrated */
2733 dwState = 1;
2734 hshell32 = LoadLibraryA("shell32.dll");
2735 if (hshell32)
2737 FARPROC pDllGetVersion;
2738 pDllGetVersion = GetProcAddress(hshell32, "DllGetVersion");
2739 dwState = pDllGetVersion ? 2 : 1;
2740 FreeLibrary(hshell32);
2743 /* Set or delete the key accordingly */
2744 dwRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
2745 "Software\\Microsoft\\Internet Explorer", 0,
2746 KEY_ALL_ACCESS, &hKey);
2747 if (!dwRet)
2749 dwRet = RegQueryValueExA(hKey, szIntegratedBrowser, 0, 0,
2750 (LPBYTE)&dwData, &dwSize);
2752 if (!dwRet && dwState == 1)
2754 /* Value exists but browser is not integrated */
2755 RegDeleteValueA(hKey, szIntegratedBrowser);
2757 else if (dwRet && dwState == 2)
2759 /* Browser is integrated but value does not exist */
2760 dwData = TRUE;
2761 RegSetValueExA(hKey, szIntegratedBrowser, 0, REG_DWORD,
2762 (LPBYTE)&dwData, sizeof(dwData));
2764 RegCloseKey(hKey);
2766 return dwState;
2769 /*************************************************************************
2770 * @ [SHLWAPI.278]
2772 * Unicode version of SHCreateWorkerWindowA.
2774 HWND WINAPI SHCreateWorkerWindowW(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
2775 DWORD dwStyle, HMENU hMenu, LONG z)
2777 static const WCHAR szClass[] = { 'W', 'o', 'r', 'k', 'e', 'r', 'W', '\0' };
2778 WNDCLASSW wc;
2779 HWND hWnd;
2781 TRACE("(0x%08x,%p,0x%08x,0x%08x,%p,0x%08x)\n",
2782 wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2784 /* If our OS is natively ASCII, use the ASCII version */
2785 if (!(GetVersion() & 0x80000000)) /* NT */
2786 return SHCreateWorkerWindowA(wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2788 /* Create Window class */
2789 wc.style = 0;
2790 wc.lpfnWndProc = DefWindowProcW;
2791 wc.cbClsExtra = 0;
2792 wc.cbWndExtra = 4;
2793 wc.hInstance = shlwapi_hInstance;
2794 wc.hIcon = NULL;
2795 wc.hCursor = LoadCursorW(NULL, (LPWSTR)IDC_ARROW);
2796 wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
2797 wc.lpszMenuName = NULL;
2798 wc.lpszClassName = szClass;
2800 SHRegisterClassW(&wc); /* Register class */
2802 /* FIXME: Set extra bits in dwExStyle */
2804 hWnd = CreateWindowExW(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
2805 hWndParent, hMenu, shlwapi_hInstance, 0);
2806 if (hWnd)
2808 SetWindowLongPtrW(hWnd, DWLP_MSGRESULT, z);
2810 if (wndProc)
2811 SetWindowLongPtrW(hWnd, GWLP_WNDPROC, wndProc);
2813 return hWnd;
2816 /*************************************************************************
2817 * @ [SHLWAPI.279]
2819 * Get and show a context menu from a shell folder.
2821 * PARAMS
2822 * hWnd [I] Window displaying the shell folder
2823 * lpFolder [I] IShellFolder interface
2824 * lpApidl [I] Id for the particular folder desired
2826 * RETURNS
2827 * Success: S_OK.
2828 * Failure: An HRESULT error code indicating the error.
2830 HRESULT WINAPI SHInvokeDefaultCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl)
2832 return SHInvokeCommand(hWnd, lpFolder, lpApidl, FALSE);
2835 /*************************************************************************
2836 * @ [SHLWAPI.281]
2838 * _SHPackDispParamsV
2840 HRESULT WINAPI SHPackDispParamsV(LPVOID w, LPVOID x, LPVOID y, LPVOID z)
2842 FIXME("%p %p %p %p\n",w,x,y,z);
2843 return E_FAIL;
2846 /*************************************************************************
2847 * @ [SHLWAPI.282]
2849 * This function seems to be a forward to SHPackDispParamsV (whatever THAT
2850 * function does...).
2852 HRESULT WINAPI SHPackDispParams(LPVOID w, LPVOID x, LPVOID y, LPVOID z)
2854 FIXME("%p %p %p %p\n", w, x, y, z);
2855 return E_FAIL;
2858 /*************************************************************************
2859 * SHLWAPI_InvokeByIID
2861 * This helper function calls IDispatch::Invoke for each sink
2862 * which implements given iid or IDispatch.
2865 static HRESULT SHLWAPI_InvokeByIID(
2866 IConnectionPoint* iCP,
2867 REFIID iid,
2868 DISPID dispId,
2869 DISPPARAMS* dispParams)
2871 IEnumConnections *enumerator;
2872 CONNECTDATA rgcd;
2874 HRESULT result = IConnectionPoint_EnumConnections(iCP, &enumerator);
2875 if (FAILED(result))
2876 return result;
2878 while(IEnumConnections_Next(enumerator, 1, &rgcd, NULL)==S_OK)
2880 IDispatch *dispIface;
2881 if (SUCCEEDED(IUnknown_QueryInterface(rgcd.pUnk, iid, (LPVOID*)&dispIface)) ||
2882 SUCCEEDED(IUnknown_QueryInterface(rgcd.pUnk, &IID_IDispatch, (LPVOID*)&dispIface)))
2884 IDispatch_Invoke(dispIface, dispId, &IID_NULL, 0, DISPATCH_METHOD, dispParams, NULL, NULL, NULL);
2885 IDispatch_Release(dispIface);
2889 IEnumConnections_Release(enumerator);
2891 return S_OK;
2894 /*************************************************************************
2895 * @ [SHLWAPI.284]
2897 * IConnectionPoint_SimpleInvoke
2899 HRESULT WINAPI IConnectionPoint_SimpleInvoke(
2900 IConnectionPoint* iCP,
2901 DISPID dispId,
2902 DISPPARAMS* dispParams)
2904 IID iid;
2905 HRESULT result;
2907 TRACE("(%p)->(0x%x %p)\n",iCP,dispId,dispParams);
2909 result = IConnectionPoint_GetConnectionInterface(iCP, &iid);
2910 if (SUCCEEDED(result))
2911 result = SHLWAPI_InvokeByIID(iCP, &iid, dispId, dispParams);
2913 return result;
2916 /*************************************************************************
2917 * @ [SHLWAPI.285]
2919 * Notify an IConnectionPoint object of changes.
2921 * PARAMS
2922 * lpCP [I] Object to notify
2923 * dispID [I]
2925 * RETURNS
2926 * Success: S_OK.
2927 * Failure: E_NOINTERFACE, if lpCP is NULL or does not support the
2928 * IConnectionPoint interface.
2930 HRESULT WINAPI IConnectionPoint_OnChanged(IConnectionPoint* lpCP, DISPID dispID)
2932 IEnumConnections *lpEnum;
2933 HRESULT hRet = E_NOINTERFACE;
2935 TRACE("(%p,0x%8X)\n", lpCP, dispID);
2937 /* Get an enumerator for the connections */
2938 if (lpCP)
2939 hRet = IConnectionPoint_EnumConnections(lpCP, &lpEnum);
2941 if (SUCCEEDED(hRet))
2943 IPropertyNotifySink *lpSink;
2944 CONNECTDATA connData;
2945 ULONG ulFetched;
2947 /* Call OnChanged() for every notify sink in the connection point */
2948 while (IEnumConnections_Next(lpEnum, 1, &connData, &ulFetched) == S_OK)
2950 if (SUCCEEDED(IUnknown_QueryInterface(connData.pUnk, &IID_IPropertyNotifySink, (void**)&lpSink)) &&
2951 lpSink)
2953 IPropertyNotifySink_OnChanged(lpSink, dispID);
2954 IPropertyNotifySink_Release(lpSink);
2956 IUnknown_Release(connData.pUnk);
2959 IEnumConnections_Release(lpEnum);
2961 return hRet;
2964 /*************************************************************************
2965 * @ [SHLWAPI.286]
2967 * IUnknown_CPContainerInvokeParam
2969 HRESULT WINAPIV IUnknown_CPContainerInvokeParam(
2970 IUnknown *container,
2971 REFIID riid,
2972 DISPID dispId,
2973 VARIANTARG* buffer,
2974 DWORD cParams, ...)
2976 HRESULT result;
2977 IConnectionPoint *iCP;
2978 IConnectionPointContainer *iCPC;
2980 if (!container)
2981 return E_NOINTERFACE;
2983 result = IUnknown_QueryInterface(container, &IID_IConnectionPointContainer,(LPVOID*) &iCPC);
2984 if (SUCCEEDED(result))
2986 result = IConnectionPointContainer_FindConnectionPoint(iCPC, riid, &iCP);
2987 IConnectionPointContainer_Release(iCPC);
2990 if (SUCCEEDED(result))
2992 ULONG cnt;
2993 VARIANTARG *curvar = buffer+cParams-1;
2994 DISPPARAMS dispParams = {buffer, NULL, cParams, 0};
2995 va_list valist;
2997 va_start(valist, cParams);
2998 for(cnt=cParams;cnt>0;cnt--,curvar--) /* backwards for some reason */
3000 enum VARENUM vt = va_arg(valist, enum VARENUM);
3001 memset(curvar, 0, sizeof(*curvar));
3002 if (vt & VT_BYREF)
3004 V_VT(curvar) = vt;
3005 V_BYREF(curvar) = va_arg(valist, LPVOID);
3006 } else
3007 switch(vt)
3009 case VT_BSTR:
3010 V_VT(curvar) = vt;
3011 V_BSTR(curvar) = va_arg(valist, BSTR);
3012 break;
3013 case VT_DISPATCH:
3014 V_VT(curvar) = vt;
3015 V_DISPATCH(curvar) = va_arg(valist, IDispatch*);
3016 break;
3017 case VT_BOOL:
3018 V_VT(curvar) = vt;
3019 V_BOOL(curvar) = va_arg(valist, int);
3020 break;
3021 case VT_UNKNOWN:
3022 V_VT(curvar) = vt;
3023 V_UNKNOWN(curvar) = va_arg(valist, IUnknown*);
3024 break;
3025 case VT_I4:
3026 default:
3027 V_VT(curvar) = VT_I4;
3028 V_I4(curvar) = va_arg(valist, LONG);
3029 break;
3032 va_end(valist);
3034 result = SHLWAPI_InvokeByIID(iCP, riid, dispId, &dispParams);
3035 IConnectionPoint_Release(iCP);
3038 return result;
3041 /*************************************************************************
3042 * @ [SHLWAPI.287]
3044 * Notify an IConnectionPointContainer object of changes.
3046 * PARAMS
3047 * lpUnknown [I] Object to notify
3048 * dispID [I]
3050 * RETURNS
3051 * Success: S_OK.
3052 * Failure: E_NOINTERFACE, if lpUnknown is NULL or does not support the
3053 * IConnectionPointContainer interface.
3055 HRESULT WINAPI IUnknown_CPContainerOnChanged(IUnknown *lpUnknown, DISPID dispID)
3057 IConnectionPointContainer* lpCPC = NULL;
3058 HRESULT hRet = E_NOINTERFACE;
3060 TRACE("(%p,0x%8X)\n", lpUnknown, dispID);
3062 if (lpUnknown)
3063 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer, (void**)&lpCPC);
3065 if (SUCCEEDED(hRet))
3067 IConnectionPoint* lpCP;
3069 hRet = IConnectionPointContainer_FindConnectionPoint(lpCPC, &IID_IPropertyNotifySink, &lpCP);
3070 IConnectionPointContainer_Release(lpCPC);
3072 hRet = IConnectionPoint_OnChanged(lpCP, dispID);
3073 IConnectionPoint_Release(lpCP);
3075 return hRet;
3078 /*************************************************************************
3079 * @ [SHLWAPI.289]
3081 * See PlaySoundW.
3083 BOOL WINAPI PlaySoundWrapW(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
3085 return PlaySoundW(pszSound, hmod, fdwSound);
3088 /*************************************************************************
3089 * @ [SHLWAPI.294]
3091 BOOL WINAPI SHGetIniStringW(LPCWSTR str1, LPCWSTR str2, LPWSTR pStr, DWORD some_len, LPCWSTR lpStr2)
3093 FIXME("(%s,%s,%p,%08x,%s): stub!\n", debugstr_w(str1), debugstr_w(str2),
3094 pStr, some_len, debugstr_w(lpStr2));
3095 return TRUE;
3098 /*************************************************************************
3099 * @ [SHLWAPI.295]
3101 * Called by ICQ2000b install via SHDOCVW:
3102 * str1: "InternetShortcut"
3103 * x: some unknown pointer
3104 * str2: "http://free.aol.com/tryaolfree/index.adp?139269"
3105 * str3: "C:\\WINDOWS\\Desktop.new2\\Free AOL & Unlimited Internet.url"
3107 * In short: this one maybe creates a desktop link :-)
3109 BOOL WINAPI SHSetIniStringW(LPWSTR str1, LPVOID x, LPWSTR str2, LPWSTR str3)
3111 FIXME("(%s, %p, %s, %s), stub.\n", debugstr_w(str1), x, debugstr_w(str2), debugstr_w(str3));
3112 return TRUE;
3115 /*************************************************************************
3116 * @ [SHLWAPI.313]
3118 * See SHGetFileInfoW.
3120 DWORD WINAPI SHGetFileInfoWrapW(LPCWSTR path, DWORD dwFileAttributes,
3121 SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
3123 return SHGetFileInfoW(path, dwFileAttributes, psfi, sizeofpsfi, flags);
3126 /*************************************************************************
3127 * @ [SHLWAPI.318]
3129 * See DragQueryFileW.
3131 UINT WINAPI DragQueryFileWrapW(HDROP hDrop, UINT lFile, LPWSTR lpszFile, UINT lLength)
3133 return DragQueryFileW(hDrop, lFile, lpszFile, lLength);
3136 /*************************************************************************
3137 * @ [SHLWAPI.333]
3139 * See SHBrowseForFolderW.
3141 LPITEMIDLIST WINAPI SHBrowseForFolderWrapW(LPBROWSEINFOW lpBi)
3143 return SHBrowseForFolderW(lpBi);
3146 /*************************************************************************
3147 * @ [SHLWAPI.334]
3149 * See SHGetPathFromIDListW.
3151 BOOL WINAPI SHGetPathFromIDListWrapW(LPCITEMIDLIST pidl,LPWSTR pszPath)
3153 return SHGetPathFromIDListW(pidl, pszPath);
3156 /*************************************************************************
3157 * @ [SHLWAPI.335]
3159 * See ShellExecuteExW.
3161 BOOL WINAPI ShellExecuteExWrapW(LPSHELLEXECUTEINFOW lpExecInfo)
3163 return ShellExecuteExW(lpExecInfo);
3166 /*************************************************************************
3167 * @ [SHLWAPI.336]
3169 * See SHFileOperationW.
3171 INT WINAPI SHFileOperationWrapW(LPSHFILEOPSTRUCTW lpFileOp)
3173 return SHFileOperationW(lpFileOp);
3176 /*************************************************************************
3177 * @ [SHLWAPI.342]
3180 PVOID WINAPI SHInterlockedCompareExchange( PVOID *dest, PVOID xchg, PVOID compare )
3182 return InterlockedCompareExchangePointer( dest, xchg, compare );
3185 /*************************************************************************
3186 * @ [SHLWAPI.350]
3188 * See GetFileVersionInfoSizeW.
3190 DWORD WINAPI GetFileVersionInfoSizeWrapW( LPCWSTR filename, LPDWORD handle )
3192 return GetFileVersionInfoSizeW( filename, handle );
3195 /*************************************************************************
3196 * @ [SHLWAPI.351]
3198 * See GetFileVersionInfoW.
3200 BOOL WINAPI GetFileVersionInfoWrapW( LPCWSTR filename, DWORD handle,
3201 DWORD datasize, LPVOID data )
3203 return GetFileVersionInfoW( filename, handle, datasize, data );
3206 /*************************************************************************
3207 * @ [SHLWAPI.352]
3209 * See VerQueryValueW.
3211 WORD WINAPI VerQueryValueWrapW( LPVOID pBlock, LPCWSTR lpSubBlock,
3212 LPVOID *lplpBuffer, UINT *puLen )
3214 return VerQueryValueW( pBlock, lpSubBlock, lplpBuffer, puLen );
3217 #define IsIface(type) SUCCEEDED((hRet = IUnknown_QueryInterface(lpUnknown, &IID_##type, (void**)&lpObj)))
3218 #define IShellBrowser_EnableModeless IShellBrowser_EnableModelessSB
3219 #define EnableModeless(type) type##_EnableModeless((type*)lpObj, bModeless)
3221 /*************************************************************************
3222 * @ [SHLWAPI.355]
3224 * Change the modality of a shell object.
3226 * PARAMS
3227 * lpUnknown [I] Object to make modeless
3228 * bModeless [I] TRUE=Make modeless, FALSE=Make modal
3230 * RETURNS
3231 * Success: S_OK. The modality lpUnknown is changed.
3232 * Failure: An HRESULT error code indicating the error.
3234 * NOTES
3235 * lpUnknown must support the IOleInPlaceFrame interface, the
3236 * IInternetSecurityMgrSite interface, the IShellBrowser interface
3237 * the IDocHostUIHandler interface, or the IOleInPlaceActiveObject interface,
3238 * or this call will fail.
3240 HRESULT WINAPI IUnknown_EnableModeless(IUnknown *lpUnknown, BOOL bModeless)
3242 IUnknown *lpObj;
3243 HRESULT hRet;
3245 TRACE("(%p,%d)\n", lpUnknown, bModeless);
3247 if (!lpUnknown)
3248 return E_FAIL;
3250 if (IsIface(IOleInPlaceActiveObject))
3251 EnableModeless(IOleInPlaceActiveObject);
3252 else if (IsIface(IOleInPlaceFrame))
3253 EnableModeless(IOleInPlaceFrame);
3254 else if (IsIface(IShellBrowser))
3255 EnableModeless(IShellBrowser);
3256 #if 0
3257 /* FIXME: Wine has no headers for these objects yet */
3258 else if (IsIface(IInternetSecurityMgrSite))
3259 EnableModeless(IInternetSecurityMgrSite);
3260 else if (IsIface(IDocHostUIHandler))
3261 EnableModeless(IDocHostUIHandler);
3262 #endif
3263 else
3264 return hRet;
3266 IUnknown_Release(lpObj);
3267 return S_OK;
3270 /*************************************************************************
3271 * @ [SHLWAPI.357]
3273 * See SHGetNewLinkInfoW.
3275 BOOL WINAPI SHGetNewLinkInfoWrapW(LPCWSTR pszLinkTo, LPCWSTR pszDir, LPWSTR pszName,
3276 BOOL *pfMustCopy, UINT uFlags)
3278 return SHGetNewLinkInfoW(pszLinkTo, pszDir, pszName, pfMustCopy, uFlags);
3281 /*************************************************************************
3282 * @ [SHLWAPI.358]
3284 * See SHDefExtractIconW.
3286 UINT WINAPI SHDefExtractIconWrapW(LPCWSTR pszIconFile, int iIndex, UINT uFlags, HICON* phiconLarge,
3287 HICON* phiconSmall, UINT nIconSize)
3289 return SHDefExtractIconW(pszIconFile, iIndex, uFlags, phiconLarge, phiconSmall, nIconSize);
3292 /*************************************************************************
3293 * @ [SHLWAPI.363]
3295 * Get and show a context menu from a shell folder.
3297 * PARAMS
3298 * hWnd [I] Window displaying the shell folder
3299 * lpFolder [I] IShellFolder interface
3300 * lpApidl [I] Id for the particular folder desired
3301 * bInvokeDefault [I] Whether to invoke the default menu item
3303 * RETURNS
3304 * Success: S_OK. If bInvokeDefault is TRUE, the default menu action was
3305 * executed.
3306 * Failure: An HRESULT error code indicating the error.
3308 HRESULT WINAPI SHInvokeCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl, BOOL bInvokeDefault)
3310 IContextMenu *iContext;
3311 HRESULT hRet = E_FAIL;
3313 TRACE("(%p,%p,%p,%d)\n", hWnd, lpFolder, lpApidl, bInvokeDefault);
3315 if (!lpFolder)
3316 return hRet;
3318 /* Get the context menu from the shell folder */
3319 hRet = IShellFolder_GetUIObjectOf(lpFolder, hWnd, 1, &lpApidl,
3320 &IID_IContextMenu, 0, (void**)&iContext);
3321 if (SUCCEEDED(hRet))
3323 HMENU hMenu;
3324 if ((hMenu = CreatePopupMenu()))
3326 HRESULT hQuery;
3327 DWORD dwDefaultId = 0;
3329 /* Add the context menu entries to the popup */
3330 hQuery = IContextMenu_QueryContextMenu(iContext, hMenu, 0, 1, 0x7FFF,
3331 bInvokeDefault ? CMF_NORMAL : CMF_DEFAULTONLY);
3333 if (SUCCEEDED(hQuery))
3335 if (bInvokeDefault &&
3336 (dwDefaultId = GetMenuDefaultItem(hMenu, 0, 0)) != 0xFFFFFFFF)
3338 CMINVOKECOMMANDINFO cmIci;
3339 /* Invoke the default item */
3340 memset(&cmIci,0,sizeof(cmIci));
3341 cmIci.cbSize = sizeof(cmIci);
3342 cmIci.fMask = CMIC_MASK_ASYNCOK;
3343 cmIci.hwnd = hWnd;
3344 cmIci.lpVerb = MAKEINTRESOURCEA(dwDefaultId);
3345 cmIci.nShow = SW_SCROLLCHILDREN;
3347 hRet = IContextMenu_InvokeCommand(iContext, &cmIci);
3350 DestroyMenu(hMenu);
3352 IContextMenu_Release(iContext);
3354 return hRet;
3357 /*************************************************************************
3358 * @ [SHLWAPI.370]
3360 * See ExtractIconW.
3362 HICON WINAPI ExtractIconWrapW(HINSTANCE hInstance, LPCWSTR lpszExeFileName,
3363 UINT nIconIndex)
3365 return ExtractIconW(hInstance, lpszExeFileName, nIconIndex);
3368 /*************************************************************************
3369 * @ [SHLWAPI.377]
3371 * Load a library from the directory of a particular process.
3373 * PARAMS
3374 * new_mod [I] Library name
3375 * inst_hwnd [I] Module whose directory is to be used
3376 * dwCrossCodePage [I] Should be FALSE (currently ignored)
3378 * RETURNS
3379 * Success: A handle to the loaded module
3380 * Failure: A NULL handle.
3382 HMODULE WINAPI MLLoadLibraryA(LPCSTR new_mod, HMODULE inst_hwnd, DWORD dwCrossCodePage)
3384 /* FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for
3385 * each call here.
3386 * FIXME: Native shows calls to:
3387 * SHRegGetUSValue for "Software\Microsoft\Internet Explorer\International"
3388 * CheckVersion
3389 * RegOpenKeyExA for "HKLM\Software\Microsoft\Internet Explorer"
3390 * RegQueryValueExA for "LPKInstalled"
3391 * RegCloseKey
3392 * RegOpenKeyExA for "HKCU\Software\Microsoft\Internet Explorer\International"
3393 * RegQueryValueExA for "ResourceLocale"
3394 * RegCloseKey
3395 * RegOpenKeyExA for "HKLM\Software\Microsoft\Active Setup\Installed Components\{guid}"
3396 * RegQueryValueExA for "Locale"
3397 * RegCloseKey
3398 * and then tests the Locale ("en" for me).
3399 * code below
3400 * after the code then a DPA_Create (first time) and DPA_InsertPtr are done.
3402 CHAR mod_path[2*MAX_PATH];
3403 LPSTR ptr;
3404 DWORD len;
3406 FIXME("(%s,%p,%d) semi-stub!\n", debugstr_a(new_mod), inst_hwnd, dwCrossCodePage);
3407 len = GetModuleFileNameA(inst_hwnd, mod_path, sizeof(mod_path));
3408 if (!len || len >= sizeof(mod_path)) return NULL;
3410 ptr = strrchr(mod_path, '\\');
3411 if (ptr) {
3412 strcpy(ptr+1, new_mod);
3413 TRACE("loading %s\n", debugstr_a(mod_path));
3414 return LoadLibraryA(mod_path);
3416 return NULL;
3419 /*************************************************************************
3420 * @ [SHLWAPI.378]
3422 * Unicode version of MLLoadLibraryA.
3424 HMODULE WINAPI MLLoadLibraryW(LPCWSTR new_mod, HMODULE inst_hwnd, DWORD dwCrossCodePage)
3426 WCHAR mod_path[2*MAX_PATH];
3427 LPWSTR ptr;
3428 DWORD len;
3430 FIXME("(%s,%p,%d) semi-stub!\n", debugstr_w(new_mod), inst_hwnd, dwCrossCodePage);
3431 len = GetModuleFileNameW(inst_hwnd, mod_path, sizeof(mod_path) / sizeof(WCHAR));
3432 if (!len || len >= sizeof(mod_path) / sizeof(WCHAR)) return NULL;
3434 ptr = strrchrW(mod_path, '\\');
3435 if (ptr) {
3436 strcpyW(ptr+1, new_mod);
3437 TRACE("loading %s\n", debugstr_w(mod_path));
3438 return LoadLibraryW(mod_path);
3440 return NULL;
3443 /*************************************************************************
3444 * ColorAdjustLuma [SHLWAPI.@]
3446 * Adjust the luminosity of a color
3448 * PARAMS
3449 * cRGB [I] RGB value to convert
3450 * dwLuma [I] Luma adjustment
3451 * bUnknown [I] Unknown
3453 * RETURNS
3454 * The adjusted RGB color.
3456 COLORREF WINAPI ColorAdjustLuma(COLORREF cRGB, int dwLuma, BOOL bUnknown)
3458 TRACE("(0x%8x,%d,%d)\n", cRGB, dwLuma, bUnknown);
3460 if (dwLuma)
3462 WORD wH, wL, wS;
3464 ColorRGBToHLS(cRGB, &wH, &wL, &wS);
3466 FIXME("Ignoring luma adjustment\n");
3468 /* FIXME: The ajdustment is not linear */
3470 cRGB = ColorHLSToRGB(wH, wL, wS);
3472 return cRGB;
3475 /*************************************************************************
3476 * @ [SHLWAPI.389]
3478 * See GetSaveFileNameW.
3480 BOOL WINAPI GetSaveFileNameWrapW(LPOPENFILENAMEW ofn)
3482 return GetSaveFileNameW(ofn);
3485 /*************************************************************************
3486 * @ [SHLWAPI.390]
3488 * See WNetRestoreConnectionW.
3490 DWORD WINAPI WNetRestoreConnectionWrapW(HWND hwndOwner, LPWSTR lpszDevice)
3492 return WNetRestoreConnectionW(hwndOwner, lpszDevice);
3495 /*************************************************************************
3496 * @ [SHLWAPI.391]
3498 * See WNetGetLastErrorW.
3500 DWORD WINAPI WNetGetLastErrorWrapW(LPDWORD lpError, LPWSTR lpErrorBuf, DWORD nErrorBufSize,
3501 LPWSTR lpNameBuf, DWORD nNameBufSize)
3503 return WNetGetLastErrorW(lpError, lpErrorBuf, nErrorBufSize, lpNameBuf, nNameBufSize);
3506 /*************************************************************************
3507 * @ [SHLWAPI.401]
3509 * See PageSetupDlgW.
3511 BOOL WINAPI PageSetupDlgWrapW(LPPAGESETUPDLGW pagedlg)
3513 return PageSetupDlgW(pagedlg);
3516 /*************************************************************************
3517 * @ [SHLWAPI.402]
3519 * See PrintDlgW.
3521 BOOL WINAPI PrintDlgWrapW(LPPRINTDLGW printdlg)
3523 return PrintDlgW(printdlg);
3526 /*************************************************************************
3527 * @ [SHLWAPI.403]
3529 * See GetOpenFileNameW.
3531 BOOL WINAPI GetOpenFileNameWrapW(LPOPENFILENAMEW ofn)
3533 return GetOpenFileNameW(ofn);
3536 /*************************************************************************
3537 * @ [SHLWAPI.404]
3539 HRESULT WINAPI IUnknown_EnumObjects(LPSHELLFOLDER lpFolder, HWND hwnd, SHCONTF flags, IEnumIDList **ppenum)
3541 IPersist *persist;
3542 HRESULT hr;
3544 hr = IShellFolder_QueryInterface(lpFolder, &IID_IPersist, (LPVOID)&persist);
3545 if(SUCCEEDED(hr))
3547 CLSID clsid;
3548 hr = IPersist_GetClassID(persist, &clsid);
3549 if(SUCCEEDED(hr))
3551 if(IsEqualCLSID(&clsid, &CLSID_ShellFSFolder))
3552 hr = IShellFolder_EnumObjects(lpFolder, hwnd, flags, ppenum);
3553 else
3554 hr = E_FAIL;
3556 IPersist_Release(persist);
3558 return hr;
3561 /* INTERNAL: Map from HLS color space to RGB */
3562 static WORD WINAPI ConvertHue(int wHue, WORD wMid1, WORD wMid2)
3564 wHue = wHue > 240 ? wHue - 240 : wHue < 0 ? wHue + 240 : wHue;
3566 if (wHue > 160)
3567 return wMid1;
3568 else if (wHue > 120)
3569 wHue = 160 - wHue;
3570 else if (wHue > 40)
3571 return wMid2;
3573 return ((wHue * (wMid2 - wMid1) + 20) / 40) + wMid1;
3576 /* Convert to RGB and scale into RGB range (0..255) */
3577 #define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240
3579 /*************************************************************************
3580 * ColorHLSToRGB [SHLWAPI.@]
3582 * Convert from hls color space into an rgb COLORREF.
3584 * PARAMS
3585 * wHue [I] Hue amount
3586 * wLuminosity [I] Luminosity amount
3587 * wSaturation [I] Saturation amount
3589 * RETURNS
3590 * A COLORREF representing the converted color.
3592 * NOTES
3593 * Input hls values are constrained to the range (0..240).
3595 COLORREF WINAPI ColorHLSToRGB(WORD wHue, WORD wLuminosity, WORD wSaturation)
3597 WORD wRed;
3599 if (wSaturation)
3601 WORD wGreen, wBlue, wMid1, wMid2;
3603 if (wLuminosity > 120)
3604 wMid2 = wSaturation + wLuminosity - (wSaturation * wLuminosity + 120) / 240;
3605 else
3606 wMid2 = ((wSaturation + 240) * wLuminosity + 120) / 240;
3608 wMid1 = wLuminosity * 2 - wMid2;
3610 wRed = GET_RGB(wHue + 80);
3611 wGreen = GET_RGB(wHue);
3612 wBlue = GET_RGB(wHue - 80);
3614 return RGB(wRed, wGreen, wBlue);
3617 wRed = wLuminosity * 255 / 240;
3618 return RGB(wRed, wRed, wRed);
3621 /*************************************************************************
3622 * @ [SHLWAPI.413]
3624 * Get the current docking status of the system.
3626 * PARAMS
3627 * dwFlags [I] DOCKINFO_ flags from "winbase.h", unused
3629 * RETURNS
3630 * One of DOCKINFO_UNDOCKED, DOCKINFO_UNDOCKED, or 0 if the system is not
3631 * a notebook.
3633 DWORD WINAPI SHGetMachineInfo(DWORD dwFlags)
3635 HW_PROFILE_INFOA hwInfo;
3637 TRACE("(0x%08x)\n", dwFlags);
3639 GetCurrentHwProfileA(&hwInfo);
3640 switch (hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED))
3642 case DOCKINFO_DOCKED:
3643 case DOCKINFO_UNDOCKED:
3644 return hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED);
3645 default:
3646 return 0;
3650 /*************************************************************************
3651 * @ [SHLWAPI.418]
3653 * Function seems to do FreeLibrary plus other things.
3655 * FIXME native shows the following calls:
3656 * RtlEnterCriticalSection
3657 * LocalFree
3658 * GetProcAddress(Comctl32??, 150L)
3659 * DPA_DeletePtr
3660 * RtlLeaveCriticalSection
3661 * followed by the FreeLibrary.
3662 * The above code may be related to .377 above.
3664 BOOL WINAPI MLFreeLibrary(HMODULE hModule)
3666 FIXME("(%p) semi-stub\n", hModule);
3667 return FreeLibrary(hModule);
3670 /*************************************************************************
3671 * @ [SHLWAPI.419]
3673 BOOL WINAPI SHFlushSFCacheWrap(void) {
3674 FIXME(": stub\n");
3675 return TRUE;
3678 /*************************************************************************
3679 * @ [SHLWAPI.425]
3681 BOOL WINAPI DeleteMenuWrap(HMENU hmenu, UINT pos, UINT flags)
3683 /* FIXME: This should do more than simply call DeleteMenu */
3684 FIXME("%p %08x %08x): semi-stub\n", hmenu, pos, flags);
3685 return DeleteMenu(hmenu, pos, flags);
3688 /*************************************************************************
3689 * @ [SHLWAPI.429]
3690 * FIXME I have no idea what this function does or what its arguments are.
3692 BOOL WINAPI MLIsMLHInstance(HINSTANCE hInst)
3694 FIXME("(%p) stub\n", hInst);
3695 return FALSE;
3699 /*************************************************************************
3700 * @ [SHLWAPI.430]
3702 DWORD WINAPI MLSetMLHInstance(HINSTANCE hInst, HANDLE hHeap)
3704 FIXME("(%p,%p) stub\n", hInst, hHeap);
3705 return E_FAIL; /* This is what is used if shlwapi not loaded */
3708 /*************************************************************************
3709 * @ [SHLWAPI.431]
3711 DWORD WINAPI MLClearMLHInstance(DWORD x)
3713 FIXME("(0x%08x)stub\n", x);
3714 return 0xabba1247;
3717 /*************************************************************************
3718 * @ [SHLWAPI.436]
3720 * Convert an Unicode string CLSID into a CLSID.
3722 * PARAMS
3723 * idstr [I] string containing a CLSID in text form
3724 * id [O] CLSID extracted from the string
3726 * RETURNS
3727 * S_OK on success or E_INVALIDARG on failure
3729 HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR idstr, CLSID *id)
3731 return CLSIDFromString((LPOLESTR)idstr, id);
3734 /*************************************************************************
3735 * @ [SHLWAPI.437]
3737 * Determine if the OS supports a given feature.
3739 * PARAMS
3740 * dwFeature [I] Feature requested (undocumented)
3742 * RETURNS
3743 * TRUE If the feature is available.
3744 * FALSE If the feature is not available.
3746 BOOL WINAPI IsOS(DWORD feature)
3748 OSVERSIONINFOA osvi;
3749 DWORD platform, majorv, minorv;
3751 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
3752 if(!GetVersionExA(&osvi)) {
3753 ERR("GetVersionEx failed\n");
3754 return FALSE;
3757 majorv = osvi.dwMajorVersion;
3758 minorv = osvi.dwMinorVersion;
3759 platform = osvi.dwPlatformId;
3761 #define ISOS_RETURN(x) \
3762 TRACE("(0x%x) ret=%d\n",feature,(x)); \
3763 return (x);
3765 switch(feature) {
3766 case OS_WIN32SORGREATER:
3767 ISOS_RETURN(platform == VER_PLATFORM_WIN32s
3768 || platform == VER_PLATFORM_WIN32_WINDOWS)
3769 case OS_NT:
3770 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3771 case OS_WIN95ORGREATER:
3772 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS)
3773 case OS_NT4ORGREATER:
3774 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 4)
3775 case OS_WIN2000ORGREATER_ALT:
3776 case OS_WIN2000ORGREATER:
3777 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5)
3778 case OS_WIN98ORGREATER:
3779 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv >= 10)
3780 case OS_WIN98_GOLD:
3781 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv == 10)
3782 case OS_WIN2000PRO:
3783 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5)
3784 case OS_WIN2000SERVER:
3785 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3786 case OS_WIN2000ADVSERVER:
3787 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3788 case OS_WIN2000DATACENTER:
3789 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3790 case OS_WIN2000TERMINAL:
3791 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3792 case OS_EMBEDDED:
3793 FIXME("(OS_EMBEDDED) What should we return here?\n");
3794 return FALSE;
3795 case OS_TERMINALCLIENT:
3796 FIXME("(OS_TERMINALCLIENT) What should we return here?\n");
3797 return FALSE;
3798 case OS_TERMINALREMOTEADMIN:
3799 FIXME("(OS_TERMINALREMOTEADMIN) What should we return here?\n");
3800 return FALSE;
3801 case OS_WIN95_GOLD:
3802 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv == 0)
3803 case OS_MEORGREATER:
3804 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv >= 90)
3805 case OS_XPORGREATER:
3806 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5 && minorv >= 1)
3807 case OS_HOME:
3808 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5 && minorv >= 1)
3809 case OS_PROFESSIONAL:
3810 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3811 case OS_DATACENTER:
3812 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3813 case OS_ADVSERVER:
3814 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5)
3815 case OS_SERVER:
3816 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3817 case OS_TERMINALSERVER:
3818 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3819 case OS_PERSONALTERMINALSERVER:
3820 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && minorv >= 1 && majorv >= 5)
3821 case OS_FASTUSERSWITCHING:
3822 FIXME("(OS_FASTUSERSWITCHING) What should we return here?\n");
3823 return TRUE;
3824 case OS_WELCOMELOGONUI:
3825 FIXME("(OS_WELCOMELOGONUI) What should we return here?\n");
3826 return FALSE;
3827 case OS_DOMAINMEMBER:
3828 FIXME("(OS_DOMAINMEMBER) What should we return here?\n");
3829 return TRUE;
3830 case OS_ANYSERVER:
3831 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3832 case OS_WOW6432:
3833 FIXME("(OS_WOW6432) Should we check this?\n");
3834 return FALSE;
3835 case OS_WEBSERVER:
3836 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3837 case OS_SMALLBUSINESSSERVER:
3838 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3839 case OS_TABLETPC:
3840 FIXME("(OS_TABLEPC) What should we return here?\n");
3841 return FALSE;
3842 case OS_SERVERADMINUI:
3843 FIXME("(OS_SERVERADMINUI) What should we return here?\n");
3844 return FALSE;
3845 case OS_MEDIACENTER:
3846 FIXME("(OS_MEDIACENTER) What should we return here?\n");
3847 return FALSE;
3848 case OS_APPLIANCE:
3849 FIXME("(OS_APPLIANCE) What should we return here?\n");
3850 return FALSE;
3853 #undef ISOS_RETURN
3855 WARN("(0x%x) unknown parameter\n",feature);
3857 return FALSE;
3860 /*************************************************************************
3861 * @ [SHLWAPI.439]
3863 HRESULT WINAPI SHLoadRegUIStringW(HKEY hkey, LPCWSTR value, LPWSTR buf, DWORD size)
3865 DWORD type, sz = size;
3867 if(RegQueryValueExW(hkey, value, NULL, &type, (LPBYTE)buf, &sz) != ERROR_SUCCESS)
3868 return E_FAIL;
3870 return SHLoadIndirectString(buf, buf, size, NULL);
3873 /*************************************************************************
3874 * @ [SHLWAPI.478]
3876 * Call IInputObject_TranslateAcceleratorIO() on an object.
3878 * PARAMS
3879 * lpUnknown [I] Object supporting the IInputObject interface.
3880 * lpMsg [I] Key message to be processed.
3882 * RETURNS
3883 * Success: S_OK.
3884 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
3886 HRESULT WINAPI IUnknown_TranslateAcceleratorIO(IUnknown *lpUnknown, LPMSG lpMsg)
3888 IInputObject* lpInput = NULL;
3889 HRESULT hRet = E_INVALIDARG;
3891 TRACE("(%p,%p)\n", lpUnknown, lpMsg);
3892 if (lpUnknown)
3894 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInputObject,
3895 (void**)&lpInput);
3896 if (SUCCEEDED(hRet) && lpInput)
3898 hRet = IInputObject_TranslateAcceleratorIO(lpInput, lpMsg);
3899 IInputObject_Release(lpInput);
3902 return hRet;
3905 /*************************************************************************
3906 * @ [SHLWAPI.481]
3908 * Call IInputObject_HasFocusIO() on an object.
3910 * PARAMS
3911 * lpUnknown [I] Object supporting the IInputObject interface.
3913 * RETURNS
3914 * Success: S_OK, if lpUnknown is an IInputObject object and has the focus,
3915 * or S_FALSE otherwise.
3916 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
3918 HRESULT WINAPI IUnknown_HasFocusIO(IUnknown *lpUnknown)
3920 IInputObject* lpInput = NULL;
3921 HRESULT hRet = E_INVALIDARG;
3923 TRACE("(%p)\n", lpUnknown);
3924 if (lpUnknown)
3926 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInputObject,
3927 (void**)&lpInput);
3928 if (SUCCEEDED(hRet) && lpInput)
3930 hRet = IInputObject_HasFocusIO(lpInput);
3931 IInputObject_Release(lpInput);
3934 return hRet;
3937 /*************************************************************************
3938 * ColorRGBToHLS [SHLWAPI.@]
3940 * Convert an rgb COLORREF into the hls color space.
3942 * PARAMS
3943 * cRGB [I] Source rgb value
3944 * pwHue [O] Destination for converted hue
3945 * pwLuminance [O] Destination for converted luminance
3946 * pwSaturation [O] Destination for converted saturation
3948 * RETURNS
3949 * Nothing. pwHue, pwLuminance and pwSaturation are set to the converted
3950 * values.
3952 * NOTES
3953 * Output HLS values are constrained to the range (0..240).
3954 * For Achromatic conversions, Hue is set to 160.
3956 VOID WINAPI ColorRGBToHLS(COLORREF cRGB, LPWORD pwHue,
3957 LPWORD pwLuminance, LPWORD pwSaturation)
3959 int wR, wG, wB, wMax, wMin, wHue, wLuminosity, wSaturation;
3961 TRACE("(%08x,%p,%p,%p)\n", cRGB, pwHue, pwLuminance, pwSaturation);
3963 wR = GetRValue(cRGB);
3964 wG = GetGValue(cRGB);
3965 wB = GetBValue(cRGB);
3967 wMax = max(wR, max(wG, wB));
3968 wMin = min(wR, min(wG, wB));
3970 /* Luminosity */
3971 wLuminosity = ((wMax + wMin) * 240 + 255) / 510;
3973 if (wMax == wMin)
3975 /* Achromatic case */
3976 wSaturation = 0;
3977 /* Hue is now unrepresentable, but this is what native returns... */
3978 wHue = 160;
3980 else
3982 /* Chromatic case */
3983 int wDelta = wMax - wMin, wRNorm, wGNorm, wBNorm;
3985 /* Saturation */
3986 if (wLuminosity <= 120)
3987 wSaturation = ((wMax + wMin)/2 + wDelta * 240) / (wMax + wMin);
3988 else
3989 wSaturation = ((510 - wMax - wMin)/2 + wDelta * 240) / (510 - wMax - wMin);
3991 /* Hue */
3992 wRNorm = (wDelta/2 + wMax * 40 - wR * 40) / wDelta;
3993 wGNorm = (wDelta/2 + wMax * 40 - wG * 40) / wDelta;
3994 wBNorm = (wDelta/2 + wMax * 40 - wB * 40) / wDelta;
3996 if (wR == wMax)
3997 wHue = wBNorm - wGNorm;
3998 else if (wG == wMax)
3999 wHue = 80 + wRNorm - wBNorm;
4000 else
4001 wHue = 160 + wGNorm - wRNorm;
4002 if (wHue < 0)
4003 wHue += 240;
4004 else if (wHue > 240)
4005 wHue -= 240;
4007 if (pwHue)
4008 *pwHue = wHue;
4009 if (pwLuminance)
4010 *pwLuminance = wLuminosity;
4011 if (pwSaturation)
4012 *pwSaturation = wSaturation;
4015 /*************************************************************************
4016 * SHCreateShellPalette [SHLWAPI.@]
4018 HPALETTE WINAPI SHCreateShellPalette(HDC hdc)
4020 FIXME("stub\n");
4021 return CreateHalftonePalette(hdc);
4024 /*************************************************************************
4025 * SHGetInverseCMAP (SHLWAPI.@)
4027 * Get an inverse color map table.
4029 * PARAMS
4030 * lpCmap [O] Destination for color map
4031 * dwSize [I] Size of memory pointed to by lpCmap
4033 * RETURNS
4034 * Success: S_OK.
4035 * Failure: E_POINTER, If lpCmap is invalid.
4036 * E_INVALIDARG, If dwFlags is invalid
4037 * E_OUTOFMEMORY, If there is no memory available
4039 * NOTES
4040 * dwSize may only be CMAP_PTR_SIZE (4) or CMAP_SIZE (8192).
4041 * If dwSize = CMAP_PTR_SIZE, *lpCmap is set to the address of this DLL's
4042 * internal CMap.
4043 * If dwSize = CMAP_SIZE, lpCmap is filled with a copy of the data from
4044 * this DLL's internal CMap.
4046 HRESULT WINAPI SHGetInverseCMAP(LPDWORD dest, DWORD dwSize)
4048 if (dwSize == 4) {
4049 FIXME(" - returning bogus address for SHGetInverseCMAP\n");
4050 *dest = (DWORD)0xabba1249;
4051 return 0;
4053 FIXME("(%p, %#x) stub\n", dest, dwSize);
4054 return 0;
4057 /*************************************************************************
4058 * SHIsLowMemoryMachine [SHLWAPI.@]
4060 * Determine if the current computer has low memory.
4062 * PARAMS
4063 * x [I] FIXME
4065 * RETURNS
4066 * TRUE if the users machine has 16 Megabytes of memory or less,
4067 * FALSE otherwise.
4069 BOOL WINAPI SHIsLowMemoryMachine (DWORD x)
4071 FIXME("(0x%08x) stub\n", x);
4072 return FALSE;
4075 /*************************************************************************
4076 * GetMenuPosFromID [SHLWAPI.@]
4078 * Return the position of a menu item from its Id.
4080 * PARAMS
4081 * hMenu [I] Menu containing the item
4082 * wID [I] Id of the menu item
4084 * RETURNS
4085 * Success: The index of the menu item in hMenu.
4086 * Failure: -1, If the item is not found.
4088 INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID)
4090 MENUITEMINFOW mi;
4091 INT nCount = GetMenuItemCount(hMenu), nIter = 0;
4093 while (nIter < nCount)
4095 mi.cbSize = sizeof(mi);
4096 mi.fMask = MIIM_ID;
4097 if (GetMenuItemInfoW(hMenu, nIter, TRUE, &mi) && mi.wID == wID)
4098 return nIter;
4099 nIter++;
4101 return -1;
4104 /*************************************************************************
4105 * @ [SHLWAPI.179]
4107 * Same as SHLWAPI.GetMenuPosFromID
4109 DWORD WINAPI SHMenuIndexFromID(HMENU hMenu, UINT uID)
4111 return GetMenuPosFromID(hMenu, uID);
4115 /*************************************************************************
4116 * @ [SHLWAPI.448]
4118 VOID WINAPI FixSlashesAndColonW(LPWSTR lpwstr)
4120 while (*lpwstr)
4122 if (*lpwstr == '/')
4123 *lpwstr = '\\';
4124 lpwstr++;
4129 /*************************************************************************
4130 * @ [SHLWAPI.461]
4132 DWORD WINAPI SHGetAppCompatFlags(DWORD dwUnknown)
4134 FIXME("(0x%08x) stub\n", dwUnknown);
4135 return 0;
4139 /*************************************************************************
4140 * @ [SHLWAPI.549]
4142 HRESULT WINAPI SHCoCreateInstanceAC(REFCLSID rclsid, LPUNKNOWN pUnkOuter,
4143 DWORD dwClsContext, REFIID iid, LPVOID *ppv)
4145 return CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, ppv);
4148 /*************************************************************************
4149 * SHSkipJunction [SHLWAPI.@]
4151 * Determine if a bind context can be bound to an object
4153 * PARAMS
4154 * pbc [I] Bind context to check
4155 * pclsid [I] CLSID of object to be bound to
4157 * RETURNS
4158 * TRUE: If it is safe to bind
4159 * FALSE: If pbc is invalid or binding would not be safe
4162 BOOL WINAPI SHSkipJunction(IBindCtx *pbc, const CLSID *pclsid)
4164 static WCHAR szSkipBinding[] = { 'S','k','i','p',' ',
4165 'B','i','n','d','i','n','g',' ','C','L','S','I','D','\0' };
4166 BOOL bRet = FALSE;
4168 if (pbc)
4170 IUnknown* lpUnk;
4172 if (SUCCEEDED(IBindCtx_GetObjectParam(pbc, (LPOLESTR)szSkipBinding, &lpUnk)))
4174 CLSID clsid;
4176 if (SUCCEEDED(IUnknown_GetClassID(lpUnk, &clsid)) &&
4177 IsEqualGUID(pclsid, &clsid))
4178 bRet = TRUE;
4180 IUnknown_Release(lpUnk);
4183 return bRet;
4186 /***********************************************************************
4187 * SHGetShellKey (SHLWAPI.@)
4189 DWORD WINAPI SHGetShellKey(DWORD a, DWORD b, DWORD c)
4191 FIXME("(%x, %x, %x): stub\n", a, b, c);
4192 return 0x50;
4195 /***********************************************************************
4196 * SHQueueUserWorkItem (SHLWAPI.@)
4198 BOOL WINAPI SHQueueUserWorkItem(LPTHREAD_START_ROUTINE pfnCallback,
4199 LPVOID pContext, LONG lPriority, DWORD_PTR dwTag,
4200 DWORD_PTR *pdwId, LPCSTR pszModule, DWORD dwFlags)
4202 TRACE("(%p, %p, %d, %lx, %p, %s, %08x)\n", pfnCallback, pContext,
4203 lPriority, dwTag, pdwId, debugstr_a(pszModule), dwFlags);
4205 if(lPriority || dwTag || pdwId || pszModule || dwFlags)
4206 FIXME("Unsupported arguments\n");
4208 return QueueUserWorkItem(pfnCallback, pContext, 0);
4211 /***********************************************************************
4212 * SHSetTimerQueueTimer (SHLWAPI.263)
4214 HANDLE WINAPI SHSetTimerQueueTimer(HANDLE hQueue,
4215 WAITORTIMERCALLBACK pfnCallback, LPVOID pContext, DWORD dwDueTime,
4216 DWORD dwPeriod, LPCSTR lpszLibrary, DWORD dwFlags)
4218 HANDLE hNewTimer;
4220 /* SHSetTimerQueueTimer flags -> CreateTimerQueueTimer flags */
4221 if (dwFlags & TPS_LONGEXECTIME) {
4222 dwFlags &= ~TPS_LONGEXECTIME;
4223 dwFlags |= WT_EXECUTELONGFUNCTION;
4225 if (dwFlags & TPS_EXECUTEIO) {
4226 dwFlags &= ~TPS_EXECUTEIO;
4227 dwFlags |= WT_EXECUTEINIOTHREAD;
4230 if (!CreateTimerQueueTimer(&hNewTimer, hQueue, pfnCallback, pContext,
4231 dwDueTime, dwPeriod, dwFlags))
4232 return NULL;
4234 return hNewTimer;
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("(%x, %s, %s, %x, %x, %x): 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;
4297 /***********************************************************************
4298 * ShellMessageBoxWrapW [SHLWAPI.388]
4300 * See shell32.ShellMessageBoxW
4302 * NOTE:
4303 * shlwapi.ShellMessageBoxWrapW is a duplicate of shell32.ShellMessageBoxW
4304 * because we can't forward to it in the .spec file since it's exported by
4305 * ordinal. If you change the implementation here please update the code in
4306 * shell32 as well.
4308 INT WINAPIV ShellMessageBoxWrapW(HINSTANCE hInstance, HWND hWnd, LPCWSTR lpText,
4309 LPCWSTR lpCaption, UINT uType, ...)
4311 WCHAR szText[100], szTitle[100];
4312 LPCWSTR pszText = szText, pszTitle = szTitle;
4313 LPWSTR pszTemp;
4314 va_list args;
4315 int ret;
4317 va_start(args, uType);
4319 TRACE("(%p,%p,%p,%p,%08x)\n", hInstance, hWnd, lpText, lpCaption, uType);
4321 if (IS_INTRESOURCE(lpCaption))
4322 LoadStringW(hInstance, LOWORD(lpCaption), szTitle, sizeof(szTitle)/sizeof(szTitle[0]));
4323 else
4324 pszTitle = lpCaption;
4326 if (IS_INTRESOURCE(lpText))
4327 LoadStringW(hInstance, LOWORD(lpText), szText, sizeof(szText)/sizeof(szText[0]));
4328 else
4329 pszText = lpText;
4331 FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
4332 pszText, 0, 0, (LPWSTR)&pszTemp, 0, &args);
4334 va_end(args);
4336 ret = MessageBoxW(hWnd, pszTemp, pszTitle, uType);
4337 LocalFree((HLOCAL)pszTemp);
4338 return ret;
4341 HRESULT WINAPI IUnknown_QueryServiceExec(IUnknown *unk, REFIID service, REFIID clsid,
4342 DWORD x1, DWORD x2, DWORD x3, void **ppvOut)
4344 FIXME("%p %s %s %08x %08x %08x %p\n", unk,
4345 debugstr_guid(service), debugstr_guid(clsid), x1, x2, x3, ppvOut);
4346 return E_NOTIMPL;
4349 HRESULT WINAPI IUnknown_ProfferService(IUnknown *unk, void *x0, void *x1, void *x2)
4351 FIXME("%p %p %p %p\n", unk, x0, x1, x2);
4352 return E_NOTIMPL;
4355 /***********************************************************************
4356 * ZoneComputePaneSize [SHLWAPI.382]
4358 UINT WINAPI ZoneComputePaneSize(HWND hwnd)
4360 FIXME("\n");
4361 return 0x95;
4364 void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
4366 SHChangeNotify(wEventId, uFlags, dwItem1, dwItem2);
4369 typedef struct SHELL_USER_SID { /* according to MSDN this should be in shlobj.h... */
4370 SID_IDENTIFIER_AUTHORITY sidAuthority;
4371 DWORD dwUserGroupID;
4372 DWORD dwUserID;
4373 } SHELL_USER_SID, *PSHELL_USER_SID;
4375 typedef struct SHELL_USER_PERMISSION { /* ...and this should be in shlwapi.h */
4376 SHELL_USER_SID susID;
4377 DWORD dwAccessType;
4378 BOOL fInherit;
4379 DWORD dwAccessMask;
4380 DWORD dwInheritMask;
4381 DWORD dwInheritAccessMask;
4382 } SHELL_USER_PERMISSION, *PSHELL_USER_PERMISSION;
4384 /***********************************************************************
4385 * GetShellSecurityDescriptor [SHLWAPI.475]
4387 * prepares SECURITY_DESCRIPTOR from a set of ACEs
4389 * PARAMS
4390 * apUserPerm [I] array of pointers to SHELL_USER_PERMISSION structures,
4391 * each of which describes permissions to apply
4392 * cUserPerm [I] number of entries in apUserPerm array
4394 * RETURNS
4395 * success: pointer to SECURITY_DESCRIPTOR
4396 * failure: NULL
4398 * NOTES
4399 * Call should free returned descriptor with LocalFree
4401 PSECURITY_DESCRIPTOR WINAPI GetShellSecurityDescriptor(PSHELL_USER_PERMISSION *apUserPerm, int cUserPerm)
4403 PSID *sidlist;
4404 PSID cur_user = NULL;
4405 BYTE tuUser[2000];
4406 DWORD acl_size;
4407 int sid_count, i;
4408 PSECURITY_DESCRIPTOR psd = NULL;
4410 TRACE("%p %d\n", apUserPerm, cUserPerm);
4412 if (apUserPerm == NULL || cUserPerm <= 0)
4413 return NULL;
4415 sidlist = HeapAlloc(GetProcessHeap(), 0, cUserPerm * sizeof(PSID));
4416 if (!sidlist)
4417 return NULL;
4419 acl_size = sizeof(ACL);
4421 for(sid_count = 0; sid_count < cUserPerm; sid_count++)
4423 static SHELL_USER_SID null_sid = {{SECURITY_NULL_SID_AUTHORITY}, 0, 0};
4424 PSHELL_USER_PERMISSION perm = apUserPerm[sid_count];
4425 PSHELL_USER_SID sid = &perm->susID;
4426 PSID pSid;
4427 BOOL ret = TRUE;
4429 if (!memcmp((void*)sid, (void*)&null_sid, sizeof(SHELL_USER_SID)))
4430 { /* current user's SID */
4431 if (!cur_user)
4433 HANDLE Token;
4434 DWORD bufsize = sizeof(tuUser);
4436 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &Token);
4437 if (ret)
4439 ret = GetTokenInformation(Token, TokenUser, (void*)tuUser, bufsize, &bufsize );
4440 if (ret)
4441 cur_user = ((PTOKEN_USER)&tuUser)->User.Sid;
4442 CloseHandle(Token);
4445 pSid = cur_user;
4446 } else if (sid->dwUserID==0) /* one sub-authority */
4447 ret = AllocateAndInitializeSid(&sid->sidAuthority, 1, sid->dwUserGroupID, 0,
4448 0, 0, 0, 0, 0, 0, &pSid);
4449 else
4450 ret = AllocateAndInitializeSid(&sid->sidAuthority, 2, sid->dwUserGroupID, sid->dwUserID,
4451 0, 0, 0, 0, 0, 0, &pSid);
4452 if (!ret)
4453 goto free_sids;
4455 sidlist[sid_count] = pSid;
4456 /* increment acl_size (1 ACE for non-inheritable and 2 ACEs for inheritable records */
4457 acl_size += (sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD) + GetLengthSid(pSid)) * (perm->fInherit ? 2 : 1);
4460 psd = LocalAlloc(0, sizeof(SECURITY_DESCRIPTOR) + acl_size);
4462 if (psd != NULL)
4464 PACL pAcl = (PACL)(((BYTE*)psd)+sizeof(SECURITY_DESCRIPTOR));
4466 if (!InitializeSecurityDescriptor(psd, SECURITY_DESCRIPTOR_REVISION))
4467 goto error;
4469 if (!InitializeAcl(pAcl, acl_size, ACL_REVISION))
4470 goto error;
4472 for(i = 0; i < sid_count; i++)
4474 PSHELL_USER_PERMISSION sup = apUserPerm[i];
4475 PSID sid = sidlist[i];
4477 switch(sup->dwAccessType)
4479 case ACCESS_ALLOWED_ACE_TYPE:
4480 if (!AddAccessAllowedAce(pAcl, ACL_REVISION, sup->dwAccessMask, sid))
4481 goto error;
4482 if (sup->fInherit && !AddAccessAllowedAceEx(pAcl, ACL_REVISION,
4483 (BYTE)sup->dwInheritMask, sup->dwInheritAccessMask, sid))
4484 goto error;
4485 break;
4486 case ACCESS_DENIED_ACE_TYPE:
4487 if (!AddAccessDeniedAce(pAcl, ACL_REVISION, sup->dwAccessMask, sid))
4488 goto error;
4489 if (sup->fInherit && !AddAccessDeniedAceEx(pAcl, ACL_REVISION,
4490 (BYTE)sup->dwInheritMask, sup->dwInheritAccessMask, sid))
4491 goto error;
4492 break;
4493 default:
4494 goto error;
4498 if (!SetSecurityDescriptorDacl(psd, TRUE, pAcl, FALSE))
4499 goto error;
4501 goto free_sids;
4503 error:
4504 LocalFree(psd);
4505 psd = NULL;
4506 free_sids:
4507 for(i = 0; i < sid_count; i++)
4509 if (!cur_user || sidlist[i] != cur_user)
4510 FreeSid(sidlist[i]);
4512 HeapFree(GetProcessHeap(), 0, sidlist);
4514 return psd;