2 * SHLWAPI ordinal functions
4 * Copyright 1997 Marcus Meissner
6 * 2001-2003 Jon Griffiths
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "wine/port.h"
31 #define NONAMELESSUNION
32 #define NONAMELESSSTRUCT
51 #include "wine/unicode.h"
52 #include "wine/debug.h"
55 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
57 /* DLL handles for late bound calls */
58 extern HINSTANCE shlwapi_hInstance
;
59 extern DWORD SHLWAPI_ThreadRef_index
;
61 HRESULT WINAPI
IUnknown_QueryService(IUnknown
*,REFGUID
,REFIID
,LPVOID
*);
62 HRESULT WINAPI
SHInvokeCommand(HWND
,IShellFolder
*,LPCITEMIDLIST
,BOOL
);
63 BOOL WINAPI
SHAboutInfoW(LPWSTR
,DWORD
);
66 NOTES: Most functions exported by ordinal seem to be superfluous.
67 The reason for these functions to be there is to provide a wrapper
68 for unicode functions to provide these functions on systems without
69 unicode functions eg. win95/win98. Since we have such functions we just
70 call these. If running Wine with native DLLs, some late bound calls may
71 fail. However, it is better to implement the functions in the forward DLL
72 and recommend the builtin rather than reimplementing the calls here!
75 /*************************************************************************
76 * SHLWAPI_DupSharedHandle
78 * Internal implemetation of SHLWAPI_11.
80 static HANDLE
SHLWAPI_DupSharedHandle(HANDLE hShared
, DWORD dwDstProcId
,
81 DWORD dwSrcProcId
, DWORD dwAccess
,
85 DWORD dwMyProcId
= GetCurrentProcessId();
88 TRACE("(%p,%d,%d,%08x,%08x)\n", hShared
, dwDstProcId
, dwSrcProcId
,
91 /* Get dest process handle */
92 if (dwDstProcId
== dwMyProcId
)
93 hDst
= GetCurrentProcess();
95 hDst
= OpenProcess(PROCESS_DUP_HANDLE
, 0, dwDstProcId
);
99 /* Get src process handle */
100 if (dwSrcProcId
== dwMyProcId
)
101 hSrc
= GetCurrentProcess();
103 hSrc
= OpenProcess(PROCESS_DUP_HANDLE
, 0, dwSrcProcId
);
107 /* Make handle available to dest process */
108 if (!DuplicateHandle(hDst
, hShared
, hSrc
, &hRet
,
109 dwAccess
, 0, dwOptions
| DUPLICATE_SAME_ACCESS
))
112 if (dwSrcProcId
!= dwMyProcId
)
116 if (dwDstProcId
!= dwMyProcId
)
120 TRACE("Returning handle %p\n", hRet
);
124 /*************************************************************************
127 * Create a block of sharable memory and initialise it with data.
130 * lpvData [I] Pointer to data to write
131 * dwSize [I] Size of data
132 * dwProcId [I] ID of process owning data
135 * Success: A shared memory handle
139 * Ordinals 7-11 provide a set of calls to create shared memory between a
140 * group of processes. The shared memory is treated opaquely in that its size
141 * is not exposed to clients who map it. This is accomplished by storing
142 * the size of the map as the first DWORD of mapped data, and then offsetting
143 * the view pointer returned by this size.
146 HANDLE WINAPI
SHAllocShared(LPCVOID lpvData
, DWORD dwSize
, DWORD dwProcId
)
152 TRACE("(%p,%d,%d)\n", lpvData
, dwSize
, dwProcId
);
154 /* Create file mapping of the correct length */
155 hMap
= CreateFileMappingA(INVALID_HANDLE_VALUE
, NULL
, FILE_MAP_READ
, 0,
156 dwSize
+ sizeof(dwSize
), NULL
);
160 /* Get a view in our process address space */
161 pMapped
= MapViewOfFile(hMap
, FILE_MAP_READ
| FILE_MAP_WRITE
, 0, 0, 0);
165 /* Write size of data, followed by the data, to the view */
166 *((DWORD
*)pMapped
) = dwSize
;
168 memcpy((char *) pMapped
+ sizeof(dwSize
), lpvData
, dwSize
);
170 /* Release view. All further views mapped will be opaque */
171 UnmapViewOfFile(pMapped
);
172 hRet
= SHLWAPI_DupSharedHandle(hMap
, dwProcId
,
173 GetCurrentProcessId(), FILE_MAP_ALL_ACCESS
,
174 DUPLICATE_SAME_ACCESS
);
181 /*************************************************************************
184 * Get a pointer to a block of shared memory from a shared memory handle.
187 * hShared [I] Shared memory handle
188 * dwProcId [I] ID of process owning hShared
191 * Success: A pointer to the shared memory
195 PVOID WINAPI
SHLockShared(HANDLE hShared
, DWORD dwProcId
)
200 TRACE("(%p %d)\n", hShared
, dwProcId
);
202 /* Get handle to shared memory for current process */
203 hDup
= SHLWAPI_DupSharedHandle(hShared
, dwProcId
, GetCurrentProcessId(),
204 FILE_MAP_ALL_ACCESS
, 0);
206 pMapped
= MapViewOfFile(hDup
, FILE_MAP_READ
| FILE_MAP_WRITE
, 0, 0, 0);
210 return (char *) pMapped
+ sizeof(DWORD
); /* Hide size */
214 /*************************************************************************
217 * Release a pointer to a block of shared memory.
220 * lpView [I] Shared memory pointer
227 BOOL WINAPI
SHUnlockShared(LPVOID lpView
)
229 TRACE("(%p)\n", lpView
);
230 return UnmapViewOfFile((char *) lpView
- sizeof(DWORD
)); /* Include size */
233 /*************************************************************************
236 * Destroy a block of sharable memory.
239 * hShared [I] Shared memory handle
240 * dwProcId [I] ID of process owning hShared
247 BOOL WINAPI
SHFreeShared(HANDLE hShared
, DWORD dwProcId
)
251 TRACE("(%p %d)\n", hShared
, dwProcId
);
253 /* Get a copy of the handle for our process, closing the source handle */
254 hClose
= SHLWAPI_DupSharedHandle(hShared
, dwProcId
, GetCurrentProcessId(),
255 FILE_MAP_ALL_ACCESS
,DUPLICATE_CLOSE_SOURCE
);
256 /* Close local copy */
257 return CloseHandle(hClose
);
260 /*************************************************************************
263 * Copy a sharable memory handle from one process to another.
266 * hShared [I] Shared memory handle to duplicate
267 * dwDstProcId [I] ID of the process wanting the duplicated handle
268 * dwSrcProcId [I] ID of the process owning hShared
269 * dwAccess [I] Desired DuplicateHandle() access
270 * dwOptions [I] Desired DuplicateHandle() options
273 * Success: A handle suitable for use by the dwDstProcId process.
274 * Failure: A NULL handle.
277 HANDLE WINAPI
SHMapHandle(HANDLE hShared
, DWORD dwDstProcId
, DWORD dwSrcProcId
,
278 DWORD dwAccess
, DWORD dwOptions
)
282 hRet
= SHLWAPI_DupSharedHandle(hShared
, dwDstProcId
, dwSrcProcId
,
283 dwAccess
, dwOptions
);
287 /*************************************************************************
290 * Create and register a clipboard enumerator for a web browser.
293 * lpBC [I] Binding context
294 * lpUnknown [I] An object exposing the IWebBrowserApp interface
298 * Failure: An HRESULT error code.
301 * The enumerator is stored as a property of the web browser. If it does not
302 * yet exist, it is created and set before being registered.
304 HRESULT WINAPI
RegisterDefaultAcceptHeaders(LPBC lpBC
, IUnknown
*lpUnknown
)
306 static const WCHAR szProperty
[] = { '{','D','0','F','C','A','4','2','0',
307 '-','D','3','F','5','-','1','1','C','F', '-','B','2','1','1','-','0',
308 '0','A','A','0','0','4','A','E','8','3','7','}','\0' };
310 IEnumFORMATETC
* pIEnumFormatEtc
= NULL
;
313 IWebBrowserApp
* pBrowser
= NULL
;
315 TRACE("(%p, %p)\n", lpBC
, lpUnknown
);
317 /* Get An IWebBrowserApp interface from lpUnknown */
318 hRet
= IUnknown_QueryService(lpUnknown
, &IID_IWebBrowserApp
, &IID_IWebBrowserApp
, (PVOID
)&pBrowser
);
319 if (FAILED(hRet
) || !pBrowser
)
320 return E_NOINTERFACE
;
322 V_VT(&var
) = VT_EMPTY
;
324 /* The property we get is the browsers clipboard enumerator */
325 property
= SysAllocString(szProperty
);
326 hRet
= IWebBrowserApp_GetProperty(pBrowser
, property
, &var
);
327 SysFreeString(property
);
331 if (V_VT(&var
) == VT_EMPTY
)
333 /* Iterate through accepted documents and RegisterClipBoardFormatA() them */
334 char szKeyBuff
[128], szValueBuff
[128];
335 DWORD dwKeySize
, dwValueSize
, dwRet
= 0, dwCount
= 0, dwNumValues
, dwType
;
336 FORMATETC
* formatList
, *format
;
339 TRACE("Registering formats and creating IEnumFORMATETC instance\n");
341 if (!RegOpenKeyA(HKEY_LOCAL_MACHINE
, "Software\\Microsoft\\Windows\\Current"
342 "Version\\Internet Settings\\Accepted Documents", &hDocs
))
345 /* Get count of values in key */
348 dwKeySize
= sizeof(szKeyBuff
);
349 dwRet
= RegEnumValueA(hDocs
,dwCount
,szKeyBuff
,&dwKeySize
,0,&dwType
,0,0);
353 dwNumValues
= dwCount
;
355 /* Note: dwCount = number of items + 1; The extra item is the end node */
356 format
= formatList
= HeapAlloc(GetProcessHeap(), 0, dwCount
* sizeof(FORMATETC
));
358 return E_OUTOFMEMORY
;
367 /* Register clipboard formats for the values and populate format list */
368 while(!dwRet
&& dwCount
< dwNumValues
)
370 dwKeySize
= sizeof(szKeyBuff
);
371 dwValueSize
= sizeof(szValueBuff
);
372 dwRet
= RegEnumValueA(hDocs
, dwCount
, szKeyBuff
, &dwKeySize
, 0, &dwType
,
373 (PBYTE
)szValueBuff
, &dwValueSize
);
377 format
->cfFormat
= RegisterClipboardFormatA(szValueBuff
);
379 format
->dwAspect
= 1;
388 /* Terminate the (maybe empty) list, last entry has a cfFormat of 0 */
389 format
->cfFormat
= 0;
391 format
->dwAspect
= 1;
395 /* Create a clipboard enumerator */
396 hRet
= CreateFormatEnumerator(dwNumValues
, formatList
, &pIEnumFormatEtc
);
398 if (FAILED(hRet
) || !pIEnumFormatEtc
)
401 /* Set our enumerator as the browsers property */
402 V_VT(&var
) = VT_UNKNOWN
;
403 V_UNKNOWN(&var
) = (IUnknown
*)pIEnumFormatEtc
;
405 property
= SysAllocString(szProperty
);
406 hRet
= IWebBrowserApp_PutProperty(pBrowser
, property
, var
);
407 SysFreeString(property
);
410 IEnumFORMATETC_Release(pIEnumFormatEtc
);
411 goto RegisterDefaultAcceptHeaders_Exit
;
415 if (V_VT(&var
) == VT_UNKNOWN
)
417 /* Our variant is holding the clipboard enumerator */
418 IUnknown
* pIUnknown
= V_UNKNOWN(&var
);
419 IEnumFORMATETC
* pClone
= NULL
;
421 TRACE("Retrieved IEnumFORMATETC property\n");
423 /* Get an IEnumFormatEtc interface from the variants value */
424 pIEnumFormatEtc
= NULL
;
425 hRet
= IUnknown_QueryInterface(pIUnknown
, &IID_IEnumFORMATETC
,
426 (PVOID
)&pIEnumFormatEtc
);
427 if (hRet
== S_OK
&& pIEnumFormatEtc
)
429 /* Clone and register the enumerator */
430 hRet
= IEnumFORMATETC_Clone(pIEnumFormatEtc
, &pClone
);
431 if (hRet
== S_OK
&& pClone
)
433 RegisterFormatEnumerator(lpBC
, pClone
, 0);
435 IEnumFORMATETC_Release(pClone
);
438 /* Release the IEnumFormatEtc interface */
439 IEnumFORMATETC_Release(pIUnknown
);
441 IUnknown_Release(V_UNKNOWN(&var
));
444 RegisterDefaultAcceptHeaders_Exit
:
445 IWebBrowserApp_Release(pBrowser
);
449 /*************************************************************************
452 * Get Explorers "AcceptLanguage" setting.
455 * langbuf [O] Destination for language string
456 * buflen [I] Length of langbuf in characters
457 * [0] Success: used length of langbuf
460 * Success: S_OK. langbuf is set to the language string found.
461 * Failure: E_FAIL, If any arguments are invalid, error occurred, or Explorer
462 * does not contain the setting.
463 * HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), If the buffer is not big enough
465 HRESULT WINAPI
GetAcceptLanguagesW( LPWSTR langbuf
, LPDWORD buflen
)
467 static const WCHAR szkeyW
[] = {
468 'S','o','f','t','w','a','r','e','\\',
469 'M','i','c','r','o','s','o','f','t','\\',
470 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
471 'I','n','t','e','r','n','a','t','i','o','n','a','l',0};
472 static const WCHAR valueW
[] = {
473 'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0};
474 DWORD mystrlen
, mytype
;
482 TRACE("(%p, %p) *%p: %d\n", langbuf
, buflen
, buflen
, buflen
? *buflen
: -1);
484 if(!langbuf
|| !buflen
|| !*buflen
)
487 mystrlen
= (*buflen
> 20) ? *buflen
: 20 ;
488 len
= mystrlen
* sizeof(WCHAR
);
489 mystr
= HeapAlloc(GetProcessHeap(), 0, len
);
491 RegOpenKeyW(HKEY_CURRENT_USER
, szkeyW
, &mykey
);
492 lres
= RegQueryValueExW(mykey
, valueW
, 0, &mytype
, (PBYTE
)mystr
, &len
);
494 len
= lstrlenW(mystr
);
496 if (!lres
&& (*buflen
> len
)) {
497 lstrcpyW(langbuf
, mystr
);
499 HeapFree(GetProcessHeap(), 0, mystr
);
503 /* Did not find a value in the registry or the user buffer is to small */
504 mylcid
= GetUserDefaultLCID();
505 retval
= LcidToRfc1766W(mylcid
, mystr
, mystrlen
);
506 len
= lstrlenW(mystr
);
508 memcpy( langbuf
, mystr
, min(*buflen
, len
+1)*sizeof(WCHAR
) );
509 HeapFree(GetProcessHeap(), 0, mystr
);
517 return __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER
);
520 /*************************************************************************
523 * Ascii version of GetAcceptLanguagesW.
525 HRESULT WINAPI
GetAcceptLanguagesA( LPSTR langbuf
, LPDWORD buflen
)
528 DWORD buflenW
, convlen
;
531 TRACE("(%p, %p) *%p: %d\n", langbuf
, buflen
, buflen
, buflen
? *buflen
: -1);
533 if(!langbuf
|| !buflen
|| !*buflen
) return E_FAIL
;
536 langbufW
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
) * buflenW
);
537 retval
= GetAcceptLanguagesW(langbufW
, &buflenW
);
541 convlen
= WideCharToMultiByte(CP_ACP
, 0, langbufW
, -1, langbuf
, *buflen
, NULL
, NULL
);
542 convlen
--; /* do not count the terminating 0 */
544 else /* copy partial string anyway */
546 convlen
= WideCharToMultiByte(CP_ACP
, 0, langbufW
, *buflen
, langbuf
, *buflen
, NULL
, NULL
);
547 if (convlen
< *buflen
)
549 langbuf
[convlen
] = 0;
550 convlen
--; /* do not count the terminating 0 */
557 *buflen
= buflenW
? convlen
: 0;
559 HeapFree(GetProcessHeap(), 0, langbufW
);
563 /*************************************************************************
566 * Convert a GUID to a string.
569 * guid [I] GUID to convert
570 * lpszDest [O] Destination for string
571 * cchMax [I] Length of output buffer
574 * The length of the string created.
576 INT WINAPI
SHStringFromGUIDA(REFGUID guid
, LPSTR lpszDest
, INT cchMax
)
581 TRACE("(%s,%p,%d)\n", debugstr_guid(guid
), lpszDest
, cchMax
);
583 sprintf(xguid
, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
584 guid
->Data1
, guid
->Data2
, guid
->Data3
,
585 guid
->Data4
[0], guid
->Data4
[1], guid
->Data4
[2], guid
->Data4
[3],
586 guid
->Data4
[4], guid
->Data4
[5], guid
->Data4
[6], guid
->Data4
[7]);
588 iLen
= strlen(xguid
) + 1;
592 memcpy(lpszDest
, xguid
, iLen
);
596 /*************************************************************************
599 * Convert a GUID to a string.
602 * guid [I] GUID to convert
603 * str [O] Destination for string
604 * cmax [I] Length of output buffer
607 * The length of the string created.
609 INT WINAPI
SHStringFromGUIDW(REFGUID guid
, LPWSTR lpszDest
, INT cchMax
)
613 static const WCHAR wszFormat
[] = {'{','%','0','8','l','X','-','%','0','4','X','-','%','0','4','X','-',
614 '%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','%','0','2','X','%','0','2',
615 'X','%','0','2','X','%','0','2','X','}',0};
617 TRACE("(%s,%p,%d)\n", debugstr_guid(guid
), lpszDest
, cchMax
);
619 sprintfW(xguid
, wszFormat
, guid
->Data1
, guid
->Data2
, guid
->Data3
,
620 guid
->Data4
[0], guid
->Data4
[1], guid
->Data4
[2], guid
->Data4
[3],
621 guid
->Data4
[4], guid
->Data4
[5], guid
->Data4
[6], guid
->Data4
[7]);
623 iLen
= strlenW(xguid
) + 1;
627 memcpy(lpszDest
, xguid
, iLen
*sizeof(WCHAR
));
631 /*************************************************************************
634 * Determine if a Unicode character is a space.
637 * wc [I] Character to check.
640 * TRUE, if wc is a space,
643 BOOL WINAPI
IsCharSpaceW(WCHAR wc
)
647 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_SPACE
);
650 /*************************************************************************
653 * Determine if a Unicode character is a blank.
656 * wc [I] Character to check.
659 * TRUE, if wc is a blank,
663 BOOL WINAPI
IsCharBlankW(WCHAR wc
)
667 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_BLANK
);
670 /*************************************************************************
673 * Determine if a Unicode character is punctuation.
676 * wc [I] Character to check.
679 * TRUE, if wc is punctuation,
682 BOOL WINAPI
IsCharPunctW(WCHAR wc
)
686 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_PUNCT
);
689 /*************************************************************************
692 * Determine if a Unicode character is a control character.
695 * wc [I] Character to check.
698 * TRUE, if wc is a control character,
701 BOOL WINAPI
IsCharCntrlW(WCHAR wc
)
705 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_CNTRL
);
708 /*************************************************************************
711 * Determine if a Unicode character is a digit.
714 * wc [I] Character to check.
717 * TRUE, if wc is a digit,
720 BOOL WINAPI
IsCharDigitW(WCHAR wc
)
724 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_DIGIT
);
727 /*************************************************************************
730 * Determine if a Unicode character is a hex digit.
733 * wc [I] Character to check.
736 * TRUE, if wc is a hex digit,
739 BOOL WINAPI
IsCharXDigitW(WCHAR wc
)
743 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_XDIGIT
);
746 /*************************************************************************
750 BOOL WINAPI
GetStringType3ExW(LPWSTR src
, INT count
, LPWORD type
)
752 return GetStringTypeW(CT_CTYPE3
, src
, count
, type
);
755 /*************************************************************************
758 * Compare two Ascii strings up to a given length.
761 * lpszSrc [I] Source string
762 * lpszCmp [I] String to compare to lpszSrc
763 * len [I] Maximum length
766 * A number greater than, less than or equal to 0 depending on whether
767 * lpszSrc is greater than, less than or equal to lpszCmp.
769 DWORD WINAPI
StrCmpNCA(LPCSTR lpszSrc
, LPCSTR lpszCmp
, INT len
)
771 return StrCmpNA(lpszSrc
, lpszCmp
, len
);
774 /*************************************************************************
777 * Unicode version of StrCmpNCA.
779 DWORD WINAPI
StrCmpNCW(LPCWSTR lpszSrc
, LPCWSTR lpszCmp
, INT len
)
781 return StrCmpNW(lpszSrc
, lpszCmp
, len
);
784 /*************************************************************************
787 * Compare two Ascii strings up to a given length, ignoring case.
790 * lpszSrc [I] Source string
791 * lpszCmp [I] String to compare to lpszSrc
792 * len [I] Maximum length
795 * A number greater than, less than or equal to 0 depending on whether
796 * lpszSrc is greater than, less than or equal to lpszCmp.
798 DWORD WINAPI
StrCmpNICA(LPCSTR lpszSrc
, LPCSTR lpszCmp
, DWORD len
)
800 return StrCmpNIA(lpszSrc
, lpszCmp
, len
);
803 /*************************************************************************
806 * Unicode version of StrCmpNICA.
808 DWORD WINAPI
StrCmpNICW(LPCWSTR lpszSrc
, LPCWSTR lpszCmp
, DWORD len
)
810 return StrCmpNIW(lpszSrc
, lpszCmp
, len
);
813 /*************************************************************************
816 * Compare two Ascii strings.
819 * lpszSrc [I] Source string
820 * lpszCmp [I] String to compare to lpszSrc
823 * A number greater than, less than or equal to 0 depending on whether
824 * lpszSrc is greater than, less than or equal to lpszCmp.
826 DWORD WINAPI
StrCmpCA(LPCSTR lpszSrc
, LPCSTR lpszCmp
)
828 return lstrcmpA(lpszSrc
, lpszCmp
);
831 /*************************************************************************
834 * Unicode version of StrCmpCA.
836 DWORD WINAPI
StrCmpCW(LPCWSTR lpszSrc
, LPCWSTR lpszCmp
)
838 return lstrcmpW(lpszSrc
, lpszCmp
);
841 /*************************************************************************
844 * Compare two Ascii strings, ignoring case.
847 * lpszSrc [I] Source string
848 * lpszCmp [I] String to compare to lpszSrc
851 * A number greater than, less than or equal to 0 depending on whether
852 * lpszSrc is greater than, less than or equal to lpszCmp.
854 DWORD WINAPI
StrCmpICA(LPCSTR lpszSrc
, LPCSTR lpszCmp
)
856 return lstrcmpiA(lpszSrc
, lpszCmp
);
859 /*************************************************************************
862 * Unicode version of StrCmpICA.
864 DWORD WINAPI
StrCmpICW(LPCWSTR lpszSrc
, LPCWSTR lpszCmp
)
866 return lstrcmpiW(lpszSrc
, lpszCmp
);
869 /*************************************************************************
872 * Get an identification string for the OS and explorer.
875 * lpszDest [O] Destination for Id string
876 * dwDestLen [I] Length of lpszDest
879 * TRUE, If the string was created successfully
882 BOOL WINAPI
SHAboutInfoA(LPSTR lpszDest
, DWORD dwDestLen
)
886 TRACE("(%p,%d)\n", lpszDest
, dwDestLen
);
888 if (lpszDest
&& SHAboutInfoW(buff
, dwDestLen
))
890 WideCharToMultiByte(CP_ACP
, 0, buff
, -1, lpszDest
, dwDestLen
, NULL
, NULL
);
896 /*************************************************************************
899 * Unicode version of SHAboutInfoA.
901 BOOL WINAPI
SHAboutInfoW(LPWSTR lpszDest
, DWORD dwDestLen
)
903 static const WCHAR szIEKey
[] = { 'S','O','F','T','W','A','R','E','\\',
904 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
905 ' ','E','x','p','l','o','r','e','r','\0' };
906 static const WCHAR szWinNtKey
[] = { 'S','O','F','T','W','A','R','E','\\',
907 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s',' ',
908 'N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
909 static const WCHAR szWinKey
[] = { 'S','O','F','T','W','A','R','E','\\',
910 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
911 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
912 static const WCHAR szRegKey
[] = { 'S','O','F','T','W','A','R','E','\\',
913 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
914 ' ','E','x','p','l','o','r','e','r','\\',
915 'R','e','g','i','s','t','r','a','t','i','o','n','\0' };
916 static const WCHAR szVersion
[] = { 'V','e','r','s','i','o','n','\0' };
917 static const WCHAR szCustomized
[] = { 'C','u','s','t','o','m','i','z','e','d',
918 'V','e','r','s','i','o','n','\0' };
919 static const WCHAR szOwner
[] = { 'R','e','g','i','s','t','e','r','e','d',
920 'O','w','n','e','r','\0' };
921 static const WCHAR szOrg
[] = { 'R','e','g','i','s','t','e','r','e','d',
922 'O','r','g','a','n','i','z','a','t','i','o','n','\0' };
923 static const WCHAR szProduct
[] = { 'P','r','o','d','u','c','t','I','d','\0' };
924 static const WCHAR szUpdate
[] = { 'I','E','A','K',
925 'U','p','d','a','t','e','U','r','l','\0' };
926 static const WCHAR szHelp
[] = { 'I','E','A','K',
927 'H','e','l','p','S','t','r','i','n','g','\0' };
932 TRACE("(%p,%d)\n", lpszDest
, dwDestLen
);
939 /* Try the NT key first, followed by 95/98 key */
940 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szWinNtKey
, 0, KEY_READ
, &hReg
) &&
941 RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szWinKey
, 0, KEY_READ
, &hReg
))
947 if (!SHGetValueW(HKEY_LOCAL_MACHINE
, szIEKey
, szVersion
, &dwType
, buff
, &dwLen
))
949 DWORD dwStrLen
= strlenW(buff
);
950 dwLen
= 30 - dwStrLen
;
951 SHGetValueW(HKEY_LOCAL_MACHINE
, szIEKey
,
952 szCustomized
, &dwType
, buff
+dwStrLen
, &dwLen
);
954 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
956 /* ~Registered Owner */
959 if (SHGetValueW(hReg
, szOwner
, 0, &dwType
, buff
+1, &dwLen
))
961 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
963 /* ~Registered Organization */
965 if (SHGetValueW(hReg
, szOrg
, 0, &dwType
, buff
+1, &dwLen
))
967 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
969 /* FIXME: Not sure where this number comes from */
973 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
977 if (SHGetValueW(HKEY_LOCAL_MACHINE
, szRegKey
, szProduct
, &dwType
, buff
+1, &dwLen
))
979 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
983 if(SHGetValueW(HKEY_LOCAL_MACHINE
, szWinKey
, szUpdate
, &dwType
, buff
+1, &dwLen
))
985 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
987 /* ~IE Help String */
989 if(SHGetValueW(hReg
, szHelp
, 0, &dwType
, buff
+1, &dwLen
))
991 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
997 /*************************************************************************
1000 * Call IOleCommandTarget_QueryStatus() on an object.
1003 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1004 * pguidCmdGroup [I] GUID for the command group
1006 * prgCmds [O] Commands
1007 * pCmdText [O] Command text
1011 * Failure: E_FAIL, if lpUnknown is NULL.
1012 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1013 * Otherwise, an error code from IOleCommandTarget_QueryStatus().
1015 HRESULT WINAPI
IUnknown_QueryStatus(IUnknown
* lpUnknown
, REFGUID pguidCmdGroup
,
1016 ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
* pCmdText
)
1018 HRESULT hRet
= E_FAIL
;
1020 TRACE("(%p,%p,%d,%p,%p)\n",lpUnknown
, pguidCmdGroup
, cCmds
, prgCmds
, pCmdText
);
1024 IOleCommandTarget
* lpOle
;
1026 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleCommandTarget
,
1029 if (SUCCEEDED(hRet
) && lpOle
)
1031 hRet
= IOleCommandTarget_QueryStatus(lpOle
, pguidCmdGroup
, cCmds
,
1033 IOleCommandTarget_Release(lpOle
);
1039 /*************************************************************************
1042 * Call IOleCommandTarget_Exec() on an object.
1045 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1046 * pguidCmdGroup [I] GUID for the command group
1050 * Failure: E_FAIL, if lpUnknown is NULL.
1051 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1052 * Otherwise, an error code from IOleCommandTarget_Exec().
1054 HRESULT WINAPI
IUnknown_Exec(IUnknown
* lpUnknown
, REFGUID pguidCmdGroup
,
1055 DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
* pvaIn
,
1058 HRESULT hRet
= E_FAIL
;
1060 TRACE("(%p,%p,%d,%d,%p,%p)\n",lpUnknown
, pguidCmdGroup
, nCmdID
,
1061 nCmdexecopt
, pvaIn
, pvaOut
);
1065 IOleCommandTarget
* lpOle
;
1067 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleCommandTarget
,
1069 if (SUCCEEDED(hRet
) && lpOle
)
1071 hRet
= IOleCommandTarget_Exec(lpOle
, pguidCmdGroup
, nCmdID
,
1072 nCmdexecopt
, pvaIn
, pvaOut
);
1073 IOleCommandTarget_Release(lpOle
);
1079 /*************************************************************************
1082 * Retrieve, modify, and re-set a value from a window.
1085 * hWnd [I] Window to get value from
1086 * offset [I] Offset of value
1087 * mask [I] Mask for flags
1088 * flags [I] Bits to set in window value
1091 * The new value as it was set, or 0 if any parameter is invalid.
1094 * Only bits specified in mask are affected - set if present in flags and
1097 LONG WINAPI
SHSetWindowBits(HWND hwnd
, INT offset
, UINT mask
, UINT flags
)
1099 LONG ret
= GetWindowLongW(hwnd
, offset
);
1100 LONG new_flags
= (flags
& mask
) | (ret
& ~mask
);
1102 TRACE("%p %d %x %x\n", hwnd
, offset
, mask
, flags
);
1104 if (new_flags
!= ret
)
1105 ret
= SetWindowLongW(hwnd
, offset
, new_flags
);
1109 /*************************************************************************
1112 * Change a window's parent.
1115 * hWnd [I] Window to change parent of
1116 * hWndParent [I] New parent window
1119 * The old parent of hWnd.
1122 * If hWndParent is NULL (desktop), the window style is changed to WS_POPUP.
1123 * If hWndParent is NOT NULL then we set the WS_CHILD style.
1125 HWND WINAPI
SHSetParentHwnd(HWND hWnd
, HWND hWndParent
)
1127 TRACE("%p, %p\n", hWnd
, hWndParent
);
1129 if(GetParent(hWnd
) == hWndParent
)
1133 SHSetWindowBits(hWnd
, GWL_STYLE
, WS_CHILD
, WS_CHILD
);
1135 SHSetWindowBits(hWnd
, GWL_STYLE
, WS_POPUP
, WS_POPUP
);
1137 return SetParent(hWnd
, hWndParent
);
1140 /*************************************************************************
1143 * Locate and advise a connection point in an IConnectionPointContainer object.
1146 * lpUnkSink [I] Sink for the connection point advise call
1147 * riid [I] REFIID of connection point to advise
1148 * fConnect [I] TRUE = Connection being establisted, FALSE = broken
1149 * lpUnknown [I] Object supporting the IConnectionPointContainer interface
1150 * lpCookie [O] Pointer to connection point cookie
1151 * lppCP [O] Destination for the IConnectionPoint found
1154 * Success: S_OK. If lppCP is non-NULL, it is filled with the IConnectionPoint
1155 * that was advised. The caller is responsible for releasing it.
1156 * Failure: E_FAIL, if any arguments are invalid.
1157 * E_NOINTERFACE, if lpUnknown isn't an IConnectionPointContainer,
1158 * Or an HRESULT error code if any call fails.
1160 HRESULT WINAPI
ConnectToConnectionPoint(IUnknown
* lpUnkSink
, REFIID riid
, BOOL fConnect
,
1161 IUnknown
* lpUnknown
, LPDWORD lpCookie
,
1162 IConnectionPoint
**lppCP
)
1165 IConnectionPointContainer
* lpContainer
;
1166 IConnectionPoint
*lpCP
;
1168 if(!lpUnknown
|| (fConnect
&& !lpUnkSink
))
1174 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IConnectionPointContainer
,
1175 (void**)&lpContainer
);
1176 if (SUCCEEDED(hRet
))
1178 hRet
= IConnectionPointContainer_FindConnectionPoint(lpContainer
, riid
, &lpCP
);
1180 if (SUCCEEDED(hRet
))
1183 hRet
= IConnectionPoint_Unadvise(lpCP
, *lpCookie
);
1185 hRet
= IConnectionPoint_Advise(lpCP
, lpUnkSink
, lpCookie
);
1190 if (lppCP
&& SUCCEEDED(hRet
))
1191 *lppCP
= lpCP
; /* Caller keeps the interface */
1193 IConnectionPoint_Release(lpCP
); /* Release it */
1196 IUnknown_Release(lpContainer
);
1201 /*************************************************************************
1204 * Release an interface.
1207 * lpUnknown [I] Object to release
1212 DWORD WINAPI
IUnknown_AtomicRelease(IUnknown
** lpUnknown
)
1216 TRACE("(%p)\n",lpUnknown
);
1218 if(!lpUnknown
|| !*((LPDWORD
)lpUnknown
)) return 0;
1222 TRACE("doing Release\n");
1224 return IUnknown_Release(temp
);
1227 /*************************************************************************
1230 * Skip '//' if present in a string.
1233 * lpszSrc [I] String to check for '//'
1236 * Success: The next character after the '//' or the string if not present
1237 * Failure: NULL, if lpszStr is NULL.
1239 LPCSTR WINAPI
PathSkipLeadingSlashesA(LPCSTR lpszSrc
)
1241 if (lpszSrc
&& lpszSrc
[0] == '/' && lpszSrc
[1] == '/')
1246 /*************************************************************************
1249 * Check if two interfaces come from the same object.
1252 * lpInt1 [I] Interface to check against lpInt2.
1253 * lpInt2 [I] Interface to check against lpInt1.
1256 * TRUE, If the interfaces come from the same object.
1259 BOOL WINAPI
SHIsSameObject(IUnknown
* lpInt1
, IUnknown
* lpInt2
)
1261 LPVOID lpUnknown1
, lpUnknown2
;
1263 TRACE("%p %p\n", lpInt1
, lpInt2
);
1265 if (!lpInt1
|| !lpInt2
)
1268 if (lpInt1
== lpInt2
)
1271 if (FAILED(IUnknown_QueryInterface(lpInt1
, &IID_IUnknown
, &lpUnknown1
)))
1274 if (FAILED(IUnknown_QueryInterface(lpInt2
, &IID_IUnknown
, &lpUnknown2
)))
1277 if (lpUnknown1
== lpUnknown2
)
1283 /*************************************************************************
1286 * Get the window handle of an object.
1289 * lpUnknown [I] Object to get the window handle of
1290 * lphWnd [O] Destination for window handle
1293 * Success: S_OK. lphWnd contains the objects window handle.
1294 * Failure: An HRESULT error code.
1297 * lpUnknown is expected to support one of the following interfaces:
1298 * IOleWindow(), IInternetSecurityMgrSite(), or IShellView().
1300 HRESULT WINAPI
IUnknown_GetWindow(IUnknown
*lpUnknown
, HWND
*lphWnd
)
1303 HRESULT hRet
= E_FAIL
;
1305 TRACE("(%p,%p)\n", lpUnknown
, lphWnd
);
1310 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleWindow
, (void**)&lpOle
);
1314 hRet
= IUnknown_QueryInterface(lpUnknown
,&IID_IShellView
, (void**)&lpOle
);
1318 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IInternetSecurityMgrSite
,
1323 if (SUCCEEDED(hRet
))
1325 /* Lazyness here - Since GetWindow() is the first method for the above 3
1326 * interfaces, we use the same call for them all.
1328 hRet
= IOleWindow_GetWindow((IOleWindow
*)lpOle
, lphWnd
);
1329 IUnknown_Release(lpOle
);
1331 TRACE("Returning HWND=%p\n", *lphWnd
);
1337 /*************************************************************************
1340 * Call a method on as as yet unidentified object.
1343 * pUnk [I] Object supporting the unidentified interface,
1344 * arg [I] Argument for the call on the object.
1349 HRESULT WINAPI
IUnknown_SetOwner(IUnknown
*pUnk
, ULONG arg
)
1351 static const GUID guid_173
= {
1352 0x5836fb00, 0x8187, 0x11cf, { 0xa1,0x2b,0x00,0xaa,0x00,0x4a,0xe8,0x37 }
1356 TRACE("(%p,%d)\n", pUnk
, arg
);
1358 /* Note: arg may not be a ULONG and pUnk2 is for sure not an IMalloc -
1359 * We use this interface as its vtable entry is compatible with the
1360 * object in question.
1361 * FIXME: Find out what this object is and where it should be defined.
1364 SUCCEEDED(IUnknown_QueryInterface(pUnk
, &guid_173
, (void**)&pUnk2
)))
1366 IMalloc_Alloc(pUnk2
, arg
); /* Faked call!! */
1367 IMalloc_Release(pUnk2
);
1372 /*************************************************************************
1375 * Call either IObjectWithSite_SetSite() or IInternetSecurityManager_SetSecuritySite() on
1379 HRESULT WINAPI
IUnknown_SetSite(
1380 IUnknown
*obj
, /* [in] OLE object */
1381 IUnknown
*site
) /* [in] Site interface */
1384 IObjectWithSite
*iobjwithsite
;
1385 IInternetSecurityManager
*isecmgr
;
1387 if (!obj
) return E_FAIL
;
1389 hr
= IUnknown_QueryInterface(obj
, &IID_IObjectWithSite
, (LPVOID
*)&iobjwithsite
);
1390 TRACE("IID_IObjectWithSite QI ret=%08x, %p\n", hr
, iobjwithsite
);
1393 hr
= IObjectWithSite_SetSite(iobjwithsite
, site
);
1394 TRACE("done IObjectWithSite_SetSite ret=%08x\n", hr
);
1395 IUnknown_Release(iobjwithsite
);
1399 hr
= IUnknown_QueryInterface(obj
, &IID_IInternetSecurityManager
, (LPVOID
*)&isecmgr
);
1400 TRACE("IID_IInternetSecurityManager QI ret=%08x, %p\n", hr
, isecmgr
);
1401 if (FAILED(hr
)) return hr
;
1403 hr
= IInternetSecurityManager_SetSecuritySite(isecmgr
, (IInternetSecurityMgrSite
*)site
);
1404 TRACE("done IInternetSecurityManager_SetSecuritySite ret=%08x\n", hr
);
1405 IUnknown_Release(isecmgr
);
1410 /*************************************************************************
1413 * Call IPersist_GetClassID() on an object.
1416 * lpUnknown [I] Object supporting the IPersist interface
1417 * lpClassId [O] Destination for Class Id
1420 * Success: S_OK. lpClassId contains the Class Id requested.
1421 * Failure: E_FAIL, If lpUnknown is NULL,
1422 * E_NOINTERFACE If lpUnknown does not support IPersist,
1423 * Or an HRESULT error code.
1425 HRESULT WINAPI
IUnknown_GetClassID(IUnknown
*lpUnknown
, CLSID
* lpClassId
)
1427 IPersist
* lpPersist
;
1428 HRESULT hRet
= E_FAIL
;
1430 TRACE("(%p,%p)\n", lpUnknown
, debugstr_guid(lpClassId
));
1434 hRet
= IUnknown_QueryInterface(lpUnknown
,&IID_IPersist
,(void**)&lpPersist
);
1435 if (SUCCEEDED(hRet
))
1437 IPersist_GetClassID(lpPersist
, lpClassId
);
1438 IPersist_Release(lpPersist
);
1444 /*************************************************************************
1447 * Retrieve a Service Interface from an object.
1450 * lpUnknown [I] Object to get an IServiceProvider interface from
1451 * sid [I] Service ID for IServiceProvider_QueryService() call
1452 * riid [I] Function requested for QueryService call
1453 * lppOut [O] Destination for the service interface pointer
1456 * Success: S_OK. lppOut contains an object providing the requested service
1457 * Failure: An HRESULT error code
1460 * lpUnknown is expected to support the IServiceProvider interface.
1462 HRESULT WINAPI
IUnknown_QueryService(IUnknown
* lpUnknown
, REFGUID sid
, REFIID riid
,
1465 IServiceProvider
* pService
= NULL
;
1476 /* Get an IServiceProvider interface from the object */
1477 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IServiceProvider
,
1478 (LPVOID
*)&pService
);
1480 if (hRet
== S_OK
&& pService
)
1482 TRACE("QueryInterface returned (IServiceProvider*)%p\n", pService
);
1484 /* Get a Service interface from the object */
1485 hRet
= IServiceProvider_QueryService(pService
, sid
, riid
, lppOut
);
1487 TRACE("(IServiceProvider*)%p returned (IUnknown*)%p\n", pService
, *lppOut
);
1489 /* Release the IServiceProvider interface */
1490 IUnknown_Release(pService
);
1495 /*************************************************************************
1498 * Call an object's UIActivateIO method.
1501 * unknown [I] Object to call the UIActivateIO method on
1502 * activate [I] Parameter for UIActivateIO call
1503 * msg [I] Parameter for UIActivateIO call
1506 * Success: Value of UI_ActivateIO call
1507 * Failure: An HRESULT error code
1510 * unknown is expected to support the IInputObject interface.
1512 HRESULT WINAPI
IUnknown_UIActivateIO(IUnknown
*unknown
, BOOL activate
, LPMSG msg
)
1514 IInputObject
* object
= NULL
;
1520 /* Get an IInputObject interface from the object */
1521 ret
= IUnknown_QueryInterface(unknown
, &IID_IInputObject
, (LPVOID
*) &object
);
1525 ret
= IInputObject_UIActivateIO(object
, activate
, msg
);
1526 IUnknown_Release(object
);
1532 /*************************************************************************
1535 * Loads a popup menu.
1538 * hInst [I] Instance handle
1539 * szName [I] Menu name
1545 BOOL WINAPI
SHLoadMenuPopup(HINSTANCE hInst
, LPCWSTR szName
)
1549 if ((hMenu
= LoadMenuW(hInst
, szName
)))
1551 if (GetSubMenu(hMenu
, 0))
1552 RemoveMenu(hMenu
, 0, MF_BYPOSITION
);
1560 typedef struct _enumWndData
1565 LRESULT (WINAPI
*pfnPost
)(HWND
,UINT
,WPARAM
,LPARAM
);
1568 /* Callback for SHLWAPI_178 */
1569 static BOOL CALLBACK
SHLWAPI_EnumChildProc(HWND hWnd
, LPARAM lParam
)
1571 enumWndData
*data
= (enumWndData
*)lParam
;
1573 TRACE("(%p,%p)\n", hWnd
, data
);
1574 data
->pfnPost(hWnd
, data
->uiMsgId
, data
->wParam
, data
->lParam
);
1578 /*************************************************************************
1581 * Send or post a message to every child of a window.
1584 * hWnd [I] Window whose children will get the messages
1585 * uiMsgId [I] Message Id
1586 * wParam [I] WPARAM of message
1587 * lParam [I] LPARAM of message
1588 * bSend [I] TRUE = Use SendMessageA(), FALSE = Use PostMessageA()
1594 * The appropriate ASCII or Unicode function is called for the window.
1596 void WINAPI
SHPropagateMessage(HWND hWnd
, UINT uiMsgId
, WPARAM wParam
, LPARAM lParam
, BOOL bSend
)
1600 TRACE("(%p,%u,%ld,%ld,%d)\n", hWnd
, uiMsgId
, wParam
, lParam
, bSend
);
1604 data
.uiMsgId
= uiMsgId
;
1605 data
.wParam
= wParam
;
1606 data
.lParam
= lParam
;
1609 data
.pfnPost
= IsWindowUnicode(hWnd
) ? (void*)SendMessageW
: (void*)SendMessageA
;
1611 data
.pfnPost
= IsWindowUnicode(hWnd
) ? (void*)PostMessageW
: (void*)PostMessageA
;
1613 EnumChildWindows(hWnd
, SHLWAPI_EnumChildProc
, (LPARAM
)&data
);
1617 /*************************************************************************
1620 * Remove all sub-menus from a menu.
1623 * hMenu [I] Menu to remove sub-menus from
1626 * Success: 0. All sub-menus under hMenu are removed
1627 * Failure: -1, if any parameter is invalid
1629 DWORD WINAPI
SHRemoveAllSubMenus(HMENU hMenu
)
1631 int iItemCount
= GetMenuItemCount(hMenu
) - 1;
1632 while (iItemCount
>= 0)
1634 HMENU hSubMenu
= GetSubMenu(hMenu
, iItemCount
);
1636 RemoveMenu(hMenu
, iItemCount
, MF_BYPOSITION
);
1642 /*************************************************************************
1645 * Enable or disable a menu item.
1648 * hMenu [I] Menu holding menu item
1649 * uID [I] ID of menu item to enable/disable
1650 * bEnable [I] Whether to enable (TRUE) or disable (FALSE) the item.
1653 * The return code from EnableMenuItem.
1655 UINT WINAPI
SHEnableMenuItem(HMENU hMenu
, UINT wItemID
, BOOL bEnable
)
1657 return EnableMenuItem(hMenu
, wItemID
, bEnable
? MF_ENABLED
: MF_GRAYED
);
1660 /*************************************************************************
1663 * Check or uncheck a menu item.
1666 * hMenu [I] Menu holding menu item
1667 * uID [I] ID of menu item to check/uncheck
1668 * bCheck [I] Whether to check (TRUE) or uncheck (FALSE) the item.
1671 * The return code from CheckMenuItem.
1673 DWORD WINAPI
SHCheckMenuItem(HMENU hMenu
, UINT uID
, BOOL bCheck
)
1675 return CheckMenuItem(hMenu
, uID
, bCheck
? MF_CHECKED
: MF_UNCHECKED
);
1678 /*************************************************************************
1681 * Register a window class if it isn't already.
1684 * lpWndClass [I] Window class to register
1687 * The result of the RegisterClassA call.
1689 DWORD WINAPI
SHRegisterClassA(WNDCLASSA
*wndclass
)
1692 if (GetClassInfoA(wndclass
->hInstance
, wndclass
->lpszClassName
, &wca
))
1694 return (DWORD
)RegisterClassA(wndclass
);
1697 /*************************************************************************
1700 BOOL WINAPI
SHSimulateDrop(IDropTarget
*pDrop
, IDataObject
*pDataObj
,
1701 DWORD grfKeyState
, PPOINTL lpPt
, DWORD
* pdwEffect
)
1703 DWORD dwEffect
= DROPEFFECT_LINK
| DROPEFFECT_MOVE
| DROPEFFECT_COPY
;
1704 POINTL pt
= { 0, 0 };
1710 pdwEffect
= &dwEffect
;
1712 IDropTarget_DragEnter(pDrop
, pDataObj
, grfKeyState
, *lpPt
, pdwEffect
);
1715 return IDropTarget_Drop(pDrop
, pDataObj
, grfKeyState
, *lpPt
, pdwEffect
);
1717 IDropTarget_DragLeave(pDrop
);
1721 /*************************************************************************
1724 * Call IPersistPropertyBag_Load() on an object.
1727 * lpUnknown [I] Object supporting the IPersistPropertyBag interface
1728 * lpPropBag [O] Destination for loaded IPropertyBag
1732 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1734 DWORD WINAPI
SHLoadFromPropertyBag(IUnknown
*lpUnknown
, IPropertyBag
* lpPropBag
)
1736 IPersistPropertyBag
* lpPPBag
;
1737 HRESULT hRet
= E_FAIL
;
1739 TRACE("(%p,%p)\n", lpUnknown
, lpPropBag
);
1743 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IPersistPropertyBag
,
1745 if (SUCCEEDED(hRet
) && lpPPBag
)
1747 hRet
= IPersistPropertyBag_Load(lpPPBag
, lpPropBag
, NULL
);
1748 IPersistPropertyBag_Release(lpPPBag
);
1754 /*************************************************************************
1757 * Call IOleControlSite_TranslateAccelerator() on an object.
1760 * lpUnknown [I] Object supporting the IOleControlSite interface.
1761 * lpMsg [I] Key message to be processed.
1762 * dwModifiers [I] Flags containing the state of the modifier keys.
1766 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
1768 HRESULT WINAPI
IUnknown_TranslateAcceleratorOCS(IUnknown
*lpUnknown
, LPMSG lpMsg
, DWORD dwModifiers
)
1770 IOleControlSite
* lpCSite
= NULL
;
1771 HRESULT hRet
= E_INVALIDARG
;
1773 TRACE("(%p,%p,0x%08x)\n", lpUnknown
, lpMsg
, dwModifiers
);
1776 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleControlSite
,
1778 if (SUCCEEDED(hRet
) && lpCSite
)
1780 hRet
= IOleControlSite_TranslateAccelerator(lpCSite
, lpMsg
, dwModifiers
);
1781 IOleControlSite_Release(lpCSite
);
1788 /*************************************************************************
1791 * Call IOleControlSite_OnFocus() on an object.
1794 * lpUnknown [I] Object supporting the IOleControlSite interface.
1795 * fGotFocus [I] Whether focus was gained (TRUE) or lost (FALSE).
1799 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1801 HRESULT WINAPI
IUnknown_OnFocusOCS(IUnknown
*lpUnknown
, BOOL fGotFocus
)
1803 IOleControlSite
* lpCSite
= NULL
;
1804 HRESULT hRet
= E_FAIL
;
1806 TRACE("(%p,%s)\n", lpUnknown
, fGotFocus
? "TRUE" : "FALSE");
1809 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleControlSite
,
1811 if (SUCCEEDED(hRet
) && lpCSite
)
1813 hRet
= IOleControlSite_OnFocus(lpCSite
, fGotFocus
);
1814 IOleControlSite_Release(lpCSite
);
1820 /*************************************************************************
1823 HRESULT WINAPI
IUnknown_HandleIRestrict(LPUNKNOWN lpUnknown
, PVOID lpArg1
,
1824 PVOID lpArg2
, PVOID lpArg3
, PVOID lpArg4
)
1826 /* FIXME: {D12F26B2-D90A-11D0-830D-00AA005B4383} - What object does this represent? */
1827 static const DWORD service_id
[] = { 0xd12f26b2, 0x11d0d90a, 0xaa000d83, 0x83435b00 };
1828 /* FIXME: {D12F26B1-D90A-11D0-830D-00AA005B4383} - Also Unknown/undocumented */
1829 static const DWORD function_id
[] = { 0xd12f26b1, 0x11d0d90a, 0xaa000d83, 0x83435b00 };
1830 HRESULT hRet
= E_INVALIDARG
;
1831 LPUNKNOWN lpUnkInner
= NULL
; /* FIXME: Real type is unknown */
1833 TRACE("(%p,%p,%p,%p,%p)\n", lpUnknown
, lpArg1
, lpArg2
, lpArg3
, lpArg4
);
1835 if (lpUnknown
&& lpArg4
)
1837 hRet
= IUnknown_QueryService(lpUnknown
, (REFGUID
)service_id
,
1838 (REFGUID
)function_id
, (void**)&lpUnkInner
);
1840 if (SUCCEEDED(hRet
) && lpUnkInner
)
1842 /* FIXME: The type of service object requested is unknown, however
1843 * testing shows that its first method is called with 4 parameters.
1844 * Fake this by using IParseDisplayName_ParseDisplayName since the
1845 * signature and position in the vtable matches our unknown object type.
1847 hRet
= IParseDisplayName_ParseDisplayName((LPPARSEDISPLAYNAME
)lpUnkInner
,
1848 lpArg1
, lpArg2
, lpArg3
, lpArg4
);
1849 IUnknown_Release(lpUnkInner
);
1855 /*************************************************************************
1858 * Get a sub-menu from a menu item.
1861 * hMenu [I] Menu to get sub-menu from
1862 * uID [I] ID of menu item containing sub-menu
1865 * The sub-menu of the item, or a NULL handle if any parameters are invalid.
1867 HMENU WINAPI
SHGetMenuFromID(HMENU hMenu
, UINT uID
)
1871 TRACE("(%p,%u)\n", hMenu
, uID
);
1873 mi
.cbSize
= sizeof(mi
);
1874 mi
.fMask
= MIIM_SUBMENU
;
1876 if (!GetMenuItemInfoW(hMenu
, uID
, FALSE
, &mi
))
1882 /*************************************************************************
1885 * Get the color depth of the primary display.
1891 * The color depth of the primary display.
1893 DWORD WINAPI
SHGetCurColorRes(void)
1901 ret
= GetDeviceCaps(hdc
, BITSPIXEL
) * GetDeviceCaps(hdc
, PLANES
);
1906 /*************************************************************************
1909 * Wait for a message to arrive, with a timeout.
1912 * hand [I] Handle to query
1913 * dwTimeout [I] Timeout in ticks or INFINITE to never timeout
1916 * STATUS_TIMEOUT if no message is received before dwTimeout ticks passes.
1917 * Otherwise returns the value from MsgWaitForMultipleObjectsEx when a
1918 * message is available.
1920 DWORD WINAPI
SHWaitForSendMessageThread(HANDLE hand
, DWORD dwTimeout
)
1922 DWORD dwEndTicks
= GetTickCount() + dwTimeout
;
1925 while ((dwRet
= MsgWaitForMultipleObjectsEx(1, &hand
, dwTimeout
, QS_SENDMESSAGE
, 0)) == 1)
1929 PeekMessageW(&msg
, NULL
, 0, 0, PM_NOREMOVE
);
1931 if (dwTimeout
!= INFINITE
)
1933 if ((int)(dwTimeout
= dwEndTicks
- GetTickCount()) <= 0)
1934 return WAIT_TIMEOUT
;
1941 /*************************************************************************
1944 * Determine if a shell folder can be expanded.
1947 * lpFolder [I] Parent folder containing the object to test.
1948 * pidl [I] Id of the object to test.
1951 * Success: S_OK, if the object is expandable, S_FALSE otherwise.
1952 * Failure: E_INVALIDARG, if any argument is invalid.
1955 * If the object to be tested does not expose the IQueryInfo() interface it
1956 * will not be identified as an expandable folder.
1958 HRESULT WINAPI
SHIsExpandableFolder(LPSHELLFOLDER lpFolder
, LPCITEMIDLIST pidl
)
1960 HRESULT hRet
= E_INVALIDARG
;
1963 if (lpFolder
&& pidl
)
1965 hRet
= IShellFolder_GetUIObjectOf(lpFolder
, NULL
, 1, &pidl
, &IID_IQueryInfo
,
1966 NULL
, (void**)&lpInfo
);
1968 hRet
= S_FALSE
; /* Doesn't expose IQueryInfo */
1973 /* MSDN states of IQueryInfo_GetInfoFlags() that "This method is not
1974 * currently used". Really? You wouldn't be holding out on me would you?
1976 hRet
= IQueryInfo_GetInfoFlags(lpInfo
, &dwFlags
);
1978 if (SUCCEEDED(hRet
))
1980 /* 0x2 is an undocumented flag apparently indicating expandability */
1981 hRet
= dwFlags
& 0x2 ? S_OK
: S_FALSE
;
1984 IQueryInfo_Release(lpInfo
);
1990 /*************************************************************************
1993 * Blank out a region of text by drawing the background only.
1996 * hDC [I] Device context to draw in
1997 * pRect [I] Area to draw in
1998 * cRef [I] Color to draw in
2003 DWORD WINAPI
SHFillRectClr(HDC hDC
, LPCRECT pRect
, COLORREF cRef
)
2005 COLORREF cOldColor
= SetBkColor(hDC
, cRef
);
2006 ExtTextOutA(hDC
, 0, 0, ETO_OPAQUE
, pRect
, 0, 0, 0);
2007 SetBkColor(hDC
, cOldColor
);
2011 /*************************************************************************
2014 * Return the value associated with a key in a map.
2017 * lpKeys [I] A list of keys of length iLen
2018 * lpValues [I] A list of values associated with lpKeys, of length iLen
2019 * iLen [I] Length of both lpKeys and lpValues
2020 * iKey [I] The key value to look up in lpKeys
2023 * The value in lpValues associated with iKey, or -1 if iKey is not
2027 * - If two elements in the map share the same key, this function returns
2028 * the value closest to the start of the map
2029 * - The native version of this function crashes if lpKeys or lpValues is NULL.
2031 int WINAPI
SHSearchMapInt(const int *lpKeys
, const int *lpValues
, int iLen
, int iKey
)
2033 if (lpKeys
&& lpValues
)
2039 if (lpKeys
[i
] == iKey
)
2040 return lpValues
[i
]; /* Found */
2044 return -1; /* Not found */
2048 /*************************************************************************
2051 * Copy an interface pointer
2054 * lppDest [O] Destination for copy
2055 * lpUnknown [I] Source for copy
2060 VOID WINAPI
IUnknown_Set(IUnknown
**lppDest
, IUnknown
*lpUnknown
)
2062 TRACE("(%p,%p)\n", lppDest
, lpUnknown
);
2065 IUnknown_AtomicRelease(lppDest
); /* Release existing interface */
2070 IUnknown_AddRef(lpUnknown
);
2071 *lppDest
= lpUnknown
;
2075 /*************************************************************************
2079 HRESULT WINAPI
MayQSForward(IUnknown
* lpUnknown
, PVOID lpReserved
,
2080 REFGUID riidCmdGrp
, ULONG cCmds
,
2081 OLECMD
*prgCmds
, OLECMDTEXT
* pCmdText
)
2083 FIXME("(%p,%p,%p,%d,%p,%p) - stub\n",
2084 lpUnknown
, lpReserved
, riidCmdGrp
, cCmds
, prgCmds
, pCmdText
);
2086 /* FIXME: Calls IsQSForward & IUnknown_QueryStatus */
2087 return DRAGDROP_E_NOTREGISTERED
;
2090 /*************************************************************************
2094 HRESULT WINAPI
MayExecForward(IUnknown
* lpUnknown
, INT iUnk
, REFGUID pguidCmdGroup
,
2095 DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
* pvaIn
,
2098 FIXME("(%p,%d,%p,%d,%d,%p,%p) - stub!\n", lpUnknown
, iUnk
, pguidCmdGroup
,
2099 nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2100 return DRAGDROP_E_NOTREGISTERED
;
2103 /*************************************************************************
2107 HRESULT WINAPI
IsQSForward(REFGUID pguidCmdGroup
,ULONG cCmds
, OLECMD
*prgCmds
)
2109 FIXME("(%p,%d,%p) - stub!\n", pguidCmdGroup
, cCmds
, prgCmds
);
2110 return DRAGDROP_E_NOTREGISTERED
;
2113 /*************************************************************************
2116 * Determine if a window is not a child of another window.
2119 * hParent [I] Suspected parent window
2120 * hChild [I] Suspected child window
2123 * TRUE: If hChild is a child window of hParent
2124 * FALSE: If hChild is not a child window of hParent, or they are equal
2126 BOOL WINAPI
SHIsChildOrSelf(HWND hParent
, HWND hChild
)
2128 TRACE("(%p,%p)\n", hParent
, hChild
);
2130 if (!hParent
|| !hChild
)
2132 else if(hParent
== hChild
)
2134 return !IsChild(hParent
, hChild
);
2137 /*************************************************************************
2138 * FDSA functions. Manage a dynamic array of fixed size memory blocks.
2143 DWORD num_items
; /* Number of elements inserted */
2144 void *mem
; /* Ptr to array */
2145 DWORD blocks_alloced
; /* Number of elements allocated */
2146 BYTE inc
; /* Number of elements to grow by when we need to expand */
2147 BYTE block_size
; /* Size in bytes of an element */
2148 BYTE flags
; /* Flags */
2151 #define FDSA_FLAG_INTERNAL_ALLOC 0x01 /* When set we have allocated mem internally */
2153 /*************************************************************************
2156 * Initialize an FDSA array.
2158 BOOL WINAPI
FDSA_Initialize(DWORD block_size
, DWORD inc
, FDSA_info
*info
, void *mem
,
2161 TRACE("(0x%08x 0x%08x %p %p 0x%08x)\n", block_size
, inc
, info
, mem
, init_blocks
);
2167 memset(mem
, 0, block_size
* init_blocks
);
2169 info
->num_items
= 0;
2172 info
->blocks_alloced
= init_blocks
;
2173 info
->block_size
= block_size
;
2179 /*************************************************************************
2182 * Destroy an FDSA array
2184 BOOL WINAPI
FDSA_Destroy(FDSA_info
*info
)
2186 TRACE("(%p)\n", info
);
2188 if(info
->flags
& FDSA_FLAG_INTERNAL_ALLOC
)
2190 HeapFree(GetProcessHeap(), 0, info
->mem
);
2197 /*************************************************************************
2200 * Insert element into an FDSA array
2202 DWORD WINAPI
FDSA_InsertItem(FDSA_info
*info
, DWORD where
, const void *block
)
2204 TRACE("(%p 0x%08x %p)\n", info
, where
, block
);
2205 if(where
> info
->num_items
)
2206 where
= info
->num_items
;
2208 if(info
->num_items
>= info
->blocks_alloced
)
2210 DWORD size
= (info
->blocks_alloced
+ info
->inc
) * info
->block_size
;
2211 if(info
->flags
& 0x1)
2212 info
->mem
= HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, info
->mem
, size
);
2215 void *old_mem
= info
->mem
;
2216 info
->mem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
2217 memcpy(info
->mem
, old_mem
, info
->blocks_alloced
* info
->block_size
);
2219 info
->blocks_alloced
+= info
->inc
;
2223 if(where
< info
->num_items
)
2225 memmove((char*)info
->mem
+ (where
+ 1) * info
->block_size
,
2226 (char*)info
->mem
+ where
* info
->block_size
,
2227 (info
->num_items
- where
) * info
->block_size
);
2229 memcpy((char*)info
->mem
+ where
* info
->block_size
, block
, info
->block_size
);
2235 /*************************************************************************
2238 * Delete an element from an FDSA array.
2240 BOOL WINAPI
FDSA_DeleteItem(FDSA_info
*info
, DWORD where
)
2242 TRACE("(%p 0x%08x)\n", info
, where
);
2244 if(where
>= info
->num_items
)
2247 if(where
< info
->num_items
- 1)
2249 memmove((char*)info
->mem
+ where
* info
->block_size
,
2250 (char*)info
->mem
+ (where
+ 1) * info
->block_size
,
2251 (info
->num_items
- where
- 1) * info
->block_size
);
2253 memset((char*)info
->mem
+ (info
->num_items
- 1) * info
->block_size
,
2254 0, info
->block_size
);
2265 /*************************************************************************
2268 * Call IUnknown_QueryInterface() on a table of objects.
2272 * Failure: E_POINTER or E_NOINTERFACE.
2274 HRESULT WINAPI
QISearch(
2275 LPVOID w
, /* [in] Table of interfaces */
2276 IFACE_INDEX_TBL
*x
, /* [in] Array of REFIIDs and indexes into the table */
2277 REFIID riid
, /* [in] REFIID to get interface for */
2278 LPVOID
*ppv
) /* [out] Destination for interface pointer */
2282 IFACE_INDEX_TBL
*xmove
;
2284 TRACE("(%p %p %s %p)\n", w
,x
,debugstr_guid(riid
),ppv
);
2287 while (xmove
->refid
) {
2288 TRACE("trying (indx %d) %s\n", xmove
->indx
, debugstr_guid(xmove
->refid
));
2289 if (IsEqualIID(riid
, xmove
->refid
)) {
2290 a_vtbl
= (IUnknown
*)(xmove
->indx
+ (LPBYTE
)w
);
2291 TRACE("matched, returning (%p)\n", a_vtbl
);
2293 IUnknown_AddRef(a_vtbl
);
2299 if (IsEqualIID(riid
, &IID_IUnknown
)) {
2300 a_vtbl
= (IUnknown
*)(x
->indx
+ (LPBYTE
)w
);
2301 TRACE("returning first for IUnknown (%p)\n", a_vtbl
);
2303 IUnknown_AddRef(a_vtbl
);
2307 ret
= E_NOINTERFACE
;
2311 TRACE("-- 0x%08x\n", ret
);
2315 /*************************************************************************
2318 * Set the Font for a window and the "PropDlgFont" property of the parent window.
2321 * hWnd [I] Parent Window to set the property
2322 * id [I] Index of child Window to set the Font
2328 HRESULT WINAPI
SHSetDefaultDialogFont(HWND hWnd
, INT id
)
2330 FIXME("(%p, %d) stub\n", hWnd
, id
);
2334 /*************************************************************************
2337 * Remove the "PropDlgFont" property from a window.
2340 * hWnd [I] Window to remove the property from
2343 * A handle to the removed property, or NULL if it did not exist.
2345 HANDLE WINAPI
SHRemoveDefaultDialogFont(HWND hWnd
)
2349 TRACE("(%p)\n", hWnd
);
2351 hProp
= GetPropA(hWnd
, "PropDlgFont");
2355 DeleteObject(hProp
);
2356 hProp
= RemovePropA(hWnd
, "PropDlgFont");
2361 /*************************************************************************
2364 * Load the in-process server of a given GUID.
2367 * refiid [I] GUID of the server to load.
2370 * Success: A handle to the loaded server dll.
2371 * Failure: A NULL handle.
2373 HMODULE WINAPI
SHPinDllOfCLSID(REFIID refiid
)
2377 CHAR value
[MAX_PATH
], string
[MAX_PATH
];
2379 strcpy(string
, "CLSID\\");
2380 SHStringFromGUIDA(refiid
, string
+ 6, sizeof(string
)/sizeof(char) - 6);
2381 strcat(string
, "\\InProcServer32");
2384 RegOpenKeyExA(HKEY_CLASSES_ROOT
, string
, 0, 1, &newkey
);
2385 RegQueryValueExA(newkey
, 0, 0, &type
, (PBYTE
)value
, &count
);
2386 RegCloseKey(newkey
);
2387 return LoadLibraryExA(value
, 0, 0);
2390 /*************************************************************************
2393 * Unicode version of SHLWAPI_183.
2395 DWORD WINAPI
SHRegisterClassW(WNDCLASSW
* lpWndClass
)
2399 TRACE("(%p %s)\n",lpWndClass
->hInstance
, debugstr_w(lpWndClass
->lpszClassName
));
2401 if (GetClassInfoW(lpWndClass
->hInstance
, lpWndClass
->lpszClassName
, &WndClass
))
2403 return RegisterClassW(lpWndClass
);
2406 /*************************************************************************
2409 * Unregister a list of classes.
2412 * hInst [I] Application instance that registered the classes
2413 * lppClasses [I] List of class names
2414 * iCount [I] Number of names in lppClasses
2419 void WINAPI
SHUnregisterClassesA(HINSTANCE hInst
, LPCSTR
*lppClasses
, INT iCount
)
2423 TRACE("(%p,%p,%d)\n", hInst
, lppClasses
, iCount
);
2427 if (GetClassInfoA(hInst
, *lppClasses
, &WndClass
))
2428 UnregisterClassA(*lppClasses
, hInst
);
2434 /*************************************************************************
2437 * Unicode version of SHUnregisterClassesA.
2439 void WINAPI
SHUnregisterClassesW(HINSTANCE hInst
, LPCWSTR
*lppClasses
, INT iCount
)
2443 TRACE("(%p,%p,%d)\n", hInst
, lppClasses
, iCount
);
2447 if (GetClassInfoW(hInst
, *lppClasses
, &WndClass
))
2448 UnregisterClassW(*lppClasses
, hInst
);
2454 /*************************************************************************
2457 * Call The correct (Ascii/Unicode) default window procedure for a window.
2460 * hWnd [I] Window to call the default procedure for
2461 * uMessage [I] Message ID
2462 * wParam [I] WPARAM of message
2463 * lParam [I] LPARAM of message
2466 * The result of calling DefWindowProcA() or DefWindowProcW().
2468 LRESULT CALLBACK
SHDefWindowProc(HWND hWnd
, UINT uMessage
, WPARAM wParam
, LPARAM lParam
)
2470 if (IsWindowUnicode(hWnd
))
2471 return DefWindowProcW(hWnd
, uMessage
, wParam
, lParam
);
2472 return DefWindowProcA(hWnd
, uMessage
, wParam
, lParam
);
2475 /*************************************************************************
2478 HRESULT WINAPI
IUnknown_GetSite(LPUNKNOWN lpUnknown
, REFIID iid
, PVOID
*lppSite
)
2480 HRESULT hRet
= E_INVALIDARG
;
2481 LPOBJECTWITHSITE lpSite
= NULL
;
2483 TRACE("(%p,%s,%p)\n", lpUnknown
, debugstr_guid(iid
), lppSite
);
2485 if (lpUnknown
&& iid
&& lppSite
)
2487 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IObjectWithSite
,
2489 if (SUCCEEDED(hRet
) && lpSite
)
2491 hRet
= IObjectWithSite_GetSite(lpSite
, iid
, lppSite
);
2492 IObjectWithSite_Release(lpSite
);
2498 /*************************************************************************
2501 * Create a worker window using CreateWindowExA().
2504 * wndProc [I] Window procedure
2505 * hWndParent [I] Parent window
2506 * dwExStyle [I] Extra style flags
2507 * dwStyle [I] Style flags
2508 * hMenu [I] Window menu
2512 * Success: The window handle of the newly created window.
2515 HWND WINAPI
SHCreateWorkerWindowA(LONG wndProc
, HWND hWndParent
, DWORD dwExStyle
,
2516 DWORD dwStyle
, HMENU hMenu
, LONG z
)
2518 static const char szClass
[] = "WorkerA";
2522 TRACE("(0x%08x,%p,0x%08x,0x%08x,%p,0x%08x)\n",
2523 wndProc
, hWndParent
, dwExStyle
, dwStyle
, hMenu
, z
);
2525 /* Create Window class */
2527 wc
.lpfnWndProc
= DefWindowProcA
;
2530 wc
.hInstance
= shlwapi_hInstance
;
2532 wc
.hCursor
= LoadCursorA(NULL
, (LPSTR
)IDC_ARROW
);
2533 wc
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
2534 wc
.lpszMenuName
= NULL
;
2535 wc
.lpszClassName
= szClass
;
2537 SHRegisterClassA(&wc
); /* Register class */
2539 /* FIXME: Set extra bits in dwExStyle */
2541 hWnd
= CreateWindowExA(dwExStyle
, szClass
, 0, dwStyle
, 0, 0, 0, 0,
2542 hWndParent
, hMenu
, shlwapi_hInstance
, 0);
2545 SetWindowLongPtrW(hWnd
, DWLP_MSGRESULT
, z
);
2548 SetWindowLongPtrA(hWnd
, GWLP_WNDPROC
, wndProc
);
2553 typedef struct tagPOLICYDATA
2555 DWORD policy
; /* flags value passed to SHRestricted */
2556 LPCWSTR appstr
; /* application str such as "Explorer" */
2557 LPCWSTR keystr
; /* name of the actual registry key / policy */
2558 } POLICYDATA
, *LPPOLICYDATA
;
2560 #define SHELL_NO_POLICY 0xffffffff
2562 /* default shell policy registry key */
2563 static const WCHAR strRegistryPolicyW
[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o',
2564 's','o','f','t','\\','W','i','n','d','o','w','s','\\',
2565 'C','u','r','r','e','n','t','V','e','r','s','i','o','n',
2566 '\\','P','o','l','i','c','i','e','s',0};
2568 /*************************************************************************
2571 * Retrieve a policy value from the registry.
2574 * lpSubKey [I] registry key name
2575 * lpSubName [I] subname of registry key
2576 * lpValue [I] value name of registry value
2579 * the value associated with the registry key or 0 if not found
2581 DWORD WINAPI
SHGetRestriction(LPCWSTR lpSubKey
, LPCWSTR lpSubName
, LPCWSTR lpValue
)
2583 DWORD retval
, datsize
= sizeof(retval
);
2587 lpSubKey
= strRegistryPolicyW
;
2589 retval
= RegOpenKeyW(HKEY_LOCAL_MACHINE
, lpSubKey
, &hKey
);
2590 if (retval
!= ERROR_SUCCESS
)
2591 retval
= RegOpenKeyW(HKEY_CURRENT_USER
, lpSubKey
, &hKey
);
2592 if (retval
!= ERROR_SUCCESS
)
2595 SHGetValueW(hKey
, lpSubName
, lpValue
, NULL
, &retval
, &datsize
);
2600 /*************************************************************************
2603 * Helper function to retrieve the possibly cached value for a specific policy
2606 * policy [I] The policy to look for
2607 * initial [I] Main registry key to open, if NULL use default
2608 * polTable [I] Table of known policies, 0 terminated
2609 * polArr [I] Cache array of policy values
2612 * The retrieved policy value or 0 if not successful
2615 * This function is used by the native SHRestricted function to search for the
2616 * policy and cache it once retrieved. The current Wine implementation uses a
2617 * different POLICYDATA structure and implements a similar algorithm adapted to
2620 DWORD WINAPI
SHRestrictionLookup(
2623 LPPOLICYDATA polTable
,
2626 TRACE("(0x%08x %s %p %p)\n", policy
, debugstr_w(initial
), polTable
, polArr
);
2628 if (!polTable
|| !polArr
)
2631 for (;polTable
->policy
; polTable
++, polArr
++)
2633 if (policy
== polTable
->policy
)
2635 /* we have a known policy */
2637 /* check if this policy has been cached */
2638 if (*polArr
== SHELL_NO_POLICY
)
2639 *polArr
= SHGetRestriction(initial
, polTable
->appstr
, polTable
->keystr
);
2643 /* we don't know this policy, return 0 */
2644 TRACE("unknown policy: (%08x)\n", policy
);
2648 /*************************************************************************
2651 * Get an interface from an object.
2654 * Success: S_OK. ppv contains the requested interface.
2655 * Failure: An HRESULT error code.
2658 * This QueryInterface asks the inner object for an interface. In case
2659 * of aggregation this request would be forwarded by the inner to the
2660 * outer object. This function asks the inner object directly for the
2661 * interface circumventing the forwarding to the outer object.
2663 HRESULT WINAPI
SHWeakQueryInterface(
2664 IUnknown
* pUnk
, /* [in] Outer object */
2665 IUnknown
* pInner
, /* [in] Inner object */
2666 IID
* riid
, /* [in] Interface GUID to query for */
2667 LPVOID
* ppv
) /* [out] Destination for queried interface */
2669 HRESULT hret
= E_NOINTERFACE
;
2670 TRACE("(pUnk=%p pInner=%p\n\tIID: %s %p)\n",pUnk
,pInner
,debugstr_guid(riid
), ppv
);
2673 if(pUnk
&& pInner
) {
2674 hret
= IUnknown_QueryInterface(pInner
, riid
, ppv
);
2675 if (SUCCEEDED(hret
)) IUnknown_Release(pUnk
);
2677 TRACE("-- 0x%08x\n", hret
);
2681 /*************************************************************************
2684 * Move a reference from one interface to another.
2687 * lpDest [O] Destination to receive the reference
2688 * lppUnknown [O] Source to give up the reference to lpDest
2693 VOID WINAPI
SHWeakReleaseInterface(IUnknown
*lpDest
, IUnknown
**lppUnknown
)
2695 TRACE("(%p,%p)\n", lpDest
, lppUnknown
);
2700 IUnknown_AddRef(lpDest
);
2701 IUnknown_AtomicRelease(lppUnknown
); /* Release existing interface */
2705 /*************************************************************************
2708 * Convert an ASCII string of a CLSID into a CLSID.
2711 * idstr [I] String representing a CLSID in registry format
2712 * id [O] Destination for the converted CLSID
2715 * Success: TRUE. id contains the converted CLSID.
2718 BOOL WINAPI
GUIDFromStringA(LPCSTR idstr
, CLSID
*id
)
2721 MultiByteToWideChar(CP_ACP
, 0, idstr
, -1, wClsid
, sizeof(wClsid
)/sizeof(WCHAR
));
2722 return SUCCEEDED(CLSIDFromString(wClsid
, id
));
2725 /*************************************************************************
2728 * Unicode version of GUIDFromStringA.
2730 BOOL WINAPI
GUIDFromStringW(LPCWSTR idstr
, CLSID
*id
)
2732 return SUCCEEDED(CLSIDFromString((LPOLESTR
)idstr
, id
));
2735 /*************************************************************************
2738 * Determine if the browser is integrated into the shell, and set a registry
2745 * 1, If the browser is not integrated.
2746 * 2, If the browser is integrated.
2749 * The key "HKLM\Software\Microsoft\Internet Explorer\IntegratedBrowser" is
2750 * either set to TRUE, or removed depending on whether the browser is deemed
2753 DWORD WINAPI
WhichPlatform(void)
2755 static const char szIntegratedBrowser
[] = "IntegratedBrowser";
2756 static DWORD dwState
= 0;
2758 DWORD dwRet
, dwData
, dwSize
;
2764 /* If shell32 exports DllGetVersion(), the browser is integrated */
2766 hshell32
= LoadLibraryA("shell32.dll");
2769 FARPROC pDllGetVersion
;
2770 pDllGetVersion
= GetProcAddress(hshell32
, "DllGetVersion");
2771 dwState
= pDllGetVersion
? 2 : 1;
2772 FreeLibrary(hshell32
);
2775 /* Set or delete the key accordingly */
2776 dwRet
= RegOpenKeyExA(HKEY_LOCAL_MACHINE
,
2777 "Software\\Microsoft\\Internet Explorer", 0,
2778 KEY_ALL_ACCESS
, &hKey
);
2781 dwRet
= RegQueryValueExA(hKey
, szIntegratedBrowser
, 0, 0,
2782 (LPBYTE
)&dwData
, &dwSize
);
2784 if (!dwRet
&& dwState
== 1)
2786 /* Value exists but browser is not integrated */
2787 RegDeleteValueA(hKey
, szIntegratedBrowser
);
2789 else if (dwRet
&& dwState
== 2)
2791 /* Browser is integrated but value does not exist */
2793 RegSetValueExA(hKey
, szIntegratedBrowser
, 0, REG_DWORD
,
2794 (LPBYTE
)&dwData
, sizeof(dwData
));
2801 /*************************************************************************
2804 * Unicode version of SHCreateWorkerWindowA.
2806 HWND WINAPI
SHCreateWorkerWindowW(LONG wndProc
, HWND hWndParent
, DWORD dwExStyle
,
2807 DWORD dwStyle
, HMENU hMenu
, LONG z
)
2809 static const WCHAR szClass
[] = { 'W', 'o', 'r', 'k', 'e', 'r', 'W', '\0' };
2813 TRACE("(0x%08x,%p,0x%08x,0x%08x,%p,0x%08x)\n",
2814 wndProc
, hWndParent
, dwExStyle
, dwStyle
, hMenu
, z
);
2816 /* If our OS is natively ASCII, use the ASCII version */
2817 if (!(GetVersion() & 0x80000000)) /* NT */
2818 return SHCreateWorkerWindowA(wndProc
, hWndParent
, dwExStyle
, dwStyle
, hMenu
, z
);
2820 /* Create Window class */
2822 wc
.lpfnWndProc
= DefWindowProcW
;
2825 wc
.hInstance
= shlwapi_hInstance
;
2827 wc
.hCursor
= LoadCursorW(NULL
, (LPWSTR
)IDC_ARROW
);
2828 wc
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
2829 wc
.lpszMenuName
= NULL
;
2830 wc
.lpszClassName
= szClass
;
2832 SHRegisterClassW(&wc
); /* Register class */
2834 /* FIXME: Set extra bits in dwExStyle */
2836 hWnd
= CreateWindowExW(dwExStyle
, szClass
, 0, dwStyle
, 0, 0, 0, 0,
2837 hWndParent
, hMenu
, shlwapi_hInstance
, 0);
2840 SetWindowLongPtrW(hWnd
, DWLP_MSGRESULT
, z
);
2843 SetWindowLongPtrW(hWnd
, GWLP_WNDPROC
, wndProc
);
2848 /*************************************************************************
2851 * Get and show a context menu from a shell folder.
2854 * hWnd [I] Window displaying the shell folder
2855 * lpFolder [I] IShellFolder interface
2856 * lpApidl [I] Id for the particular folder desired
2860 * Failure: An HRESULT error code indicating the error.
2862 HRESULT WINAPI
SHInvokeDefaultCommand(HWND hWnd
, IShellFolder
* lpFolder
, LPCITEMIDLIST lpApidl
)
2864 return SHInvokeCommand(hWnd
, lpFolder
, lpApidl
, FALSE
);
2867 /*************************************************************************
2870 * _SHPackDispParamsV
2872 HRESULT WINAPI
SHPackDispParamsV(DISPPARAMS
*params
, VARIANTARG
*args
, UINT cnt
, __ms_va_list valist
)
2876 TRACE("(%p %p %u ...)\n", params
, args
, cnt
);
2878 params
->rgvarg
= args
;
2879 params
->rgdispidNamedArgs
= NULL
;
2880 params
->cArgs
= cnt
;
2881 params
->cNamedArgs
= 0;
2885 while(iter
-- > args
) {
2886 V_VT(iter
) = va_arg(valist
, enum VARENUM
);
2888 TRACE("vt=%d\n", V_VT(iter
));
2890 if(V_VT(iter
) & VT_BYREF
) {
2891 V_BYREF(iter
) = va_arg(valist
, LPVOID
);
2893 switch(V_VT(iter
)) {
2895 V_I4(iter
) = va_arg(valist
, LONG
);
2898 V_BSTR(iter
) = va_arg(valist
, BSTR
);
2901 V_DISPATCH(iter
) = va_arg(valist
, IDispatch
*);
2904 V_BOOL(iter
) = va_arg(valist
, int);
2907 V_UNKNOWN(iter
) = va_arg(valist
, IUnknown
*);
2911 V_I4(iter
) = va_arg(valist
, LONG
);
2919 /*************************************************************************
2924 HRESULT WINAPIV
SHPackDispParams(DISPPARAMS
*params
, VARIANTARG
*args
, UINT cnt
, ...)
2926 __ms_va_list valist
;
2929 __ms_va_start(valist
, cnt
);
2930 hres
= SHPackDispParamsV(params
, args
, cnt
, valist
);
2931 __ms_va_end(valist
);
2935 /*************************************************************************
2936 * SHLWAPI_InvokeByIID
2938 * This helper function calls IDispatch::Invoke for each sink
2939 * which implements given iid or IDispatch.
2942 static HRESULT
SHLWAPI_InvokeByIID(
2943 IConnectionPoint
* iCP
,
2946 DISPPARAMS
* dispParams
)
2948 IEnumConnections
*enumerator
;
2950 static DISPPARAMS empty
= {NULL
, NULL
, 0, 0};
2951 DISPPARAMS
* params
= dispParams
;
2953 HRESULT result
= IConnectionPoint_EnumConnections(iCP
, &enumerator
);
2957 /* Invoke is never happening with an NULL dispParams */
2961 while(IEnumConnections_Next(enumerator
, 1, &rgcd
, NULL
)==S_OK
)
2963 IDispatch
*dispIface
;
2964 if ((iid
&& SUCCEEDED(IUnknown_QueryInterface(rgcd
.pUnk
, iid
, (LPVOID
*)&dispIface
))) ||
2965 SUCCEEDED(IUnknown_QueryInterface(rgcd
.pUnk
, &IID_IDispatch
, (LPVOID
*)&dispIface
)))
2967 IDispatch_Invoke(dispIface
, dispId
, &IID_NULL
, 0, DISPATCH_METHOD
, params
, NULL
, NULL
, NULL
);
2968 IDispatch_Release(dispIface
);
2970 IUnknown_Release(rgcd
.pUnk
);
2973 IEnumConnections_Release(enumerator
);
2978 /*************************************************************************
2979 * IConnectionPoint_InvokeWithCancel [SHLWAPI.283]
2981 HRESULT WINAPI
IConnectionPoint_InvokeWithCancel( IConnectionPoint
* iCP
,
2982 DISPID dispId
, DISPPARAMS
* dispParams
,
2983 DWORD unknown1
, DWORD unknown2
)
2988 FIXME("(%p)->(0x%x %p %x %x) partial stub\n", iCP
, dispId
, dispParams
, unknown1
, unknown2
);
2990 result
= IConnectionPoint_GetConnectionInterface(iCP
, &iid
);
2991 if (SUCCEEDED(result
))
2992 result
= SHLWAPI_InvokeByIID(iCP
, &iid
, dispId
, dispParams
);
2994 result
= SHLWAPI_InvokeByIID(iCP
, NULL
, dispId
, dispParams
);
3000 /*************************************************************************
3003 * IConnectionPoint_SimpleInvoke
3005 HRESULT WINAPI
IConnectionPoint_SimpleInvoke(
3006 IConnectionPoint
* iCP
,
3008 DISPPARAMS
* dispParams
)
3013 TRACE("(%p)->(0x%x %p)\n",iCP
,dispId
,dispParams
);
3015 result
= IConnectionPoint_GetConnectionInterface(iCP
, &iid
);
3016 if (SUCCEEDED(result
))
3017 result
= SHLWAPI_InvokeByIID(iCP
, &iid
, dispId
, dispParams
);
3019 result
= SHLWAPI_InvokeByIID(iCP
, NULL
, dispId
, dispParams
);
3024 /*************************************************************************
3027 * Notify an IConnectionPoint object of changes.
3030 * lpCP [I] Object to notify
3035 * Failure: E_NOINTERFACE, if lpCP is NULL or does not support the
3036 * IConnectionPoint interface.
3038 HRESULT WINAPI
IConnectionPoint_OnChanged(IConnectionPoint
* lpCP
, DISPID dispID
)
3040 IEnumConnections
*lpEnum
;
3041 HRESULT hRet
= E_NOINTERFACE
;
3043 TRACE("(%p,0x%8X)\n", lpCP
, dispID
);
3045 /* Get an enumerator for the connections */
3047 hRet
= IConnectionPoint_EnumConnections(lpCP
, &lpEnum
);
3049 if (SUCCEEDED(hRet
))
3051 IPropertyNotifySink
*lpSink
;
3052 CONNECTDATA connData
;
3055 /* Call OnChanged() for every notify sink in the connection point */
3056 while (IEnumConnections_Next(lpEnum
, 1, &connData
, &ulFetched
) == S_OK
)
3058 if (SUCCEEDED(IUnknown_QueryInterface(connData
.pUnk
, &IID_IPropertyNotifySink
, (void**)&lpSink
)) &&
3061 IPropertyNotifySink_OnChanged(lpSink
, dispID
);
3062 IPropertyNotifySink_Release(lpSink
);
3064 IUnknown_Release(connData
.pUnk
);
3067 IEnumConnections_Release(lpEnum
);
3072 /*************************************************************************
3075 * IUnknown_CPContainerInvokeParam
3077 HRESULT WINAPIV
IUnknown_CPContainerInvokeParam(
3078 IUnknown
*container
,
3085 IConnectionPoint
*iCP
;
3086 IConnectionPointContainer
*iCPC
;
3087 DISPPARAMS dispParams
= {buffer
, NULL
, cParams
, 0};
3088 __ms_va_list valist
;
3091 return E_NOINTERFACE
;
3093 result
= IUnknown_QueryInterface(container
, &IID_IConnectionPointContainer
,(LPVOID
*) &iCPC
);
3097 result
= IConnectionPointContainer_FindConnectionPoint(iCPC
, riid
, &iCP
);
3098 IConnectionPointContainer_Release(iCPC
);
3102 __ms_va_start(valist
, cParams
);
3103 SHPackDispParamsV(&dispParams
, buffer
, cParams
, valist
);
3104 __ms_va_end(valist
);
3106 result
= SHLWAPI_InvokeByIID(iCP
, riid
, dispId
, &dispParams
);
3107 IConnectionPoint_Release(iCP
);
3112 /*************************************************************************
3115 * Notify an IConnectionPointContainer object of changes.
3118 * lpUnknown [I] Object to notify
3123 * Failure: E_NOINTERFACE, if lpUnknown is NULL or does not support the
3124 * IConnectionPointContainer interface.
3126 HRESULT WINAPI
IUnknown_CPContainerOnChanged(IUnknown
*lpUnknown
, DISPID dispID
)
3128 IConnectionPointContainer
* lpCPC
= NULL
;
3129 HRESULT hRet
= E_NOINTERFACE
;
3131 TRACE("(%p,0x%8X)\n", lpUnknown
, dispID
);
3134 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IConnectionPointContainer
, (void**)&lpCPC
);
3136 if (SUCCEEDED(hRet
))
3138 IConnectionPoint
* lpCP
;
3140 hRet
= IConnectionPointContainer_FindConnectionPoint(lpCPC
, &IID_IPropertyNotifySink
, &lpCP
);
3141 IConnectionPointContainer_Release(lpCPC
);
3143 hRet
= IConnectionPoint_OnChanged(lpCP
, dispID
);
3144 IConnectionPoint_Release(lpCP
);
3149 /*************************************************************************
3154 BOOL WINAPI
PlaySoundWrapW(LPCWSTR pszSound
, HMODULE hmod
, DWORD fdwSound
)
3156 return PlaySoundW(pszSound
, hmod
, fdwSound
);
3159 /*************************************************************************
3162 BOOL WINAPI
SHGetIniStringW(LPCWSTR str1
, LPCWSTR str2
, LPWSTR pStr
, DWORD some_len
, LPCWSTR lpStr2
)
3164 FIXME("(%s,%s,%p,%08x,%s): stub!\n", debugstr_w(str1
), debugstr_w(str2
),
3165 pStr
, some_len
, debugstr_w(lpStr2
));
3169 /*************************************************************************
3172 * Called by ICQ2000b install via SHDOCVW:
3173 * str1: "InternetShortcut"
3174 * x: some unknown pointer
3175 * str2: "http://free.aol.com/tryaolfree/index.adp?139269"
3176 * str3: "C:\\WINDOWS\\Desktop.new2\\Free AOL & Unlimited Internet.url"
3178 * In short: this one maybe creates a desktop link :-)
3180 BOOL WINAPI
SHSetIniStringW(LPWSTR str1
, LPVOID x
, LPWSTR str2
, LPWSTR str3
)
3182 FIXME("(%s, %p, %s, %s), stub.\n", debugstr_w(str1
), x
, debugstr_w(str2
), debugstr_w(str3
));
3186 /*************************************************************************
3189 * See SHGetFileInfoW.
3191 DWORD WINAPI
SHGetFileInfoWrapW(LPCWSTR path
, DWORD dwFileAttributes
,
3192 SHFILEINFOW
*psfi
, UINT sizeofpsfi
, UINT flags
)
3194 return SHGetFileInfoW(path
, dwFileAttributes
, psfi
, sizeofpsfi
, flags
);
3197 /*************************************************************************
3200 * See DragQueryFileW.
3202 UINT WINAPI
DragQueryFileWrapW(HDROP hDrop
, UINT lFile
, LPWSTR lpszFile
, UINT lLength
)
3204 return DragQueryFileW(hDrop
, lFile
, lpszFile
, lLength
);
3207 /*************************************************************************
3210 * See SHBrowseForFolderW.
3212 LPITEMIDLIST WINAPI
SHBrowseForFolderWrapW(LPBROWSEINFOW lpBi
)
3214 return SHBrowseForFolderW(lpBi
);
3217 /*************************************************************************
3220 * See SHGetPathFromIDListW.
3222 BOOL WINAPI
SHGetPathFromIDListWrapW(LPCITEMIDLIST pidl
,LPWSTR pszPath
)
3224 return SHGetPathFromIDListW(pidl
, pszPath
);
3227 /*************************************************************************
3230 * See ShellExecuteExW.
3232 BOOL WINAPI
ShellExecuteExWrapW(LPSHELLEXECUTEINFOW lpExecInfo
)
3234 return ShellExecuteExW(lpExecInfo
);
3237 /*************************************************************************
3240 * See SHFileOperationW.
3242 INT WINAPI
SHFileOperationWrapW(LPSHFILEOPSTRUCTW lpFileOp
)
3244 return SHFileOperationW(lpFileOp
);
3247 /*************************************************************************
3251 PVOID WINAPI
SHInterlockedCompareExchange( PVOID
*dest
, PVOID xchg
, PVOID compare
)
3253 return InterlockedCompareExchangePointer( dest
, xchg
, compare
);
3256 /*************************************************************************
3259 * See GetFileVersionInfoSizeW.
3261 DWORD WINAPI
GetFileVersionInfoSizeWrapW( LPCWSTR filename
, LPDWORD handle
)
3263 return GetFileVersionInfoSizeW( filename
, handle
);
3266 /*************************************************************************
3269 * See GetFileVersionInfoW.
3271 BOOL WINAPI
GetFileVersionInfoWrapW( LPCWSTR filename
, DWORD handle
,
3272 DWORD datasize
, LPVOID data
)
3274 return GetFileVersionInfoW( filename
, handle
, datasize
, data
);
3277 /*************************************************************************
3280 * See VerQueryValueW.
3282 WORD WINAPI
VerQueryValueWrapW( LPVOID pBlock
, LPCWSTR lpSubBlock
,
3283 LPVOID
*lplpBuffer
, UINT
*puLen
)
3285 return VerQueryValueW( pBlock
, lpSubBlock
, lplpBuffer
, puLen
);
3288 #define IsIface(type) SUCCEEDED((hRet = IUnknown_QueryInterface(lpUnknown, &IID_##type, (void**)&lpObj)))
3289 #define IShellBrowser_EnableModeless IShellBrowser_EnableModelessSB
3290 #define EnableModeless(type) type##_EnableModeless((type*)lpObj, bModeless)
3292 /*************************************************************************
3295 * Change the modality of a shell object.
3298 * lpUnknown [I] Object to make modeless
3299 * bModeless [I] TRUE=Make modeless, FALSE=Make modal
3302 * Success: S_OK. The modality lpUnknown is changed.
3303 * Failure: An HRESULT error code indicating the error.
3306 * lpUnknown must support the IOleInPlaceFrame interface, the
3307 * IInternetSecurityMgrSite interface, the IShellBrowser interface
3308 * the IDocHostUIHandler interface, or the IOleInPlaceActiveObject interface,
3309 * or this call will fail.
3311 HRESULT WINAPI
IUnknown_EnableModeless(IUnknown
*lpUnknown
, BOOL bModeless
)
3316 TRACE("(%p,%d)\n", lpUnknown
, bModeless
);
3321 if (IsIface(IOleInPlaceActiveObject
))
3322 EnableModeless(IOleInPlaceActiveObject
);
3323 else if (IsIface(IOleInPlaceFrame
))
3324 EnableModeless(IOleInPlaceFrame
);
3325 else if (IsIface(IShellBrowser
))
3326 EnableModeless(IShellBrowser
);
3327 else if (IsIface(IInternetSecurityMgrSite
))
3328 EnableModeless(IInternetSecurityMgrSite
);
3329 else if (IsIface(IDocHostUIHandler
))
3330 EnableModeless(IDocHostUIHandler
);
3334 IUnknown_Release(lpObj
);
3338 /*************************************************************************
3341 * See SHGetNewLinkInfoW.
3343 BOOL WINAPI
SHGetNewLinkInfoWrapW(LPCWSTR pszLinkTo
, LPCWSTR pszDir
, LPWSTR pszName
,
3344 BOOL
*pfMustCopy
, UINT uFlags
)
3346 return SHGetNewLinkInfoW(pszLinkTo
, pszDir
, pszName
, pfMustCopy
, uFlags
);
3349 /*************************************************************************
3352 * See SHDefExtractIconW.
3354 UINT WINAPI
SHDefExtractIconWrapW(LPCWSTR pszIconFile
, int iIndex
, UINT uFlags
, HICON
* phiconLarge
,
3355 HICON
* phiconSmall
, UINT nIconSize
)
3357 return SHDefExtractIconW(pszIconFile
, iIndex
, uFlags
, phiconLarge
, phiconSmall
, nIconSize
);
3360 /*************************************************************************
3363 * Get and show a context menu from a shell folder.
3366 * hWnd [I] Window displaying the shell folder
3367 * lpFolder [I] IShellFolder interface
3368 * lpApidl [I] Id for the particular folder desired
3369 * bInvokeDefault [I] Whether to invoke the default menu item
3372 * Success: S_OK. If bInvokeDefault is TRUE, the default menu action was
3374 * Failure: An HRESULT error code indicating the error.
3376 HRESULT WINAPI
SHInvokeCommand(HWND hWnd
, IShellFolder
* lpFolder
, LPCITEMIDLIST lpApidl
, BOOL bInvokeDefault
)
3378 IContextMenu
*iContext
;
3379 HRESULT hRet
= E_FAIL
;
3381 TRACE("(%p,%p,%p,%d)\n", hWnd
, lpFolder
, lpApidl
, bInvokeDefault
);
3386 /* Get the context menu from the shell folder */
3387 hRet
= IShellFolder_GetUIObjectOf(lpFolder
, hWnd
, 1, &lpApidl
,
3388 &IID_IContextMenu
, 0, (void**)&iContext
);
3389 if (SUCCEEDED(hRet
))
3392 if ((hMenu
= CreatePopupMenu()))
3395 DWORD dwDefaultId
= 0;
3397 /* Add the context menu entries to the popup */
3398 hQuery
= IContextMenu_QueryContextMenu(iContext
, hMenu
, 0, 1, 0x7FFF,
3399 bInvokeDefault
? CMF_NORMAL
: CMF_DEFAULTONLY
);
3401 if (SUCCEEDED(hQuery
))
3403 if (bInvokeDefault
&&
3404 (dwDefaultId
= GetMenuDefaultItem(hMenu
, 0, 0)) != 0xFFFFFFFF)
3406 CMINVOKECOMMANDINFO cmIci
;
3407 /* Invoke the default item */
3408 memset(&cmIci
,0,sizeof(cmIci
));
3409 cmIci
.cbSize
= sizeof(cmIci
);
3410 cmIci
.fMask
= CMIC_MASK_ASYNCOK
;
3412 cmIci
.lpVerb
= MAKEINTRESOURCEA(dwDefaultId
);
3413 cmIci
.nShow
= SW_SCROLLCHILDREN
;
3415 hRet
= IContextMenu_InvokeCommand(iContext
, &cmIci
);
3420 IContextMenu_Release(iContext
);
3425 /*************************************************************************
3430 HICON WINAPI
ExtractIconWrapW(HINSTANCE hInstance
, LPCWSTR lpszExeFileName
,
3433 return ExtractIconW(hInstance
, lpszExeFileName
, nIconIndex
);
3436 /*************************************************************************
3439 * Load a library from the directory of a particular process.
3442 * new_mod [I] Library name
3443 * inst_hwnd [I] Module whose directory is to be used
3444 * dwCrossCodePage [I] Should be FALSE (currently ignored)
3447 * Success: A handle to the loaded module
3448 * Failure: A NULL handle.
3450 HMODULE WINAPI
MLLoadLibraryA(LPCSTR new_mod
, HMODULE inst_hwnd
, DWORD dwCrossCodePage
)
3452 /* FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for
3454 * FIXME: Native shows calls to:
3455 * SHRegGetUSValue for "Software\Microsoft\Internet Explorer\International"
3457 * RegOpenKeyExA for "HKLM\Software\Microsoft\Internet Explorer"
3458 * RegQueryValueExA for "LPKInstalled"
3460 * RegOpenKeyExA for "HKCU\Software\Microsoft\Internet Explorer\International"
3461 * RegQueryValueExA for "ResourceLocale"
3463 * RegOpenKeyExA for "HKLM\Software\Microsoft\Active Setup\Installed Components\{guid}"
3464 * RegQueryValueExA for "Locale"
3466 * and then tests the Locale ("en" for me).
3468 * after the code then a DPA_Create (first time) and DPA_InsertPtr are done.
3470 CHAR mod_path
[2*MAX_PATH
];
3474 FIXME("(%s,%p,%d) semi-stub!\n", debugstr_a(new_mod
), inst_hwnd
, dwCrossCodePage
);
3475 len
= GetModuleFileNameA(inst_hwnd
, mod_path
, sizeof(mod_path
));
3476 if (!len
|| len
>= sizeof(mod_path
)) return NULL
;
3478 ptr
= strrchr(mod_path
, '\\');
3480 strcpy(ptr
+1, new_mod
);
3481 TRACE("loading %s\n", debugstr_a(mod_path
));
3482 return LoadLibraryA(mod_path
);
3487 /*************************************************************************
3490 * Unicode version of MLLoadLibraryA.
3492 HMODULE WINAPI
MLLoadLibraryW(LPCWSTR new_mod
, HMODULE inst_hwnd
, DWORD dwCrossCodePage
)
3494 WCHAR mod_path
[2*MAX_PATH
];
3498 FIXME("(%s,%p,%d) semi-stub!\n", debugstr_w(new_mod
), inst_hwnd
, dwCrossCodePage
);
3499 len
= GetModuleFileNameW(inst_hwnd
, mod_path
, sizeof(mod_path
) / sizeof(WCHAR
));
3500 if (!len
|| len
>= sizeof(mod_path
) / sizeof(WCHAR
)) return NULL
;
3502 ptr
= strrchrW(mod_path
, '\\');
3504 strcpyW(ptr
+1, new_mod
);
3505 TRACE("loading %s\n", debugstr_w(mod_path
));
3506 return LoadLibraryW(mod_path
);
3511 /*************************************************************************
3512 * ColorAdjustLuma [SHLWAPI.@]
3514 * Adjust the luminosity of a color
3517 * cRGB [I] RGB value to convert
3518 * dwLuma [I] Luma adjustment
3519 * bUnknown [I] Unknown
3522 * The adjusted RGB color.
3524 COLORREF WINAPI
ColorAdjustLuma(COLORREF cRGB
, int dwLuma
, BOOL bUnknown
)
3526 TRACE("(0x%8x,%d,%d)\n", cRGB
, dwLuma
, bUnknown
);
3532 ColorRGBToHLS(cRGB
, &wH
, &wL
, &wS
);
3534 FIXME("Ignoring luma adjustment\n");
3536 /* FIXME: The adjustment is not linear */
3538 cRGB
= ColorHLSToRGB(wH
, wL
, wS
);
3543 /*************************************************************************
3546 * See GetSaveFileNameW.
3548 BOOL WINAPI
GetSaveFileNameWrapW(LPOPENFILENAMEW ofn
)
3550 return GetSaveFileNameW(ofn
);
3553 /*************************************************************************
3556 * See WNetRestoreConnectionW.
3558 DWORD WINAPI
WNetRestoreConnectionWrapW(HWND hwndOwner
, LPWSTR lpszDevice
)
3560 return WNetRestoreConnectionW(hwndOwner
, lpszDevice
);
3563 /*************************************************************************
3566 * See WNetGetLastErrorW.
3568 DWORD WINAPI
WNetGetLastErrorWrapW(LPDWORD lpError
, LPWSTR lpErrorBuf
, DWORD nErrorBufSize
,
3569 LPWSTR lpNameBuf
, DWORD nNameBufSize
)
3571 return WNetGetLastErrorW(lpError
, lpErrorBuf
, nErrorBufSize
, lpNameBuf
, nNameBufSize
);
3574 /*************************************************************************
3577 * See PageSetupDlgW.
3579 BOOL WINAPI
PageSetupDlgWrapW(LPPAGESETUPDLGW pagedlg
)
3581 return PageSetupDlgW(pagedlg
);
3584 /*************************************************************************
3589 BOOL WINAPI
PrintDlgWrapW(LPPRINTDLGW printdlg
)
3591 return PrintDlgW(printdlg
);
3594 /*************************************************************************
3597 * See GetOpenFileNameW.
3599 BOOL WINAPI
GetOpenFileNameWrapW(LPOPENFILENAMEW ofn
)
3601 return GetOpenFileNameW(ofn
);
3604 /*************************************************************************
3607 HRESULT WINAPI
SHIShellFolder_EnumObjects(LPSHELLFOLDER lpFolder
, HWND hwnd
, SHCONTF flags
, IEnumIDList
**ppenum
)
3612 hr
= IShellFolder_QueryInterface(lpFolder
, &IID_IPersist
, (LPVOID
)&persist
);
3616 hr
= IPersist_GetClassID(persist
, &clsid
);
3619 if(IsEqualCLSID(&clsid
, &CLSID_ShellFSFolder
))
3620 hr
= IShellFolder_EnumObjects(lpFolder
, hwnd
, flags
, ppenum
);
3624 IPersist_Release(persist
);
3629 /* INTERNAL: Map from HLS color space to RGB */
3630 static WORD
ConvertHue(int wHue
, WORD wMid1
, WORD wMid2
)
3632 wHue
= wHue
> 240 ? wHue
- 240 : wHue
< 0 ? wHue
+ 240 : wHue
;
3636 else if (wHue
> 120)
3641 return ((wHue
* (wMid2
- wMid1
) + 20) / 40) + wMid1
;
3644 /* Convert to RGB and scale into RGB range (0..255) */
3645 #define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240
3647 /*************************************************************************
3648 * ColorHLSToRGB [SHLWAPI.@]
3650 * Convert from hls color space into an rgb COLORREF.
3653 * wHue [I] Hue amount
3654 * wLuminosity [I] Luminosity amount
3655 * wSaturation [I] Saturation amount
3658 * A COLORREF representing the converted color.
3661 * Input hls values are constrained to the range (0..240).
3663 COLORREF WINAPI
ColorHLSToRGB(WORD wHue
, WORD wLuminosity
, WORD wSaturation
)
3669 WORD wGreen
, wBlue
, wMid1
, wMid2
;
3671 if (wLuminosity
> 120)
3672 wMid2
= wSaturation
+ wLuminosity
- (wSaturation
* wLuminosity
+ 120) / 240;
3674 wMid2
= ((wSaturation
+ 240) * wLuminosity
+ 120) / 240;
3676 wMid1
= wLuminosity
* 2 - wMid2
;
3678 wRed
= GET_RGB(wHue
+ 80);
3679 wGreen
= GET_RGB(wHue
);
3680 wBlue
= GET_RGB(wHue
- 80);
3682 return RGB(wRed
, wGreen
, wBlue
);
3685 wRed
= wLuminosity
* 255 / 240;
3686 return RGB(wRed
, wRed
, wRed
);
3689 /*************************************************************************
3692 * Get the current docking status of the system.
3695 * dwFlags [I] DOCKINFO_ flags from "winbase.h", unused
3698 * One of DOCKINFO_UNDOCKED, DOCKINFO_UNDOCKED, or 0 if the system is not
3701 DWORD WINAPI
SHGetMachineInfo(DWORD dwFlags
)
3703 HW_PROFILE_INFOA hwInfo
;
3705 TRACE("(0x%08x)\n", dwFlags
);
3707 GetCurrentHwProfileA(&hwInfo
);
3708 switch (hwInfo
.dwDockInfo
& (DOCKINFO_DOCKED
|DOCKINFO_UNDOCKED
))
3710 case DOCKINFO_DOCKED
:
3711 case DOCKINFO_UNDOCKED
:
3712 return hwInfo
.dwDockInfo
& (DOCKINFO_DOCKED
|DOCKINFO_UNDOCKED
);
3718 /*************************************************************************
3721 * Function seems to do FreeLibrary plus other things.
3723 * FIXME native shows the following calls:
3724 * RtlEnterCriticalSection
3726 * GetProcAddress(Comctl32??, 150L)
3728 * RtlLeaveCriticalSection
3729 * followed by the FreeLibrary.
3730 * The above code may be related to .377 above.
3732 BOOL WINAPI
MLFreeLibrary(HMODULE hModule
)
3734 FIXME("(%p) semi-stub\n", hModule
);
3735 return FreeLibrary(hModule
);
3738 /*************************************************************************
3741 BOOL WINAPI
SHFlushSFCacheWrap(void) {
3746 /*************************************************************************
3748 * FIXME I have no idea what this function does or what its arguments are.
3750 BOOL WINAPI
MLIsMLHInstance(HINSTANCE hInst
)
3752 FIXME("(%p) stub\n", hInst
);
3757 /*************************************************************************
3760 DWORD WINAPI
MLSetMLHInstance(HINSTANCE hInst
, HANDLE hHeap
)
3762 FIXME("(%p,%p) stub\n", hInst
, hHeap
);
3763 return E_FAIL
; /* This is what is used if shlwapi not loaded */
3766 /*************************************************************************
3769 DWORD WINAPI
MLClearMLHInstance(DWORD x
)
3771 FIXME("(0x%08x)stub\n", x
);
3775 /*************************************************************************
3778 * See SHSendMessageBroadcastW
3781 DWORD WINAPI
SHSendMessageBroadcastA(UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3783 return SendMessageTimeoutA(HWND_BROADCAST
, uMsg
, wParam
, lParam
,
3784 SMTO_ABORTIFHUNG
, 2000, NULL
);
3787 /*************************************************************************
3790 * A wrapper for sending Broadcast Messages to all top level Windows
3793 DWORD WINAPI
SHSendMessageBroadcastW(UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3795 return SendMessageTimeoutW(HWND_BROADCAST
, uMsg
, wParam
, lParam
,
3796 SMTO_ABORTIFHUNG
, 2000, NULL
);
3799 /*************************************************************************
3802 * Convert a Unicode string CLSID into a CLSID.
3805 * idstr [I] string containing a CLSID in text form
3806 * id [O] CLSID extracted from the string
3809 * S_OK on success or E_INVALIDARG on failure
3811 HRESULT WINAPI
CLSIDFromStringWrap(LPCWSTR idstr
, CLSID
*id
)
3813 return CLSIDFromString((LPOLESTR
)idstr
, id
);
3816 /*************************************************************************
3819 * Determine if the OS supports a given feature.
3822 * dwFeature [I] Feature requested (undocumented)
3825 * TRUE If the feature is available.
3826 * FALSE If the feature is not available.
3828 BOOL WINAPI
IsOS(DWORD feature
)
3830 OSVERSIONINFOA osvi
;
3831 DWORD platform
, majorv
, minorv
;
3833 osvi
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFOA
);
3834 if(!GetVersionExA(&osvi
)) {
3835 ERR("GetVersionEx failed\n");
3839 majorv
= osvi
.dwMajorVersion
;
3840 minorv
= osvi
.dwMinorVersion
;
3841 platform
= osvi
.dwPlatformId
;
3843 #define ISOS_RETURN(x) \
3844 TRACE("(0x%x) ret=%d\n",feature,(x)); \
3848 case OS_WIN32SORGREATER
:
3849 ISOS_RETURN(platform
== VER_PLATFORM_WIN32s
3850 || platform
== VER_PLATFORM_WIN32_WINDOWS
)
3852 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3853 case OS_WIN95ORGREATER
:
3854 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
)
3855 case OS_NT4ORGREATER
:
3856 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 4)
3857 case OS_WIN2000ORGREATER_ALT
:
3858 case OS_WIN2000ORGREATER
:
3859 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5)
3860 case OS_WIN98ORGREATER
:
3861 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
&& minorv
>= 10)
3863 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
&& minorv
== 10)
3865 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5)
3866 case OS_WIN2000SERVER
:
3867 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& (minorv
== 0 || minorv
== 1))
3868 case OS_WIN2000ADVSERVER
:
3869 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& (minorv
== 0 || minorv
== 1))
3870 case OS_WIN2000DATACENTER
:
3871 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& (minorv
== 0 || minorv
== 1))
3872 case OS_WIN2000TERMINAL
:
3873 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& (minorv
== 0 || minorv
== 1))
3875 FIXME("(OS_EMBEDDED) What should we return here?\n");
3877 case OS_TERMINALCLIENT
:
3878 FIXME("(OS_TERMINALCLIENT) What should we return here?\n");
3880 case OS_TERMINALREMOTEADMIN
:
3881 FIXME("(OS_TERMINALREMOTEADMIN) What should we return here?\n");
3884 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
&& minorv
== 0)
3885 case OS_MEORGREATER
:
3886 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
&& minorv
>= 90)
3887 case OS_XPORGREATER
:
3888 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5 && minorv
>= 1)
3890 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5 && minorv
>= 1)
3891 case OS_PROFESSIONAL
:
3892 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3894 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3896 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5)
3898 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3899 case OS_TERMINALSERVER
:
3900 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3901 case OS_PERSONALTERMINALSERVER
:
3902 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& minorv
>= 1 && majorv
>= 5)
3903 case OS_FASTUSERSWITCHING
:
3904 FIXME("(OS_FASTUSERSWITCHING) What should we return here?\n");
3906 case OS_WELCOMELOGONUI
:
3907 FIXME("(OS_WELCOMELOGONUI) What should we return here?\n");
3909 case OS_DOMAINMEMBER
:
3910 FIXME("(OS_DOMAINMEMBER) What should we return here?\n");
3913 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3915 FIXME("(OS_WOW6432) Should we check this?\n");
3918 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3919 case OS_SMALLBUSINESSSERVER
:
3920 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3922 FIXME("(OS_TABLEPC) What should we return here?\n");
3924 case OS_SERVERADMINUI
:
3925 FIXME("(OS_SERVERADMINUI) What should we return here?\n");
3927 case OS_MEDIACENTER
:
3928 FIXME("(OS_MEDIACENTER) What should we return here?\n");
3931 FIXME("(OS_APPLIANCE) What should we return here?\n");
3933 case 0x25: /*OS_VISTAORGREATER*/
3934 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 6)
3939 WARN("(0x%x) unknown parameter\n",feature
);
3944 /*************************************************************************
3947 HRESULT WINAPI
SHLoadRegUIStringW(HKEY hkey
, LPCWSTR value
, LPWSTR buf
, DWORD size
)
3949 DWORD type
, sz
= size
;
3951 if(RegQueryValueExW(hkey
, value
, NULL
, &type
, (LPBYTE
)buf
, &sz
) != ERROR_SUCCESS
)
3954 return SHLoadIndirectString(buf
, buf
, size
, NULL
);
3957 /*************************************************************************
3960 * Call IInputObject_TranslateAcceleratorIO() on an object.
3963 * lpUnknown [I] Object supporting the IInputObject interface.
3964 * lpMsg [I] Key message to be processed.
3968 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
3970 HRESULT WINAPI
IUnknown_TranslateAcceleratorIO(IUnknown
*lpUnknown
, LPMSG lpMsg
)
3972 IInputObject
* lpInput
= NULL
;
3973 HRESULT hRet
= E_INVALIDARG
;
3975 TRACE("(%p,%p)\n", lpUnknown
, lpMsg
);
3978 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IInputObject
,
3980 if (SUCCEEDED(hRet
) && lpInput
)
3982 hRet
= IInputObject_TranslateAcceleratorIO(lpInput
, lpMsg
);
3983 IInputObject_Release(lpInput
);
3989 /*************************************************************************
3992 * Call IInputObject_HasFocusIO() on an object.
3995 * lpUnknown [I] Object supporting the IInputObject interface.
3998 * Success: S_OK, if lpUnknown is an IInputObject object and has the focus,
3999 * or S_FALSE otherwise.
4000 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
4002 HRESULT WINAPI
IUnknown_HasFocusIO(IUnknown
*lpUnknown
)
4004 IInputObject
* lpInput
= NULL
;
4005 HRESULT hRet
= E_INVALIDARG
;
4007 TRACE("(%p)\n", lpUnknown
);
4010 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IInputObject
,
4012 if (SUCCEEDED(hRet
) && lpInput
)
4014 hRet
= IInputObject_HasFocusIO(lpInput
);
4015 IInputObject_Release(lpInput
);
4021 /*************************************************************************
4022 * ColorRGBToHLS [SHLWAPI.@]
4024 * Convert an rgb COLORREF into the hls color space.
4027 * cRGB [I] Source rgb value
4028 * pwHue [O] Destination for converted hue
4029 * pwLuminance [O] Destination for converted luminance
4030 * pwSaturation [O] Destination for converted saturation
4033 * Nothing. pwHue, pwLuminance and pwSaturation are set to the converted
4037 * Output HLS values are constrained to the range (0..240).
4038 * For Achromatic conversions, Hue is set to 160.
4040 VOID WINAPI
ColorRGBToHLS(COLORREF cRGB
, LPWORD pwHue
,
4041 LPWORD pwLuminance
, LPWORD pwSaturation
)
4043 int wR
, wG
, wB
, wMax
, wMin
, wHue
, wLuminosity
, wSaturation
;
4045 TRACE("(%08x,%p,%p,%p)\n", cRGB
, pwHue
, pwLuminance
, pwSaturation
);
4047 wR
= GetRValue(cRGB
);
4048 wG
= GetGValue(cRGB
);
4049 wB
= GetBValue(cRGB
);
4051 wMax
= max(wR
, max(wG
, wB
));
4052 wMin
= min(wR
, min(wG
, wB
));
4055 wLuminosity
= ((wMax
+ wMin
) * 240 + 255) / 510;
4059 /* Achromatic case */
4061 /* Hue is now unrepresentable, but this is what native returns... */
4066 /* Chromatic case */
4067 int wDelta
= wMax
- wMin
, wRNorm
, wGNorm
, wBNorm
;
4070 if (wLuminosity
<= 120)
4071 wSaturation
= ((wMax
+ wMin
)/2 + wDelta
* 240) / (wMax
+ wMin
);
4073 wSaturation
= ((510 - wMax
- wMin
)/2 + wDelta
* 240) / (510 - wMax
- wMin
);
4076 wRNorm
= (wDelta
/2 + wMax
* 40 - wR
* 40) / wDelta
;
4077 wGNorm
= (wDelta
/2 + wMax
* 40 - wG
* 40) / wDelta
;
4078 wBNorm
= (wDelta
/2 + wMax
* 40 - wB
* 40) / wDelta
;
4081 wHue
= wBNorm
- wGNorm
;
4082 else if (wG
== wMax
)
4083 wHue
= 80 + wRNorm
- wBNorm
;
4085 wHue
= 160 + wGNorm
- wRNorm
;
4088 else if (wHue
> 240)
4094 *pwLuminance
= wLuminosity
;
4096 *pwSaturation
= wSaturation
;
4099 /*************************************************************************
4100 * SHCreateShellPalette [SHLWAPI.@]
4102 HPALETTE WINAPI
SHCreateShellPalette(HDC hdc
)
4105 return CreateHalftonePalette(hdc
);
4108 /*************************************************************************
4109 * SHGetInverseCMAP (SHLWAPI.@)
4111 * Get an inverse color map table.
4114 * lpCmap [O] Destination for color map
4115 * dwSize [I] Size of memory pointed to by lpCmap
4119 * Failure: E_POINTER, If lpCmap is invalid.
4120 * E_INVALIDARG, If dwFlags is invalid
4121 * E_OUTOFMEMORY, If there is no memory available
4124 * dwSize may only be CMAP_PTR_SIZE (4) or CMAP_SIZE (8192).
4125 * If dwSize = CMAP_PTR_SIZE, *lpCmap is set to the address of this DLL's
4127 * If dwSize = CMAP_SIZE, lpCmap is filled with a copy of the data from
4128 * this DLL's internal CMap.
4130 HRESULT WINAPI
SHGetInverseCMAP(LPDWORD dest
, DWORD dwSize
)
4133 FIXME(" - returning bogus address for SHGetInverseCMAP\n");
4134 *dest
= (DWORD
)0xabba1249;
4137 FIXME("(%p, %#x) stub\n", dest
, dwSize
);
4141 /*************************************************************************
4142 * SHIsLowMemoryMachine [SHLWAPI.@]
4144 * Determine if the current computer has low memory.
4150 * TRUE if the users machine has 16 Megabytes of memory or less,
4153 BOOL WINAPI
SHIsLowMemoryMachine (DWORD x
)
4155 FIXME("(0x%08x) stub\n", x
);
4159 /*************************************************************************
4160 * GetMenuPosFromID [SHLWAPI.@]
4162 * Return the position of a menu item from its Id.
4165 * hMenu [I] Menu containing the item
4166 * wID [I] Id of the menu item
4169 * Success: The index of the menu item in hMenu.
4170 * Failure: -1, If the item is not found.
4172 INT WINAPI
GetMenuPosFromID(HMENU hMenu
, UINT wID
)
4175 INT nCount
= GetMenuItemCount(hMenu
), nIter
= 0;
4177 while (nIter
< nCount
)
4179 mi
.cbSize
= sizeof(mi
);
4181 if (GetMenuItemInfoW(hMenu
, nIter
, TRUE
, &mi
) && mi
.wID
== wID
)
4188 /*************************************************************************
4191 * Same as SHLWAPI.GetMenuPosFromID
4193 DWORD WINAPI
SHMenuIndexFromID(HMENU hMenu
, UINT uID
)
4195 return GetMenuPosFromID(hMenu
, uID
);
4199 /*************************************************************************
4202 VOID WINAPI
FixSlashesAndColonW(LPWSTR lpwstr
)
4213 /*************************************************************************
4216 DWORD WINAPI
SHGetAppCompatFlags(DWORD dwUnknown
)
4218 FIXME("(0x%08x) stub\n", dwUnknown
);
4223 /*************************************************************************
4226 HRESULT WINAPI
SHCoCreateInstanceAC(REFCLSID rclsid
, LPUNKNOWN pUnkOuter
,
4227 DWORD dwClsContext
, REFIID iid
, LPVOID
*ppv
)
4229 return CoCreateInstance(rclsid
, pUnkOuter
, dwClsContext
, iid
, ppv
);
4232 /*************************************************************************
4233 * SHSkipJunction [SHLWAPI.@]
4235 * Determine if a bind context can be bound to an object
4238 * pbc [I] Bind context to check
4239 * pclsid [I] CLSID of object to be bound to
4242 * TRUE: If it is safe to bind
4243 * FALSE: If pbc is invalid or binding would not be safe
4246 BOOL WINAPI
SHSkipJunction(IBindCtx
*pbc
, const CLSID
*pclsid
)
4248 static WCHAR szSkipBinding
[] = { 'S','k','i','p',' ',
4249 'B','i','n','d','i','n','g',' ','C','L','S','I','D','\0' };
4256 if (SUCCEEDED(IBindCtx_GetObjectParam(pbc
, szSkipBinding
, &lpUnk
)))
4260 if (SUCCEEDED(IUnknown_GetClassID(lpUnk
, &clsid
)) &&
4261 IsEqualGUID(pclsid
, &clsid
))
4264 IUnknown_Release(lpUnk
);
4270 /***********************************************************************
4271 * SHGetShellKey (SHLWAPI.@)
4273 DWORD WINAPI
SHGetShellKey(DWORD a
, DWORD b
, DWORD c
)
4275 FIXME("(%x, %x, %x): stub\n", a
, b
, c
);
4279 /***********************************************************************
4280 * SHQueueUserWorkItem (SHLWAPI.@)
4282 BOOL WINAPI
SHQueueUserWorkItem(LPTHREAD_START_ROUTINE pfnCallback
,
4283 LPVOID pContext
, LONG lPriority
, DWORD_PTR dwTag
,
4284 DWORD_PTR
*pdwId
, LPCSTR pszModule
, DWORD dwFlags
)
4286 TRACE("(%p, %p, %d, %lx, %p, %s, %08x)\n", pfnCallback
, pContext
,
4287 lPriority
, dwTag
, pdwId
, debugstr_a(pszModule
), dwFlags
);
4289 if(lPriority
|| dwTag
|| pdwId
|| pszModule
|| dwFlags
)
4290 FIXME("Unsupported arguments\n");
4292 return QueueUserWorkItem(pfnCallback
, pContext
, 0);
4295 /***********************************************************************
4296 * SHSetTimerQueueTimer (SHLWAPI.263)
4298 HANDLE WINAPI
SHSetTimerQueueTimer(HANDLE hQueue
,
4299 WAITORTIMERCALLBACK pfnCallback
, LPVOID pContext
, DWORD dwDueTime
,
4300 DWORD dwPeriod
, LPCSTR lpszLibrary
, DWORD dwFlags
)
4304 /* SHSetTimerQueueTimer flags -> CreateTimerQueueTimer flags */
4305 if (dwFlags
& TPS_LONGEXECTIME
) {
4306 dwFlags
&= ~TPS_LONGEXECTIME
;
4307 dwFlags
|= WT_EXECUTELONGFUNCTION
;
4309 if (dwFlags
& TPS_EXECUTEIO
) {
4310 dwFlags
&= ~TPS_EXECUTEIO
;
4311 dwFlags
|= WT_EXECUTEINIOTHREAD
;
4314 if (!CreateTimerQueueTimer(&hNewTimer
, hQueue
, pfnCallback
, pContext
,
4315 dwDueTime
, dwPeriod
, dwFlags
))
4321 /***********************************************************************
4322 * IUnknown_OnFocusChangeIS (SHLWAPI.@)
4324 HRESULT WINAPI
IUnknown_OnFocusChangeIS(LPUNKNOWN lpUnknown
, LPUNKNOWN pFocusObject
, BOOL bFocus
)
4326 IInputObjectSite
*pIOS
= NULL
;
4327 HRESULT hRet
= E_INVALIDARG
;
4329 TRACE("(%p, %p, %s)\n", lpUnknown
, pFocusObject
, bFocus
? "TRUE" : "FALSE");
4333 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IInputObjectSite
,
4335 if (SUCCEEDED(hRet
) && pIOS
)
4337 hRet
= IInputObjectSite_OnFocusChangeIS(pIOS
, pFocusObject
, bFocus
);
4338 IInputObjectSite_Release(pIOS
);
4344 /***********************************************************************
4345 * SHGetValueW (SHLWAPI.@)
4347 HRESULT WINAPI
SKGetValueW(DWORD a
, LPWSTR b
, LPWSTR c
, DWORD d
, DWORD e
, DWORD f
)
4349 FIXME("(%x, %s, %s, %x, %x, %x): stub\n", a
, debugstr_w(b
), debugstr_w(c
), d
, e
, f
);
4353 typedef HRESULT (WINAPI
*DllGetVersion_func
)(DLLVERSIONINFO
*);
4355 /***********************************************************************
4356 * GetUIVersion (SHLWAPI.452)
4358 DWORD WINAPI
GetUIVersion(void)
4360 static DWORD version
;
4364 DllGetVersion_func pDllGetVersion
;
4365 HMODULE dll
= LoadLibraryA("shell32.dll");
4368 pDllGetVersion
= (DllGetVersion_func
)GetProcAddress(dll
, "DllGetVersion");
4372 dvi
.cbSize
= sizeof(DLLVERSIONINFO
);
4373 if (pDllGetVersion(&dvi
) == S_OK
) version
= dvi
.dwMajorVersion
;
4376 if (!version
) version
= 3; /* old shell dlls don't have DllGetVersion */
4381 /***********************************************************************
4382 * ShellMessageBoxWrapW [SHLWAPI.388]
4384 * See shell32.ShellMessageBoxW
4387 * shlwapi.ShellMessageBoxWrapW is a duplicate of shell32.ShellMessageBoxW
4388 * because we can't forward to it in the .spec file since it's exported by
4389 * ordinal. If you change the implementation here please update the code in
4392 INT WINAPIV
ShellMessageBoxWrapW(HINSTANCE hInstance
, HWND hWnd
, LPCWSTR lpText
,
4393 LPCWSTR lpCaption
, UINT uType
, ...)
4395 WCHAR szText
[100], szTitle
[100];
4396 LPCWSTR pszText
= szText
, pszTitle
= szTitle
;
4401 __ms_va_start(args
, uType
);
4403 TRACE("(%p,%p,%p,%p,%08x)\n", hInstance
, hWnd
, lpText
, lpCaption
, uType
);
4405 if (IS_INTRESOURCE(lpCaption
))
4406 LoadStringW(hInstance
, LOWORD(lpCaption
), szTitle
, sizeof(szTitle
)/sizeof(szTitle
[0]));
4408 pszTitle
= lpCaption
;
4410 if (IS_INTRESOURCE(lpText
))
4411 LoadStringW(hInstance
, LOWORD(lpText
), szText
, sizeof(szText
)/sizeof(szText
[0]));
4415 FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_STRING
,
4416 pszText
, 0, 0, (LPWSTR
)&pszTemp
, 0, &args
);
4420 ret
= MessageBoxW(hWnd
, pszTemp
, pszTitle
, uType
);
4425 HRESULT WINAPI
IUnknown_QueryServiceExec(IUnknown
*unk
, REFIID service
, REFIID clsid
,
4426 DWORD x1
, DWORD x2
, DWORD x3
, void **ppvOut
)
4428 FIXME("%p %s %s %08x %08x %08x %p\n", unk
,
4429 debugstr_guid(service
), debugstr_guid(clsid
), x1
, x2
, x3
, ppvOut
);
4433 HRESULT WINAPI
IUnknown_ProfferService(IUnknown
*unk
, void *x0
, void *x1
, void *x2
)
4435 FIXME("%p %p %p %p\n", unk
, x0
, x1
, x2
);
4439 /***********************************************************************
4440 * ZoneComputePaneSize [SHLWAPI.382]
4442 UINT WINAPI
ZoneComputePaneSize(HWND hwnd
)
4448 /***********************************************************************
4449 * SHChangeNotifyWrap [SHLWAPI.394]
4451 void WINAPI
SHChangeNotifyWrap(LONG wEventId
, UINT uFlags
, LPCVOID dwItem1
, LPCVOID dwItem2
)
4453 SHChangeNotify(wEventId
, uFlags
, dwItem1
, dwItem2
);
4456 typedef struct SHELL_USER_SID
{ /* according to MSDN this should be in shlobj.h... */
4457 SID_IDENTIFIER_AUTHORITY sidAuthority
;
4458 DWORD dwUserGroupID
;
4460 } SHELL_USER_SID
, *PSHELL_USER_SID
;
4462 typedef struct SHELL_USER_PERMISSION
{ /* ...and this should be in shlwapi.h */
4463 SHELL_USER_SID susID
;
4467 DWORD dwInheritMask
;
4468 DWORD dwInheritAccessMask
;
4469 } SHELL_USER_PERMISSION
, *PSHELL_USER_PERMISSION
;
4471 /***********************************************************************
4472 * GetShellSecurityDescriptor [SHLWAPI.475]
4474 * prepares SECURITY_DESCRIPTOR from a set of ACEs
4477 * apUserPerm [I] array of pointers to SHELL_USER_PERMISSION structures,
4478 * each of which describes permissions to apply
4479 * cUserPerm [I] number of entries in apUserPerm array
4482 * success: pointer to SECURITY_DESCRIPTOR
4486 * Call should free returned descriptor with LocalFree
4488 PSECURITY_DESCRIPTOR WINAPI
GetShellSecurityDescriptor(PSHELL_USER_PERMISSION
*apUserPerm
, int cUserPerm
)
4491 PSID cur_user
= NULL
;
4495 PSECURITY_DESCRIPTOR psd
= NULL
;
4497 TRACE("%p %d\n", apUserPerm
, cUserPerm
);
4499 if (apUserPerm
== NULL
|| cUserPerm
<= 0)
4502 sidlist
= HeapAlloc(GetProcessHeap(), 0, cUserPerm
* sizeof(PSID
));
4506 acl_size
= sizeof(ACL
);
4508 for(sid_count
= 0; sid_count
< cUserPerm
; sid_count
++)
4510 static SHELL_USER_SID null_sid
= {{SECURITY_NULL_SID_AUTHORITY
}, 0, 0};
4511 PSHELL_USER_PERMISSION perm
= apUserPerm
[sid_count
];
4512 PSHELL_USER_SID sid
= &perm
->susID
;
4516 if (!memcmp((void*)sid
, (void*)&null_sid
, sizeof(SHELL_USER_SID
)))
4517 { /* current user's SID */
4521 DWORD bufsize
= sizeof(tuUser
);
4523 ret
= OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY
, &Token
);
4526 ret
= GetTokenInformation(Token
, TokenUser
, (void*)tuUser
, bufsize
, &bufsize
);
4528 cur_user
= ((PTOKEN_USER
)tuUser
)->User
.Sid
;
4533 } else if (sid
->dwUserID
==0) /* one sub-authority */
4534 ret
= AllocateAndInitializeSid(&sid
->sidAuthority
, 1, sid
->dwUserGroupID
, 0,
4535 0, 0, 0, 0, 0, 0, &pSid
);
4537 ret
= AllocateAndInitializeSid(&sid
->sidAuthority
, 2, sid
->dwUserGroupID
, sid
->dwUserID
,
4538 0, 0, 0, 0, 0, 0, &pSid
);
4542 sidlist
[sid_count
] = pSid
;
4543 /* increment acl_size (1 ACE for non-inheritable and 2 ACEs for inheritable records */
4544 acl_size
+= (sizeof(ACCESS_ALLOWED_ACE
)-sizeof(DWORD
) + GetLengthSid(pSid
)) * (perm
->fInherit
? 2 : 1);
4547 psd
= LocalAlloc(0, sizeof(SECURITY_DESCRIPTOR
) + acl_size
);
4551 PACL pAcl
= (PACL
)(((BYTE
*)psd
)+sizeof(SECURITY_DESCRIPTOR
));
4553 if (!InitializeSecurityDescriptor(psd
, SECURITY_DESCRIPTOR_REVISION
))
4556 if (!InitializeAcl(pAcl
, acl_size
, ACL_REVISION
))
4559 for(i
= 0; i
< sid_count
; i
++)
4561 PSHELL_USER_PERMISSION sup
= apUserPerm
[i
];
4562 PSID sid
= sidlist
[i
];
4564 switch(sup
->dwAccessType
)
4566 case ACCESS_ALLOWED_ACE_TYPE
:
4567 if (!AddAccessAllowedAce(pAcl
, ACL_REVISION
, sup
->dwAccessMask
, sid
))
4569 if (sup
->fInherit
&& !AddAccessAllowedAceEx(pAcl
, ACL_REVISION
,
4570 (BYTE
)sup
->dwInheritMask
, sup
->dwInheritAccessMask
, sid
))
4573 case ACCESS_DENIED_ACE_TYPE
:
4574 if (!AddAccessDeniedAce(pAcl
, ACL_REVISION
, sup
->dwAccessMask
, sid
))
4576 if (sup
->fInherit
&& !AddAccessDeniedAceEx(pAcl
, ACL_REVISION
,
4577 (BYTE
)sup
->dwInheritMask
, sup
->dwInheritAccessMask
, sid
))
4585 if (!SetSecurityDescriptorDacl(psd
, TRUE
, pAcl
, FALSE
))
4594 for(i
= 0; i
< sid_count
; i
++)
4596 if (!cur_user
|| sidlist
[i
] != cur_user
)
4597 FreeSid(sidlist
[i
]);
4599 HeapFree(GetProcessHeap(), 0, sidlist
);
4604 /***********************************************************************
4605 * SHCreatePropertyBagOnRegKey [SHLWAPI.471]
4607 * Creates a property bag from a registry key
4610 * hKey [I] Handle to the desired registry key
4611 * subkey [I] Name of desired subkey, or NULL to open hKey directly
4612 * grfMode [I] Optional flags
4613 * riid [I] IID of requested property bag interface
4614 * ppv [O] Address to receive pointer to the new interface
4618 * failure: error code
4621 HRESULT WINAPI
SHCreatePropertyBagOnRegKey (HKEY hKey
, LPCWSTR subkey
,
4622 DWORD grfMode
, REFIID riid
, void **ppv
)
4624 FIXME("%p %s %d %s %p STUB\n", hKey
, debugstr_w(subkey
), grfMode
,
4625 debugstr_guid(riid
), ppv
);
4630 /***********************************************************************
4631 * SHGetViewStatePropertyBag [SHLWAPI.515]
4633 * Retrieves a property bag in which the view state information of a folder
4637 * pidl [I] PIDL of the folder requested
4638 * bag_name [I] Name of the property bag requested
4639 * flags [I] Optional flags
4640 * riid [I] IID of requested property bag interface
4641 * ppv [O] Address to receive pointer to the new interface
4645 * failure: error code
4648 HRESULT WINAPI
SHGetViewStatePropertyBag(LPCITEMIDLIST pidl
, LPWSTR bag_name
,
4649 DWORD flags
, REFIID riid
, void **ppv
)
4651 FIXME("%p %s %d %s %p STUB\n", pidl
, debugstr_w(bag_name
), flags
,
4652 debugstr_guid(riid
), ppv
);
4657 /***********************************************************************
4658 * SHFormatDateTimeW [SHLWAPI.354]
4660 * Produces a string representation of a time.
4663 * fileTime [I] Pointer to FILETIME structure specifying the time
4664 * flags [I] Flags specifying the desired output
4665 * buf [O] Pointer to buffer for output
4666 * size [I] Number of characters that can be contained in buffer
4669 * success: number of characters written to the buffer
4673 INT WINAPI
SHFormatDateTimeW(const FILETIME UNALIGNED
*fileTime
, DWORD
*flags
,
4674 LPWSTR buf
, UINT size
)
4676 #define SHFORMATDT_UNSUPPORTED_FLAGS (FDTF_RELATIVE | FDTF_LTRDATE | FDTF_RTLDATE | FDTF_NOAUTOREADINGORDER)
4677 DWORD fmt_flags
= flags
? *flags
: FDTF_DEFAULT
;
4682 TRACE("%p %p %p %u\n", fileTime
, flags
, buf
, size
);
4687 if (fmt_flags
& SHFORMATDT_UNSUPPORTED_FLAGS
)
4688 FIXME("ignoring some flags - 0x%08x\n", fmt_flags
& SHFORMATDT_UNSUPPORTED_FLAGS
);
4690 FileTimeToLocalFileTime(fileTime
, &ft
);
4691 FileTimeToSystemTime(&ft
, &st
);
4693 /* first of all date */
4694 if (fmt_flags
& (FDTF_LONGDATE
| FDTF_SHORTDATE
))
4696 static const WCHAR sep1
[] = {',',' ',0};
4697 static const WCHAR sep2
[] = {' ',0};
4699 DWORD date
= fmt_flags
& FDTF_LONGDATE
? DATE_LONGDATE
: DATE_SHORTDATE
;
4700 ret
= GetDateFormatW(LOCALE_USER_DEFAULT
, date
, &st
, NULL
, buf
, size
);
4701 if (ret
>= size
) return ret
;
4704 if (ret
< size
&& (fmt_flags
& (FDTF_LONGTIME
| FDTF_SHORTTIME
)))
4706 if ((fmt_flags
& FDTF_LONGDATE
) && (ret
< size
+ 2))
4710 lstrcatW(&buf
[ret
-1], sep1
);
4716 lstrcatW(&buf
[ret
-1], sep2
);
4722 if (fmt_flags
& (FDTF_LONGTIME
| FDTF_SHORTTIME
))
4724 DWORD time
= fmt_flags
& FDTF_LONGTIME
? 0 : TIME_NOSECONDS
;
4727 ret
+= GetTimeFormatW(LOCALE_USER_DEFAULT
, time
, &st
, NULL
, &buf
[ret
], size
- ret
);
4732 #undef SHFORMATDT_UNSUPPORTED_FLAGS
4735 /***********************************************************************
4736 * SHFormatDateTimeA [SHLWAPI.353]
4738 * See SHFormatDateTimeW.
4741 INT WINAPI
SHFormatDateTimeA(const FILETIME UNALIGNED
*fileTime
, DWORD
*flags
,
4742 LPSTR buf
, UINT size
)
4750 bufW
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
) * size
);
4751 retval
= SHFormatDateTimeW(fileTime
, flags
, bufW
, size
);
4754 WideCharToMultiByte(CP_ACP
, 0, bufW
, -1, buf
, size
, NULL
, NULL
);
4756 HeapFree(GetProcessHeap(), 0, bufW
);
4760 /***********************************************************************
4761 * ZoneCheckUrlExW [SHLWAPI.231]
4763 * Checks the details of the security zone for the supplied site. (?)
4767 * szURL [I] Pointer to the URL to check
4769 * Other parameters currently unknown.
4775 INT WINAPI
ZoneCheckUrlExW(LPWSTR szURL
, PVOID pUnknown
, DWORD dwUnknown2
,
4776 DWORD dwUnknown3
, DWORD dwUnknown4
, DWORD dwUnknown5
, DWORD dwUnknown6
,
4779 FIXME("(%s,%p,%x,%x,%x,%x,%x,%x) STUB\n", debugstr_w(szURL
), pUnknown
, dwUnknown2
,
4780 dwUnknown3
, dwUnknown4
, dwUnknown5
, dwUnknown6
, dwUnknown7
);
4785 /***********************************************************************
4786 * SHVerbExistsNA [SHLWAPI.196]
4791 * verb [I] a string, often appears to be an extension.
4793 * Other parameters currently unknown.
4798 INT WINAPI
SHVerbExistsNA(LPSTR verb
, PVOID pUnknown
, PVOID pUnknown2
, DWORD dwUnknown3
)
4800 FIXME("(%s, %p, %p, %i) STUB\n",verb
, pUnknown
, pUnknown2
, dwUnknown3
);
4804 /*************************************************************************
4807 * Undocumented: Implementation guessed at via Name and behavior
4810 * lpUnknown [I] Object to get an IServiceProvider interface from
4811 * riid [I] Function requested for QueryService call
4812 * lppOut [O] Destination for the service interface pointer
4815 * Success: S_OK. lppOut contains an object providing the requested service
4816 * Failure: An HRESULT error code
4819 * lpUnknown is expected to support the IServiceProvider interface.
4821 HRESULT WINAPI
IUnknown_QueryServiceForWebBrowserApp(IUnknown
* lpUnknown
,
4822 REFGUID riid
, LPVOID
*lppOut
)
4824 FIXME("%p %s %p semi-STUB\n", lpUnknown
, debugstr_guid(riid
), lppOut
);
4825 return IUnknown_QueryService(lpUnknown
,&IID_IWebBrowserApp
,riid
,lppOut
);
4828 /**************************************************************************
4829 * SHPropertyBag_ReadLONG (SHLWAPI.496)
4831 * This function asks a property bag to read a named property as a LONG.
4834 * ppb: a IPropertyBag interface
4835 * pszPropName: Unicode string that names the property
4836 * pValue: address to receive the property value as a 32-bit signed integer
4841 BOOL WINAPI
SHPropertyBag_ReadLONG(IPropertyBag
*ppb
, LPCWSTR pszPropName
, LPLONG pValue
)
4845 TRACE("%p %s %p\n", ppb
,debugstr_w(pszPropName
),pValue
);
4846 if (!pszPropName
|| !ppb
|| !pValue
)
4847 return E_INVALIDARG
;
4849 hr
= IPropertyBag_Read(ppb
, pszPropName
, &var
, NULL
);
4852 if (V_VT(&var
) == VT_I4
)
4853 *pValue
= V_I4(&var
);
4855 hr
= DISP_E_BADVARTYPE
;
4860 /* return flags for SHGetObjectCompatFlags, names derived from registry value names */
4861 #define OBJCOMPAT_OTNEEDSSFCACHE 0x00000001
4862 #define OBJCOMPAT_NO_WEBVIEW 0x00000002
4863 #define OBJCOMPAT_UNBINDABLE 0x00000004
4864 #define OBJCOMPAT_PINDLL 0x00000008
4865 #define OBJCOMPAT_NEEDSFILESYSANCESTOR 0x00000010
4866 #define OBJCOMPAT_NOTAFILESYSTEM 0x00000020
4867 #define OBJCOMPAT_CTXMENU_NOVERBS 0x00000040
4868 #define OBJCOMPAT_CTXMENU_LIMITEDQI 0x00000080
4869 #define OBJCOMPAT_COCREATESHELLFOLDERONLY 0x00000100
4870 #define OBJCOMPAT_NEEDSSTORAGEANCESTOR 0x00000200
4871 #define OBJCOMPAT_NOLEGACYWEBVIEW 0x00000400
4872 #define OBJCOMPAT_CTXMENU_XPQCMFLAGS 0x00001000
4873 #define OBJCOMPAT_NOIPROPERTYSTORE 0x00002000
4875 /* a search table for compatibility flags */
4876 struct objcompat_entry
{
4877 const WCHAR name
[30];
4881 /* expected to be sorted by name */
4882 static const struct objcompat_entry objcompat_table
[] = {
4883 { {'C','O','C','R','E','A','T','E','S','H','E','L','L','F','O','L','D','E','R','O','N','L','Y',0},
4884 OBJCOMPAT_COCREATESHELLFOLDERONLY
},
4885 { {'C','T','X','M','E','N','U','_','L','I','M','I','T','E','D','Q','I',0},
4886 OBJCOMPAT_CTXMENU_LIMITEDQI
},
4887 { {'C','T','X','M','E','N','U','_','N','O','V','E','R','B','S',0},
4888 OBJCOMPAT_CTXMENU_LIMITEDQI
},
4889 { {'C','T','X','M','E','N','U','_','X','P','Q','C','M','F','L','A','G','S',0},
4890 OBJCOMPAT_CTXMENU_XPQCMFLAGS
},
4891 { {'N','E','E','D','S','F','I','L','E','S','Y','S','A','N','C','E','S','T','O','R',0},
4892 OBJCOMPAT_NEEDSFILESYSANCESTOR
},
4893 { {'N','E','E','D','S','S','T','O','R','A','G','E','A','N','C','E','S','T','O','R',0},
4894 OBJCOMPAT_NEEDSSTORAGEANCESTOR
},
4895 { {'N','O','I','P','R','O','P','E','R','T','Y','S','T','O','R','E',0},
4896 OBJCOMPAT_NOIPROPERTYSTORE
},
4897 { {'N','O','L','E','G','A','C','Y','W','E','B','V','I','E','W',0},
4898 OBJCOMPAT_NOLEGACYWEBVIEW
},
4899 { {'N','O','T','A','F','I','L','E','S','Y','S','T','E','M',0},
4900 OBJCOMPAT_NOTAFILESYSTEM
},
4901 { {'N','O','_','W','E','B','V','I','E','W',0},
4902 OBJCOMPAT_NO_WEBVIEW
},
4903 { {'O','T','N','E','E','D','S','S','F','C','A','C','H','E',0},
4904 OBJCOMPAT_OTNEEDSSFCACHE
},
4905 { {'P','I','N','D','L','L',0},
4907 { {'U','N','B','I','N','D','A','B','L','E',0},
4908 OBJCOMPAT_UNBINDABLE
}
4911 /**************************************************************************
4912 * SHGetObjectCompatFlags (SHLWAPI.476)
4914 * Function returns an integer representation of compatibility flags stored
4915 * in registry for CLSID under ShellCompatibility subkey.
4918 * pUnk: pointer to object IUnknown interface, idetifies CLSID
4919 * clsid: pointer to CLSID to retrieve data for
4922 * 0 on failure, flags set on success
4924 DWORD WINAPI
SHGetObjectCompatFlags(IUnknown
*pUnk
, const CLSID
*clsid
)
4926 static const WCHAR compatpathW
[] =
4927 {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
4928 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
4929 'S','h','e','l','l','C','o','m','p','a','t','i','b','i','l','i','t','y','\\',
4930 'O','b','j','e','c','t','s','\\','%','s',0};
4931 WCHAR strW
[sizeof(compatpathW
)/sizeof(WCHAR
) + 38 /* { CLSID } */];
4932 DWORD ret
, length
= sizeof(strW
)/sizeof(WCHAR
);
4937 TRACE("%p %s\n", pUnk
, debugstr_guid(clsid
));
4939 if (!pUnk
&& !clsid
) return 0;
4943 FIXME("iface not handled\n");
4947 StringFromCLSID(clsid
, &clsid_str
);
4948 sprintfW(strW
, compatpathW
, clsid_str
);
4949 CoTaskMemFree(clsid_str
);
4951 ret
= RegOpenKeyW(HKEY_LOCAL_MACHINE
, strW
, &key
);
4952 if (ret
!= ERROR_SUCCESS
) return 0;
4954 /* now collect flag values */
4956 for (i
= 0; RegEnumValueW(key
, i
, strW
, &length
, NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
; i
++)
4958 INT left
, right
, res
, x
;
4960 /* search in table */
4962 right
= sizeof(objcompat_table
) / sizeof(struct objcompat_entry
) - 1;
4964 while (right
>= left
) {
4965 x
= (left
+ right
) / 2;
4966 res
= strcmpW(strW
, objcompat_table
[x
].name
);
4969 ret
|= objcompat_table
[x
].value
;
4978 length
= sizeof(strW
)/sizeof(WCHAR
);