shlwapi: Added OS_VISTAORGREATER flag to IsOS (undocumented).
[wine/multimedia.git] / dlls / shlwapi / ordinal.c
blob9bb26cf57be439670ea3495f7d281e013f18e0cd
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 "winnls.h"
37 #include "winreg.h"
38 #include "wingdi.h"
39 #include "winuser.h"
40 #include "winver.h"
41 #include "winnetwk.h"
42 #include "mmsystem.h"
43 #include "objbase.h"
44 #include "exdisp.h"
45 #include "shlobj.h"
46 #include "shlwapi.h"
47 #include "shellapi.h"
48 #include "commdlg.h"
49 #include "mshtmhst.h"
50 #include "wine/unicode.h"
51 #include "wine/debug.h"
54 WINE_DEFAULT_DEBUG_CHANNEL(shell);
56 /* DLL handles for late bound calls */
57 extern HINSTANCE shlwapi_hInstance;
58 extern DWORD SHLWAPI_ThreadRef_index;
60 HRESULT WINAPI IUnknown_QueryService(IUnknown*,REFGUID,REFIID,LPVOID*);
61 HRESULT WINAPI SHInvokeCommand(HWND,IShellFolder*,LPCITEMIDLIST,BOOL);
62 BOOL WINAPI SHAboutInfoW(LPWSTR,DWORD);
65 NOTES: Most functions exported by ordinal seem to be superfluous.
66 The reason for these functions to be there is to provide a wrapper
67 for unicode functions to provide these functions on systems without
68 unicode functions eg. win95/win98. Since we have such functions we just
69 call these. If running Wine with native DLLs, some late bound calls may
70 fail. However, it is better to implement the functions in the forward DLL
71 and recommend the builtin rather than reimplementing the calls here!
74 /*************************************************************************
75 * SHLWAPI_DupSharedHandle
77 * Internal implemetation of SHLWAPI_11.
79 static HANDLE SHLWAPI_DupSharedHandle(HANDLE hShared, DWORD dwDstProcId,
80 DWORD dwSrcProcId, DWORD dwAccess,
81 DWORD dwOptions)
83 HANDLE hDst, hSrc;
84 DWORD dwMyProcId = GetCurrentProcessId();
85 HANDLE hRet = NULL;
87 TRACE("(%p,%d,%d,%08x,%08x)\n", hShared, dwDstProcId, dwSrcProcId,
88 dwAccess, dwOptions);
90 /* Get dest process handle */
91 if (dwDstProcId == dwMyProcId)
92 hDst = GetCurrentProcess();
93 else
94 hDst = OpenProcess(PROCESS_DUP_HANDLE, 0, dwDstProcId);
96 if (hDst)
98 /* Get src process handle */
99 if (dwSrcProcId == dwMyProcId)
100 hSrc = GetCurrentProcess();
101 else
102 hSrc = OpenProcess(PROCESS_DUP_HANDLE, 0, dwSrcProcId);
104 if (hSrc)
106 /* Make handle available to dest process */
107 if (!DuplicateHandle(hDst, hShared, hSrc, &hRet,
108 dwAccess, 0, dwOptions | DUPLICATE_SAME_ACCESS))
109 hRet = NULL;
111 if (dwSrcProcId != dwMyProcId)
112 CloseHandle(hSrc);
115 if (dwDstProcId != dwMyProcId)
116 CloseHandle(hDst);
119 TRACE("Returning handle %p\n", hRet);
120 return hRet;
123 /*************************************************************************
124 * @ [SHLWAPI.7]
126 * Create a block of sharable memory and initialise it with data.
128 * PARAMS
129 * lpvData [I] Pointer to data to write
130 * dwSize [I] Size of data
131 * dwProcId [I] ID of process owning data
133 * RETURNS
134 * Success: A shared memory handle
135 * Failure: NULL
137 * NOTES
138 * Ordinals 7-11 provide a set of calls to create shared memory between a
139 * group of processes. The shared memory is treated opaquely in that its size
140 * is not exposed to clients who map it. This is accomplished by storing
141 * the size of the map as the first DWORD of mapped data, and then offsetting
142 * the view pointer returned by this size.
145 HANDLE WINAPI SHAllocShared(LPCVOID lpvData, DWORD dwSize, DWORD dwProcId)
147 HANDLE hMap;
148 LPVOID pMapped;
149 HANDLE hRet = NULL;
151 TRACE("(%p,%d,%d)\n", lpvData, dwSize, dwProcId);
153 /* Create file mapping of the correct length */
154 hMap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, FILE_MAP_READ, 0,
155 dwSize + sizeof(dwSize), NULL);
156 if (!hMap)
157 return hRet;
159 /* Get a view in our process address space */
160 pMapped = MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
162 if (pMapped)
164 /* Write size of data, followed by the data, to the view */
165 *((DWORD*)pMapped) = dwSize;
166 if (lpvData)
167 memcpy((char *) pMapped + sizeof(dwSize), lpvData, dwSize);
169 /* Release view. All further views mapped will be opaque */
170 UnmapViewOfFile(pMapped);
171 hRet = SHLWAPI_DupSharedHandle(hMap, dwProcId,
172 GetCurrentProcessId(), FILE_MAP_ALL_ACCESS,
173 DUPLICATE_SAME_ACCESS);
176 CloseHandle(hMap);
177 return hRet;
180 /*************************************************************************
181 * @ [SHLWAPI.8]
183 * Get a pointer to a block of shared memory from a shared memory handle.
185 * PARAMS
186 * hShared [I] Shared memory handle
187 * dwProcId [I] ID of process owning hShared
189 * RETURNS
190 * Success: A pointer to the shared memory
191 * Failure: NULL
194 PVOID WINAPI SHLockShared(HANDLE hShared, DWORD dwProcId)
196 HANDLE hDup;
197 LPVOID pMapped;
199 TRACE("(%p %d)\n", hShared, dwProcId);
201 /* Get handle to shared memory for current process */
202 hDup = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
203 FILE_MAP_ALL_ACCESS, 0);
204 /* Get View */
205 pMapped = MapViewOfFile(hDup, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
206 CloseHandle(hDup);
208 if (pMapped)
209 return (char *) pMapped + sizeof(DWORD); /* Hide size */
210 return NULL;
213 /*************************************************************************
214 * @ [SHLWAPI.9]
216 * Release a pointer to a block of shared memory.
218 * PARAMS
219 * lpView [I] Shared memory pointer
221 * RETURNS
222 * Success: TRUE
223 * Failure: FALSE
226 BOOL WINAPI SHUnlockShared(LPVOID lpView)
228 TRACE("(%p)\n", lpView);
229 return UnmapViewOfFile((char *) lpView - sizeof(DWORD)); /* Include size */
232 /*************************************************************************
233 * @ [SHLWAPI.10]
235 * Destroy a block of sharable memory.
237 * PARAMS
238 * hShared [I] Shared memory handle
239 * dwProcId [I] ID of process owning hShared
241 * RETURNS
242 * Success: TRUE
243 * Failure: FALSE
246 BOOL WINAPI SHFreeShared(HANDLE hShared, DWORD dwProcId)
248 HANDLE hClose;
250 TRACE("(%p %d)\n", hShared, dwProcId);
252 /* Get a copy of the handle for our process, closing the source handle */
253 hClose = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
254 FILE_MAP_ALL_ACCESS,DUPLICATE_CLOSE_SOURCE);
255 /* Close local copy */
256 return CloseHandle(hClose);
259 /*************************************************************************
260 * @ [SHLWAPI.11]
262 * Copy a sharable memory handle from one process to another.
264 * PARAMS
265 * hShared [I] Shared memory handle to duplicate
266 * dwDstProcId [I] ID of the process wanting the duplicated handle
267 * dwSrcProcId [I] ID of the process owning hShared
268 * dwAccess [I] Desired DuplicateHandle() access
269 * dwOptions [I] Desired DuplicateHandle() options
271 * RETURNS
272 * Success: A handle suitable for use by the dwDstProcId process.
273 * Failure: A NULL handle.
276 HANDLE WINAPI SHMapHandle(HANDLE hShared, DWORD dwDstProcId, DWORD dwSrcProcId,
277 DWORD dwAccess, DWORD dwOptions)
279 HANDLE hRet;
281 hRet = SHLWAPI_DupSharedHandle(hShared, dwDstProcId, dwSrcProcId,
282 dwAccess, dwOptions);
283 return hRet;
286 /*************************************************************************
287 * @ [SHLWAPI.13]
289 * Create and register a clipboard enumerator for a web browser.
291 * PARAMS
292 * lpBC [I] Binding context
293 * lpUnknown [I] An object exposing the IWebBrowserApp interface
295 * RETURNS
296 * Success: S_OK.
297 * Failure: An HRESULT error code.
299 * NOTES
300 * The enumerator is stored as a property of the web browser. If it does not
301 * yet exist, it is created and set before being registered.
303 HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown)
305 static const WCHAR szProperty[] = { '{','D','0','F','C','A','4','2','0',
306 '-','D','3','F','5','-','1','1','C','F', '-','B','2','1','1','-','0',
307 '0','A','A','0','0','4','A','E','8','3','7','}','\0' };
308 BSTR property;
309 IEnumFORMATETC* pIEnumFormatEtc = NULL;
310 VARIANTARG var;
311 HRESULT hRet;
312 IWebBrowserApp* pBrowser = NULL;
314 TRACE("(%p, %p)\n", lpBC, lpUnknown);
316 /* Get An IWebBrowserApp interface from lpUnknown */
317 hRet = IUnknown_QueryService(lpUnknown, &IID_IWebBrowserApp, &IID_IWebBrowserApp, (PVOID)&pBrowser);
318 if (FAILED(hRet) || !pBrowser)
319 return E_NOINTERFACE;
321 V_VT(&var) = VT_EMPTY;
323 /* The property we get is the browsers clipboard enumerator */
324 property = SysAllocString(szProperty);
325 hRet = IWebBrowserApp_GetProperty(pBrowser, property, &var);
326 SysFreeString(property);
327 if (FAILED(hRet))
328 return hRet;
330 if (V_VT(&var) == VT_EMPTY)
332 /* Iterate through accepted documents and RegisterClipBoardFormatA() them */
333 char szKeyBuff[128], szValueBuff[128];
334 DWORD dwKeySize, dwValueSize, dwRet = 0, dwCount = 0, dwNumValues, dwType;
335 FORMATETC* formatList, *format;
336 HKEY hDocs;
338 TRACE("Registering formats and creating IEnumFORMATETC instance\n");
340 if (!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\Current"
341 "Version\\Internet Settings\\Accepted Documents", &hDocs))
342 return E_FAIL;
344 /* Get count of values in key */
345 while (!dwRet)
347 dwKeySize = sizeof(szKeyBuff);
348 dwRet = RegEnumValueA(hDocs,dwCount,szKeyBuff,&dwKeySize,0,&dwType,0,0);
349 dwCount++;
352 dwNumValues = dwCount;
354 /* Note: dwCount = number of items + 1; The extra item is the end node */
355 format = formatList = HeapAlloc(GetProcessHeap(), 0, dwCount * sizeof(FORMATETC));
356 if (!formatList)
357 return E_OUTOFMEMORY;
359 if (dwNumValues > 1)
361 dwRet = 0;
362 dwCount = 0;
364 dwNumValues--;
366 /* Register clipboard formats for the values and populate format list */
367 while(!dwRet && dwCount < dwNumValues)
369 dwKeySize = sizeof(szKeyBuff);
370 dwValueSize = sizeof(szValueBuff);
371 dwRet = RegEnumValueA(hDocs, dwCount, szKeyBuff, &dwKeySize, 0, &dwType,
372 (PBYTE)szValueBuff, &dwValueSize);
373 if (!dwRet)
374 return E_FAIL;
376 format->cfFormat = RegisterClipboardFormatA(szValueBuff);
377 format->ptd = NULL;
378 format->dwAspect = 1;
379 format->lindex = 4;
380 format->tymed = -1;
382 format++;
383 dwCount++;
387 /* Terminate the (maybe empty) list, last entry has a cfFormat of 0 */
388 format->cfFormat = 0;
389 format->ptd = NULL;
390 format->dwAspect = 1;
391 format->lindex = 4;
392 format->tymed = -1;
394 /* Create a clipboard enumerator */
395 hRet = CreateFormatEnumerator(dwNumValues, formatList, &pIEnumFormatEtc);
397 if (FAILED(hRet) || !pIEnumFormatEtc)
398 return hRet;
400 /* Set our enumerator as the browsers property */
401 V_VT(&var) = VT_UNKNOWN;
402 V_UNKNOWN(&var) = (IUnknown*)pIEnumFormatEtc;
404 hRet = IWebBrowserApp_PutProperty(pBrowser, (BSTR)szProperty, var);
405 if (FAILED(hRet))
407 IEnumFORMATETC_Release(pIEnumFormatEtc);
408 goto RegisterDefaultAcceptHeaders_Exit;
412 if (V_VT(&var) == VT_UNKNOWN)
414 /* Our variant is holding the clipboard enumerator */
415 IUnknown* pIUnknown = V_UNKNOWN(&var);
416 IEnumFORMATETC* pClone = NULL;
418 TRACE("Retrieved IEnumFORMATETC property\n");
420 /* Get an IEnumFormatEtc interface from the variants value */
421 pIEnumFormatEtc = NULL;
422 hRet = IUnknown_QueryInterface(pIUnknown, &IID_IEnumFORMATETC,
423 (PVOID)&pIEnumFormatEtc);
424 if (hRet == S_OK && pIEnumFormatEtc)
426 /* Clone and register the enumerator */
427 hRet = IEnumFORMATETC_Clone(pIEnumFormatEtc, &pClone);
428 if (hRet == S_OK && pClone)
430 RegisterFormatEnumerator(lpBC, pClone, 0);
432 IEnumFORMATETC_Release(pClone);
435 /* Release the IEnumFormatEtc interface */
436 IEnumFORMATETC_Release(pIUnknown);
438 IUnknown_Release(V_UNKNOWN(&var));
441 RegisterDefaultAcceptHeaders_Exit:
442 IWebBrowserApp_Release(pBrowser);
443 return hRet;
446 /*************************************************************************
447 * @ [SHLWAPI.15]
449 * Get Explorers "AcceptLanguage" setting.
451 * PARAMS
452 * langbuf [O] Destination for language string
453 * buflen [I] Length of langbuf
454 * [0] Success: used length of langbuf
456 * RETURNS
457 * Success: S_OK. langbuf is set to the language string found.
458 * Failure: E_FAIL, If any arguments are invalid, error occurred, or Explorer
459 * does not contain the setting.
460 * E_INVALIDARG, If the buffer is not big enough
462 HRESULT WINAPI GetAcceptLanguagesW( LPWSTR langbuf, LPDWORD buflen)
464 static const WCHAR szkeyW[] = {
465 'S','o','f','t','w','a','r','e','\\',
466 'M','i','c','r','o','s','o','f','t','\\',
467 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
468 'I','n','t','e','r','n','a','t','i','o','n','a','l',0};
469 static const WCHAR valueW[] = {
470 'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0};
471 static const WCHAR enusW[] = {'e','n','-','u','s',0};
472 DWORD mystrlen, mytype;
473 HKEY mykey;
474 HRESULT retval;
475 LCID mylcid;
476 WCHAR *mystr;
478 if(!langbuf || !buflen || !*buflen)
479 return E_FAIL;
481 mystrlen = (*buflen > 20) ? *buflen : 20 ;
482 mystr = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * mystrlen);
483 RegOpenKeyW(HKEY_CURRENT_USER, szkeyW, &mykey);
484 if(RegQueryValueExW(mykey, valueW, 0, &mytype, (PBYTE)mystr, &mystrlen)) {
485 /* Did not find value */
486 mylcid = GetUserDefaultLCID();
487 /* somehow the mylcid translates into "en-us"
488 * this is similar to "LOCALE_SABBREVLANGNAME"
489 * which could be gotten via GetLocaleInfo.
490 * The only problem is LOCALE_SABBREVLANGUAGE" is
491 * a 3 char string (first 2 are country code and third is
492 * letter for "sublanguage", which does not come close to
493 * "en-us"
495 lstrcpyW(mystr, enusW);
496 mystrlen = lstrlenW(mystr);
497 } else {
498 /* handle returned string */
499 FIXME("missing code\n");
501 memcpy( langbuf, mystr, min(*buflen,strlenW(mystr)+1)*sizeof(WCHAR) );
503 if(*buflen > strlenW(mystr)) {
504 *buflen = strlenW(mystr);
505 retval = S_OK;
506 } else {
507 *buflen = 0;
508 retval = E_INVALIDARG;
509 SetLastError(ERROR_INSUFFICIENT_BUFFER);
511 RegCloseKey(mykey);
512 HeapFree(GetProcessHeap(), 0, mystr);
513 return retval;
516 /*************************************************************************
517 * @ [SHLWAPI.14]
519 * Ascii version of GetAcceptLanguagesW.
521 HRESULT WINAPI GetAcceptLanguagesA( LPSTR langbuf, LPDWORD buflen)
523 WCHAR *langbufW;
524 DWORD buflenW, convlen;
525 HRESULT retval;
527 if(!langbuf || !buflen || !*buflen) return E_FAIL;
529 buflenW = *buflen;
530 langbufW = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * buflenW);
531 retval = GetAcceptLanguagesW(langbufW, &buflenW);
533 if (retval == S_OK)
535 convlen = WideCharToMultiByte(CP_ACP, 0, langbufW, -1, langbuf, *buflen, NULL, NULL);
537 else /* copy partial string anyway */
539 convlen = WideCharToMultiByte(CP_ACP, 0, langbufW, *buflen, langbuf, *buflen, NULL, NULL);
540 if (convlen < *buflen) langbuf[convlen] = 0;
542 *buflen = buflenW ? convlen : 0;
544 HeapFree(GetProcessHeap(), 0, langbufW);
545 return retval;
548 /*************************************************************************
549 * @ [SHLWAPI.23]
551 * Convert a GUID to a string.
553 * PARAMS
554 * guid [I] GUID to convert
555 * lpszDest [O] Destination for string
556 * cchMax [I] Length of output buffer
558 * RETURNS
559 * The length of the string created.
561 INT WINAPI SHStringFromGUIDA(REFGUID guid, LPSTR lpszDest, INT cchMax)
563 char xguid[40];
564 INT iLen;
566 TRACE("(%s,%p,%d)\n", debugstr_guid(guid), lpszDest, cchMax);
568 sprintf(xguid, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
569 guid->Data1, guid->Data2, guid->Data3,
570 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
571 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
573 iLen = strlen(xguid) + 1;
575 if (iLen > cchMax)
576 return 0;
577 memcpy(lpszDest, xguid, iLen);
578 return iLen;
581 /*************************************************************************
582 * @ [SHLWAPI.24]
584 * Convert a GUID to a string.
586 * PARAMS
587 * guid [I] GUID to convert
588 * str [O] Destination for string
589 * cmax [I] Length of output buffer
591 * RETURNS
592 * The length of the string created.
594 INT WINAPI SHStringFromGUIDW(REFGUID guid, LPWSTR lpszDest, INT cchMax)
596 WCHAR xguid[40];
597 INT iLen;
598 static const WCHAR wszFormat[] = {'{','%','0','8','l','X','-','%','0','4','X','-','%','0','4','X','-',
599 '%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','%','0','2','X','%','0','2',
600 'X','%','0','2','X','%','0','2','X','}',0};
602 TRACE("(%s,%p,%d)\n", debugstr_guid(guid), lpszDest, cchMax);
604 sprintfW(xguid, wszFormat, guid->Data1, guid->Data2, guid->Data3,
605 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
606 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
608 iLen = strlenW(xguid) + 1;
610 if (iLen > cchMax)
611 return 0;
612 memcpy(lpszDest, xguid, iLen*sizeof(WCHAR));
613 return iLen;
616 /*************************************************************************
617 * @ [SHLWAPI.29]
619 * Determine if a Unicode character is a space.
621 * PARAMS
622 * wc [I] Character to check.
624 * RETURNS
625 * TRUE, if wc is a space,
626 * FALSE otherwise.
628 BOOL WINAPI IsCharSpaceW(WCHAR wc)
630 WORD CharType;
632 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_SPACE);
635 /*************************************************************************
636 * @ [SHLWAPI.30]
638 * Determine if a Unicode character is a blank.
640 * PARAMS
641 * wc [I] Character to check.
643 * RETURNS
644 * TRUE, if wc is a blank,
645 * FALSE otherwise.
648 BOOL WINAPI IsCharBlankW(WCHAR wc)
650 WORD CharType;
652 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_BLANK);
655 /*************************************************************************
656 * @ [SHLWAPI.31]
658 * Determine if a Unicode character is punctuation.
660 * PARAMS
661 * wc [I] Character to check.
663 * RETURNS
664 * TRUE, if wc is punctuation,
665 * FALSE otherwise.
667 BOOL WINAPI IsCharPunctW(WCHAR wc)
669 WORD CharType;
671 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_PUNCT);
674 /*************************************************************************
675 * @ [SHLWAPI.32]
677 * Determine if a Unicode character is a control character.
679 * PARAMS
680 * wc [I] Character to check.
682 * RETURNS
683 * TRUE, if wc is a control character,
684 * FALSE otherwise.
686 BOOL WINAPI IsCharCntrlW(WCHAR wc)
688 WORD CharType;
690 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_CNTRL);
693 /*************************************************************************
694 * @ [SHLWAPI.33]
696 * Determine if a Unicode character is a digit.
698 * PARAMS
699 * wc [I] Character to check.
701 * RETURNS
702 * TRUE, if wc is a digit,
703 * FALSE otherwise.
705 BOOL WINAPI IsCharDigitW(WCHAR wc)
707 WORD CharType;
709 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_DIGIT);
712 /*************************************************************************
713 * @ [SHLWAPI.34]
715 * Determine if a Unicode character is a hex digit.
717 * PARAMS
718 * wc [I] Character to check.
720 * RETURNS
721 * TRUE, if wc is a hex digit,
722 * FALSE otherwise.
724 BOOL WINAPI IsCharXDigitW(WCHAR wc)
726 WORD CharType;
728 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_XDIGIT);
731 /*************************************************************************
732 * @ [SHLWAPI.35]
735 BOOL WINAPI GetStringType3ExW(LPWSTR src, INT count, LPWORD type)
737 return GetStringTypeW(CT_CTYPE3, src, count, type);
740 /*************************************************************************
741 * @ [SHLWAPI.151]
743 * Compare two Ascii strings up to a given length.
745 * PARAMS
746 * lpszSrc [I] Source string
747 * lpszCmp [I] String to compare to lpszSrc
748 * len [I] Maximum length
750 * RETURNS
751 * A number greater than, less than or equal to 0 depending on whether
752 * lpszSrc is greater than, less than or equal to lpszCmp.
754 DWORD WINAPI StrCmpNCA(LPCSTR lpszSrc, LPCSTR lpszCmp, INT len)
756 return StrCmpNA(lpszSrc, lpszCmp, len);
759 /*************************************************************************
760 * @ [SHLWAPI.152]
762 * Unicode version of StrCmpNCA.
764 DWORD WINAPI StrCmpNCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, INT len)
766 return StrCmpNW(lpszSrc, lpszCmp, len);
769 /*************************************************************************
770 * @ [SHLWAPI.153]
772 * Compare two Ascii strings up to a given length, ignoring case.
774 * PARAMS
775 * lpszSrc [I] Source string
776 * lpszCmp [I] String to compare to lpszSrc
777 * len [I] Maximum length
779 * RETURNS
780 * A number greater than, less than or equal to 0 depending on whether
781 * lpszSrc is greater than, less than or equal to lpszCmp.
783 DWORD WINAPI StrCmpNICA(LPCSTR lpszSrc, LPCSTR lpszCmp, DWORD len)
785 return StrCmpNIA(lpszSrc, lpszCmp, len);
788 /*************************************************************************
789 * @ [SHLWAPI.154]
791 * Unicode version of StrCmpNICA.
793 DWORD WINAPI StrCmpNICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, DWORD len)
795 return StrCmpNIW(lpszSrc, lpszCmp, len);
798 /*************************************************************************
799 * @ [SHLWAPI.155]
801 * Compare two Ascii strings.
803 * PARAMS
804 * lpszSrc [I] Source string
805 * lpszCmp [I] String to compare to lpszSrc
807 * RETURNS
808 * A number greater than, less than or equal to 0 depending on whether
809 * lpszSrc is greater than, less than or equal to lpszCmp.
811 DWORD WINAPI StrCmpCA(LPCSTR lpszSrc, LPCSTR lpszCmp)
813 return lstrcmpA(lpszSrc, lpszCmp);
816 /*************************************************************************
817 * @ [SHLWAPI.156]
819 * Unicode version of StrCmpCA.
821 DWORD WINAPI StrCmpCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp)
823 return lstrcmpW(lpszSrc, lpszCmp);
826 /*************************************************************************
827 * @ [SHLWAPI.157]
829 * Compare two Ascii strings, ignoring case.
831 * PARAMS
832 * lpszSrc [I] Source string
833 * lpszCmp [I] String to compare to lpszSrc
835 * RETURNS
836 * A number greater than, less than or equal to 0 depending on whether
837 * lpszSrc is greater than, less than or equal to lpszCmp.
839 DWORD WINAPI StrCmpICA(LPCSTR lpszSrc, LPCSTR lpszCmp)
841 return lstrcmpiA(lpszSrc, lpszCmp);
844 /*************************************************************************
845 * @ [SHLWAPI.158]
847 * Unicode version of StrCmpICA.
849 DWORD WINAPI StrCmpICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp)
851 return lstrcmpiW(lpszSrc, lpszCmp);
854 /*************************************************************************
855 * @ [SHLWAPI.160]
857 * Get an identification string for the OS and explorer.
859 * PARAMS
860 * lpszDest [O] Destination for Id string
861 * dwDestLen [I] Length of lpszDest
863 * RETURNS
864 * TRUE, If the string was created successfully
865 * FALSE, Otherwise
867 BOOL WINAPI SHAboutInfoA(LPSTR lpszDest, DWORD dwDestLen)
869 WCHAR buff[2084];
871 TRACE("(%p,%d)\n", lpszDest, dwDestLen);
873 if (lpszDest && SHAboutInfoW(buff, dwDestLen))
875 WideCharToMultiByte(CP_ACP, 0, buff, -1, lpszDest, dwDestLen, NULL, NULL);
876 return TRUE;
878 return FALSE;
881 /*************************************************************************
882 * @ [SHLWAPI.161]
884 * Unicode version of SHAboutInfoA.
886 BOOL WINAPI SHAboutInfoW(LPWSTR lpszDest, DWORD dwDestLen)
888 static const WCHAR szIEKey[] = { 'S','O','F','T','W','A','R','E','\\',
889 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
890 ' ','E','x','p','l','o','r','e','r','\0' };
891 static const WCHAR szWinNtKey[] = { 'S','O','F','T','W','A','R','E','\\',
892 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s',' ',
893 'N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
894 static const WCHAR szWinKey[] = { 'S','O','F','T','W','A','R','E','\\',
895 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
896 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
897 static const WCHAR szRegKey[] = { 'S','O','F','T','W','A','R','E','\\',
898 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
899 ' ','E','x','p','l','o','r','e','r','\\',
900 'R','e','g','i','s','t','r','a','t','i','o','n','\0' };
901 static const WCHAR szVersion[] = { 'V','e','r','s','i','o','n','\0' };
902 static const WCHAR szCustomized[] = { 'C','u','s','t','o','m','i','z','e','d',
903 'V','e','r','s','i','o','n','\0' };
904 static const WCHAR szOwner[] = { 'R','e','g','i','s','t','e','r','e','d',
905 'O','w','n','e','r','\0' };
906 static const WCHAR szOrg[] = { 'R','e','g','i','s','t','e','r','e','d',
907 'O','r','g','a','n','i','z','a','t','i','o','n','\0' };
908 static const WCHAR szProduct[] = { 'P','r','o','d','u','c','t','I','d','\0' };
909 static const WCHAR szUpdate[] = { 'I','E','A','K',
910 'U','p','d','a','t','e','U','r','l','\0' };
911 static const WCHAR szHelp[] = { 'I','E','A','K',
912 'H','e','l','p','S','t','r','i','n','g','\0' };
913 WCHAR buff[2084];
914 HKEY hReg;
915 DWORD dwType, dwLen;
917 TRACE("(%p,%d)\n", lpszDest, dwDestLen);
919 if (!lpszDest)
920 return FALSE;
922 *lpszDest = '\0';
924 /* Try the NT key first, followed by 95/98 key */
925 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinNtKey, 0, KEY_READ, &hReg) &&
926 RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinKey, 0, KEY_READ, &hReg))
927 return FALSE;
929 /* OS Version */
930 buff[0] = '\0';
931 dwLen = 30;
932 if (!SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey, szVersion, &dwType, buff, &dwLen))
934 DWORD dwStrLen = strlenW(buff);
935 dwLen = 30 - dwStrLen;
936 SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey,
937 szCustomized, &dwType, buff+dwStrLen, &dwLen);
939 StrCatBuffW(lpszDest, buff, dwDestLen);
941 /* ~Registered Owner */
942 buff[0] = '~';
943 dwLen = 256;
944 if (SHGetValueW(hReg, szOwner, 0, &dwType, buff+1, &dwLen))
945 buff[1] = '\0';
946 StrCatBuffW(lpszDest, buff, dwDestLen);
948 /* ~Registered Organization */
949 dwLen = 256;
950 if (SHGetValueW(hReg, szOrg, 0, &dwType, buff+1, &dwLen))
951 buff[1] = '\0';
952 StrCatBuffW(lpszDest, buff, dwDestLen);
954 /* FIXME: Not sure where this number comes from */
955 buff[0] = '~';
956 buff[1] = '0';
957 buff[2] = '\0';
958 StrCatBuffW(lpszDest, buff, dwDestLen);
960 /* ~Product Id */
961 dwLen = 256;
962 if (SHGetValueW(HKEY_LOCAL_MACHINE, szRegKey, szProduct, &dwType, buff+1, &dwLen))
963 buff[1] = '\0';
964 StrCatBuffW(lpszDest, buff, dwDestLen);
966 /* ~IE Update Url */
967 dwLen = 2048;
968 if(SHGetValueW(HKEY_LOCAL_MACHINE, szWinKey, szUpdate, &dwType, buff+1, &dwLen))
969 buff[1] = '\0';
970 StrCatBuffW(lpszDest, buff, dwDestLen);
972 /* ~IE Help String */
973 dwLen = 256;
974 if(SHGetValueW(hReg, szHelp, 0, &dwType, buff+1, &dwLen))
975 buff[1] = '\0';
976 StrCatBuffW(lpszDest, buff, dwDestLen);
978 RegCloseKey(hReg);
979 return TRUE;
982 /*************************************************************************
983 * @ [SHLWAPI.163]
985 * Call IOleCommandTarget_QueryStatus() on an object.
987 * PARAMS
988 * lpUnknown [I] Object supporting the IOleCommandTarget interface
989 * pguidCmdGroup [I] GUID for the command group
990 * cCmds [I]
991 * prgCmds [O] Commands
992 * pCmdText [O] Command text
994 * RETURNS
995 * Success: S_OK.
996 * Failure: E_FAIL, if lpUnknown is NULL.
997 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
998 * Otherwise, an error code from IOleCommandTarget_QueryStatus().
1000 HRESULT WINAPI IUnknown_QueryStatus(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
1001 ULONG cCmds, OLECMD *prgCmds, OLECMDTEXT* pCmdText)
1003 HRESULT hRet = E_FAIL;
1005 TRACE("(%p,%p,%d,%p,%p)\n",lpUnknown, pguidCmdGroup, cCmds, prgCmds, pCmdText);
1007 if (lpUnknown)
1009 IOleCommandTarget* lpOle;
1011 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
1012 (void**)&lpOle);
1014 if (SUCCEEDED(hRet) && lpOle)
1016 hRet = IOleCommandTarget_QueryStatus(lpOle, pguidCmdGroup, cCmds,
1017 prgCmds, pCmdText);
1018 IOleCommandTarget_Release(lpOle);
1021 return hRet;
1024 /*************************************************************************
1025 * @ [SHLWAPI.164]
1027 * Call IOleCommandTarget_Exec() on an object.
1029 * PARAMS
1030 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1031 * pguidCmdGroup [I] GUID for the command group
1033 * RETURNS
1034 * Success: S_OK.
1035 * Failure: E_FAIL, if lpUnknown is NULL.
1036 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1037 * Otherwise, an error code from IOleCommandTarget_Exec().
1039 HRESULT WINAPI IUnknown_Exec(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
1040 DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
1041 VARIANT* pvaOut)
1043 HRESULT hRet = E_FAIL;
1045 TRACE("(%p,%p,%d,%d,%p,%p)\n",lpUnknown, pguidCmdGroup, nCmdID,
1046 nCmdexecopt, pvaIn, pvaOut);
1048 if (lpUnknown)
1050 IOleCommandTarget* lpOle;
1052 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
1053 (void**)&lpOle);
1054 if (SUCCEEDED(hRet) && lpOle)
1056 hRet = IOleCommandTarget_Exec(lpOle, pguidCmdGroup, nCmdID,
1057 nCmdexecopt, pvaIn, pvaOut);
1058 IOleCommandTarget_Release(lpOle);
1061 return hRet;
1064 /*************************************************************************
1065 * @ [SHLWAPI.165]
1067 * Retrieve, modify, and re-set a value from a window.
1069 * PARAMS
1070 * hWnd [I] Window to get value from
1071 * offset [I] Offset of value
1072 * wMask [I] Mask for uiFlags
1073 * wFlags [I] Bits to set in window value
1075 * RETURNS
1076 * The new value as it was set, or 0 if any parameter is invalid.
1078 * NOTES
1079 * Any bits set in uiMask are cleared from the value, then any bits set in
1080 * uiFlags are set in the value.
1082 LONG WINAPI SHSetWindowBits(HWND hwnd, INT offset, UINT wMask, UINT wFlags)
1084 LONG ret = GetWindowLongA(hwnd, offset);
1085 LONG newFlags = (wFlags & wMask) | (ret & ~wFlags);
1087 if (newFlags != ret)
1088 ret = SetWindowLongA(hwnd, offset, newFlags);
1089 return ret;
1092 /*************************************************************************
1093 * @ [SHLWAPI.167]
1095 * Change a window's parent.
1097 * PARAMS
1098 * hWnd [I] Window to change parent of
1099 * hWndParent [I] New parent window
1101 * RETURNS
1102 * The old parent of hWnd.
1104 * NOTES
1105 * If hWndParent is NULL (desktop), the window style is changed to WS_POPUP.
1106 * If hWndParent is NOT NULL then we set the WS_CHILD style.
1108 HWND WINAPI SHSetParentHwnd(HWND hWnd, HWND hWndParent)
1110 TRACE("%p, %p\n", hWnd, hWndParent);
1112 if(GetParent(hWnd) == hWndParent)
1113 return 0;
1115 if(hWndParent)
1116 SHSetWindowBits(hWnd, GWL_STYLE, WS_CHILD, WS_CHILD);
1117 else
1118 SHSetWindowBits(hWnd, GWL_STYLE, WS_POPUP, WS_POPUP);
1120 return SetParent(hWnd, hWndParent);
1123 /*************************************************************************
1124 * @ [SHLWAPI.168]
1126 * Locate and advise a connection point in an IConnectionPointContainer object.
1128 * PARAMS
1129 * lpUnkSink [I] Sink for the connection point advise call
1130 * riid [I] REFIID of connection point to advise
1131 * fConnect [I] TRUE = Connection being establisted, FALSE = broken
1132 * lpUnknown [I] Object supporting the IConnectionPointContainer interface
1133 * lpCookie [O] Pointer to connection point cookie
1134 * lppCP [O] Destination for the IConnectionPoint found
1136 * RETURNS
1137 * Success: S_OK. If lppCP is non-NULL, it is filled with the IConnectionPoint
1138 * that was advised. The caller is responsible for releasing it.
1139 * Failure: E_FAIL, if any arguments are invalid.
1140 * E_NOINTERFACE, if lpUnknown isn't an IConnectionPointContainer,
1141 * Or an HRESULT error code if any call fails.
1143 HRESULT WINAPI ConnectToConnectionPoint(IUnknown* lpUnkSink, REFIID riid, BOOL fConnect,
1144 IUnknown* lpUnknown, LPDWORD lpCookie,
1145 IConnectionPoint **lppCP)
1147 HRESULT hRet;
1148 IConnectionPointContainer* lpContainer;
1149 IConnectionPoint *lpCP;
1151 if(!lpUnknown || (fConnect && !lpUnkSink))
1152 return E_FAIL;
1154 if(lppCP)
1155 *lppCP = NULL;
1157 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer,
1158 (void**)&lpContainer);
1159 if (SUCCEEDED(hRet))
1161 hRet = IConnectionPointContainer_FindConnectionPoint(lpContainer, riid, &lpCP);
1163 if (SUCCEEDED(hRet))
1165 if(!fConnect)
1166 hRet = IConnectionPoint_Unadvise(lpCP, *lpCookie);
1167 else
1168 hRet = IConnectionPoint_Advise(lpCP, lpUnkSink, lpCookie);
1170 if (FAILED(hRet))
1171 *lpCookie = 0;
1173 if (lppCP && SUCCEEDED(hRet))
1174 *lppCP = lpCP; /* Caller keeps the interface */
1175 else
1176 IConnectionPoint_Release(lpCP); /* Release it */
1179 IUnknown_Release(lpContainer);
1181 return hRet;
1184 /*************************************************************************
1185 * @ [SHLWAPI.169]
1187 * Release an interface.
1189 * PARAMS
1190 * lpUnknown [I] Object to release
1192 * RETURNS
1193 * Nothing.
1195 DWORD WINAPI IUnknown_AtomicRelease(IUnknown ** lpUnknown)
1197 IUnknown *temp;
1199 TRACE("(%p)\n",lpUnknown);
1201 if(!lpUnknown || !*((LPDWORD)lpUnknown)) return 0;
1202 temp = *lpUnknown;
1203 *lpUnknown = NULL;
1205 TRACE("doing Release\n");
1207 return IUnknown_Release(temp);
1210 /*************************************************************************
1211 * @ [SHLWAPI.170]
1213 * Skip '//' if present in a string.
1215 * PARAMS
1216 * lpszSrc [I] String to check for '//'
1218 * RETURNS
1219 * Success: The next character after the '//' or the string if not present
1220 * Failure: NULL, if lpszStr is NULL.
1222 LPCSTR WINAPI PathSkipLeadingSlashesA(LPCSTR lpszSrc)
1224 if (lpszSrc && lpszSrc[0] == '/' && lpszSrc[1] == '/')
1225 lpszSrc += 2;
1226 return lpszSrc;
1229 /*************************************************************************
1230 * @ [SHLWAPI.171]
1232 * Check if two interfaces come from the same object.
1234 * PARAMS
1235 * lpInt1 [I] Interface to check against lpInt2.
1236 * lpInt2 [I] Interface to check against lpInt1.
1238 * RETURNS
1239 * TRUE, If the interfaces come from the same object.
1240 * FALSE Otherwise.
1242 BOOL WINAPI SHIsSameObject(IUnknown* lpInt1, IUnknown* lpInt2)
1244 LPVOID lpUnknown1, lpUnknown2;
1246 TRACE("%p %p\n", lpInt1, lpInt2);
1248 if (!lpInt1 || !lpInt2)
1249 return FALSE;
1251 if (lpInt1 == lpInt2)
1252 return TRUE;
1254 if (FAILED(IUnknown_QueryInterface(lpInt1, &IID_IUnknown, &lpUnknown1)))
1255 return FALSE;
1257 if (FAILED(IUnknown_QueryInterface(lpInt2, &IID_IUnknown, &lpUnknown2)))
1258 return FALSE;
1260 if (lpUnknown1 == lpUnknown2)
1261 return TRUE;
1263 return FALSE;
1266 /*************************************************************************
1267 * @ [SHLWAPI.172]
1269 * Get the window handle of an object.
1271 * PARAMS
1272 * lpUnknown [I] Object to get the window handle of
1273 * lphWnd [O] Destination for window handle
1275 * RETURNS
1276 * Success: S_OK. lphWnd contains the objects window handle.
1277 * Failure: An HRESULT error code.
1279 * NOTES
1280 * lpUnknown is expected to support one of the following interfaces:
1281 * IOleWindow(), IInternetSecurityMgrSite(), or IShellView().
1283 HRESULT WINAPI IUnknown_GetWindow(IUnknown *lpUnknown, HWND *lphWnd)
1285 IUnknown *lpOle;
1286 HRESULT hRet = E_FAIL;
1288 TRACE("(%p,%p)\n", lpUnknown, lphWnd);
1290 if (!lpUnknown)
1291 return hRet;
1293 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleWindow, (void**)&lpOle);
1295 if (FAILED(hRet))
1297 hRet = IUnknown_QueryInterface(lpUnknown,&IID_IShellView, (void**)&lpOle);
1299 if (FAILED(hRet))
1301 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInternetSecurityMgrSite,
1302 (void**)&lpOle);
1306 if (SUCCEEDED(hRet))
1308 /* Lazyness here - Since GetWindow() is the first method for the above 3
1309 * interfaces, we use the same call for them all.
1311 hRet = IOleWindow_GetWindow((IOleWindow*)lpOle, lphWnd);
1312 IUnknown_Release(lpOle);
1313 if (lphWnd)
1314 TRACE("Returning HWND=%p\n", *lphWnd);
1317 return hRet;
1320 /*************************************************************************
1321 * @ [SHLWAPI.173]
1323 * Call a method on as as yet unidentified object.
1325 * PARAMS
1326 * pUnk [I] Object supporting the unidentified interface,
1327 * arg [I] Argument for the call on the object.
1329 * RETURNS
1330 * S_OK.
1332 HRESULT WINAPI IUnknown_SetOwner(IUnknown *pUnk, ULONG arg)
1334 static const GUID guid_173 = {
1335 0x5836fb00, 0x8187, 0x11cf, { 0xa1,0x2b,0x00,0xaa,0x00,0x4a,0xe8,0x37 }
1337 IMalloc *pUnk2;
1339 TRACE("(%p,%d)\n", pUnk, arg);
1341 /* Note: arg may not be a ULONG and pUnk2 is for sure not an IMalloc -
1342 * We use this interface as its vtable entry is compatible with the
1343 * object in question.
1344 * FIXME: Find out what this object is and where it should be defined.
1346 if (pUnk &&
1347 SUCCEEDED(IUnknown_QueryInterface(pUnk, &guid_173, (void**)&pUnk2)))
1349 IMalloc_Alloc(pUnk2, arg); /* Faked call!! */
1350 IMalloc_Release(pUnk2);
1352 return S_OK;
1355 /*************************************************************************
1356 * @ [SHLWAPI.174]
1358 * Call either IObjectWithSite_SetSite() or IInternetSecurityManager_SetSecuritySite() on
1359 * an object.
1362 HRESULT WINAPI IUnknown_SetSite(
1363 IUnknown *obj, /* [in] OLE object */
1364 IUnknown *site) /* [in] Site interface */
1366 HRESULT hr;
1367 IObjectWithSite *iobjwithsite;
1368 IInternetSecurityManager *isecmgr;
1370 if (!obj) return E_FAIL;
1372 hr = IUnknown_QueryInterface(obj, &IID_IObjectWithSite, (LPVOID *)&iobjwithsite);
1373 TRACE("IID_IObjectWithSite QI ret=%08x, %p\n", hr, iobjwithsite);
1374 if (SUCCEEDED(hr))
1376 hr = IObjectWithSite_SetSite(iobjwithsite, site);
1377 TRACE("done IObjectWithSite_SetSite ret=%08x\n", hr);
1378 IUnknown_Release(iobjwithsite);
1380 else
1382 hr = IUnknown_QueryInterface(obj, &IID_IInternetSecurityManager, (LPVOID *)&isecmgr);
1383 TRACE("IID_IInternetSecurityManager QI ret=%08x, %p\n", hr, isecmgr);
1384 if (FAILED(hr)) return hr;
1386 hr = IInternetSecurityManager_SetSecuritySite(isecmgr, (IInternetSecurityMgrSite *)site);
1387 TRACE("done IInternetSecurityManager_SetSecuritySite ret=%08x\n", hr);
1388 IUnknown_Release(isecmgr);
1390 return hr;
1393 /*************************************************************************
1394 * @ [SHLWAPI.175]
1396 * Call IPersist_GetClassID() on an object.
1398 * PARAMS
1399 * lpUnknown [I] Object supporting the IPersist interface
1400 * lpClassId [O] Destination for Class Id
1402 * RETURNS
1403 * Success: S_OK. lpClassId contains the Class Id requested.
1404 * Failure: E_FAIL, If lpUnknown is NULL,
1405 * E_NOINTERFACE If lpUnknown does not support IPersist,
1406 * Or an HRESULT error code.
1408 HRESULT WINAPI IUnknown_GetClassID(IUnknown *lpUnknown, CLSID* lpClassId)
1410 IPersist* lpPersist;
1411 HRESULT hRet = E_FAIL;
1413 TRACE("(%p,%p)\n", lpUnknown, debugstr_guid(lpClassId));
1415 if (lpUnknown)
1417 hRet = IUnknown_QueryInterface(lpUnknown,&IID_IPersist,(void**)&lpPersist);
1418 if (SUCCEEDED(hRet))
1420 IPersist_GetClassID(lpPersist, lpClassId);
1421 IPersist_Release(lpPersist);
1424 return hRet;
1427 /*************************************************************************
1428 * @ [SHLWAPI.176]
1430 * Retrieve a Service Interface from an object.
1432 * PARAMS
1433 * lpUnknown [I] Object to get an IServiceProvider interface from
1434 * sid [I] Service ID for IServiceProvider_QueryService() call
1435 * riid [I] Function requested for QueryService call
1436 * lppOut [O] Destination for the service interface pointer
1438 * RETURNS
1439 * Success: S_OK. lppOut contains an object providing the requested service
1440 * Failure: An HRESULT error code
1442 * NOTES
1443 * lpUnknown is expected to support the IServiceProvider interface.
1445 HRESULT WINAPI IUnknown_QueryService(IUnknown* lpUnknown, REFGUID sid, REFIID riid,
1446 LPVOID *lppOut)
1448 IServiceProvider* pService = NULL;
1449 HRESULT hRet;
1451 if (!lppOut)
1452 return E_FAIL;
1454 *lppOut = NULL;
1456 if (!lpUnknown)
1457 return E_FAIL;
1459 /* Get an IServiceProvider interface from the object */
1460 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IServiceProvider,
1461 (LPVOID*)&pService);
1463 if (hRet == S_OK && pService)
1465 TRACE("QueryInterface returned (IServiceProvider*)%p\n", pService);
1467 /* Get a Service interface from the object */
1468 hRet = IServiceProvider_QueryService(pService, sid, riid, lppOut);
1470 TRACE("(IServiceProvider*)%p returned (IUnknown*)%p\n", pService, *lppOut);
1472 /* Release the IServiceProvider interface */
1473 IUnknown_Release(pService);
1475 return hRet;
1478 /*************************************************************************
1479 * @ [SHLWAPI.479]
1481 * Call an object's UIActivateIO method.
1483 * PARAMS
1484 * unknown [I] Object to call the UIActivateIO method on
1485 * activate [I] Parameter for UIActivateIO call
1486 * msg [I] Parameter for UIActivateIO call
1488 * RETURNS
1489 * Success: Value of UI_ActivateIO call
1490 * Failure: An HRESULT error code
1492 * NOTES
1493 * unknown is expected to support the IInputObject interface.
1495 HRESULT WINAPI IUnknown_UIActivateIO(IUnknown *unknown, BOOL activate, LPMSG msg)
1497 IInputObject* object = NULL;
1498 HRESULT ret;
1500 if (!unknown)
1501 return E_FAIL;
1503 /* Get an IInputObject interface from the object */
1504 ret = IUnknown_QueryInterface(unknown, &IID_IInputObject, (LPVOID*) &object);
1506 if (ret == S_OK)
1508 ret = IInputObject_UIActivateIO(object, activate, msg);
1509 IUnknown_Release(object);
1512 return ret;
1515 /*************************************************************************
1516 * @ [SHLWAPI.177]
1518 * Loads a popup menu.
1520 * PARAMS
1521 * hInst [I] Instance handle
1522 * szName [I] Menu name
1524 * RETURNS
1525 * Success: TRUE.
1526 * Failure: FALSE.
1528 BOOL WINAPI SHLoadMenuPopup(HINSTANCE hInst, LPCWSTR szName)
1530 HMENU hMenu;
1532 if ((hMenu = LoadMenuW(hInst, szName)))
1534 if (GetSubMenu(hMenu, 0))
1535 RemoveMenu(hMenu, 0, MF_BYPOSITION);
1537 DestroyMenu(hMenu);
1538 return TRUE;
1540 return FALSE;
1543 typedef struct _enumWndData
1545 UINT uiMsgId;
1546 WPARAM wParam;
1547 LPARAM lParam;
1548 LRESULT (WINAPI *pfnPost)(HWND,UINT,WPARAM,LPARAM);
1549 } enumWndData;
1551 /* Callback for SHLWAPI_178 */
1552 static BOOL CALLBACK SHLWAPI_EnumChildProc(HWND hWnd, LPARAM lParam)
1554 enumWndData *data = (enumWndData *)lParam;
1556 TRACE("(%p,%p)\n", hWnd, data);
1557 data->pfnPost(hWnd, data->uiMsgId, data->wParam, data->lParam);
1558 return TRUE;
1561 /*************************************************************************
1562 * @ [SHLWAPI.178]
1564 * Send or post a message to every child of a window.
1566 * PARAMS
1567 * hWnd [I] Window whose children will get the messages
1568 * uiMsgId [I] Message Id
1569 * wParam [I] WPARAM of message
1570 * lParam [I] LPARAM of message
1571 * bSend [I] TRUE = Use SendMessageA(), FALSE = Use PostMessageA()
1573 * RETURNS
1574 * Nothing.
1576 * NOTES
1577 * The appropriate ASCII or Unicode function is called for the window.
1579 void WINAPI SHPropagateMessage(HWND hWnd, UINT uiMsgId, WPARAM wParam, LPARAM lParam, BOOL bSend)
1581 enumWndData data;
1583 TRACE("(%p,%u,%ld,%ld,%d)\n", hWnd, uiMsgId, wParam, lParam, bSend);
1585 if(hWnd)
1587 data.uiMsgId = uiMsgId;
1588 data.wParam = wParam;
1589 data.lParam = lParam;
1591 if (bSend)
1592 data.pfnPost = IsWindowUnicode(hWnd) ? (void*)SendMessageW : (void*)SendMessageA;
1593 else
1594 data.pfnPost = IsWindowUnicode(hWnd) ? (void*)PostMessageW : (void*)PostMessageA;
1596 EnumChildWindows(hWnd, SHLWAPI_EnumChildProc, (LPARAM)&data);
1600 /*************************************************************************
1601 * @ [SHLWAPI.180]
1603 * Remove all sub-menus from a menu.
1605 * PARAMS
1606 * hMenu [I] Menu to remove sub-menus from
1608 * RETURNS
1609 * Success: 0. All sub-menus under hMenu are removed
1610 * Failure: -1, if any parameter is invalid
1612 DWORD WINAPI SHRemoveAllSubMenus(HMENU hMenu)
1614 int iItemCount = GetMenuItemCount(hMenu) - 1;
1615 while (iItemCount >= 0)
1617 HMENU hSubMenu = GetSubMenu(hMenu, iItemCount);
1618 if (hSubMenu)
1619 RemoveMenu(hMenu, iItemCount, MF_BYPOSITION);
1620 iItemCount--;
1622 return iItemCount;
1625 /*************************************************************************
1626 * @ [SHLWAPI.181]
1628 * Enable or disable a menu item.
1630 * PARAMS
1631 * hMenu [I] Menu holding menu item
1632 * uID [I] ID of menu item to enable/disable
1633 * bEnable [I] Whether to enable (TRUE) or disable (FALSE) the item.
1635 * RETURNS
1636 * The return code from EnableMenuItem.
1638 UINT WINAPI SHEnableMenuItem(HMENU hMenu, UINT wItemID, BOOL bEnable)
1640 return EnableMenuItem(hMenu, wItemID, bEnable ? MF_ENABLED : MF_GRAYED);
1643 /*************************************************************************
1644 * @ [SHLWAPI.182]
1646 * Check or uncheck a menu item.
1648 * PARAMS
1649 * hMenu [I] Menu holding menu item
1650 * uID [I] ID of menu item to check/uncheck
1651 * bCheck [I] Whether to check (TRUE) or uncheck (FALSE) the item.
1653 * RETURNS
1654 * The return code from CheckMenuItem.
1656 DWORD WINAPI SHCheckMenuItem(HMENU hMenu, UINT uID, BOOL bCheck)
1658 return CheckMenuItem(hMenu, uID, bCheck ? MF_CHECKED : MF_UNCHECKED);
1661 /*************************************************************************
1662 * @ [SHLWAPI.183]
1664 * Register a window class if it isn't already.
1666 * PARAMS
1667 * lpWndClass [I] Window class to register
1669 * RETURNS
1670 * The result of the RegisterClassA call.
1672 DWORD WINAPI SHRegisterClassA(WNDCLASSA *wndclass)
1674 WNDCLASSA wca;
1675 if (GetClassInfoA(wndclass->hInstance, wndclass->lpszClassName, &wca))
1676 return TRUE;
1677 return (DWORD)RegisterClassA(wndclass);
1680 /*************************************************************************
1681 * @ [SHLWAPI.186]
1683 BOOL WINAPI SHSimulateDrop(IDropTarget *pDrop, IDataObject *pDataObj,
1684 DWORD grfKeyState, PPOINTL lpPt, DWORD* pdwEffect)
1686 DWORD dwEffect = DROPEFFECT_LINK | DROPEFFECT_MOVE | DROPEFFECT_COPY;
1687 POINTL pt = { 0, 0 };
1689 if (!lpPt)
1690 lpPt = &pt;
1692 if (!pdwEffect)
1693 pdwEffect = &dwEffect;
1695 IDropTarget_DragEnter(pDrop, pDataObj, grfKeyState, *lpPt, pdwEffect);
1697 if (*pdwEffect)
1698 return IDropTarget_Drop(pDrop, pDataObj, grfKeyState, *lpPt, pdwEffect);
1700 IDropTarget_DragLeave(pDrop);
1701 return TRUE;
1704 /*************************************************************************
1705 * @ [SHLWAPI.187]
1707 * Call IPersistPropertyBag_Load() on an object.
1709 * PARAMS
1710 * lpUnknown [I] Object supporting the IPersistPropertyBag interface
1711 * lpPropBag [O] Destination for loaded IPropertyBag
1713 * RETURNS
1714 * Success: S_OK.
1715 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1717 DWORD WINAPI SHLoadFromPropertyBag(IUnknown *lpUnknown, IPropertyBag* lpPropBag)
1719 IPersistPropertyBag* lpPPBag;
1720 HRESULT hRet = E_FAIL;
1722 TRACE("(%p,%p)\n", lpUnknown, lpPropBag);
1724 if (lpUnknown)
1726 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IPersistPropertyBag,
1727 (void**)&lpPPBag);
1728 if (SUCCEEDED(hRet) && lpPPBag)
1730 hRet = IPersistPropertyBag_Load(lpPPBag, lpPropBag, NULL);
1731 IPersistPropertyBag_Release(lpPPBag);
1734 return hRet;
1737 /*************************************************************************
1738 * @ [SHLWAPI.188]
1740 * Call IOleControlSite_TranslateAccelerator() on an object.
1742 * PARAMS
1743 * lpUnknown [I] Object supporting the IOleControlSite interface.
1744 * lpMsg [I] Key message to be processed.
1745 * dwModifiers [I] Flags containing the state of the modifier keys.
1747 * RETURNS
1748 * Success: S_OK.
1749 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
1751 HRESULT WINAPI IUnknown_TranslateAcceleratorOCS(IUnknown *lpUnknown, LPMSG lpMsg, DWORD dwModifiers)
1753 IOleControlSite* lpCSite = NULL;
1754 HRESULT hRet = E_INVALIDARG;
1756 TRACE("(%p,%p,0x%08x)\n", lpUnknown, lpMsg, dwModifiers);
1757 if (lpUnknown)
1759 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleControlSite,
1760 (void**)&lpCSite);
1761 if (SUCCEEDED(hRet) && lpCSite)
1763 hRet = IOleControlSite_TranslateAccelerator(lpCSite, lpMsg, dwModifiers);
1764 IOleControlSite_Release(lpCSite);
1767 return hRet;
1771 /*************************************************************************
1772 * @ [SHLWAPI.189]
1774 * Call IOleControlSite_OnFocus() on an object.
1776 * PARAMS
1777 * lpUnknown [I] Object supporting the IOleControlSite interface.
1778 * fGotFocus [I] Whether focus was gained (TRUE) or lost (FALSE).
1780 * RETURNS
1781 * Success: S_OK.
1782 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1784 HRESULT WINAPI IUnknown_OnFocusOCS(IUnknown *lpUnknown, BOOL fGotFocus)
1786 IOleControlSite* lpCSite = NULL;
1787 HRESULT hRet = E_FAIL;
1789 TRACE("(%p,%s)\n", lpUnknown, fGotFocus ? "TRUE" : "FALSE");
1790 if (lpUnknown)
1792 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleControlSite,
1793 (void**)&lpCSite);
1794 if (SUCCEEDED(hRet) && lpCSite)
1796 hRet = IOleControlSite_OnFocus(lpCSite, fGotFocus);
1797 IOleControlSite_Release(lpCSite);
1800 return hRet;
1803 /*************************************************************************
1804 * @ [SHLWAPI.190]
1806 HRESULT WINAPI IUnknown_HandleIRestrict(LPUNKNOWN lpUnknown, PVOID lpArg1,
1807 PVOID lpArg2, PVOID lpArg3, PVOID lpArg4)
1809 /* FIXME: {D12F26B2-D90A-11D0-830D-00AA005B4383} - What object does this represent? */
1810 static const DWORD service_id[] = { 0xd12f26b2, 0x11d0d90a, 0xaa000d83, 0x83435b00 };
1811 /* FIXME: {D12F26B1-D90A-11D0-830D-00AA005B4383} - Also Unknown/undocumented */
1812 static const DWORD function_id[] = { 0xd12f26b1, 0x11d0d90a, 0xaa000d83, 0x83435b00 };
1813 HRESULT hRet = E_INVALIDARG;
1814 LPUNKNOWN lpUnkInner = NULL; /* FIXME: Real type is unknown */
1816 TRACE("(%p,%p,%p,%p,%p)\n", lpUnknown, lpArg1, lpArg2, lpArg3, lpArg4);
1818 if (lpUnknown && lpArg4)
1820 hRet = IUnknown_QueryService(lpUnknown, (REFGUID)service_id,
1821 (REFGUID)function_id, (void**)&lpUnkInner);
1823 if (SUCCEEDED(hRet) && lpUnkInner)
1825 /* FIXME: The type of service object requested is unknown, however
1826 * testing shows that its first method is called with 4 parameters.
1827 * Fake this by using IParseDisplayName_ParseDisplayName since the
1828 * signature and position in the vtable matches our unknown object type.
1830 hRet = IParseDisplayName_ParseDisplayName((LPPARSEDISPLAYNAME)lpUnkInner,
1831 lpArg1, lpArg2, lpArg3, lpArg4);
1832 IUnknown_Release(lpUnkInner);
1835 return hRet;
1838 /*************************************************************************
1839 * @ [SHLWAPI.192]
1841 * Get a sub-menu from a menu item.
1843 * PARAMS
1844 * hMenu [I] Menu to get sub-menu from
1845 * uID [I] ID of menu item containing sub-menu
1847 * RETURNS
1848 * The sub-menu of the item, or a NULL handle if any parameters are invalid.
1850 HMENU WINAPI SHGetMenuFromID(HMENU hMenu, UINT uID)
1852 MENUITEMINFOW mi;
1854 TRACE("(%p,%u)\n", hMenu, uID);
1856 mi.cbSize = sizeof(mi);
1857 mi.fMask = MIIM_SUBMENU;
1859 if (!GetMenuItemInfoW(hMenu, uID, FALSE, &mi))
1860 return NULL;
1862 return mi.hSubMenu;
1865 /*************************************************************************
1866 * @ [SHLWAPI.193]
1868 * Get the color depth of the primary display.
1870 * PARAMS
1871 * None.
1873 * RETURNS
1874 * The color depth of the primary display.
1876 DWORD WINAPI SHGetCurColorRes(void)
1878 HDC hdc;
1879 DWORD ret;
1881 TRACE("()\n");
1883 hdc = GetDC(0);
1884 ret = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
1885 ReleaseDC(0, hdc);
1886 return ret;
1889 /*************************************************************************
1890 * @ [SHLWAPI.194]
1892 * Wait for a message to arrive, with a timeout.
1894 * PARAMS
1895 * hand [I] Handle to query
1896 * dwTimeout [I] Timeout in ticks or INFINITE to never timeout
1898 * RETURNS
1899 * STATUS_TIMEOUT if no message is received before dwTimeout ticks passes.
1900 * Otherwise returns the value from MsgWaitForMultipleObjectsEx when a
1901 * message is available.
1903 DWORD WINAPI SHWaitForSendMessageThread(HANDLE hand, DWORD dwTimeout)
1905 DWORD dwEndTicks = GetTickCount() + dwTimeout;
1906 DWORD dwRet;
1908 while ((dwRet = MsgWaitForMultipleObjectsEx(1, &hand, dwTimeout, QS_SENDMESSAGE, 0)) == 1)
1910 MSG msg;
1912 PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE);
1914 if (dwTimeout != INFINITE)
1916 if ((int)(dwTimeout = dwEndTicks - GetTickCount()) <= 0)
1917 return WAIT_TIMEOUT;
1921 return dwRet;
1924 /*************************************************************************
1925 * @ [SHLWAPI.195]
1927 * Determine if a shell folder can be expanded.
1929 * PARAMS
1930 * lpFolder [I] Parent folder containing the object to test.
1931 * pidl [I] Id of the object to test.
1933 * RETURNS
1934 * Success: S_OK, if the object is expandable, S_FALSE otherwise.
1935 * Failure: E_INVALIDARG, if any argument is invalid.
1937 * NOTES
1938 * If the object to be tested does not expose the IQueryInfo() interface it
1939 * will not be identified as an expandable folder.
1941 HRESULT WINAPI SHIsExpandableFolder(LPSHELLFOLDER lpFolder, LPCITEMIDLIST pidl)
1943 HRESULT hRet = E_INVALIDARG;
1944 IQueryInfo *lpInfo;
1946 if (lpFolder && pidl)
1948 hRet = IShellFolder_GetUIObjectOf(lpFolder, NULL, 1, &pidl, &IID_IQueryInfo,
1949 NULL, (void**)&lpInfo);
1950 if (FAILED(hRet))
1951 hRet = S_FALSE; /* Doesn't expose IQueryInfo */
1952 else
1954 DWORD dwFlags = 0;
1956 /* MSDN states of IQueryInfo_GetInfoFlags() that "This method is not
1957 * currently used". Really? You wouldn't be holding out on me would you?
1959 hRet = IQueryInfo_GetInfoFlags(lpInfo, &dwFlags);
1961 if (SUCCEEDED(hRet))
1963 /* 0x2 is an undocumented flag apparently indicating expandability */
1964 hRet = dwFlags & 0x2 ? S_OK : S_FALSE;
1967 IQueryInfo_Release(lpInfo);
1970 return hRet;
1973 /*************************************************************************
1974 * @ [SHLWAPI.197]
1976 * Blank out a region of text by drawing the background only.
1978 * PARAMS
1979 * hDC [I] Device context to draw in
1980 * pRect [I] Area to draw in
1981 * cRef [I] Color to draw in
1983 * RETURNS
1984 * Nothing.
1986 DWORD WINAPI SHFillRectClr(HDC hDC, LPCRECT pRect, COLORREF cRef)
1988 COLORREF cOldColor = SetBkColor(hDC, cRef);
1989 ExtTextOutA(hDC, 0, 0, ETO_OPAQUE, pRect, 0, 0, 0);
1990 SetBkColor(hDC, cOldColor);
1991 return 0;
1994 /*************************************************************************
1995 * @ [SHLWAPI.198]
1997 * Return the value associated with a key in a map.
1999 * PARAMS
2000 * lpKeys [I] A list of keys of length iLen
2001 * lpValues [I] A list of values associated with lpKeys, of length iLen
2002 * iLen [I] Length of both lpKeys and lpValues
2003 * iKey [I] The key value to look up in lpKeys
2005 * RETURNS
2006 * The value in lpValues associated with iKey, or -1 if iKey is not
2007 * found in lpKeys.
2009 * NOTES
2010 * - If two elements in the map share the same key, this function returns
2011 * the value closest to the start of the map
2012 * - The native version of this function crashes if lpKeys or lpValues is NULL.
2014 int WINAPI SHSearchMapInt(const int *lpKeys, const int *lpValues, int iLen, int iKey)
2016 if (lpKeys && lpValues)
2018 int i = 0;
2020 while (i < iLen)
2022 if (lpKeys[i] == iKey)
2023 return lpValues[i]; /* Found */
2024 i++;
2027 return -1; /* Not found */
2031 /*************************************************************************
2032 * @ [SHLWAPI.199]
2034 * Copy an interface pointer
2036 * PARAMS
2037 * lppDest [O] Destination for copy
2038 * lpUnknown [I] Source for copy
2040 * RETURNS
2041 * Nothing.
2043 VOID WINAPI IUnknown_Set(IUnknown **lppDest, IUnknown *lpUnknown)
2045 TRACE("(%p,%p)\n", lppDest, lpUnknown);
2047 if (lppDest)
2048 IUnknown_AtomicRelease(lppDest); /* Release existing interface */
2050 if (lpUnknown)
2052 /* Copy */
2053 IUnknown_AddRef(lpUnknown);
2054 *lppDest = lpUnknown;
2058 /*************************************************************************
2059 * @ [SHLWAPI.200]
2062 HRESULT WINAPI MayQSForward(IUnknown* lpUnknown, PVOID lpReserved,
2063 REFGUID riidCmdGrp, ULONG cCmds,
2064 OLECMD *prgCmds, OLECMDTEXT* pCmdText)
2066 FIXME("(%p,%p,%p,%d,%p,%p) - stub\n",
2067 lpUnknown, lpReserved, riidCmdGrp, cCmds, prgCmds, pCmdText);
2069 /* FIXME: Calls IsQSForward & IUnknown_QueryStatus */
2070 return DRAGDROP_E_NOTREGISTERED;
2073 /*************************************************************************
2074 * @ [SHLWAPI.201]
2077 HRESULT WINAPI MayExecForward(IUnknown* lpUnknown, INT iUnk, REFGUID pguidCmdGroup,
2078 DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
2079 VARIANT* pvaOut)
2081 FIXME("(%p,%d,%p,%d,%d,%p,%p) - stub!\n", lpUnknown, iUnk, pguidCmdGroup,
2082 nCmdID, nCmdexecopt, pvaIn, pvaOut);
2083 return DRAGDROP_E_NOTREGISTERED;
2086 /*************************************************************************
2087 * @ [SHLWAPI.202]
2090 HRESULT WINAPI IsQSForward(REFGUID pguidCmdGroup,ULONG cCmds, OLECMD *prgCmds)
2092 FIXME("(%p,%d,%p) - stub!\n", pguidCmdGroup, cCmds, prgCmds);
2093 return DRAGDROP_E_NOTREGISTERED;
2096 /*************************************************************************
2097 * @ [SHLWAPI.204]
2099 * Determine if a window is not a child of another window.
2101 * PARAMS
2102 * hParent [I] Suspected parent window
2103 * hChild [I] Suspected child window
2105 * RETURNS
2106 * TRUE: If hChild is a child window of hParent
2107 * FALSE: If hChild is not a child window of hParent, or they are equal
2109 BOOL WINAPI SHIsChildOrSelf(HWND hParent, HWND hChild)
2111 TRACE("(%p,%p)\n", hParent, hChild);
2113 if (!hParent || !hChild)
2114 return TRUE;
2115 else if(hParent == hChild)
2116 return FALSE;
2117 return !IsChild(hParent, hChild);
2120 /*************************************************************************
2121 * FDSA functions. Manage a dynamic array of fixed size memory blocks.
2124 typedef struct
2126 DWORD num_items; /* Number of elements inserted */
2127 void *mem; /* Ptr to array */
2128 DWORD blocks_alloced; /* Number of elements allocated */
2129 BYTE inc; /* Number of elements to grow by when we need to expand */
2130 BYTE block_size; /* Size in bytes of an element */
2131 BYTE flags; /* Flags */
2132 } FDSA_info;
2134 #define FDSA_FLAG_INTERNAL_ALLOC 0x01 /* When set we have allocated mem internally */
2136 /*************************************************************************
2137 * @ [SHLWAPI.208]
2139 * Initialize an FDSA array.
2141 BOOL WINAPI FDSA_Initialize(DWORD block_size, DWORD inc, FDSA_info *info, void *mem,
2142 DWORD init_blocks)
2144 TRACE("(0x%08x 0x%08x %p %p 0x%08x)\n", block_size, inc, info, mem, init_blocks);
2146 if(inc == 0)
2147 inc = 1;
2149 if(mem)
2150 memset(mem, 0, block_size * init_blocks);
2152 info->num_items = 0;
2153 info->inc = inc;
2154 info->mem = mem;
2155 info->blocks_alloced = init_blocks;
2156 info->block_size = block_size;
2157 info->flags = 0;
2159 return TRUE;
2162 /*************************************************************************
2163 * @ [SHLWAPI.209]
2165 * Destroy an FDSA array
2167 BOOL WINAPI FDSA_Destroy(FDSA_info *info)
2169 TRACE("(%p)\n", info);
2171 if(info->flags & FDSA_FLAG_INTERNAL_ALLOC)
2173 HeapFree(GetProcessHeap(), 0, info->mem);
2174 return FALSE;
2177 return TRUE;
2180 /*************************************************************************
2181 * @ [SHLWAPI.210]
2183 * Insert element into an FDSA array
2185 DWORD WINAPI FDSA_InsertItem(FDSA_info *info, DWORD where, const void *block)
2187 TRACE("(%p 0x%08x %p)\n", info, where, block);
2188 if(where > info->num_items)
2189 where = info->num_items;
2191 if(info->num_items >= info->blocks_alloced)
2193 DWORD size = (info->blocks_alloced + info->inc) * info->block_size;
2194 if(info->flags & 0x1)
2195 info->mem = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->mem, size);
2196 else
2198 void *old_mem = info->mem;
2199 info->mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
2200 memcpy(info->mem, old_mem, info->blocks_alloced * info->block_size);
2202 info->blocks_alloced += info->inc;
2203 info->flags |= 0x1;
2206 if(where < info->num_items)
2208 memmove((char*)info->mem + (where + 1) * info->block_size,
2209 (char*)info->mem + where * info->block_size,
2210 (info->num_items - where) * info->block_size);
2212 memcpy((char*)info->mem + where * info->block_size, block, info->block_size);
2214 info->num_items++;
2215 return where;
2218 /*************************************************************************
2219 * @ [SHLWAPI.211]
2221 * Delete an element from an FDSA array.
2223 BOOL WINAPI FDSA_DeleteItem(FDSA_info *info, DWORD where)
2225 TRACE("(%p 0x%08x)\n", info, where);
2227 if(where >= info->num_items)
2228 return FALSE;
2230 if(where < info->num_items - 1)
2232 memmove((char*)info->mem + where * info->block_size,
2233 (char*)info->mem + (where + 1) * info->block_size,
2234 (info->num_items - where - 1) * info->block_size);
2236 memset((char*)info->mem + (info->num_items - 1) * info->block_size,
2237 0, info->block_size);
2238 info->num_items--;
2239 return TRUE;
2243 typedef struct {
2244 REFIID refid;
2245 DWORD indx;
2246 } IFACE_INDEX_TBL;
2248 /*************************************************************************
2249 * @ [SHLWAPI.219]
2251 * Call IUnknown_QueryInterface() on a table of objects.
2253 * RETURNS
2254 * Success: S_OK.
2255 * Failure: E_POINTER or E_NOINTERFACE.
2257 HRESULT WINAPI QISearch(
2258 LPVOID w, /* [in] Table of interfaces */
2259 IFACE_INDEX_TBL *x, /* [in] Array of REFIIDs and indexes into the table */
2260 REFIID riid, /* [in] REFIID to get interface for */
2261 LPVOID *ppv) /* [out] Destination for interface pointer */
2263 HRESULT ret;
2264 IUnknown *a_vtbl;
2265 IFACE_INDEX_TBL *xmove;
2267 TRACE("(%p %p %s %p)\n", w,x,debugstr_guid(riid),ppv);
2268 if (ppv) {
2269 xmove = x;
2270 while (xmove->refid) {
2271 TRACE("trying (indx %d) %s\n", xmove->indx, debugstr_guid(xmove->refid));
2272 if (IsEqualIID(riid, xmove->refid)) {
2273 a_vtbl = (IUnknown*)(xmove->indx + (LPBYTE)w);
2274 TRACE("matched, returning (%p)\n", a_vtbl);
2275 *ppv = a_vtbl;
2276 IUnknown_AddRef(a_vtbl);
2277 return S_OK;
2279 xmove++;
2282 if (IsEqualIID(riid, &IID_IUnknown)) {
2283 a_vtbl = (IUnknown*)(x->indx + (LPBYTE)w);
2284 TRACE("returning first for IUnknown (%p)\n", a_vtbl);
2285 *ppv = a_vtbl;
2286 IUnknown_AddRef(a_vtbl);
2287 return S_OK;
2289 *ppv = 0;
2290 ret = E_NOINTERFACE;
2291 } else
2292 ret = E_POINTER;
2294 TRACE("-- 0x%08x\n", ret);
2295 return ret;
2298 /*************************************************************************
2299 * @ [SHLWAPI.220]
2301 * Set the Font for a window and the "PropDlgFont" property of the parent window.
2303 * PARAMS
2304 * hWnd [I] Parent Window to set the property
2305 * id [I] Index of child Window to set the Font
2307 * RETURNS
2308 * Success: S_OK
2311 HRESULT WINAPI SHSetDefaultDialogFont(HWND hWnd, INT id)
2313 FIXME("(%p, %d) stub\n", hWnd, id);
2314 return S_OK;
2317 /*************************************************************************
2318 * @ [SHLWAPI.221]
2320 * Remove the "PropDlgFont" property from a window.
2322 * PARAMS
2323 * hWnd [I] Window to remove the property from
2325 * RETURNS
2326 * A handle to the removed property, or NULL if it did not exist.
2328 HANDLE WINAPI SHRemoveDefaultDialogFont(HWND hWnd)
2330 HANDLE hProp;
2332 TRACE("(%p)\n", hWnd);
2334 hProp = GetPropA(hWnd, "PropDlgFont");
2336 if(hProp)
2338 DeleteObject(hProp);
2339 hProp = RemovePropA(hWnd, "PropDlgFont");
2341 return hProp;
2344 /*************************************************************************
2345 * @ [SHLWAPI.236]
2347 * Load the in-process server of a given GUID.
2349 * PARAMS
2350 * refiid [I] GUID of the server to load.
2352 * RETURNS
2353 * Success: A handle to the loaded server dll.
2354 * Failure: A NULL handle.
2356 HMODULE WINAPI SHPinDllOfCLSID(REFIID refiid)
2358 HKEY newkey;
2359 DWORD type, count;
2360 CHAR value[MAX_PATH], string[MAX_PATH];
2362 strcpy(string, "CLSID\\");
2363 SHStringFromGUIDA(refiid, string + 6, sizeof(string)/sizeof(char) - 6);
2364 strcat(string, "\\InProcServer32");
2366 count = MAX_PATH;
2367 RegOpenKeyExA(HKEY_CLASSES_ROOT, string, 0, 1, &newkey);
2368 RegQueryValueExA(newkey, 0, 0, &type, (PBYTE)value, &count);
2369 RegCloseKey(newkey);
2370 return LoadLibraryExA(value, 0, 0);
2373 /*************************************************************************
2374 * @ [SHLWAPI.237]
2376 * Unicode version of SHLWAPI_183.
2378 DWORD WINAPI SHRegisterClassW(WNDCLASSW * lpWndClass)
2380 WNDCLASSW WndClass;
2382 TRACE("(%p %s)\n",lpWndClass->hInstance, debugstr_w(lpWndClass->lpszClassName));
2384 if (GetClassInfoW(lpWndClass->hInstance, lpWndClass->lpszClassName, &WndClass))
2385 return TRUE;
2386 return RegisterClassW(lpWndClass);
2389 /*************************************************************************
2390 * @ [SHLWAPI.238]
2392 * Unregister a list of classes.
2394 * PARAMS
2395 * hInst [I] Application instance that registered the classes
2396 * lppClasses [I] List of class names
2397 * iCount [I] Number of names in lppClasses
2399 * RETURNS
2400 * Nothing.
2402 void WINAPI SHUnregisterClassesA(HINSTANCE hInst, LPCSTR *lppClasses, INT iCount)
2404 WNDCLASSA WndClass;
2406 TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);
2408 while (iCount > 0)
2410 if (GetClassInfoA(hInst, *lppClasses, &WndClass))
2411 UnregisterClassA(*lppClasses, hInst);
2412 lppClasses++;
2413 iCount--;
2417 /*************************************************************************
2418 * @ [SHLWAPI.239]
2420 * Unicode version of SHUnregisterClassesA.
2422 void WINAPI SHUnregisterClassesW(HINSTANCE hInst, LPCWSTR *lppClasses, INT iCount)
2424 WNDCLASSW WndClass;
2426 TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);
2428 while (iCount > 0)
2430 if (GetClassInfoW(hInst, *lppClasses, &WndClass))
2431 UnregisterClassW(*lppClasses, hInst);
2432 lppClasses++;
2433 iCount--;
2437 /*************************************************************************
2438 * @ [SHLWAPI.240]
2440 * Call The correct (Ascii/Unicode) default window procedure for a window.
2442 * PARAMS
2443 * hWnd [I] Window to call the default procedure for
2444 * uMessage [I] Message ID
2445 * wParam [I] WPARAM of message
2446 * lParam [I] LPARAM of message
2448 * RETURNS
2449 * The result of calling DefWindowProcA() or DefWindowProcW().
2451 LRESULT CALLBACK SHDefWindowProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
2453 if (IsWindowUnicode(hWnd))
2454 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
2455 return DefWindowProcA(hWnd, uMessage, wParam, lParam);
2458 /*************************************************************************
2459 * @ [SHLWAPI.256]
2461 HRESULT WINAPI IUnknown_GetSite(LPUNKNOWN lpUnknown, REFIID iid, PVOID *lppSite)
2463 HRESULT hRet = E_INVALIDARG;
2464 LPOBJECTWITHSITE lpSite = NULL;
2466 TRACE("(%p,%s,%p)\n", lpUnknown, debugstr_guid(iid), lppSite);
2468 if (lpUnknown && iid && lppSite)
2470 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IObjectWithSite,
2471 (void**)&lpSite);
2472 if (SUCCEEDED(hRet) && lpSite)
2474 hRet = IObjectWithSite_GetSite(lpSite, iid, lppSite);
2475 IObjectWithSite_Release(lpSite);
2478 return hRet;
2481 /*************************************************************************
2482 * @ [SHLWAPI.257]
2484 * Create a worker window using CreateWindowExA().
2486 * PARAMS
2487 * wndProc [I] Window procedure
2488 * hWndParent [I] Parent window
2489 * dwExStyle [I] Extra style flags
2490 * dwStyle [I] Style flags
2491 * hMenu [I] Window menu
2492 * z [I] Unknown
2494 * RETURNS
2495 * Success: The window handle of the newly created window.
2496 * Failure: 0.
2498 HWND WINAPI SHCreateWorkerWindowA(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
2499 DWORD dwStyle, HMENU hMenu, LONG z)
2501 static const char szClass[] = "WorkerA";
2502 WNDCLASSA wc;
2503 HWND hWnd;
2505 TRACE("(0x%08x,%p,0x%08x,0x%08x,%p,0x%08x)\n",
2506 wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2508 /* Create Window class */
2509 wc.style = 0;
2510 wc.lpfnWndProc = DefWindowProcA;
2511 wc.cbClsExtra = 0;
2512 wc.cbWndExtra = 4;
2513 wc.hInstance = shlwapi_hInstance;
2514 wc.hIcon = NULL;
2515 wc.hCursor = LoadCursorA(NULL, (LPSTR)IDC_ARROW);
2516 wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
2517 wc.lpszMenuName = NULL;
2518 wc.lpszClassName = szClass;
2520 SHRegisterClassA(&wc); /* Register class */
2522 /* FIXME: Set extra bits in dwExStyle */
2524 hWnd = CreateWindowExA(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
2525 hWndParent, hMenu, shlwapi_hInstance, 0);
2526 if (hWnd)
2528 SetWindowLongPtrW(hWnd, DWLP_MSGRESULT, z);
2530 if (wndProc)
2531 SetWindowLongPtrA(hWnd, GWLP_WNDPROC, wndProc);
2533 return hWnd;
2536 typedef struct tagPOLICYDATA
2538 DWORD policy; /* flags value passed to SHRestricted */
2539 LPCWSTR appstr; /* application str such as "Explorer" */
2540 LPCWSTR keystr; /* name of the actual registry key / policy */
2541 } POLICYDATA, *LPPOLICYDATA;
2543 #define SHELL_NO_POLICY 0xffffffff
2545 /* default shell policy registry key */
2546 static const WCHAR strRegistryPolicyW[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o',
2547 's','o','f','t','\\','W','i','n','d','o','w','s','\\',
2548 'C','u','r','r','e','n','t','V','e','r','s','i','o','n',
2549 '\\','P','o','l','i','c','i','e','s',0};
2551 /*************************************************************************
2552 * @ [SHLWAPI.271]
2554 * Retrieve a policy value from the registry.
2556 * PARAMS
2557 * lpSubKey [I] registry key name
2558 * lpSubName [I] subname of registry key
2559 * lpValue [I] value name of registry value
2561 * RETURNS
2562 * the value associated with the registry key or 0 if not found
2564 DWORD WINAPI SHGetRestriction(LPCWSTR lpSubKey, LPCWSTR lpSubName, LPCWSTR lpValue)
2566 DWORD retval, datsize = sizeof(retval);
2567 HKEY hKey;
2569 if (!lpSubKey)
2570 lpSubKey = strRegistryPolicyW;
2572 retval = RegOpenKeyW(HKEY_LOCAL_MACHINE, lpSubKey, &hKey);
2573 if (retval != ERROR_SUCCESS)
2574 retval = RegOpenKeyW(HKEY_CURRENT_USER, lpSubKey, &hKey);
2575 if (retval != ERROR_SUCCESS)
2576 return 0;
2578 SHGetValueW(hKey, lpSubName, lpValue, NULL, &retval, &datsize);
2579 RegCloseKey(hKey);
2580 return retval;
2583 /*************************************************************************
2584 * @ [SHLWAPI.266]
2586 * Helper function to retrieve the possibly cached value for a specific policy
2588 * PARAMS
2589 * policy [I] The policy to look for
2590 * initial [I] Main registry key to open, if NULL use default
2591 * polTable [I] Table of known policies, 0 terminated
2592 * polArr [I] Cache array of policy values
2594 * RETURNS
2595 * The retrieved policy value or 0 if not successful
2597 * NOTES
2598 * This function is used by the native SHRestricted function to search for the
2599 * policy and cache it once retrieved. The current Wine implementation uses a
2600 * different POLICYDATA structure and implements a similar algorithm adapted to
2601 * that structure.
2603 DWORD WINAPI SHRestrictionLookup(
2604 DWORD policy,
2605 LPCWSTR initial,
2606 LPPOLICYDATA polTable,
2607 LPDWORD polArr)
2609 TRACE("(0x%08x %s %p %p)\n", policy, debugstr_w(initial), polTable, polArr);
2611 if (!polTable || !polArr)
2612 return 0;
2614 for (;polTable->policy; polTable++, polArr++)
2616 if (policy == polTable->policy)
2618 /* we have a known policy */
2620 /* check if this policy has been cached */
2621 if (*polArr == SHELL_NO_POLICY)
2622 *polArr = SHGetRestriction(initial, polTable->appstr, polTable->keystr);
2623 return *polArr;
2626 /* we don't know this policy, return 0 */
2627 TRACE("unknown policy: (%08x)\n", policy);
2628 return 0;
2631 /*************************************************************************
2632 * @ [SHLWAPI.267]
2634 * Get an interface from an object.
2636 * RETURNS
2637 * Success: S_OK. ppv contains the requested interface.
2638 * Failure: An HRESULT error code.
2640 * NOTES
2641 * This QueryInterface asks the inner object for an interface. In case
2642 * of aggregation this request would be forwarded by the inner to the
2643 * outer object. This function asks the inner object directly for the
2644 * interface circumventing the forwarding to the outer object.
2646 HRESULT WINAPI SHWeakQueryInterface(
2647 IUnknown * pUnk, /* [in] Outer object */
2648 IUnknown * pInner, /* [in] Inner object */
2649 IID * riid, /* [in] Interface GUID to query for */
2650 LPVOID* ppv) /* [out] Destination for queried interface */
2652 HRESULT hret = E_NOINTERFACE;
2653 TRACE("(pUnk=%p pInner=%p\n\tIID: %s %p)\n",pUnk,pInner,debugstr_guid(riid), ppv);
2655 *ppv = NULL;
2656 if(pUnk && pInner) {
2657 hret = IUnknown_QueryInterface(pInner, riid, ppv);
2658 if (SUCCEEDED(hret)) IUnknown_Release(pUnk);
2660 TRACE("-- 0x%08x\n", hret);
2661 return hret;
2664 /*************************************************************************
2665 * @ [SHLWAPI.268]
2667 * Move a reference from one interface to another.
2669 * PARAMS
2670 * lpDest [O] Destination to receive the reference
2671 * lppUnknown [O] Source to give up the reference to lpDest
2673 * RETURNS
2674 * Nothing.
2676 VOID WINAPI SHWeakReleaseInterface(IUnknown *lpDest, IUnknown **lppUnknown)
2678 TRACE("(%p,%p)\n", lpDest, lppUnknown);
2680 if (*lppUnknown)
2682 /* Copy Reference*/
2683 IUnknown_AddRef(lpDest);
2684 IUnknown_AtomicRelease(lppUnknown); /* Release existing interface */
2688 /*************************************************************************
2689 * @ [SHLWAPI.269]
2691 * Convert an ASCII string of a CLSID into a CLSID.
2693 * PARAMS
2694 * idstr [I] String representing a CLSID in registry format
2695 * id [O] Destination for the converted CLSID
2697 * RETURNS
2698 * Success: TRUE. id contains the converted CLSID.
2699 * Failure: FALSE.
2701 BOOL WINAPI GUIDFromStringA(LPCSTR idstr, CLSID *id)
2703 WCHAR wClsid[40];
2704 MultiByteToWideChar(CP_ACP, 0, idstr, -1, wClsid, sizeof(wClsid)/sizeof(WCHAR));
2705 return SUCCEEDED(CLSIDFromString(wClsid, id));
2708 /*************************************************************************
2709 * @ [SHLWAPI.270]
2711 * Unicode version of GUIDFromStringA.
2713 BOOL WINAPI GUIDFromStringW(LPCWSTR idstr, CLSID *id)
2715 return SUCCEEDED(CLSIDFromString((LPOLESTR)idstr, id));
2718 /*************************************************************************
2719 * @ [SHLWAPI.276]
2721 * Determine if the browser is integrated into the shell, and set a registry
2722 * key accordingly.
2724 * PARAMS
2725 * None.
2727 * RETURNS
2728 * 1, If the browser is not integrated.
2729 * 2, If the browser is integrated.
2731 * NOTES
2732 * The key "HKLM\Software\Microsoft\Internet Explorer\IntegratedBrowser" is
2733 * either set to TRUE, or removed depending on whether the browser is deemed
2734 * to be integrated.
2736 DWORD WINAPI WhichPlatform(void)
2738 static const char szIntegratedBrowser[] = "IntegratedBrowser";
2739 static DWORD dwState = 0;
2740 HKEY hKey;
2741 DWORD dwRet, dwData, dwSize;
2742 HMODULE hshell32;
2744 if (dwState)
2745 return dwState;
2747 /* If shell32 exports DllGetVersion(), the browser is integrated */
2748 dwState = 1;
2749 hshell32 = LoadLibraryA("shell32.dll");
2750 if (hshell32)
2752 FARPROC pDllGetVersion;
2753 pDllGetVersion = GetProcAddress(hshell32, "DllGetVersion");
2754 dwState = pDllGetVersion ? 2 : 1;
2755 FreeLibrary(hshell32);
2758 /* Set or delete the key accordingly */
2759 dwRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
2760 "Software\\Microsoft\\Internet Explorer", 0,
2761 KEY_ALL_ACCESS, &hKey);
2762 if (!dwRet)
2764 dwRet = RegQueryValueExA(hKey, szIntegratedBrowser, 0, 0,
2765 (LPBYTE)&dwData, &dwSize);
2767 if (!dwRet && dwState == 1)
2769 /* Value exists but browser is not integrated */
2770 RegDeleteValueA(hKey, szIntegratedBrowser);
2772 else if (dwRet && dwState == 2)
2774 /* Browser is integrated but value does not exist */
2775 dwData = TRUE;
2776 RegSetValueExA(hKey, szIntegratedBrowser, 0, REG_DWORD,
2777 (LPBYTE)&dwData, sizeof(dwData));
2779 RegCloseKey(hKey);
2781 return dwState;
2784 /*************************************************************************
2785 * @ [SHLWAPI.278]
2787 * Unicode version of SHCreateWorkerWindowA.
2789 HWND WINAPI SHCreateWorkerWindowW(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
2790 DWORD dwStyle, HMENU hMenu, LONG z)
2792 static const WCHAR szClass[] = { 'W', 'o', 'r', 'k', 'e', 'r', 'W', '\0' };
2793 WNDCLASSW wc;
2794 HWND hWnd;
2796 TRACE("(0x%08x,%p,0x%08x,0x%08x,%p,0x%08x)\n",
2797 wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2799 /* If our OS is natively ASCII, use the ASCII version */
2800 if (!(GetVersion() & 0x80000000)) /* NT */
2801 return SHCreateWorkerWindowA(wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2803 /* Create Window class */
2804 wc.style = 0;
2805 wc.lpfnWndProc = DefWindowProcW;
2806 wc.cbClsExtra = 0;
2807 wc.cbWndExtra = 4;
2808 wc.hInstance = shlwapi_hInstance;
2809 wc.hIcon = NULL;
2810 wc.hCursor = LoadCursorW(NULL, (LPWSTR)IDC_ARROW);
2811 wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
2812 wc.lpszMenuName = NULL;
2813 wc.lpszClassName = szClass;
2815 SHRegisterClassW(&wc); /* Register class */
2817 /* FIXME: Set extra bits in dwExStyle */
2819 hWnd = CreateWindowExW(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
2820 hWndParent, hMenu, shlwapi_hInstance, 0);
2821 if (hWnd)
2823 SetWindowLongPtrW(hWnd, DWLP_MSGRESULT, z);
2825 if (wndProc)
2826 SetWindowLongPtrW(hWnd, GWLP_WNDPROC, wndProc);
2828 return hWnd;
2831 /*************************************************************************
2832 * @ [SHLWAPI.279]
2834 * Get and show a context menu from a shell folder.
2836 * PARAMS
2837 * hWnd [I] Window displaying the shell folder
2838 * lpFolder [I] IShellFolder interface
2839 * lpApidl [I] Id for the particular folder desired
2841 * RETURNS
2842 * Success: S_OK.
2843 * Failure: An HRESULT error code indicating the error.
2845 HRESULT WINAPI SHInvokeDefaultCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl)
2847 return SHInvokeCommand(hWnd, lpFolder, lpApidl, FALSE);
2850 /*************************************************************************
2851 * @ [SHLWAPI.281]
2853 * _SHPackDispParamsV
2855 HRESULT WINAPI SHPackDispParamsV(DISPPARAMS *params, VARIANTARG *args, UINT cnt, __ms_va_list valist)
2857 VARIANTARG *iter;
2859 TRACE("(%p %p %u ...)\n", params, args, cnt);
2861 params->rgvarg = args;
2862 params->rgdispidNamedArgs = NULL;
2863 params->cArgs = cnt;
2864 params->cNamedArgs = 0;
2866 iter = args+cnt;
2868 while(iter-- > args) {
2869 V_VT(iter) = va_arg(valist, enum VARENUM);
2871 TRACE("vt=%d\n", V_VT(iter));
2873 if(V_VT(iter) & VT_BYREF) {
2874 V_BYREF(iter) = va_arg(valist, LPVOID);
2875 } else {
2876 switch(V_VT(iter)) {
2877 case VT_I4:
2878 V_I4(iter) = va_arg(valist, LONG);
2879 break;
2880 case VT_BSTR:
2881 V_BSTR(iter) = va_arg(valist, BSTR);
2882 break;
2883 case VT_DISPATCH:
2884 V_DISPATCH(iter) = va_arg(valist, IDispatch*);
2885 break;
2886 case VT_BOOL:
2887 V_BOOL(iter) = va_arg(valist, int);
2888 break;
2889 case VT_UNKNOWN:
2890 V_UNKNOWN(iter) = va_arg(valist, IUnknown*);
2891 break;
2892 default:
2893 V_VT(iter) = VT_I4;
2894 V_I4(iter) = va_arg(valist, LONG);
2899 return S_OK;
2902 /*************************************************************************
2903 * @ [SHLWAPI.282]
2905 * SHPackDispParams
2907 HRESULT WINAPIV SHPackDispParams(DISPPARAMS *params, VARIANTARG *args, UINT cnt, ...)
2909 __ms_va_list valist;
2910 HRESULT hres;
2912 __ms_va_start(valist, cnt);
2913 hres = SHPackDispParamsV(params, args, cnt, valist);
2914 __ms_va_end(valist);
2915 return hres;
2918 /*************************************************************************
2919 * SHLWAPI_InvokeByIID
2921 * This helper function calls IDispatch::Invoke for each sink
2922 * which implements given iid or IDispatch.
2925 static HRESULT SHLWAPI_InvokeByIID(
2926 IConnectionPoint* iCP,
2927 REFIID iid,
2928 DISPID dispId,
2929 DISPPARAMS* dispParams)
2931 IEnumConnections *enumerator;
2932 CONNECTDATA rgcd;
2933 static DISPPARAMS empty = {NULL, NULL, 0, 0};
2934 DISPPARAMS* params = dispParams;
2936 HRESULT result = IConnectionPoint_EnumConnections(iCP, &enumerator);
2937 if (FAILED(result))
2938 return result;
2940 /* Invoke is never happening with an NULL dispParams */
2941 if (!params)
2942 params = &empty;
2944 while(IEnumConnections_Next(enumerator, 1, &rgcd, NULL)==S_OK)
2946 IDispatch *dispIface;
2947 if ((iid && SUCCEEDED(IUnknown_QueryInterface(rgcd.pUnk, iid, (LPVOID*)&dispIface))) ||
2948 SUCCEEDED(IUnknown_QueryInterface(rgcd.pUnk, &IID_IDispatch, (LPVOID*)&dispIface)))
2950 IDispatch_Invoke(dispIface, dispId, &IID_NULL, 0, DISPATCH_METHOD, params, NULL, NULL, NULL);
2951 IDispatch_Release(dispIface);
2953 IUnknown_Release(rgcd.pUnk);
2956 IEnumConnections_Release(enumerator);
2958 return S_OK;
2961 /*************************************************************************
2962 * IConnectionPoint_InvokeWithCancel [SHLWAPI.283]
2964 HRESULT WINAPI IConnectionPoint_InvokeWithCancel( IConnectionPoint* iCP,
2965 DISPID dispId, DISPPARAMS* dispParams,
2966 DWORD unknown1, DWORD unknown2 )
2968 IID iid;
2969 HRESULT result;
2971 FIXME("(%p)->(0x%x %p %x %x) partial stub\n", iCP, dispId, dispParams, unknown1, unknown2);
2973 result = IConnectionPoint_GetConnectionInterface(iCP, &iid);
2974 if (SUCCEEDED(result))
2975 result = SHLWAPI_InvokeByIID(iCP, &iid, dispId, dispParams);
2976 else
2977 result = SHLWAPI_InvokeByIID(iCP, NULL, dispId, dispParams);
2979 return result;
2983 /*************************************************************************
2984 * @ [SHLWAPI.284]
2986 * IConnectionPoint_SimpleInvoke
2988 HRESULT WINAPI IConnectionPoint_SimpleInvoke(
2989 IConnectionPoint* iCP,
2990 DISPID dispId,
2991 DISPPARAMS* dispParams)
2993 IID iid;
2994 HRESULT result;
2996 TRACE("(%p)->(0x%x %p)\n",iCP,dispId,dispParams);
2998 result = IConnectionPoint_GetConnectionInterface(iCP, &iid);
2999 if (SUCCEEDED(result))
3000 result = SHLWAPI_InvokeByIID(iCP, &iid, dispId, dispParams);
3001 else
3002 result = SHLWAPI_InvokeByIID(iCP, NULL, dispId, dispParams);
3004 return result;
3007 /*************************************************************************
3008 * @ [SHLWAPI.285]
3010 * Notify an IConnectionPoint object of changes.
3012 * PARAMS
3013 * lpCP [I] Object to notify
3014 * dispID [I]
3016 * RETURNS
3017 * Success: S_OK.
3018 * Failure: E_NOINTERFACE, if lpCP is NULL or does not support the
3019 * IConnectionPoint interface.
3021 HRESULT WINAPI IConnectionPoint_OnChanged(IConnectionPoint* lpCP, DISPID dispID)
3023 IEnumConnections *lpEnum;
3024 HRESULT hRet = E_NOINTERFACE;
3026 TRACE("(%p,0x%8X)\n", lpCP, dispID);
3028 /* Get an enumerator for the connections */
3029 if (lpCP)
3030 hRet = IConnectionPoint_EnumConnections(lpCP, &lpEnum);
3032 if (SUCCEEDED(hRet))
3034 IPropertyNotifySink *lpSink;
3035 CONNECTDATA connData;
3036 ULONG ulFetched;
3038 /* Call OnChanged() for every notify sink in the connection point */
3039 while (IEnumConnections_Next(lpEnum, 1, &connData, &ulFetched) == S_OK)
3041 if (SUCCEEDED(IUnknown_QueryInterface(connData.pUnk, &IID_IPropertyNotifySink, (void**)&lpSink)) &&
3042 lpSink)
3044 IPropertyNotifySink_OnChanged(lpSink, dispID);
3045 IPropertyNotifySink_Release(lpSink);
3047 IUnknown_Release(connData.pUnk);
3050 IEnumConnections_Release(lpEnum);
3052 return hRet;
3055 /*************************************************************************
3056 * @ [SHLWAPI.286]
3058 * IUnknown_CPContainerInvokeParam
3060 HRESULT WINAPIV IUnknown_CPContainerInvokeParam(
3061 IUnknown *container,
3062 REFIID riid,
3063 DISPID dispId,
3064 VARIANTARG* buffer,
3065 DWORD cParams, ...)
3067 HRESULT result;
3068 IConnectionPoint *iCP;
3069 IConnectionPointContainer *iCPC;
3070 DISPPARAMS dispParams = {buffer, NULL, cParams, 0};
3071 __ms_va_list valist;
3073 if (!container)
3074 return E_NOINTERFACE;
3076 result = IUnknown_QueryInterface(container, &IID_IConnectionPointContainer,(LPVOID*) &iCPC);
3077 if (FAILED(result))
3078 return result;
3080 result = IConnectionPointContainer_FindConnectionPoint(iCPC, riid, &iCP);
3081 IConnectionPointContainer_Release(iCPC);
3082 if(FAILED(result))
3083 return result;
3085 __ms_va_start(valist, cParams);
3086 SHPackDispParamsV(&dispParams, buffer, cParams, valist);
3087 __ms_va_end(valist);
3089 result = SHLWAPI_InvokeByIID(iCP, riid, dispId, &dispParams);
3090 IConnectionPoint_Release(iCP);
3092 return result;
3095 /*************************************************************************
3096 * @ [SHLWAPI.287]
3098 * Notify an IConnectionPointContainer object of changes.
3100 * PARAMS
3101 * lpUnknown [I] Object to notify
3102 * dispID [I]
3104 * RETURNS
3105 * Success: S_OK.
3106 * Failure: E_NOINTERFACE, if lpUnknown is NULL or does not support the
3107 * IConnectionPointContainer interface.
3109 HRESULT WINAPI IUnknown_CPContainerOnChanged(IUnknown *lpUnknown, DISPID dispID)
3111 IConnectionPointContainer* lpCPC = NULL;
3112 HRESULT hRet = E_NOINTERFACE;
3114 TRACE("(%p,0x%8X)\n", lpUnknown, dispID);
3116 if (lpUnknown)
3117 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer, (void**)&lpCPC);
3119 if (SUCCEEDED(hRet))
3121 IConnectionPoint* lpCP;
3123 hRet = IConnectionPointContainer_FindConnectionPoint(lpCPC, &IID_IPropertyNotifySink, &lpCP);
3124 IConnectionPointContainer_Release(lpCPC);
3126 hRet = IConnectionPoint_OnChanged(lpCP, dispID);
3127 IConnectionPoint_Release(lpCP);
3129 return hRet;
3132 /*************************************************************************
3133 * @ [SHLWAPI.289]
3135 * See PlaySoundW.
3137 BOOL WINAPI PlaySoundWrapW(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
3139 return PlaySoundW(pszSound, hmod, fdwSound);
3142 /*************************************************************************
3143 * @ [SHLWAPI.294]
3145 BOOL WINAPI SHGetIniStringW(LPCWSTR str1, LPCWSTR str2, LPWSTR pStr, DWORD some_len, LPCWSTR lpStr2)
3147 FIXME("(%s,%s,%p,%08x,%s): stub!\n", debugstr_w(str1), debugstr_w(str2),
3148 pStr, some_len, debugstr_w(lpStr2));
3149 return TRUE;
3152 /*************************************************************************
3153 * @ [SHLWAPI.295]
3155 * Called by ICQ2000b install via SHDOCVW:
3156 * str1: "InternetShortcut"
3157 * x: some unknown pointer
3158 * str2: "http://free.aol.com/tryaolfree/index.adp?139269"
3159 * str3: "C:\\WINDOWS\\Desktop.new2\\Free AOL & Unlimited Internet.url"
3161 * In short: this one maybe creates a desktop link :-)
3163 BOOL WINAPI SHSetIniStringW(LPWSTR str1, LPVOID x, LPWSTR str2, LPWSTR str3)
3165 FIXME("(%s, %p, %s, %s), stub.\n", debugstr_w(str1), x, debugstr_w(str2), debugstr_w(str3));
3166 return TRUE;
3169 /*************************************************************************
3170 * @ [SHLWAPI.313]
3172 * See SHGetFileInfoW.
3174 DWORD WINAPI SHGetFileInfoWrapW(LPCWSTR path, DWORD dwFileAttributes,
3175 SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
3177 return SHGetFileInfoW(path, dwFileAttributes, psfi, sizeofpsfi, flags);
3180 /*************************************************************************
3181 * @ [SHLWAPI.318]
3183 * See DragQueryFileW.
3185 UINT WINAPI DragQueryFileWrapW(HDROP hDrop, UINT lFile, LPWSTR lpszFile, UINT lLength)
3187 return DragQueryFileW(hDrop, lFile, lpszFile, lLength);
3190 /*************************************************************************
3191 * @ [SHLWAPI.333]
3193 * See SHBrowseForFolderW.
3195 LPITEMIDLIST WINAPI SHBrowseForFolderWrapW(LPBROWSEINFOW lpBi)
3197 return SHBrowseForFolderW(lpBi);
3200 /*************************************************************************
3201 * @ [SHLWAPI.334]
3203 * See SHGetPathFromIDListW.
3205 BOOL WINAPI SHGetPathFromIDListWrapW(LPCITEMIDLIST pidl,LPWSTR pszPath)
3207 return SHGetPathFromIDListW(pidl, pszPath);
3210 /*************************************************************************
3211 * @ [SHLWAPI.335]
3213 * See ShellExecuteExW.
3215 BOOL WINAPI ShellExecuteExWrapW(LPSHELLEXECUTEINFOW lpExecInfo)
3217 return ShellExecuteExW(lpExecInfo);
3220 /*************************************************************************
3221 * @ [SHLWAPI.336]
3223 * See SHFileOperationW.
3225 INT WINAPI SHFileOperationWrapW(LPSHFILEOPSTRUCTW lpFileOp)
3227 return SHFileOperationW(lpFileOp);
3230 /*************************************************************************
3231 * @ [SHLWAPI.342]
3234 PVOID WINAPI SHInterlockedCompareExchange( PVOID *dest, PVOID xchg, PVOID compare )
3236 return InterlockedCompareExchangePointer( dest, xchg, compare );
3239 /*************************************************************************
3240 * @ [SHLWAPI.350]
3242 * See GetFileVersionInfoSizeW.
3244 DWORD WINAPI GetFileVersionInfoSizeWrapW( LPCWSTR filename, LPDWORD handle )
3246 return GetFileVersionInfoSizeW( filename, handle );
3249 /*************************************************************************
3250 * @ [SHLWAPI.351]
3252 * See GetFileVersionInfoW.
3254 BOOL WINAPI GetFileVersionInfoWrapW( LPCWSTR filename, DWORD handle,
3255 DWORD datasize, LPVOID data )
3257 return GetFileVersionInfoW( filename, handle, datasize, data );
3260 /*************************************************************************
3261 * @ [SHLWAPI.352]
3263 * See VerQueryValueW.
3265 WORD WINAPI VerQueryValueWrapW( LPVOID pBlock, LPCWSTR lpSubBlock,
3266 LPVOID *lplpBuffer, UINT *puLen )
3268 return VerQueryValueW( pBlock, lpSubBlock, lplpBuffer, puLen );
3271 #define IsIface(type) SUCCEEDED((hRet = IUnknown_QueryInterface(lpUnknown, &IID_##type, (void**)&lpObj)))
3272 #define IShellBrowser_EnableModeless IShellBrowser_EnableModelessSB
3273 #define EnableModeless(type) type##_EnableModeless((type*)lpObj, bModeless)
3275 /*************************************************************************
3276 * @ [SHLWAPI.355]
3278 * Change the modality of a shell object.
3280 * PARAMS
3281 * lpUnknown [I] Object to make modeless
3282 * bModeless [I] TRUE=Make modeless, FALSE=Make modal
3284 * RETURNS
3285 * Success: S_OK. The modality lpUnknown is changed.
3286 * Failure: An HRESULT error code indicating the error.
3288 * NOTES
3289 * lpUnknown must support the IOleInPlaceFrame interface, the
3290 * IInternetSecurityMgrSite interface, the IShellBrowser interface
3291 * the IDocHostUIHandler interface, or the IOleInPlaceActiveObject interface,
3292 * or this call will fail.
3294 HRESULT WINAPI IUnknown_EnableModeless(IUnknown *lpUnknown, BOOL bModeless)
3296 IUnknown *lpObj;
3297 HRESULT hRet;
3299 TRACE("(%p,%d)\n", lpUnknown, bModeless);
3301 if (!lpUnknown)
3302 return E_FAIL;
3304 if (IsIface(IOleInPlaceActiveObject))
3305 EnableModeless(IOleInPlaceActiveObject);
3306 else if (IsIface(IOleInPlaceFrame))
3307 EnableModeless(IOleInPlaceFrame);
3308 else if (IsIface(IShellBrowser))
3309 EnableModeless(IShellBrowser);
3310 else if (IsIface(IInternetSecurityMgrSite))
3311 EnableModeless(IInternetSecurityMgrSite);
3312 else if (IsIface(IDocHostUIHandler))
3313 EnableModeless(IDocHostUIHandler);
3314 else
3315 return hRet;
3317 IUnknown_Release(lpObj);
3318 return S_OK;
3321 /*************************************************************************
3322 * @ [SHLWAPI.357]
3324 * See SHGetNewLinkInfoW.
3326 BOOL WINAPI SHGetNewLinkInfoWrapW(LPCWSTR pszLinkTo, LPCWSTR pszDir, LPWSTR pszName,
3327 BOOL *pfMustCopy, UINT uFlags)
3329 return SHGetNewLinkInfoW(pszLinkTo, pszDir, pszName, pfMustCopy, uFlags);
3332 /*************************************************************************
3333 * @ [SHLWAPI.358]
3335 * See SHDefExtractIconW.
3337 UINT WINAPI SHDefExtractIconWrapW(LPCWSTR pszIconFile, int iIndex, UINT uFlags, HICON* phiconLarge,
3338 HICON* phiconSmall, UINT nIconSize)
3340 return SHDefExtractIconW(pszIconFile, iIndex, uFlags, phiconLarge, phiconSmall, nIconSize);
3343 /*************************************************************************
3344 * @ [SHLWAPI.363]
3346 * Get and show a context menu from a shell folder.
3348 * PARAMS
3349 * hWnd [I] Window displaying the shell folder
3350 * lpFolder [I] IShellFolder interface
3351 * lpApidl [I] Id for the particular folder desired
3352 * bInvokeDefault [I] Whether to invoke the default menu item
3354 * RETURNS
3355 * Success: S_OK. If bInvokeDefault is TRUE, the default menu action was
3356 * executed.
3357 * Failure: An HRESULT error code indicating the error.
3359 HRESULT WINAPI SHInvokeCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl, BOOL bInvokeDefault)
3361 IContextMenu *iContext;
3362 HRESULT hRet = E_FAIL;
3364 TRACE("(%p,%p,%p,%d)\n", hWnd, lpFolder, lpApidl, bInvokeDefault);
3366 if (!lpFolder)
3367 return hRet;
3369 /* Get the context menu from the shell folder */
3370 hRet = IShellFolder_GetUIObjectOf(lpFolder, hWnd, 1, &lpApidl,
3371 &IID_IContextMenu, 0, (void**)&iContext);
3372 if (SUCCEEDED(hRet))
3374 HMENU hMenu;
3375 if ((hMenu = CreatePopupMenu()))
3377 HRESULT hQuery;
3378 DWORD dwDefaultId = 0;
3380 /* Add the context menu entries to the popup */
3381 hQuery = IContextMenu_QueryContextMenu(iContext, hMenu, 0, 1, 0x7FFF,
3382 bInvokeDefault ? CMF_NORMAL : CMF_DEFAULTONLY);
3384 if (SUCCEEDED(hQuery))
3386 if (bInvokeDefault &&
3387 (dwDefaultId = GetMenuDefaultItem(hMenu, 0, 0)) != 0xFFFFFFFF)
3389 CMINVOKECOMMANDINFO cmIci;
3390 /* Invoke the default item */
3391 memset(&cmIci,0,sizeof(cmIci));
3392 cmIci.cbSize = sizeof(cmIci);
3393 cmIci.fMask = CMIC_MASK_ASYNCOK;
3394 cmIci.hwnd = hWnd;
3395 cmIci.lpVerb = MAKEINTRESOURCEA(dwDefaultId);
3396 cmIci.nShow = SW_SCROLLCHILDREN;
3398 hRet = IContextMenu_InvokeCommand(iContext, &cmIci);
3401 DestroyMenu(hMenu);
3403 IContextMenu_Release(iContext);
3405 return hRet;
3408 /*************************************************************************
3409 * @ [SHLWAPI.370]
3411 * See ExtractIconW.
3413 HICON WINAPI ExtractIconWrapW(HINSTANCE hInstance, LPCWSTR lpszExeFileName,
3414 UINT nIconIndex)
3416 return ExtractIconW(hInstance, lpszExeFileName, nIconIndex);
3419 /*************************************************************************
3420 * @ [SHLWAPI.377]
3422 * Load a library from the directory of a particular process.
3424 * PARAMS
3425 * new_mod [I] Library name
3426 * inst_hwnd [I] Module whose directory is to be used
3427 * dwCrossCodePage [I] Should be FALSE (currently ignored)
3429 * RETURNS
3430 * Success: A handle to the loaded module
3431 * Failure: A NULL handle.
3433 HMODULE WINAPI MLLoadLibraryA(LPCSTR new_mod, HMODULE inst_hwnd, DWORD dwCrossCodePage)
3435 /* FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for
3436 * each call here.
3437 * FIXME: Native shows calls to:
3438 * SHRegGetUSValue for "Software\Microsoft\Internet Explorer\International"
3439 * CheckVersion
3440 * RegOpenKeyExA for "HKLM\Software\Microsoft\Internet Explorer"
3441 * RegQueryValueExA for "LPKInstalled"
3442 * RegCloseKey
3443 * RegOpenKeyExA for "HKCU\Software\Microsoft\Internet Explorer\International"
3444 * RegQueryValueExA for "ResourceLocale"
3445 * RegCloseKey
3446 * RegOpenKeyExA for "HKLM\Software\Microsoft\Active Setup\Installed Components\{guid}"
3447 * RegQueryValueExA for "Locale"
3448 * RegCloseKey
3449 * and then tests the Locale ("en" for me).
3450 * code below
3451 * after the code then a DPA_Create (first time) and DPA_InsertPtr are done.
3453 CHAR mod_path[2*MAX_PATH];
3454 LPSTR ptr;
3455 DWORD len;
3457 FIXME("(%s,%p,%d) semi-stub!\n", debugstr_a(new_mod), inst_hwnd, dwCrossCodePage);
3458 len = GetModuleFileNameA(inst_hwnd, mod_path, sizeof(mod_path));
3459 if (!len || len >= sizeof(mod_path)) return NULL;
3461 ptr = strrchr(mod_path, '\\');
3462 if (ptr) {
3463 strcpy(ptr+1, new_mod);
3464 TRACE("loading %s\n", debugstr_a(mod_path));
3465 return LoadLibraryA(mod_path);
3467 return NULL;
3470 /*************************************************************************
3471 * @ [SHLWAPI.378]
3473 * Unicode version of MLLoadLibraryA.
3475 HMODULE WINAPI MLLoadLibraryW(LPCWSTR new_mod, HMODULE inst_hwnd, DWORD dwCrossCodePage)
3477 WCHAR mod_path[2*MAX_PATH];
3478 LPWSTR ptr;
3479 DWORD len;
3481 FIXME("(%s,%p,%d) semi-stub!\n", debugstr_w(new_mod), inst_hwnd, dwCrossCodePage);
3482 len = GetModuleFileNameW(inst_hwnd, mod_path, sizeof(mod_path) / sizeof(WCHAR));
3483 if (!len || len >= sizeof(mod_path) / sizeof(WCHAR)) return NULL;
3485 ptr = strrchrW(mod_path, '\\');
3486 if (ptr) {
3487 strcpyW(ptr+1, new_mod);
3488 TRACE("loading %s\n", debugstr_w(mod_path));
3489 return LoadLibraryW(mod_path);
3491 return NULL;
3494 /*************************************************************************
3495 * ColorAdjustLuma [SHLWAPI.@]
3497 * Adjust the luminosity of a color
3499 * PARAMS
3500 * cRGB [I] RGB value to convert
3501 * dwLuma [I] Luma adjustment
3502 * bUnknown [I] Unknown
3504 * RETURNS
3505 * The adjusted RGB color.
3507 COLORREF WINAPI ColorAdjustLuma(COLORREF cRGB, int dwLuma, BOOL bUnknown)
3509 TRACE("(0x%8x,%d,%d)\n", cRGB, dwLuma, bUnknown);
3511 if (dwLuma)
3513 WORD wH, wL, wS;
3515 ColorRGBToHLS(cRGB, &wH, &wL, &wS);
3517 FIXME("Ignoring luma adjustment\n");
3519 /* FIXME: The adjustment is not linear */
3521 cRGB = ColorHLSToRGB(wH, wL, wS);
3523 return cRGB;
3526 /*************************************************************************
3527 * @ [SHLWAPI.389]
3529 * See GetSaveFileNameW.
3531 BOOL WINAPI GetSaveFileNameWrapW(LPOPENFILENAMEW ofn)
3533 return GetSaveFileNameW(ofn);
3536 /*************************************************************************
3537 * @ [SHLWAPI.390]
3539 * See WNetRestoreConnectionW.
3541 DWORD WINAPI WNetRestoreConnectionWrapW(HWND hwndOwner, LPWSTR lpszDevice)
3543 return WNetRestoreConnectionW(hwndOwner, lpszDevice);
3546 /*************************************************************************
3547 * @ [SHLWAPI.391]
3549 * See WNetGetLastErrorW.
3551 DWORD WINAPI WNetGetLastErrorWrapW(LPDWORD lpError, LPWSTR lpErrorBuf, DWORD nErrorBufSize,
3552 LPWSTR lpNameBuf, DWORD nNameBufSize)
3554 return WNetGetLastErrorW(lpError, lpErrorBuf, nErrorBufSize, lpNameBuf, nNameBufSize);
3557 /*************************************************************************
3558 * @ [SHLWAPI.401]
3560 * See PageSetupDlgW.
3562 BOOL WINAPI PageSetupDlgWrapW(LPPAGESETUPDLGW pagedlg)
3564 return PageSetupDlgW(pagedlg);
3567 /*************************************************************************
3568 * @ [SHLWAPI.402]
3570 * See PrintDlgW.
3572 BOOL WINAPI PrintDlgWrapW(LPPRINTDLGW printdlg)
3574 return PrintDlgW(printdlg);
3577 /*************************************************************************
3578 * @ [SHLWAPI.403]
3580 * See GetOpenFileNameW.
3582 BOOL WINAPI GetOpenFileNameWrapW(LPOPENFILENAMEW ofn)
3584 return GetOpenFileNameW(ofn);
3587 /*************************************************************************
3588 * @ [SHLWAPI.404]
3590 HRESULT WINAPI SHIShellFolder_EnumObjects(LPSHELLFOLDER lpFolder, HWND hwnd, SHCONTF flags, IEnumIDList **ppenum)
3592 IPersist *persist;
3593 HRESULT hr;
3595 hr = IShellFolder_QueryInterface(lpFolder, &IID_IPersist, (LPVOID)&persist);
3596 if(SUCCEEDED(hr))
3598 CLSID clsid;
3599 hr = IPersist_GetClassID(persist, &clsid);
3600 if(SUCCEEDED(hr))
3602 if(IsEqualCLSID(&clsid, &CLSID_ShellFSFolder))
3603 hr = IShellFolder_EnumObjects(lpFolder, hwnd, flags, ppenum);
3604 else
3605 hr = E_FAIL;
3607 IPersist_Release(persist);
3609 return hr;
3612 /* INTERNAL: Map from HLS color space to RGB */
3613 static WORD ConvertHue(int wHue, WORD wMid1, WORD wMid2)
3615 wHue = wHue > 240 ? wHue - 240 : wHue < 0 ? wHue + 240 : wHue;
3617 if (wHue > 160)
3618 return wMid1;
3619 else if (wHue > 120)
3620 wHue = 160 - wHue;
3621 else if (wHue > 40)
3622 return wMid2;
3624 return ((wHue * (wMid2 - wMid1) + 20) / 40) + wMid1;
3627 /* Convert to RGB and scale into RGB range (0..255) */
3628 #define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240
3630 /*************************************************************************
3631 * ColorHLSToRGB [SHLWAPI.@]
3633 * Convert from hls color space into an rgb COLORREF.
3635 * PARAMS
3636 * wHue [I] Hue amount
3637 * wLuminosity [I] Luminosity amount
3638 * wSaturation [I] Saturation amount
3640 * RETURNS
3641 * A COLORREF representing the converted color.
3643 * NOTES
3644 * Input hls values are constrained to the range (0..240).
3646 COLORREF WINAPI ColorHLSToRGB(WORD wHue, WORD wLuminosity, WORD wSaturation)
3648 WORD wRed;
3650 if (wSaturation)
3652 WORD wGreen, wBlue, wMid1, wMid2;
3654 if (wLuminosity > 120)
3655 wMid2 = wSaturation + wLuminosity - (wSaturation * wLuminosity + 120) / 240;
3656 else
3657 wMid2 = ((wSaturation + 240) * wLuminosity + 120) / 240;
3659 wMid1 = wLuminosity * 2 - wMid2;
3661 wRed = GET_RGB(wHue + 80);
3662 wGreen = GET_RGB(wHue);
3663 wBlue = GET_RGB(wHue - 80);
3665 return RGB(wRed, wGreen, wBlue);
3668 wRed = wLuminosity * 255 / 240;
3669 return RGB(wRed, wRed, wRed);
3672 /*************************************************************************
3673 * @ [SHLWAPI.413]
3675 * Get the current docking status of the system.
3677 * PARAMS
3678 * dwFlags [I] DOCKINFO_ flags from "winbase.h", unused
3680 * RETURNS
3681 * One of DOCKINFO_UNDOCKED, DOCKINFO_UNDOCKED, or 0 if the system is not
3682 * a notebook.
3684 DWORD WINAPI SHGetMachineInfo(DWORD dwFlags)
3686 HW_PROFILE_INFOA hwInfo;
3688 TRACE("(0x%08x)\n", dwFlags);
3690 GetCurrentHwProfileA(&hwInfo);
3691 switch (hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED))
3693 case DOCKINFO_DOCKED:
3694 case DOCKINFO_UNDOCKED:
3695 return hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED);
3696 default:
3697 return 0;
3701 /*************************************************************************
3702 * @ [SHLWAPI.418]
3704 * Function seems to do FreeLibrary plus other things.
3706 * FIXME native shows the following calls:
3707 * RtlEnterCriticalSection
3708 * LocalFree
3709 * GetProcAddress(Comctl32??, 150L)
3710 * DPA_DeletePtr
3711 * RtlLeaveCriticalSection
3712 * followed by the FreeLibrary.
3713 * The above code may be related to .377 above.
3715 BOOL WINAPI MLFreeLibrary(HMODULE hModule)
3717 FIXME("(%p) semi-stub\n", hModule);
3718 return FreeLibrary(hModule);
3721 /*************************************************************************
3722 * @ [SHLWAPI.419]
3724 BOOL WINAPI SHFlushSFCacheWrap(void) {
3725 FIXME(": stub\n");
3726 return TRUE;
3729 /*************************************************************************
3730 * @ [SHLWAPI.429]
3731 * FIXME I have no idea what this function does or what its arguments are.
3733 BOOL WINAPI MLIsMLHInstance(HINSTANCE hInst)
3735 FIXME("(%p) stub\n", hInst);
3736 return FALSE;
3740 /*************************************************************************
3741 * @ [SHLWAPI.430]
3743 DWORD WINAPI MLSetMLHInstance(HINSTANCE hInst, HANDLE hHeap)
3745 FIXME("(%p,%p) stub\n", hInst, hHeap);
3746 return E_FAIL; /* This is what is used if shlwapi not loaded */
3749 /*************************************************************************
3750 * @ [SHLWAPI.431]
3752 DWORD WINAPI MLClearMLHInstance(DWORD x)
3754 FIXME("(0x%08x)stub\n", x);
3755 return 0xabba1247;
3758 /*************************************************************************
3759 * @ [SHLWAPI.432]
3761 * See SHSendMessageBroadcastW
3764 DWORD WINAPI SHSendMessageBroadcastA(UINT uMsg, WPARAM wParam, LPARAM lParam)
3766 return SendMessageTimeoutA(HWND_BROADCAST, uMsg, wParam, lParam,
3767 SMTO_ABORTIFHUNG, 2000, NULL);
3770 /*************************************************************************
3771 * @ [SHLWAPI.433]
3773 * A wrapper for sending Broadcast Messages to all top level Windows
3776 DWORD WINAPI SHSendMessageBroadcastW(UINT uMsg, WPARAM wParam, LPARAM lParam)
3778 return SendMessageTimeoutW(HWND_BROADCAST, uMsg, wParam, lParam,
3779 SMTO_ABORTIFHUNG, 2000, NULL);
3782 /*************************************************************************
3783 * @ [SHLWAPI.436]
3785 * Convert a Unicode string CLSID into a CLSID.
3787 * PARAMS
3788 * idstr [I] string containing a CLSID in text form
3789 * id [O] CLSID extracted from the string
3791 * RETURNS
3792 * S_OK on success or E_INVALIDARG on failure
3794 HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR idstr, CLSID *id)
3796 return CLSIDFromString((LPOLESTR)idstr, id);
3799 /*************************************************************************
3800 * @ [SHLWAPI.437]
3802 * Determine if the OS supports a given feature.
3804 * PARAMS
3805 * dwFeature [I] Feature requested (undocumented)
3807 * RETURNS
3808 * TRUE If the feature is available.
3809 * FALSE If the feature is not available.
3811 BOOL WINAPI IsOS(DWORD feature)
3813 OSVERSIONINFOA osvi;
3814 DWORD platform, majorv, minorv;
3816 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
3817 if(!GetVersionExA(&osvi)) {
3818 ERR("GetVersionEx failed\n");
3819 return FALSE;
3822 majorv = osvi.dwMajorVersion;
3823 minorv = osvi.dwMinorVersion;
3824 platform = osvi.dwPlatformId;
3826 #define ISOS_RETURN(x) \
3827 TRACE("(0x%x) ret=%d\n",feature,(x)); \
3828 return (x);
3830 switch(feature) {
3831 case OS_WIN32SORGREATER:
3832 ISOS_RETURN(platform == VER_PLATFORM_WIN32s
3833 || platform == VER_PLATFORM_WIN32_WINDOWS)
3834 case OS_NT:
3835 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3836 case OS_WIN95ORGREATER:
3837 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS)
3838 case OS_NT4ORGREATER:
3839 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 4)
3840 case OS_WIN2000ORGREATER_ALT:
3841 case OS_WIN2000ORGREATER:
3842 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5)
3843 case OS_WIN98ORGREATER:
3844 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv >= 10)
3845 case OS_WIN98_GOLD:
3846 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv == 10)
3847 case OS_WIN2000PRO:
3848 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5)
3849 case OS_WIN2000SERVER:
3850 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3851 case OS_WIN2000ADVSERVER:
3852 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3853 case OS_WIN2000DATACENTER:
3854 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3855 case OS_WIN2000TERMINAL:
3856 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3857 case OS_EMBEDDED:
3858 FIXME("(OS_EMBEDDED) What should we return here?\n");
3859 return FALSE;
3860 case OS_TERMINALCLIENT:
3861 FIXME("(OS_TERMINALCLIENT) What should we return here?\n");
3862 return FALSE;
3863 case OS_TERMINALREMOTEADMIN:
3864 FIXME("(OS_TERMINALREMOTEADMIN) What should we return here?\n");
3865 return FALSE;
3866 case OS_WIN95_GOLD:
3867 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv == 0)
3868 case OS_MEORGREATER:
3869 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv >= 90)
3870 case OS_XPORGREATER:
3871 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5 && minorv >= 1)
3872 case OS_HOME:
3873 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5 && minorv >= 1)
3874 case OS_PROFESSIONAL:
3875 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3876 case OS_DATACENTER:
3877 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3878 case OS_ADVSERVER:
3879 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5)
3880 case OS_SERVER:
3881 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3882 case OS_TERMINALSERVER:
3883 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3884 case OS_PERSONALTERMINALSERVER:
3885 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && minorv >= 1 && majorv >= 5)
3886 case OS_FASTUSERSWITCHING:
3887 FIXME("(OS_FASTUSERSWITCHING) What should we return here?\n");
3888 return TRUE;
3889 case OS_WELCOMELOGONUI:
3890 FIXME("(OS_WELCOMELOGONUI) What should we return here?\n");
3891 return FALSE;
3892 case OS_DOMAINMEMBER:
3893 FIXME("(OS_DOMAINMEMBER) What should we return here?\n");
3894 return TRUE;
3895 case OS_ANYSERVER:
3896 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3897 case OS_WOW6432:
3898 FIXME("(OS_WOW6432) Should we check this?\n");
3899 return FALSE;
3900 case OS_WEBSERVER:
3901 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3902 case OS_SMALLBUSINESSSERVER:
3903 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3904 case OS_TABLETPC:
3905 FIXME("(OS_TABLEPC) What should we return here?\n");
3906 return FALSE;
3907 case OS_SERVERADMINUI:
3908 FIXME("(OS_SERVERADMINUI) What should we return here?\n");
3909 return FALSE;
3910 case OS_MEDIACENTER:
3911 FIXME("(OS_MEDIACENTER) What should we return here?\n");
3912 return FALSE;
3913 case OS_APPLIANCE:
3914 FIXME("(OS_APPLIANCE) What should we return here?\n");
3915 return FALSE;
3916 case 0x25: /*OS_VISTAORGREATER*/
3917 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 6)
3920 #undef ISOS_RETURN
3922 WARN("(0x%x) unknown parameter\n",feature);
3924 return FALSE;
3927 /*************************************************************************
3928 * @ [SHLWAPI.439]
3930 HRESULT WINAPI SHLoadRegUIStringW(HKEY hkey, LPCWSTR value, LPWSTR buf, DWORD size)
3932 DWORD type, sz = size;
3934 if(RegQueryValueExW(hkey, value, NULL, &type, (LPBYTE)buf, &sz) != ERROR_SUCCESS)
3935 return E_FAIL;
3937 return SHLoadIndirectString(buf, buf, size, NULL);
3940 /*************************************************************************
3941 * @ [SHLWAPI.478]
3943 * Call IInputObject_TranslateAcceleratorIO() on an object.
3945 * PARAMS
3946 * lpUnknown [I] Object supporting the IInputObject interface.
3947 * lpMsg [I] Key message to be processed.
3949 * RETURNS
3950 * Success: S_OK.
3951 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
3953 HRESULT WINAPI IUnknown_TranslateAcceleratorIO(IUnknown *lpUnknown, LPMSG lpMsg)
3955 IInputObject* lpInput = NULL;
3956 HRESULT hRet = E_INVALIDARG;
3958 TRACE("(%p,%p)\n", lpUnknown, lpMsg);
3959 if (lpUnknown)
3961 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInputObject,
3962 (void**)&lpInput);
3963 if (SUCCEEDED(hRet) && lpInput)
3965 hRet = IInputObject_TranslateAcceleratorIO(lpInput, lpMsg);
3966 IInputObject_Release(lpInput);
3969 return hRet;
3972 /*************************************************************************
3973 * @ [SHLWAPI.481]
3975 * Call IInputObject_HasFocusIO() on an object.
3977 * PARAMS
3978 * lpUnknown [I] Object supporting the IInputObject interface.
3980 * RETURNS
3981 * Success: S_OK, if lpUnknown is an IInputObject object and has the focus,
3982 * or S_FALSE otherwise.
3983 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
3985 HRESULT WINAPI IUnknown_HasFocusIO(IUnknown *lpUnknown)
3987 IInputObject* lpInput = NULL;
3988 HRESULT hRet = E_INVALIDARG;
3990 TRACE("(%p)\n", lpUnknown);
3991 if (lpUnknown)
3993 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInputObject,
3994 (void**)&lpInput);
3995 if (SUCCEEDED(hRet) && lpInput)
3997 hRet = IInputObject_HasFocusIO(lpInput);
3998 IInputObject_Release(lpInput);
4001 return hRet;
4004 /*************************************************************************
4005 * ColorRGBToHLS [SHLWAPI.@]
4007 * Convert an rgb COLORREF into the hls color space.
4009 * PARAMS
4010 * cRGB [I] Source rgb value
4011 * pwHue [O] Destination for converted hue
4012 * pwLuminance [O] Destination for converted luminance
4013 * pwSaturation [O] Destination for converted saturation
4015 * RETURNS
4016 * Nothing. pwHue, pwLuminance and pwSaturation are set to the converted
4017 * values.
4019 * NOTES
4020 * Output HLS values are constrained to the range (0..240).
4021 * For Achromatic conversions, Hue is set to 160.
4023 VOID WINAPI ColorRGBToHLS(COLORREF cRGB, LPWORD pwHue,
4024 LPWORD pwLuminance, LPWORD pwSaturation)
4026 int wR, wG, wB, wMax, wMin, wHue, wLuminosity, wSaturation;
4028 TRACE("(%08x,%p,%p,%p)\n", cRGB, pwHue, pwLuminance, pwSaturation);
4030 wR = GetRValue(cRGB);
4031 wG = GetGValue(cRGB);
4032 wB = GetBValue(cRGB);
4034 wMax = max(wR, max(wG, wB));
4035 wMin = min(wR, min(wG, wB));
4037 /* Luminosity */
4038 wLuminosity = ((wMax + wMin) * 240 + 255) / 510;
4040 if (wMax == wMin)
4042 /* Achromatic case */
4043 wSaturation = 0;
4044 /* Hue is now unrepresentable, but this is what native returns... */
4045 wHue = 160;
4047 else
4049 /* Chromatic case */
4050 int wDelta = wMax - wMin, wRNorm, wGNorm, wBNorm;
4052 /* Saturation */
4053 if (wLuminosity <= 120)
4054 wSaturation = ((wMax + wMin)/2 + wDelta * 240) / (wMax + wMin);
4055 else
4056 wSaturation = ((510 - wMax - wMin)/2 + wDelta * 240) / (510 - wMax - wMin);
4058 /* Hue */
4059 wRNorm = (wDelta/2 + wMax * 40 - wR * 40) / wDelta;
4060 wGNorm = (wDelta/2 + wMax * 40 - wG * 40) / wDelta;
4061 wBNorm = (wDelta/2 + wMax * 40 - wB * 40) / wDelta;
4063 if (wR == wMax)
4064 wHue = wBNorm - wGNorm;
4065 else if (wG == wMax)
4066 wHue = 80 + wRNorm - wBNorm;
4067 else
4068 wHue = 160 + wGNorm - wRNorm;
4069 if (wHue < 0)
4070 wHue += 240;
4071 else if (wHue > 240)
4072 wHue -= 240;
4074 if (pwHue)
4075 *pwHue = wHue;
4076 if (pwLuminance)
4077 *pwLuminance = wLuminosity;
4078 if (pwSaturation)
4079 *pwSaturation = wSaturation;
4082 /*************************************************************************
4083 * SHCreateShellPalette [SHLWAPI.@]
4085 HPALETTE WINAPI SHCreateShellPalette(HDC hdc)
4087 FIXME("stub\n");
4088 return CreateHalftonePalette(hdc);
4091 /*************************************************************************
4092 * SHGetInverseCMAP (SHLWAPI.@)
4094 * Get an inverse color map table.
4096 * PARAMS
4097 * lpCmap [O] Destination for color map
4098 * dwSize [I] Size of memory pointed to by lpCmap
4100 * RETURNS
4101 * Success: S_OK.
4102 * Failure: E_POINTER, If lpCmap is invalid.
4103 * E_INVALIDARG, If dwFlags is invalid
4104 * E_OUTOFMEMORY, If there is no memory available
4106 * NOTES
4107 * dwSize may only be CMAP_PTR_SIZE (4) or CMAP_SIZE (8192).
4108 * If dwSize = CMAP_PTR_SIZE, *lpCmap is set to the address of this DLL's
4109 * internal CMap.
4110 * If dwSize = CMAP_SIZE, lpCmap is filled with a copy of the data from
4111 * this DLL's internal CMap.
4113 HRESULT WINAPI SHGetInverseCMAP(LPDWORD dest, DWORD dwSize)
4115 if (dwSize == 4) {
4116 FIXME(" - returning bogus address for SHGetInverseCMAP\n");
4117 *dest = (DWORD)0xabba1249;
4118 return 0;
4120 FIXME("(%p, %#x) stub\n", dest, dwSize);
4121 return 0;
4124 /*************************************************************************
4125 * SHIsLowMemoryMachine [SHLWAPI.@]
4127 * Determine if the current computer has low memory.
4129 * PARAMS
4130 * x [I] FIXME
4132 * RETURNS
4133 * TRUE if the users machine has 16 Megabytes of memory or less,
4134 * FALSE otherwise.
4136 BOOL WINAPI SHIsLowMemoryMachine (DWORD x)
4138 FIXME("(0x%08x) stub\n", x);
4139 return FALSE;
4142 /*************************************************************************
4143 * GetMenuPosFromID [SHLWAPI.@]
4145 * Return the position of a menu item from its Id.
4147 * PARAMS
4148 * hMenu [I] Menu containing the item
4149 * wID [I] Id of the menu item
4151 * RETURNS
4152 * Success: The index of the menu item in hMenu.
4153 * Failure: -1, If the item is not found.
4155 INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID)
4157 MENUITEMINFOW mi;
4158 INT nCount = GetMenuItemCount(hMenu), nIter = 0;
4160 while (nIter < nCount)
4162 mi.cbSize = sizeof(mi);
4163 mi.fMask = MIIM_ID;
4164 if (GetMenuItemInfoW(hMenu, nIter, TRUE, &mi) && mi.wID == wID)
4165 return nIter;
4166 nIter++;
4168 return -1;
4171 /*************************************************************************
4172 * @ [SHLWAPI.179]
4174 * Same as SHLWAPI.GetMenuPosFromID
4176 DWORD WINAPI SHMenuIndexFromID(HMENU hMenu, UINT uID)
4178 return GetMenuPosFromID(hMenu, uID);
4182 /*************************************************************************
4183 * @ [SHLWAPI.448]
4185 VOID WINAPI FixSlashesAndColonW(LPWSTR lpwstr)
4187 while (*lpwstr)
4189 if (*lpwstr == '/')
4190 *lpwstr = '\\';
4191 lpwstr++;
4196 /*************************************************************************
4197 * @ [SHLWAPI.461]
4199 DWORD WINAPI SHGetAppCompatFlags(DWORD dwUnknown)
4201 FIXME("(0x%08x) stub\n", dwUnknown);
4202 return 0;
4206 /*************************************************************************
4207 * @ [SHLWAPI.549]
4209 HRESULT WINAPI SHCoCreateInstanceAC(REFCLSID rclsid, LPUNKNOWN pUnkOuter,
4210 DWORD dwClsContext, REFIID iid, LPVOID *ppv)
4212 return CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, ppv);
4215 /*************************************************************************
4216 * SHSkipJunction [SHLWAPI.@]
4218 * Determine if a bind context can be bound to an object
4220 * PARAMS
4221 * pbc [I] Bind context to check
4222 * pclsid [I] CLSID of object to be bound to
4224 * RETURNS
4225 * TRUE: If it is safe to bind
4226 * FALSE: If pbc is invalid or binding would not be safe
4229 BOOL WINAPI SHSkipJunction(IBindCtx *pbc, const CLSID *pclsid)
4231 static WCHAR szSkipBinding[] = { 'S','k','i','p',' ',
4232 'B','i','n','d','i','n','g',' ','C','L','S','I','D','\0' };
4233 BOOL bRet = FALSE;
4235 if (pbc)
4237 IUnknown* lpUnk;
4239 if (SUCCEEDED(IBindCtx_GetObjectParam(pbc, szSkipBinding, &lpUnk)))
4241 CLSID clsid;
4243 if (SUCCEEDED(IUnknown_GetClassID(lpUnk, &clsid)) &&
4244 IsEqualGUID(pclsid, &clsid))
4245 bRet = TRUE;
4247 IUnknown_Release(lpUnk);
4250 return bRet;
4253 /***********************************************************************
4254 * SHGetShellKey (SHLWAPI.@)
4256 DWORD WINAPI SHGetShellKey(DWORD a, DWORD b, DWORD c)
4258 FIXME("(%x, %x, %x): stub\n", a, b, c);
4259 return 0x50;
4262 /***********************************************************************
4263 * SHQueueUserWorkItem (SHLWAPI.@)
4265 BOOL WINAPI SHQueueUserWorkItem(LPTHREAD_START_ROUTINE pfnCallback,
4266 LPVOID pContext, LONG lPriority, DWORD_PTR dwTag,
4267 DWORD_PTR *pdwId, LPCSTR pszModule, DWORD dwFlags)
4269 TRACE("(%p, %p, %d, %lx, %p, %s, %08x)\n", pfnCallback, pContext,
4270 lPriority, dwTag, pdwId, debugstr_a(pszModule), dwFlags);
4272 if(lPriority || dwTag || pdwId || pszModule || dwFlags)
4273 FIXME("Unsupported arguments\n");
4275 return QueueUserWorkItem(pfnCallback, pContext, 0);
4278 /***********************************************************************
4279 * SHSetTimerQueueTimer (SHLWAPI.263)
4281 HANDLE WINAPI SHSetTimerQueueTimer(HANDLE hQueue,
4282 WAITORTIMERCALLBACK pfnCallback, LPVOID pContext, DWORD dwDueTime,
4283 DWORD dwPeriod, LPCSTR lpszLibrary, DWORD dwFlags)
4285 HANDLE hNewTimer;
4287 /* SHSetTimerQueueTimer flags -> CreateTimerQueueTimer flags */
4288 if (dwFlags & TPS_LONGEXECTIME) {
4289 dwFlags &= ~TPS_LONGEXECTIME;
4290 dwFlags |= WT_EXECUTELONGFUNCTION;
4292 if (dwFlags & TPS_EXECUTEIO) {
4293 dwFlags &= ~TPS_EXECUTEIO;
4294 dwFlags |= WT_EXECUTEINIOTHREAD;
4297 if (!CreateTimerQueueTimer(&hNewTimer, hQueue, pfnCallback, pContext,
4298 dwDueTime, dwPeriod, dwFlags))
4299 return NULL;
4301 return hNewTimer;
4304 /***********************************************************************
4305 * IUnknown_OnFocusChangeIS (SHLWAPI.@)
4307 HRESULT WINAPI IUnknown_OnFocusChangeIS(LPUNKNOWN lpUnknown, LPUNKNOWN pFocusObject, BOOL bFocus)
4309 IInputObjectSite *pIOS = NULL;
4310 HRESULT hRet = E_INVALIDARG;
4312 TRACE("(%p, %p, %s)\n", lpUnknown, pFocusObject, bFocus ? "TRUE" : "FALSE");
4314 if (lpUnknown)
4316 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInputObjectSite,
4317 (void **)&pIOS);
4318 if (SUCCEEDED(hRet) && pIOS)
4320 hRet = IInputObjectSite_OnFocusChangeIS(pIOS, pFocusObject, bFocus);
4321 IInputObjectSite_Release(pIOS);
4324 return hRet;
4327 /***********************************************************************
4328 * SHGetValueW (SHLWAPI.@)
4330 HRESULT WINAPI SKGetValueW(DWORD a, LPWSTR b, LPWSTR c, DWORD d, DWORD e, DWORD f)
4332 FIXME("(%x, %s, %s, %x, %x, %x): stub\n", a, debugstr_w(b), debugstr_w(c), d, e, f);
4333 return E_FAIL;
4336 typedef HRESULT (WINAPI *DllGetVersion_func)(DLLVERSIONINFO *);
4338 /***********************************************************************
4339 * GetUIVersion (SHLWAPI.452)
4341 DWORD WINAPI GetUIVersion(void)
4343 static DWORD version;
4345 if (!version)
4347 DllGetVersion_func pDllGetVersion;
4348 HMODULE dll = LoadLibraryA("shell32.dll");
4349 if (!dll) return 0;
4351 pDllGetVersion = (DllGetVersion_func)GetProcAddress(dll, "DllGetVersion");
4352 if (pDllGetVersion)
4354 DLLVERSIONINFO dvi;
4355 dvi.cbSize = sizeof(DLLVERSIONINFO);
4356 if (pDllGetVersion(&dvi) == S_OK) version = dvi.dwMajorVersion;
4358 FreeLibrary( dll );
4359 if (!version) version = 3; /* old shell dlls don't have DllGetVersion */
4361 return version;
4364 /***********************************************************************
4365 * ShellMessageBoxWrapW [SHLWAPI.388]
4367 * See shell32.ShellMessageBoxW
4369 * NOTE:
4370 * shlwapi.ShellMessageBoxWrapW is a duplicate of shell32.ShellMessageBoxW
4371 * because we can't forward to it in the .spec file since it's exported by
4372 * ordinal. If you change the implementation here please update the code in
4373 * shell32 as well.
4375 INT WINAPIV ShellMessageBoxWrapW(HINSTANCE hInstance, HWND hWnd, LPCWSTR lpText,
4376 LPCWSTR lpCaption, UINT uType, ...)
4378 WCHAR szText[100], szTitle[100];
4379 LPCWSTR pszText = szText, pszTitle = szTitle;
4380 LPWSTR pszTemp;
4381 __ms_va_list args;
4382 int ret;
4384 __ms_va_start(args, uType);
4386 TRACE("(%p,%p,%p,%p,%08x)\n", hInstance, hWnd, lpText, lpCaption, uType);
4388 if (IS_INTRESOURCE(lpCaption))
4389 LoadStringW(hInstance, LOWORD(lpCaption), szTitle, sizeof(szTitle)/sizeof(szTitle[0]));
4390 else
4391 pszTitle = lpCaption;
4393 if (IS_INTRESOURCE(lpText))
4394 LoadStringW(hInstance, LOWORD(lpText), szText, sizeof(szText)/sizeof(szText[0]));
4395 else
4396 pszText = lpText;
4398 FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
4399 pszText, 0, 0, (LPWSTR)&pszTemp, 0, &args);
4401 __ms_va_end(args);
4403 ret = MessageBoxW(hWnd, pszTemp, pszTitle, uType);
4404 LocalFree(pszTemp);
4405 return ret;
4408 HRESULT WINAPI IUnknown_QueryServiceExec(IUnknown *unk, REFIID service, REFIID clsid,
4409 DWORD x1, DWORD x2, DWORD x3, void **ppvOut)
4411 FIXME("%p %s %s %08x %08x %08x %p\n", unk,
4412 debugstr_guid(service), debugstr_guid(clsid), x1, x2, x3, ppvOut);
4413 return E_NOTIMPL;
4416 HRESULT WINAPI IUnknown_ProfferService(IUnknown *unk, void *x0, void *x1, void *x2)
4418 FIXME("%p %p %p %p\n", unk, x0, x1, x2);
4419 return E_NOTIMPL;
4422 /***********************************************************************
4423 * ZoneComputePaneSize [SHLWAPI.382]
4425 UINT WINAPI ZoneComputePaneSize(HWND hwnd)
4427 FIXME("\n");
4428 return 0x95;
4431 /***********************************************************************
4432 * SHChangeNotifyWrap [SHLWAPI.394]
4434 void WINAPI SHChangeNotifyWrap(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
4436 SHChangeNotify(wEventId, uFlags, dwItem1, dwItem2);
4439 typedef struct SHELL_USER_SID { /* according to MSDN this should be in shlobj.h... */
4440 SID_IDENTIFIER_AUTHORITY sidAuthority;
4441 DWORD dwUserGroupID;
4442 DWORD dwUserID;
4443 } SHELL_USER_SID, *PSHELL_USER_SID;
4445 typedef struct SHELL_USER_PERMISSION { /* ...and this should be in shlwapi.h */
4446 SHELL_USER_SID susID;
4447 DWORD dwAccessType;
4448 BOOL fInherit;
4449 DWORD dwAccessMask;
4450 DWORD dwInheritMask;
4451 DWORD dwInheritAccessMask;
4452 } SHELL_USER_PERMISSION, *PSHELL_USER_PERMISSION;
4454 /***********************************************************************
4455 * GetShellSecurityDescriptor [SHLWAPI.475]
4457 * prepares SECURITY_DESCRIPTOR from a set of ACEs
4459 * PARAMS
4460 * apUserPerm [I] array of pointers to SHELL_USER_PERMISSION structures,
4461 * each of which describes permissions to apply
4462 * cUserPerm [I] number of entries in apUserPerm array
4464 * RETURNS
4465 * success: pointer to SECURITY_DESCRIPTOR
4466 * failure: NULL
4468 * NOTES
4469 * Call should free returned descriptor with LocalFree
4471 PSECURITY_DESCRIPTOR WINAPI GetShellSecurityDescriptor(PSHELL_USER_PERMISSION *apUserPerm, int cUserPerm)
4473 PSID *sidlist;
4474 PSID cur_user = NULL;
4475 BYTE tuUser[2000];
4476 DWORD acl_size;
4477 int sid_count, i;
4478 PSECURITY_DESCRIPTOR psd = NULL;
4480 TRACE("%p %d\n", apUserPerm, cUserPerm);
4482 if (apUserPerm == NULL || cUserPerm <= 0)
4483 return NULL;
4485 sidlist = HeapAlloc(GetProcessHeap(), 0, cUserPerm * sizeof(PSID));
4486 if (!sidlist)
4487 return NULL;
4489 acl_size = sizeof(ACL);
4491 for(sid_count = 0; sid_count < cUserPerm; sid_count++)
4493 static SHELL_USER_SID null_sid = {{SECURITY_NULL_SID_AUTHORITY}, 0, 0};
4494 PSHELL_USER_PERMISSION perm = apUserPerm[sid_count];
4495 PSHELL_USER_SID sid = &perm->susID;
4496 PSID pSid;
4497 BOOL ret = TRUE;
4499 if (!memcmp((void*)sid, (void*)&null_sid, sizeof(SHELL_USER_SID)))
4500 { /* current user's SID */
4501 if (!cur_user)
4503 HANDLE Token;
4504 DWORD bufsize = sizeof(tuUser);
4506 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &Token);
4507 if (ret)
4509 ret = GetTokenInformation(Token, TokenUser, (void*)tuUser, bufsize, &bufsize );
4510 if (ret)
4511 cur_user = ((PTOKEN_USER)tuUser)->User.Sid;
4512 CloseHandle(Token);
4515 pSid = cur_user;
4516 } else if (sid->dwUserID==0) /* one sub-authority */
4517 ret = AllocateAndInitializeSid(&sid->sidAuthority, 1, sid->dwUserGroupID, 0,
4518 0, 0, 0, 0, 0, 0, &pSid);
4519 else
4520 ret = AllocateAndInitializeSid(&sid->sidAuthority, 2, sid->dwUserGroupID, sid->dwUserID,
4521 0, 0, 0, 0, 0, 0, &pSid);
4522 if (!ret)
4523 goto free_sids;
4525 sidlist[sid_count] = pSid;
4526 /* increment acl_size (1 ACE for non-inheritable and 2 ACEs for inheritable records */
4527 acl_size += (sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD) + GetLengthSid(pSid)) * (perm->fInherit ? 2 : 1);
4530 psd = LocalAlloc(0, sizeof(SECURITY_DESCRIPTOR) + acl_size);
4532 if (psd != NULL)
4534 PACL pAcl = (PACL)(((BYTE*)psd)+sizeof(SECURITY_DESCRIPTOR));
4536 if (!InitializeSecurityDescriptor(psd, SECURITY_DESCRIPTOR_REVISION))
4537 goto error;
4539 if (!InitializeAcl(pAcl, acl_size, ACL_REVISION))
4540 goto error;
4542 for(i = 0; i < sid_count; i++)
4544 PSHELL_USER_PERMISSION sup = apUserPerm[i];
4545 PSID sid = sidlist[i];
4547 switch(sup->dwAccessType)
4549 case ACCESS_ALLOWED_ACE_TYPE:
4550 if (!AddAccessAllowedAce(pAcl, ACL_REVISION, sup->dwAccessMask, sid))
4551 goto error;
4552 if (sup->fInherit && !AddAccessAllowedAceEx(pAcl, ACL_REVISION,
4553 (BYTE)sup->dwInheritMask, sup->dwInheritAccessMask, sid))
4554 goto error;
4555 break;
4556 case ACCESS_DENIED_ACE_TYPE:
4557 if (!AddAccessDeniedAce(pAcl, ACL_REVISION, sup->dwAccessMask, sid))
4558 goto error;
4559 if (sup->fInherit && !AddAccessDeniedAceEx(pAcl, ACL_REVISION,
4560 (BYTE)sup->dwInheritMask, sup->dwInheritAccessMask, sid))
4561 goto error;
4562 break;
4563 default:
4564 goto error;
4568 if (!SetSecurityDescriptorDacl(psd, TRUE, pAcl, FALSE))
4569 goto error;
4571 goto free_sids;
4573 error:
4574 LocalFree(psd);
4575 psd = NULL;
4576 free_sids:
4577 for(i = 0; i < sid_count; i++)
4579 if (!cur_user || sidlist[i] != cur_user)
4580 FreeSid(sidlist[i]);
4582 HeapFree(GetProcessHeap(), 0, sidlist);
4584 return psd;
4587 /***********************************************************************
4588 * SHCreatePropertyBagOnRegKey [SHLWAPI.471]
4590 * Creates a property bag from a registry key
4592 * PARAMS
4593 * hKey [I] Handle to the desired registry key
4594 * subkey [I] Name of desired subkey, or NULL to open hKey directly
4595 * grfMode [I] Optional flags
4596 * riid [I] IID of requested property bag interface
4597 * ppv [O] Address to receive pointer to the new interface
4599 * RETURNS
4600 * success: 0
4601 * failure: error code
4604 HRESULT WINAPI SHCreatePropertyBagOnRegKey (HKEY hKey, LPCWSTR subkey,
4605 DWORD grfMode, REFIID riid, void **ppv)
4607 FIXME("%p %s %d %s %p STUB\n", hKey, debugstr_w(subkey), grfMode,
4608 debugstr_guid(riid), ppv);
4610 return E_NOTIMPL;
4613 /***********************************************************************
4614 * SHGetViewStatePropertyBag [SHLWAPI.515]
4616 * Retrieves a property bag in which the view state information of a folder
4617 * can be stored.
4619 * PARAMS
4620 * pidl [I] PIDL of the folder requested
4621 * bag_name [I] Name of the property bag requested
4622 * flags [I] Optional flags
4623 * riid [I] IID of requested property bag interface
4624 * ppv [O] Address to receive pointer to the new interface
4626 * RETURNS
4627 * success: S_OK
4628 * failure: error code
4631 HRESULT WINAPI SHGetViewStatePropertyBag(LPCITEMIDLIST pidl, LPWSTR bag_name,
4632 DWORD flags, REFIID riid, void **ppv)
4634 FIXME("%p %s %d %s %p STUB\n", pidl, debugstr_w(bag_name), flags,
4635 debugstr_guid(riid), ppv);
4637 return E_NOTIMPL;
4640 /***********************************************************************
4641 * SHFormatDateTimeW [SHLWAPI.354]
4643 * Produces a string representation of a time.
4645 * PARAMS
4646 * fileTime [I] Pointer to FILETIME structure specifying the time
4647 * flags [I] Flags specifying the desired output
4648 * buf [O] Pointer to buffer for output
4649 * bufSize [I] Number of characters that can be contained in buffer
4651 * RETURNS
4652 * success: number of characters written to the buffer
4653 * failure: 0
4656 INT WINAPI SHFormatDateTimeW(const FILETIME UNALIGNED *fileTime, DWORD *flags,
4657 LPWSTR buf, UINT bufSize)
4659 FIXME("%p %p %s %d STUB\n", fileTime, flags, debugstr_w(buf), bufSize);
4660 return 0;
4663 /***********************************************************************
4664 * SHFormatDateTimeA [SHLWAPI.353]
4666 * See SHFormatDateTimeW.
4669 INT WINAPI SHFormatDateTimeA(const FILETIME UNALIGNED *fileTime, DWORD *flags,
4670 LPCSTR buf, UINT bufSize)
4672 WCHAR *bufW;
4673 DWORD buflenW, convlen;
4674 INT retval;
4676 if (!buf || !bufSize)
4677 return 0;
4679 buflenW = bufSize;
4680 bufW = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * buflenW);
4681 retval = SHFormatDateTimeW(fileTime, flags, bufW, buflenW);
4683 if (retval != 0)
4684 convlen = WideCharToMultiByte(CP_ACP, 0, bufW, -1, (LPSTR) buf, bufSize, NULL, NULL);
4686 HeapFree(GetProcessHeap(), 0, bufW);
4687 return retval;
4690 /***********************************************************************
4691 * ZoneCheckUrlExW [SHLWAPI.231]
4693 * Checks the details of the security zone for the supplied site. (?)
4695 * PARAMS
4697 * szURL [I] Pointer to the URL to check
4699 * Other parameters currently unknown.
4701 * RETURNS
4702 * unknown
4705 INT WINAPI ZoneCheckUrlExW(LPWSTR szURL, PVOID pUnknown, DWORD dwUnknown2,
4706 DWORD dwUnknown3, DWORD dwUnknown4, DWORD dwUnknown5, DWORD dwUnknown6,
4707 DWORD dwUnknown7)
4709 FIXME("(%s,%p,%x,%x,%x,%x,%x,%x) STUB\n", debugstr_w(szURL), pUnknown, dwUnknown2,
4710 dwUnknown3, dwUnknown4, dwUnknown5, dwUnknown6, dwUnknown7);
4712 return 0;
4715 /***********************************************************************
4716 * SHVerbExistsNA [SHLWAPI.196]
4719 * PARAMS
4721 * verb [I] a string, often appears to be an extension.
4723 * Other parameters currently unknown.
4725 * RETURNS
4726 * unknown
4728 INT WINAPI SHVerbExistsNA(LPSTR verb, PVOID pUnknown, PVOID pUnknown2, DWORD dwUnknown3)
4730 FIXME("(%s, %p, %p, %i) STUB\n",verb, pUnknown, pUnknown2, dwUnknown3);
4731 return 0;
4734 /*************************************************************************
4735 * @ [SHLWAPI.538]
4737 * Undocumented: Implementation guessed at via Name and behavior
4739 * PARAMS
4740 * lpUnknown [I] Object to get an IServiceProvider interface from
4741 * riid [I] Function requested for QueryService call
4742 * lppOut [O] Destination for the service interface pointer
4744 * RETURNS
4745 * Success: S_OK. lppOut contains an object providing the requested service
4746 * Failure: An HRESULT error code
4748 * NOTES
4749 * lpUnknown is expected to support the IServiceProvider interface.
4751 HRESULT WINAPI IUnknown_QueryServiceForWebBrowserApp(IUnknown* lpUnknown,
4752 REFGUID riid, LPVOID *lppOut)
4754 FIXME("%p %s %p semi-STUB\n", lpUnknown, debugstr_guid(riid), lppOut);
4755 return IUnknown_QueryService(lpUnknown,&IID_IWebBrowserApp,riid,lppOut);
4758 /**************************************************************************
4759 * SHPropertyBag_ReadLONG (SHLWAPI.496)
4761 * This function asks a property bag to read a named property as a LONG.
4763 * PARAMS
4764 * ppb: a IPropertyBag interface
4765 * pszPropName: Unicode string that names the property
4766 * pValue: address to receive the property value as a 32-bit signed integer
4768 * RETURNS
4769 * 0 for Success
4771 BOOL WINAPI SHPropertyBag_ReadLONG(IPropertyBag *ppb, LPCWSTR pszPropName, LPLONG pValue)
4773 VARIANT var;
4774 HRESULT hr;
4775 TRACE("%p %s %p\n", ppb,debugstr_w(pszPropName),pValue);
4776 if (!pszPropName || !ppb || !pValue)
4777 return E_INVALIDARG;
4778 V_VT(&var) = VT_I4;
4779 hr = IPropertyBag_Read(ppb, pszPropName, &var, NULL);
4780 if (SUCCEEDED(hr))
4782 if (V_VT(&var) == VT_I4)
4783 *pValue = V_I4(&var);
4784 else
4785 hr = DISP_E_BADVARTYPE;
4787 return hr;