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
30 #include <shdeprecated.h>
36 /* DLL handles for late bound calls */
37 extern HINSTANCE shlwapi_hInstance
;
38 extern DWORD SHLWAPI_ThreadRef_index
;
40 HRESULT WINAPI
IUnknown_QueryService(IUnknown
*,REFGUID
,REFIID
,LPVOID
*);
41 HRESULT WINAPI
SHInvokeCommand(HWND
,IShellFolder
*,LPCITEMIDLIST
,DWORD
);
42 BOOL WINAPI
SHAboutInfoW(LPWSTR
,DWORD
);
45 NOTES: Most functions exported by ordinal seem to be superfluous.
46 The reason for these functions to be there is to provide a wrapper
47 for unicode functions to provide these functions on systems without
48 unicode functions eg. win95/win98. Since we have such functions we just
49 call these. If running Wine with native DLLs, some late bound calls may
50 fail. However, it is better to implement the functions in the forward DLL
51 and recommend the builtin rather than reimplementing the calls here!
54 /*************************************************************************
57 * Copy a sharable memory handle from one process to another.
60 * hShared [I] Shared memory handle to duplicate
61 * dwSrcProcId [I] ID of the process owning hShared
62 * dwDstProcId [I] ID of the process wanting the duplicated handle
63 * dwAccess [I] Desired DuplicateHandle() access
64 * dwOptions [I] Desired DuplicateHandle() options
67 * Success: A handle suitable for use by the dwDstProcId process.
68 * Failure: A NULL handle.
71 HANDLE WINAPI
SHMapHandle(HANDLE hShared
, DWORD dwSrcProcId
, DWORD dwDstProcId
,
72 DWORD dwAccess
, DWORD dwOptions
)
75 DWORD dwMyProcId
= GetCurrentProcessId();
78 TRACE("(%p,%d,%d,%08x,%08x)\n", hShared
, dwDstProcId
, dwSrcProcId
,
81 /* Get dest process handle */
82 if (dwDstProcId
== dwMyProcId
)
83 hDst
= GetCurrentProcess();
85 hDst
= OpenProcess(PROCESS_DUP_HANDLE
, 0, dwDstProcId
);
89 /* Get src process handle */
90 if (dwSrcProcId
== dwMyProcId
)
91 hSrc
= GetCurrentProcess();
93 hSrc
= OpenProcess(PROCESS_DUP_HANDLE
, 0, dwSrcProcId
);
97 /* Make handle available to dest process */
98 if (!DuplicateHandle(hSrc
, hShared
, hDst
, &hRet
,
99 dwAccess
, 0, dwOptions
| DUPLICATE_SAME_ACCESS
))
102 if (dwSrcProcId
!= dwMyProcId
)
106 if (dwDstProcId
!= dwMyProcId
)
110 TRACE("Returning handle %p\n", hRet
);
114 /*************************************************************************
117 * Create a block of sharable memory and initialise it with data.
120 * lpvData [I] Pointer to data to write
121 * dwSize [I] Size of data
122 * dwProcId [I] ID of process owning data
125 * Success: A shared memory handle
129 * Ordinals 7-11 provide a set of calls to create shared memory between a
130 * group of processes. The shared memory is treated opaquely in that its size
131 * is not exposed to clients who map it. This is accomplished by storing
132 * the size of the map as the first DWORD of mapped data, and then offsetting
133 * the view pointer returned by this size.
136 HANDLE WINAPI
SHAllocShared(LPCVOID lpvData
, DWORD dwSize
, DWORD dwProcId
)
142 TRACE("(%p,%d,%d)\n", lpvData
, dwSize
, dwProcId
);
144 /* Create file mapping of the correct length */
145 hMap
= CreateFileMappingA(INVALID_HANDLE_VALUE
, NULL
, FILE_MAP_READ
, 0,
146 dwSize
+ sizeof(dwSize
), NULL
);
150 /* Get a view in our process address space */
151 pMapped
= MapViewOfFile(hMap
, FILE_MAP_READ
| FILE_MAP_WRITE
, 0, 0, 0);
155 /* Write size of data, followed by the data, to the view */
156 *((DWORD
*)pMapped
) = dwSize
;
158 memcpy((char *) pMapped
+ sizeof(dwSize
), lpvData
, dwSize
);
160 /* Release view. All further views mapped will be opaque */
161 UnmapViewOfFile(pMapped
);
162 hRet
= SHMapHandle(hMap
, GetCurrentProcessId(), dwProcId
,
163 FILE_MAP_ALL_ACCESS
, DUPLICATE_SAME_ACCESS
);
170 /*************************************************************************
173 * Get a pointer to a block of shared memory from a shared memory handle.
176 * hShared [I] Shared memory handle
177 * dwProcId [I] ID of process owning hShared
180 * Success: A pointer to the shared memory
184 PVOID WINAPI
SHLockShared(HANDLE hShared
, DWORD dwProcId
)
189 TRACE("(%p %d)\n", hShared
, dwProcId
);
191 /* Get handle to shared memory for current process */
192 hDup
= SHMapHandle(hShared
, dwProcId
, GetCurrentProcessId(), FILE_MAP_ALL_ACCESS
, 0);
195 pMapped
= MapViewOfFile(hDup
, FILE_MAP_READ
| FILE_MAP_WRITE
, 0, 0, 0);
199 return (char *) pMapped
+ sizeof(DWORD
); /* Hide size */
203 /*************************************************************************
206 * Release a pointer to a block of shared memory.
209 * lpView [I] Shared memory pointer
216 BOOL WINAPI
SHUnlockShared(LPVOID lpView
)
218 TRACE("(%p)\n", lpView
);
219 return UnmapViewOfFile((char *) lpView
- sizeof(DWORD
)); /* Include size */
222 /*************************************************************************
225 * Destroy a block of sharable memory.
228 * hShared [I] Shared memory handle
229 * dwProcId [I] ID of process owning hShared
236 BOOL WINAPI
SHFreeShared(HANDLE hShared
, DWORD dwProcId
)
240 TRACE("(%p %d)\n", hShared
, dwProcId
);
245 /* Get a copy of the handle for our process, closing the source handle */
246 hClose
= SHMapHandle(hShared
, dwProcId
, GetCurrentProcessId(),
247 FILE_MAP_ALL_ACCESS
,DUPLICATE_CLOSE_SOURCE
);
248 /* Close local copy */
249 return CloseHandle(hClose
);
252 /*************************************************************************
255 * Create and register a clipboard enumerator for a web browser.
258 * lpBC [I] Binding context
259 * lpUnknown [I] An object exposing the IWebBrowserApp interface
263 * Failure: An HRESULT error code.
266 * The enumerator is stored as a property of the web browser. If it does not
267 * yet exist, it is created and set before being registered.
269 HRESULT WINAPI
RegisterDefaultAcceptHeaders(LPBC lpBC
, IUnknown
*lpUnknown
)
271 static const WCHAR szProperty
[] = { '{','D','0','F','C','A','4','2','0',
272 '-','D','3','F','5','-','1','1','C','F', '-','B','2','1','1','-','0',
273 '0','A','A','0','0','4','A','E','8','3','7','}','\0' };
275 IEnumFORMATETC
* pIEnumFormatEtc
= NULL
;
278 IWebBrowserApp
* pBrowser
;
280 TRACE("(%p, %p)\n", lpBC
, lpUnknown
);
282 hr
= IUnknown_QueryService(lpUnknown
, &IID_IWebBrowserApp
, &IID_IWebBrowserApp
, (void**)&pBrowser
);
286 V_VT(&var
) = VT_EMPTY
;
288 /* The property we get is the browsers clipboard enumerator */
289 property
= SysAllocString(szProperty
);
290 hr
= IWebBrowserApp_GetProperty(pBrowser
, property
, &var
);
291 SysFreeString(property
);
292 if (FAILED(hr
)) goto exit
;
294 if (V_VT(&var
) == VT_EMPTY
)
296 /* Iterate through accepted documents and RegisterClipBoardFormatA() them */
297 char szKeyBuff
[128], szValueBuff
[128];
298 DWORD dwKeySize
, dwValueSize
, dwRet
= 0, dwCount
= 0, dwNumValues
, dwType
;
299 FORMATETC
* formatList
, *format
;
302 TRACE("Registering formats and creating IEnumFORMATETC instance\n");
304 if (!RegOpenKeyA(HKEY_LOCAL_MACHINE
, "Software\\Microsoft\\Windows\\Current"
305 "Version\\Internet Settings\\Accepted Documents", &hDocs
))
311 /* Get count of values in key */
314 dwKeySize
= sizeof(szKeyBuff
);
315 dwRet
= RegEnumValueA(hDocs
,dwCount
,szKeyBuff
,&dwKeySize
,0,&dwType
,0,0);
319 dwNumValues
= dwCount
;
321 /* Note: dwCount = number of items + 1; The extra item is the end node */
322 format
= formatList
= HeapAlloc(GetProcessHeap(), 0, dwCount
* sizeof(FORMATETC
));
337 /* Register clipboard formats for the values and populate format list */
338 while(!dwRet
&& dwCount
< dwNumValues
)
340 dwKeySize
= sizeof(szKeyBuff
);
341 dwValueSize
= sizeof(szValueBuff
);
342 dwRet
= RegEnumValueA(hDocs
, dwCount
, szKeyBuff
, &dwKeySize
, 0, &dwType
,
343 (PBYTE
)szValueBuff
, &dwValueSize
);
346 HeapFree(GetProcessHeap(), 0, formatList
);
352 format
->cfFormat
= RegisterClipboardFormatA(szValueBuff
);
354 format
->dwAspect
= 1;
365 /* Terminate the (maybe empty) list, last entry has a cfFormat of 0 */
366 format
->cfFormat
= 0;
368 format
->dwAspect
= 1;
372 /* Create a clipboard enumerator */
373 hr
= CreateFormatEnumerator(dwNumValues
, formatList
, &pIEnumFormatEtc
);
374 HeapFree(GetProcessHeap(), 0, formatList
);
375 if (FAILED(hr
)) goto exit
;
377 /* Set our enumerator as the browsers property */
378 V_VT(&var
) = VT_UNKNOWN
;
379 V_UNKNOWN(&var
) = (IUnknown
*)pIEnumFormatEtc
;
381 property
= SysAllocString(szProperty
);
382 hr
= IWebBrowserApp_PutProperty(pBrowser
, property
, var
);
383 SysFreeString(property
);
386 IEnumFORMATETC_Release(pIEnumFormatEtc
);
391 if (V_VT(&var
) == VT_UNKNOWN
)
393 /* Our variant is holding the clipboard enumerator */
394 IUnknown
* pIUnknown
= V_UNKNOWN(&var
);
395 IEnumFORMATETC
* pClone
= NULL
;
397 TRACE("Retrieved IEnumFORMATETC property\n");
399 /* Get an IEnumFormatEtc interface from the variants value */
400 pIEnumFormatEtc
= NULL
;
401 hr
= IUnknown_QueryInterface(pIUnknown
, &IID_IEnumFORMATETC
, (void**)&pIEnumFormatEtc
);
402 if (hr
== S_OK
&& pIEnumFormatEtc
)
404 /* Clone and register the enumerator */
405 hr
= IEnumFORMATETC_Clone(pIEnumFormatEtc
, &pClone
);
406 if (hr
== S_OK
&& pClone
)
408 RegisterFormatEnumerator(lpBC
, pClone
, 0);
410 IEnumFORMATETC_Release(pClone
);
413 IUnknown_Release(pIUnknown
);
415 IUnknown_Release(V_UNKNOWN(&var
));
419 IWebBrowserApp_Release(pBrowser
);
423 /*************************************************************************
426 * Get Explorers "AcceptLanguage" setting.
429 * langbuf [O] Destination for language string
430 * buflen [I] Length of langbuf in characters
431 * [0] Success: used length of langbuf
434 * Success: S_OK. langbuf is set to the language string found.
435 * Failure: E_FAIL, If any arguments are invalid, error occurred, or Explorer
436 * does not contain the setting.
437 * E_NOT_SUFFICIENT_BUFFER, If the buffer is not big enough
439 HRESULT WINAPI
GetAcceptLanguagesW( LPWSTR langbuf
, LPDWORD buflen
)
441 static const WCHAR szkeyW
[] = {
442 'S','o','f','t','w','a','r','e','\\',
443 'M','i','c','r','o','s','o','f','t','\\',
444 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
445 'I','n','t','e','r','n','a','t','i','o','n','a','l',0};
446 static const WCHAR valueW
[] = {
447 'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0};
448 DWORD mystrlen
, mytype
;
455 TRACE("(%p, %p) *%p: %d\n", langbuf
, buflen
, buflen
, buflen
? *buflen
: -1);
457 if(!langbuf
|| !buflen
|| !*buflen
)
460 mystrlen
= (*buflen
> 20) ? *buflen
: 20 ;
461 len
= mystrlen
* sizeof(WCHAR
);
462 mystr
= HeapAlloc(GetProcessHeap(), 0, len
);
464 RegOpenKeyW(HKEY_CURRENT_USER
, szkeyW
, &mykey
);
465 lres
= RegQueryValueExW(mykey
, valueW
, 0, &mytype
, (PBYTE
)mystr
, &len
);
467 len
= lstrlenW(mystr
);
469 if (!lres
&& (*buflen
> len
)) {
470 lstrcpyW(langbuf
, mystr
);
472 HeapFree(GetProcessHeap(), 0, mystr
);
476 /* Did not find a value in the registry or the user buffer is too small */
477 mylcid
= GetUserDefaultLCID();
478 LcidToRfc1766W(mylcid
, mystr
, mystrlen
);
479 len
= lstrlenW(mystr
);
481 memcpy( langbuf
, mystr
, min(*buflen
, len
+1)*sizeof(WCHAR
) );
482 HeapFree(GetProcessHeap(), 0, mystr
);
490 return E_NOT_SUFFICIENT_BUFFER
;
493 /*************************************************************************
496 * Ascii version of GetAcceptLanguagesW.
498 HRESULT WINAPI
GetAcceptLanguagesA( LPSTR langbuf
, LPDWORD buflen
)
501 DWORD buflenW
, convlen
;
504 TRACE("(%p, %p) *%p: %d\n", langbuf
, buflen
, buflen
, buflen
? *buflen
: -1);
506 if(!langbuf
|| !buflen
|| !*buflen
) return E_FAIL
;
509 langbufW
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
) * buflenW
);
510 retval
= GetAcceptLanguagesW(langbufW
, &buflenW
);
514 convlen
= WideCharToMultiByte(CP_ACP
, 0, langbufW
, -1, langbuf
, *buflen
, NULL
, NULL
);
515 convlen
--; /* do not count the terminating 0 */
517 else /* copy partial string anyway */
519 convlen
= WideCharToMultiByte(CP_ACP
, 0, langbufW
, *buflen
, langbuf
, *buflen
, NULL
, NULL
);
520 if (convlen
< *buflen
)
522 langbuf
[convlen
] = 0;
523 convlen
--; /* do not count the terminating 0 */
530 *buflen
= buflenW
? convlen
: 0;
532 HeapFree(GetProcessHeap(), 0, langbufW
);
536 /*************************************************************************
539 * Convert a GUID to a string.
542 * guid [I] GUID to convert
543 * lpszDest [O] Destination for string
544 * cchMax [I] Length of output buffer
547 * The length of the string created.
549 INT WINAPI
SHStringFromGUIDA(REFGUID guid
, LPSTR lpszDest
, INT cchMax
)
554 TRACE("(%s,%p,%d)\n", debugstr_guid(guid
), lpszDest
, cchMax
);
556 sprintf(xguid
, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
557 guid
->Data1
, guid
->Data2
, guid
->Data3
,
558 guid
->Data4
[0], guid
->Data4
[1], guid
->Data4
[2], guid
->Data4
[3],
559 guid
->Data4
[4], guid
->Data4
[5], guid
->Data4
[6], guid
->Data4
[7]);
561 iLen
= strlen(xguid
) + 1;
565 memcpy(lpszDest
, xguid
, iLen
);
569 /*************************************************************************
572 * Convert a GUID to a string.
575 * guid [I] GUID to convert
576 * str [O] Destination for string
577 * cmax [I] Length of output buffer
580 * The length of the string created.
582 INT WINAPI
SHStringFromGUIDW(REFGUID guid
, LPWSTR lpszDest
, INT cchMax
)
586 static const WCHAR wszFormat
[] = {'{','%','0','8','l','X','-','%','0','4','X','-','%','0','4','X','-',
587 '%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','%','0','2','X','%','0','2',
588 'X','%','0','2','X','%','0','2','X','}',0};
590 TRACE("(%s,%p,%d)\n", debugstr_guid(guid
), lpszDest
, cchMax
);
592 sprintfW(xguid
, wszFormat
, guid
->Data1
, guid
->Data2
, guid
->Data3
,
593 guid
->Data4
[0], guid
->Data4
[1], guid
->Data4
[2], guid
->Data4
[3],
594 guid
->Data4
[4], guid
->Data4
[5], guid
->Data4
[6], guid
->Data4
[7]);
596 iLen
= strlenW(xguid
) + 1;
600 memcpy(lpszDest
, xguid
, iLen
*sizeof(WCHAR
));
604 /*************************************************************************
607 * Determine if a Unicode character is a blank.
610 * wc [I] Character to check.
613 * TRUE, if wc is a blank,
617 BOOL WINAPI
IsCharBlankW(WCHAR wc
)
621 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_BLANK
);
624 /*************************************************************************
627 * Determine if a Unicode character is punctuation.
630 * wc [I] Character to check.
633 * TRUE, if wc is punctuation,
636 BOOL WINAPI
IsCharPunctW(WCHAR wc
)
640 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_PUNCT
);
643 /*************************************************************************
646 * Determine if a Unicode character is a control character.
649 * wc [I] Character to check.
652 * TRUE, if wc is a control character,
655 BOOL WINAPI
IsCharCntrlW(WCHAR wc
)
659 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_CNTRL
);
662 /*************************************************************************
665 * Determine if a Unicode character is a digit.
668 * wc [I] Character to check.
671 * TRUE, if wc is a digit,
674 BOOL WINAPI
IsCharDigitW(WCHAR wc
)
678 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_DIGIT
);
681 /*************************************************************************
684 * Determine if a Unicode character is a hex digit.
687 * wc [I] Character to check.
690 * TRUE, if wc is a hex digit,
693 BOOL WINAPI
IsCharXDigitW(WCHAR wc
)
697 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_XDIGIT
);
700 /*************************************************************************
704 BOOL WINAPI
GetStringType3ExW(LPWSTR src
, INT count
, LPWORD type
)
706 return GetStringTypeW(CT_CTYPE3
, src
, count
, type
);
709 /*************************************************************************
712 * Compare two Ascii strings up to a given length.
715 * lpszSrc [I] Source string
716 * lpszCmp [I] String to compare to lpszSrc
717 * len [I] Maximum length
720 * A number greater than, less than or equal to 0 depending on whether
721 * lpszSrc is greater than, less than or equal to lpszCmp.
723 DWORD WINAPI
StrCmpNCA(LPCSTR lpszSrc
, LPCSTR lpszCmp
, INT len
)
725 return StrCmpNA(lpszSrc
, lpszCmp
, len
);
728 /*************************************************************************
731 * Unicode version of StrCmpNCA.
733 DWORD WINAPI
StrCmpNCW(LPCWSTR lpszSrc
, LPCWSTR lpszCmp
, INT len
)
735 return StrCmpNW(lpszSrc
, lpszCmp
, len
);
738 /*************************************************************************
741 * Compare two Ascii strings up to a given length, ignoring case.
744 * lpszSrc [I] Source string
745 * lpszCmp [I] String to compare to lpszSrc
746 * len [I] Maximum length
749 * A number greater than, less than or equal to 0 depending on whether
750 * lpszSrc is greater than, less than or equal to lpszCmp.
752 DWORD WINAPI
StrCmpNICA(LPCSTR lpszSrc
, LPCSTR lpszCmp
, DWORD len
)
754 return StrCmpNIA(lpszSrc
, lpszCmp
, len
);
757 /*************************************************************************
760 * Unicode version of StrCmpNICA.
762 DWORD WINAPI
StrCmpNICW(LPCWSTR lpszSrc
, LPCWSTR lpszCmp
, DWORD len
)
764 return StrCmpNIW(lpszSrc
, lpszCmp
, len
);
767 /*************************************************************************
770 * Compare two Ascii strings.
773 * lpszSrc [I] Source string
774 * lpszCmp [I] String to compare to lpszSrc
777 * A number greater than, less than or equal to 0 depending on whether
778 * lpszSrc is greater than, less than or equal to lpszCmp.
780 DWORD WINAPI
StrCmpCA(LPCSTR lpszSrc
, LPCSTR lpszCmp
)
782 return lstrcmpA(lpszSrc
, lpszCmp
);
785 /*************************************************************************
788 * Unicode version of StrCmpCA.
790 DWORD WINAPI
StrCmpCW(LPCWSTR lpszSrc
, LPCWSTR lpszCmp
)
792 return lstrcmpW(lpszSrc
, lpszCmp
);
795 /*************************************************************************
798 * Compare two Ascii strings, ignoring case.
801 * lpszSrc [I] Source string
802 * lpszCmp [I] String to compare to lpszSrc
805 * A number greater than, less than or equal to 0 depending on whether
806 * lpszSrc is greater than, less than or equal to lpszCmp.
808 DWORD WINAPI
StrCmpICA(LPCSTR lpszSrc
, LPCSTR lpszCmp
)
810 return lstrcmpiA(lpszSrc
, lpszCmp
);
813 /*************************************************************************
816 * Unicode version of StrCmpICA.
818 DWORD WINAPI
StrCmpICW(LPCWSTR lpszSrc
, LPCWSTR lpszCmp
)
820 return lstrcmpiW(lpszSrc
, lpszCmp
);
823 /*************************************************************************
826 * Get an identification string for the OS and explorer.
829 * lpszDest [O] Destination for Id string
830 * dwDestLen [I] Length of lpszDest
833 * TRUE, If the string was created successfully
836 BOOL WINAPI
SHAboutInfoA(LPSTR lpszDest
, DWORD dwDestLen
)
840 TRACE("(%p,%d)\n", lpszDest
, dwDestLen
);
842 if (lpszDest
&& SHAboutInfoW(buff
, dwDestLen
))
844 WideCharToMultiByte(CP_ACP
, 0, buff
, -1, lpszDest
, dwDestLen
, NULL
, NULL
);
850 /*************************************************************************
853 * Unicode version of SHAboutInfoA.
855 BOOL WINAPI
SHAboutInfoW(LPWSTR lpszDest
, DWORD dwDestLen
)
857 static const WCHAR szIEKey
[] = { 'S','O','F','T','W','A','R','E','\\',
858 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
859 ' ','E','x','p','l','o','r','e','r','\0' };
860 static const WCHAR szWinNtKey
[] = { 'S','O','F','T','W','A','R','E','\\',
861 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s',' ',
862 'N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
863 static const WCHAR szWinKey
[] = { 'S','O','F','T','W','A','R','E','\\',
864 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
865 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
866 static const WCHAR szRegKey
[] = { 'S','O','F','T','W','A','R','E','\\',
867 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
868 ' ','E','x','p','l','o','r','e','r','\\',
869 'R','e','g','i','s','t','r','a','t','i','o','n','\0' };
870 static const WCHAR szVersion
[] = { 'V','e','r','s','i','o','n','\0' };
871 static const WCHAR szCustomized
[] = { 'C','u','s','t','o','m','i','z','e','d',
872 'V','e','r','s','i','o','n','\0' };
873 static const WCHAR szOwner
[] = { 'R','e','g','i','s','t','e','r','e','d',
874 'O','w','n','e','r','\0' };
875 static const WCHAR szOrg
[] = { 'R','e','g','i','s','t','e','r','e','d',
876 'O','r','g','a','n','i','z','a','t','i','o','n','\0' };
877 static const WCHAR szProduct
[] = { 'P','r','o','d','u','c','t','I','d','\0' };
878 static const WCHAR szUpdate
[] = { 'I','E','A','K',
879 'U','p','d','a','t','e','U','r','l','\0' };
880 static const WCHAR szHelp
[] = { 'I','E','A','K',
881 'H','e','l','p','S','t','r','i','n','g','\0' };
886 TRACE("(%p,%d)\n", lpszDest
, dwDestLen
);
893 /* Try the NT key first, followed by 95/98 key */
894 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szWinNtKey
, 0, KEY_READ
, &hReg
) &&
895 RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szWinKey
, 0, KEY_READ
, &hReg
))
901 if (!SHGetValueW(HKEY_LOCAL_MACHINE
, szIEKey
, szVersion
, &dwType
, buff
, &dwLen
))
903 DWORD dwStrLen
= strlenW(buff
);
904 dwLen
= 30 - dwStrLen
;
905 SHGetValueW(HKEY_LOCAL_MACHINE
, szIEKey
,
906 szCustomized
, &dwType
, buff
+dwStrLen
, &dwLen
);
908 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
910 /* ~Registered Owner */
913 if (SHGetValueW(hReg
, szOwner
, 0, &dwType
, buff
+1, &dwLen
))
915 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
917 /* ~Registered Organization */
919 if (SHGetValueW(hReg
, szOrg
, 0, &dwType
, buff
+1, &dwLen
))
921 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
923 /* FIXME: Not sure where this number comes from */
927 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
931 if (SHGetValueW(HKEY_LOCAL_MACHINE
, szRegKey
, szProduct
, &dwType
, buff
+1, &dwLen
))
933 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
937 if(SHGetValueW(HKEY_LOCAL_MACHINE
, szWinKey
, szUpdate
, &dwType
, buff
+1, &dwLen
))
939 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
941 /* ~IE Help String */
943 if(SHGetValueW(hReg
, szHelp
, 0, &dwType
, buff
+1, &dwLen
))
945 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
951 /*************************************************************************
954 * Call IOleCommandTarget_QueryStatus() on an object.
957 * lpUnknown [I] Object supporting the IOleCommandTarget interface
958 * pguidCmdGroup [I] GUID for the command group
960 * prgCmds [O] Commands
961 * pCmdText [O] Command text
965 * Failure: E_FAIL, if lpUnknown is NULL.
966 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
967 * Otherwise, an error code from IOleCommandTarget_QueryStatus().
969 HRESULT WINAPI
IUnknown_QueryStatus(IUnknown
* lpUnknown
, REFGUID pguidCmdGroup
,
970 ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
* pCmdText
)
972 HRESULT hRet
= E_FAIL
;
974 TRACE("(%p,%p,%d,%p,%p)\n",lpUnknown
, pguidCmdGroup
, cCmds
, prgCmds
, pCmdText
);
978 IOleCommandTarget
* lpOle
;
980 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleCommandTarget
,
983 if (SUCCEEDED(hRet
) && lpOle
)
985 hRet
= IOleCommandTarget_QueryStatus(lpOle
, pguidCmdGroup
, cCmds
,
987 IOleCommandTarget_Release(lpOle
);
993 /*************************************************************************
996 * Call IOleCommandTarget_Exec() on an object.
999 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1000 * pguidCmdGroup [I] GUID for the command group
1004 * Failure: E_FAIL, if lpUnknown is NULL.
1005 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1006 * Otherwise, an error code from IOleCommandTarget_Exec().
1008 HRESULT WINAPI
IUnknown_Exec(IUnknown
* lpUnknown
, REFGUID pguidCmdGroup
,
1009 DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
* pvaIn
,
1012 HRESULT hRet
= E_FAIL
;
1014 TRACE("(%p,%p,%d,%d,%p,%p)\n",lpUnknown
, pguidCmdGroup
, nCmdID
,
1015 nCmdexecopt
, pvaIn
, pvaOut
);
1019 IOleCommandTarget
* lpOle
;
1021 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleCommandTarget
,
1023 if (SUCCEEDED(hRet
) && lpOle
)
1025 hRet
= IOleCommandTarget_Exec(lpOle
, pguidCmdGroup
, nCmdID
,
1026 nCmdexecopt
, pvaIn
, pvaOut
);
1027 IOleCommandTarget_Release(lpOle
);
1033 /*************************************************************************
1036 * Retrieve, modify, and re-set a value from a window.
1039 * hWnd [I] Window to get value from
1040 * offset [I] Offset of value
1041 * mask [I] Mask for flags
1042 * flags [I] Bits to set in window value
1045 * The new value as it was set, or 0 if any parameter is invalid.
1048 * Only bits specified in mask are affected - set if present in flags and
1051 LONG WINAPI
SHSetWindowBits(HWND hwnd
, INT offset
, UINT mask
, UINT flags
)
1053 LONG ret
= GetWindowLongW(hwnd
, offset
);
1054 LONG new_flags
= (flags
& mask
) | (ret
& ~mask
);
1056 TRACE("%p %d %x %x\n", hwnd
, offset
, mask
, flags
);
1058 if (new_flags
!= ret
)
1059 ret
= SetWindowLongW(hwnd
, offset
, new_flags
);
1063 /*************************************************************************
1066 * Change a window's parent.
1069 * hWnd [I] Window to change parent of
1070 * hWndParent [I] New parent window
1073 * The old parent of hWnd.
1076 * If hWndParent is NULL (desktop), the window style is changed to WS_POPUP.
1077 * If hWndParent is NOT NULL then we set the WS_CHILD style.
1079 HWND WINAPI
SHSetParentHwnd(HWND hWnd
, HWND hWndParent
)
1081 TRACE("%p, %p\n", hWnd
, hWndParent
);
1083 if(GetParent(hWnd
) == hWndParent
)
1087 SHSetWindowBits(hWnd
, GWL_STYLE
, WS_CHILD
| WS_POPUP
, WS_CHILD
);
1089 SHSetWindowBits(hWnd
, GWL_STYLE
, WS_CHILD
| WS_POPUP
, WS_POPUP
);
1091 return hWndParent
? SetParent(hWnd
, hWndParent
) : NULL
;
1094 /*************************************************************************
1097 * Locate and advise a connection point in an IConnectionPointContainer object.
1100 * lpUnkSink [I] Sink for the connection point advise call
1101 * riid [I] REFIID of connection point to advise
1102 * fConnect [I] TRUE = Connection being establisted, FALSE = broken
1103 * lpUnknown [I] Object supporting the IConnectionPointContainer interface
1104 * lpCookie [O] Pointer to connection point cookie
1105 * lppCP [O] Destination for the IConnectionPoint found
1108 * Success: S_OK. If lppCP is non-NULL, it is filled with the IConnectionPoint
1109 * that was advised. The caller is responsible for releasing it.
1110 * Failure: E_FAIL, if any arguments are invalid.
1111 * E_NOINTERFACE, if lpUnknown isn't an IConnectionPointContainer,
1112 * Or an HRESULT error code if any call fails.
1114 HRESULT WINAPI
ConnectToConnectionPoint(IUnknown
* lpUnkSink
, REFIID riid
, BOOL fConnect
,
1115 IUnknown
* lpUnknown
, LPDWORD lpCookie
,
1116 IConnectionPoint
**lppCP
)
1119 IConnectionPointContainer
* lpContainer
;
1120 IConnectionPoint
*lpCP
;
1122 if(!lpUnknown
|| (fConnect
&& !lpUnkSink
))
1128 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IConnectionPointContainer
,
1129 (void**)&lpContainer
);
1130 if (SUCCEEDED(hRet
))
1132 hRet
= IConnectionPointContainer_FindConnectionPoint(lpContainer
, riid
, &lpCP
);
1134 if (SUCCEEDED(hRet
))
1137 hRet
= IConnectionPoint_Unadvise(lpCP
, *lpCookie
);
1139 hRet
= IConnectionPoint_Advise(lpCP
, lpUnkSink
, lpCookie
);
1144 if (lppCP
&& SUCCEEDED(hRet
))
1145 *lppCP
= lpCP
; /* Caller keeps the interface */
1147 IConnectionPoint_Release(lpCP
); /* Release it */
1150 IConnectionPointContainer_Release(lpContainer
);
1155 /*************************************************************************
1158 * Release an interface and zero a supplied pointer.
1161 * lpUnknown [I] Object to release
1166 void WINAPI
IUnknown_AtomicRelease(IUnknown
** lpUnknown
)
1168 TRACE("(%p)\n", lpUnknown
);
1170 if(!lpUnknown
|| !*lpUnknown
) return;
1172 TRACE("doing Release\n");
1174 IUnknown_Release(*lpUnknown
);
1178 /*************************************************************************
1181 * Skip '//' if present in a string.
1184 * lpszSrc [I] String to check for '//'
1187 * Success: The next character after the '//' or the string if not present
1188 * Failure: NULL, if lpszStr is NULL.
1190 LPCSTR WINAPI
PathSkipLeadingSlashesA(LPCSTR lpszSrc
)
1192 if (lpszSrc
&& lpszSrc
[0] == '/' && lpszSrc
[1] == '/')
1197 /*************************************************************************
1200 * Check if two interfaces come from the same object.
1203 * lpInt1 [I] Interface to check against lpInt2.
1204 * lpInt2 [I] Interface to check against lpInt1.
1207 * TRUE, If the interfaces come from the same object.
1210 BOOL WINAPI
SHIsSameObject(IUnknown
* lpInt1
, IUnknown
* lpInt2
)
1212 IUnknown
*lpUnknown1
, *lpUnknown2
;
1215 TRACE("(%p %p)\n", lpInt1
, lpInt2
);
1217 if (!lpInt1
|| !lpInt2
)
1220 if (lpInt1
== lpInt2
)
1223 if (IUnknown_QueryInterface(lpInt1
, &IID_IUnknown
, (void**)&lpUnknown1
) != S_OK
)
1226 if (IUnknown_QueryInterface(lpInt2
, &IID_IUnknown
, (void**)&lpUnknown2
) != S_OK
)
1228 IUnknown_Release(lpUnknown1
);
1232 ret
= lpUnknown1
== lpUnknown2
;
1234 IUnknown_Release(lpUnknown1
);
1235 IUnknown_Release(lpUnknown2
);
1240 /*************************************************************************
1243 * Get the window handle of an object.
1246 * lpUnknown [I] Object to get the window handle of
1247 * lphWnd [O] Destination for window handle
1250 * Success: S_OK. lphWnd contains the objects window handle.
1251 * Failure: An HRESULT error code.
1254 * lpUnknown is expected to support one of the following interfaces:
1255 * IOleWindow(), IInternetSecurityMgrSite(), or IShellView().
1257 HRESULT WINAPI
IUnknown_GetWindow(IUnknown
*lpUnknown
, HWND
*lphWnd
)
1260 HRESULT hRet
= E_FAIL
;
1262 TRACE("(%p,%p)\n", lpUnknown
, lphWnd
);
1267 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleWindow
, (void**)&lpOle
);
1271 hRet
= IUnknown_QueryInterface(lpUnknown
,&IID_IShellView
, (void**)&lpOle
);
1275 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IInternetSecurityMgrSite
,
1280 if (SUCCEEDED(hRet
))
1282 /* Laziness here - Since GetWindow() is the first method for the above 3
1283 * interfaces, we use the same call for them all.
1285 hRet
= IOleWindow_GetWindow((IOleWindow
*)lpOle
, lphWnd
);
1286 IUnknown_Release(lpOle
);
1288 TRACE("Returning HWND=%p\n", *lphWnd
);
1294 /*************************************************************************
1297 * Call a SetOwner method of IShellService from specified object.
1300 * iface [I] Object that supports IShellService
1301 * pUnk [I] Argument for the SetOwner call
1304 * Corresponding return value from last call or E_FAIL for null input
1306 HRESULT WINAPI
IUnknown_SetOwner(IUnknown
*iface
, IUnknown
*pUnk
)
1308 IShellService
*service
;
1311 TRACE("(%p, %p)\n", iface
, pUnk
);
1313 if (!iface
) return E_FAIL
;
1315 hr
= IUnknown_QueryInterface(iface
, &IID_IShellService
, (void**)&service
);
1318 hr
= IShellService_SetOwner(service
, pUnk
);
1319 IShellService_Release(service
);
1325 /*************************************************************************
1328 * Call either IObjectWithSite_SetSite() or IInternetSecurityManager_SetSecuritySite() on
1332 HRESULT WINAPI
IUnknown_SetSite(
1333 IUnknown
*obj
, /* [in] OLE object */
1334 IUnknown
*site
) /* [in] Site interface */
1337 IObjectWithSite
*iobjwithsite
;
1338 IInternetSecurityManager
*isecmgr
;
1340 if (!obj
) return E_FAIL
;
1342 hr
= IUnknown_QueryInterface(obj
, &IID_IObjectWithSite
, (LPVOID
*)&iobjwithsite
);
1343 TRACE("IID_IObjectWithSite QI ret=%08x, %p\n", hr
, iobjwithsite
);
1346 hr
= IObjectWithSite_SetSite(iobjwithsite
, site
);
1347 TRACE("done IObjectWithSite_SetSite ret=%08x\n", hr
);
1348 IObjectWithSite_Release(iobjwithsite
);
1352 hr
= IUnknown_QueryInterface(obj
, &IID_IInternetSecurityManager
, (LPVOID
*)&isecmgr
);
1353 TRACE("IID_IInternetSecurityManager QI ret=%08x, %p\n", hr
, isecmgr
);
1354 if (FAILED(hr
)) return hr
;
1356 hr
= IInternetSecurityManager_SetSecuritySite(isecmgr
, (IInternetSecurityMgrSite
*)site
);
1357 TRACE("done IInternetSecurityManager_SetSecuritySite ret=%08x\n", hr
);
1358 IInternetSecurityManager_Release(isecmgr
);
1363 /*************************************************************************
1366 * Call IPersist_GetClassID() on an object.
1369 * lpUnknown [I] Object supporting the IPersist interface
1370 * clsid [O] Destination for Class Id
1373 * Success: S_OK. lpClassId contains the Class Id requested.
1374 * Failure: E_FAIL, If lpUnknown is NULL,
1375 * E_NOINTERFACE If lpUnknown does not support IPersist,
1376 * Or an HRESULT error code.
1378 HRESULT WINAPI
IUnknown_GetClassID(IUnknown
*lpUnknown
, CLSID
*clsid
)
1383 TRACE("(%p, %p)\n", lpUnknown
, clsid
);
1387 memset(clsid
, 0, sizeof(*clsid
));
1391 hr
= IUnknown_QueryInterface(lpUnknown
, &IID_IPersist
, (void**)&persist
);
1394 hr
= IUnknown_QueryInterface(lpUnknown
, &IID_IPersistFolder
, (void**)&persist
);
1399 hr
= IPersist_GetClassID(persist
, clsid
);
1400 IPersist_Release(persist
);
1404 /*************************************************************************
1407 * Retrieve a Service Interface from an object.
1410 * lpUnknown [I] Object to get an IServiceProvider interface from
1411 * sid [I] Service ID for IServiceProvider_QueryService() call
1412 * riid [I] Function requested for QueryService call
1413 * lppOut [O] Destination for the service interface pointer
1416 * Success: S_OK. lppOut contains an object providing the requested service
1417 * Failure: An HRESULT error code
1420 * lpUnknown is expected to support the IServiceProvider interface.
1422 HRESULT WINAPI
IUnknown_QueryService(IUnknown
* lpUnknown
, REFGUID sid
, REFIID riid
,
1425 IServiceProvider
* pService
= NULL
;
1436 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IServiceProvider
,
1437 (LPVOID
*)&pService
);
1439 if (hRet
== S_OK
&& pService
)
1441 TRACE("QueryInterface returned (IServiceProvider*)%p\n", pService
);
1443 /* Get a Service interface from the object */
1444 hRet
= IServiceProvider_QueryService(pService
, sid
, riid
, lppOut
);
1446 TRACE("(IServiceProvider*)%p returned (IUnknown*)%p\n", pService
, *lppOut
);
1448 IServiceProvider_Release(pService
);
1453 /*************************************************************************
1456 * Calls IOleCommandTarget::Exec() for specified service object.
1459 * lpUnknown [I] Object to get an IServiceProvider interface from
1460 * service [I] Service ID for IServiceProvider_QueryService() call
1461 * group [I] Group ID for IOleCommandTarget::Exec() call
1462 * cmdId [I] Command ID for IOleCommandTarget::Exec() call
1463 * cmdOpt [I] Options flags for command
1464 * pIn [I] Input arguments for command
1465 * pOut [O] Output arguments for command
1468 * Success: S_OK. lppOut contains an object providing the requested service
1469 * Failure: An HRESULT error code
1472 * lpUnknown is expected to support the IServiceProvider interface.
1474 HRESULT WINAPI
IUnknown_QueryServiceExec(IUnknown
*lpUnknown
, REFIID service
,
1475 const GUID
*group
, DWORD cmdId
, DWORD cmdOpt
, VARIANT
*pIn
, VARIANT
*pOut
)
1477 IOleCommandTarget
*target
;
1480 TRACE("%p %s %s %d %08x %p %p\n", lpUnknown
, debugstr_guid(service
),
1481 debugstr_guid(group
), cmdId
, cmdOpt
, pIn
, pOut
);
1483 hr
= IUnknown_QueryService(lpUnknown
, service
, &IID_IOleCommandTarget
, (void**)&target
);
1486 hr
= IOleCommandTarget_Exec(target
, group
, cmdId
, cmdOpt
, pIn
, pOut
);
1487 IOleCommandTarget_Release(target
);
1490 TRACE("<-- hr=0x%08x\n", hr
);
1495 /*************************************************************************
1498 * Calls IProfferService methods to proffer/revoke specified service.
1501 * lpUnknown [I] Object to get an IServiceProvider interface from
1502 * service [I] Service ID for IProfferService::Proffer/Revoke calls
1503 * pService [I] Service to proffer. If NULL ::Revoke is called
1504 * pCookie [IO] Group ID for IOleCommandTarget::Exec() call
1507 * Success: S_OK. IProffer method returns S_OK
1508 * Failure: An HRESULT error code
1511 * lpUnknown is expected to support the IServiceProvider interface.
1513 HRESULT WINAPI
IUnknown_ProfferService(IUnknown
*lpUnknown
, REFGUID service
, IServiceProvider
*pService
, DWORD
*pCookie
)
1515 IProfferService
*proffer
;
1518 TRACE("%p %s %p %p\n", lpUnknown
, debugstr_guid(service
), pService
, pCookie
);
1520 hr
= IUnknown_QueryService(lpUnknown
, &IID_IProfferService
, &IID_IProfferService
, (void**)&proffer
);
1524 hr
= IProfferService_ProfferService(proffer
, service
, pService
, pCookie
);
1527 hr
= IProfferService_RevokeService(proffer
, *pCookie
);
1531 IProfferService_Release(proffer
);
1537 /*************************************************************************
1540 * Call an object's UIActivateIO method.
1543 * unknown [I] Object to call the UIActivateIO method on
1544 * activate [I] Parameter for UIActivateIO call
1545 * msg [I] Parameter for UIActivateIO call
1548 * Success: Value of UI_ActivateIO call
1549 * Failure: An HRESULT error code
1552 * unknown is expected to support the IInputObject interface.
1554 HRESULT WINAPI
IUnknown_UIActivateIO(IUnknown
*unknown
, BOOL activate
, LPMSG msg
)
1556 IInputObject
* object
= NULL
;
1562 /* Get an IInputObject interface from the object */
1563 ret
= IUnknown_QueryInterface(unknown
, &IID_IInputObject
, (LPVOID
*) &object
);
1567 ret
= IInputObject_UIActivateIO(object
, activate
, msg
);
1568 IInputObject_Release(object
);
1574 /*************************************************************************
1577 * Loads a popup menu.
1580 * hInst [I] Instance handle
1581 * szName [I] Menu name
1587 BOOL WINAPI
SHLoadMenuPopup(HINSTANCE hInst
, LPCWSTR szName
)
1591 TRACE("%p %s\n", hInst
, debugstr_w(szName
));
1593 if ((hMenu
= LoadMenuW(hInst
, szName
)))
1595 if (GetSubMenu(hMenu
, 0))
1596 RemoveMenu(hMenu
, 0, MF_BYPOSITION
);
1604 typedef struct _enumWndData
1609 LRESULT (WINAPI
*pfnPost
)(HWND
,UINT
,WPARAM
,LPARAM
);
1612 /* Callback for SHLWAPI_178 */
1613 static BOOL CALLBACK
SHLWAPI_EnumChildProc(HWND hWnd
, LPARAM lParam
)
1615 enumWndData
*data
= (enumWndData
*)lParam
;
1617 TRACE("(%p,%p)\n", hWnd
, data
);
1618 data
->pfnPost(hWnd
, data
->uiMsgId
, data
->wParam
, data
->lParam
);
1622 /*************************************************************************
1625 * Send or post a message to every child of a window.
1628 * hWnd [I] Window whose children will get the messages
1629 * uiMsgId [I] Message Id
1630 * wParam [I] WPARAM of message
1631 * lParam [I] LPARAM of message
1632 * bSend [I] TRUE = Use SendMessageA(), FALSE = Use PostMessageA()
1638 * The appropriate ASCII or Unicode function is called for the window.
1640 void WINAPI
SHPropagateMessage(HWND hWnd
, UINT uiMsgId
, WPARAM wParam
, LPARAM lParam
, BOOL bSend
)
1644 TRACE("(%p,%u,%ld,%ld,%d)\n", hWnd
, uiMsgId
, wParam
, lParam
, bSend
);
1648 data
.uiMsgId
= uiMsgId
;
1649 data
.wParam
= wParam
;
1650 data
.lParam
= lParam
;
1653 data
.pfnPost
= IsWindowUnicode(hWnd
) ? (void*)SendMessageW
: (void*)SendMessageA
;
1655 data
.pfnPost
= IsWindowUnicode(hWnd
) ? (void*)PostMessageW
: (void*)PostMessageA
;
1657 EnumChildWindows(hWnd
, SHLWAPI_EnumChildProc
, (LPARAM
)&data
);
1661 /*************************************************************************
1664 * Remove all sub-menus from a menu.
1667 * hMenu [I] Menu to remove sub-menus from
1670 * Success: 0. All sub-menus under hMenu are removed
1671 * Failure: -1, if any parameter is invalid
1673 DWORD WINAPI
SHRemoveAllSubMenus(HMENU hMenu
)
1675 int iItemCount
= GetMenuItemCount(hMenu
) - 1;
1677 TRACE("%p\n", hMenu
);
1679 while (iItemCount
>= 0)
1681 HMENU hSubMenu
= GetSubMenu(hMenu
, iItemCount
);
1683 RemoveMenu(hMenu
, iItemCount
, MF_BYPOSITION
);
1689 /*************************************************************************
1692 * Enable or disable a menu item.
1695 * hMenu [I] Menu holding menu item
1696 * uID [I] ID of menu item to enable/disable
1697 * bEnable [I] Whether to enable (TRUE) or disable (FALSE) the item.
1700 * The return code from EnableMenuItem.
1702 UINT WINAPI
SHEnableMenuItem(HMENU hMenu
, UINT wItemID
, BOOL bEnable
)
1704 TRACE("%p, %u, %d\n", hMenu
, wItemID
, bEnable
);
1705 return EnableMenuItem(hMenu
, wItemID
, bEnable
? MF_ENABLED
: MF_GRAYED
);
1708 /*************************************************************************
1711 * Check or uncheck a menu item.
1714 * hMenu [I] Menu holding menu item
1715 * uID [I] ID of menu item to check/uncheck
1716 * bCheck [I] Whether to check (TRUE) or uncheck (FALSE) the item.
1719 * The return code from CheckMenuItem.
1721 DWORD WINAPI
SHCheckMenuItem(HMENU hMenu
, UINT uID
, BOOL bCheck
)
1723 TRACE("%p, %u, %d\n", hMenu
, uID
, bCheck
);
1724 return CheckMenuItem(hMenu
, uID
, bCheck
? MF_CHECKED
: MF_UNCHECKED
);
1727 /*************************************************************************
1730 * Register a window class if it isn't already.
1733 * lpWndClass [I] Window class to register
1736 * The result of the RegisterClassA call.
1738 DWORD WINAPI
SHRegisterClassA(WNDCLASSA
*wndclass
)
1741 if (GetClassInfoA(wndclass
->hInstance
, wndclass
->lpszClassName
, &wca
))
1743 return (DWORD
)RegisterClassA(wndclass
);
1746 /*************************************************************************
1749 BOOL WINAPI
SHSimulateDrop(IDropTarget
*pDrop
, IDataObject
*pDataObj
,
1750 DWORD grfKeyState
, PPOINTL lpPt
, DWORD
* pdwEffect
)
1752 DWORD dwEffect
= DROPEFFECT_LINK
| DROPEFFECT_MOVE
| DROPEFFECT_COPY
;
1753 POINTL pt
= { 0, 0 };
1755 TRACE("%p %p 0x%08x %p %p\n", pDrop
, pDataObj
, grfKeyState
, lpPt
, pdwEffect
);
1761 pdwEffect
= &dwEffect
;
1763 IDropTarget_DragEnter(pDrop
, pDataObj
, grfKeyState
, *lpPt
, pdwEffect
);
1765 if (*pdwEffect
!= DROPEFFECT_NONE
)
1766 return IDropTarget_Drop(pDrop
, pDataObj
, grfKeyState
, *lpPt
, pdwEffect
);
1768 IDropTarget_DragLeave(pDrop
);
1772 /*************************************************************************
1775 * Call IPersistPropertyBag_Load() on an object.
1778 * lpUnknown [I] Object supporting the IPersistPropertyBag interface
1779 * lpPropBag [O] Destination for loaded IPropertyBag
1783 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1785 DWORD WINAPI
SHLoadFromPropertyBag(IUnknown
*lpUnknown
, IPropertyBag
* lpPropBag
)
1787 IPersistPropertyBag
* lpPPBag
;
1788 HRESULT hRet
= E_FAIL
;
1790 TRACE("(%p,%p)\n", lpUnknown
, lpPropBag
);
1794 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IPersistPropertyBag
,
1796 if (SUCCEEDED(hRet
) && lpPPBag
)
1798 hRet
= IPersistPropertyBag_Load(lpPPBag
, lpPropBag
, NULL
);
1799 IPersistPropertyBag_Release(lpPPBag
);
1805 /*************************************************************************
1808 * Call IOleControlSite_TranslateAccelerator() on an object.
1811 * lpUnknown [I] Object supporting the IOleControlSite interface.
1812 * lpMsg [I] Key message to be processed.
1813 * dwModifiers [I] Flags containing the state of the modifier keys.
1817 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
1819 HRESULT WINAPI
IUnknown_TranslateAcceleratorOCS(IUnknown
*lpUnknown
, LPMSG lpMsg
, DWORD dwModifiers
)
1821 IOleControlSite
* lpCSite
= NULL
;
1822 HRESULT hRet
= E_INVALIDARG
;
1824 TRACE("(%p,%p,0x%08x)\n", lpUnknown
, lpMsg
, dwModifiers
);
1827 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleControlSite
,
1829 if (SUCCEEDED(hRet
) && lpCSite
)
1831 hRet
= IOleControlSite_TranslateAccelerator(lpCSite
, lpMsg
, dwModifiers
);
1832 IOleControlSite_Release(lpCSite
);
1839 /*************************************************************************
1842 * Call IOleControlSite_OnFocus() on an object.
1845 * lpUnknown [I] Object supporting the IOleControlSite interface.
1846 * fGotFocus [I] Whether focus was gained (TRUE) or lost (FALSE).
1850 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1852 HRESULT WINAPI
IUnknown_OnFocusOCS(IUnknown
*lpUnknown
, BOOL fGotFocus
)
1854 IOleControlSite
* lpCSite
= NULL
;
1855 HRESULT hRet
= E_FAIL
;
1857 TRACE("(%p, %d)\n", lpUnknown
, fGotFocus
);
1860 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleControlSite
,
1862 if (SUCCEEDED(hRet
) && lpCSite
)
1864 hRet
= IOleControlSite_OnFocus(lpCSite
, fGotFocus
);
1865 IOleControlSite_Release(lpCSite
);
1871 /*************************************************************************
1874 HRESULT WINAPI
IUnknown_HandleIRestrict(LPUNKNOWN lpUnknown
, PVOID lpArg1
,
1875 PVOID lpArg2
, PVOID lpArg3
, PVOID lpArg4
)
1877 /* FIXME: {D12F26B2-D90A-11D0-830D-00AA005B4383} - What object does this represent? */
1878 static const DWORD service_id
[] = { 0xd12f26b2, 0x11d0d90a, 0xaa000d83, 0x83435b00 };
1879 /* FIXME: {D12F26B1-D90A-11D0-830D-00AA005B4383} - Also Unknown/undocumented */
1880 static const DWORD function_id
[] = { 0xd12f26b1, 0x11d0d90a, 0xaa000d83, 0x83435b00 };
1881 HRESULT hRet
= E_INVALIDARG
;
1882 LPUNKNOWN lpUnkInner
= NULL
; /* FIXME: Real type is unknown */
1884 TRACE("(%p,%p,%p,%p,%p)\n", lpUnknown
, lpArg1
, lpArg2
, lpArg3
, lpArg4
);
1886 if (lpUnknown
&& lpArg4
)
1888 hRet
= IUnknown_QueryService(lpUnknown
, (REFGUID
)service_id
,
1889 (REFGUID
)function_id
, (void**)&lpUnkInner
);
1891 if (SUCCEEDED(hRet
) && lpUnkInner
)
1893 /* FIXME: The type of service object requested is unknown, however
1894 * testing shows that its first method is called with 4 parameters.
1895 * Fake this by using IParseDisplayName_ParseDisplayName since the
1896 * signature and position in the vtable matches our unknown object type.
1898 hRet
= IParseDisplayName_ParseDisplayName((LPPARSEDISPLAYNAME
)lpUnkInner
,
1899 lpArg1
, lpArg2
, lpArg3
, lpArg4
);
1900 IUnknown_Release(lpUnkInner
);
1906 /*************************************************************************
1909 * Get a sub-menu from a menu item.
1912 * hMenu [I] Menu to get sub-menu from
1913 * uID [I] ID of menu item containing sub-menu
1916 * The sub-menu of the item, or a NULL handle if any parameters are invalid.
1918 HMENU WINAPI
SHGetMenuFromID(HMENU hMenu
, UINT uID
)
1922 TRACE("(%p,%u)\n", hMenu
, uID
);
1924 mi
.cbSize
= sizeof(mi
);
1925 mi
.fMask
= MIIM_SUBMENU
;
1927 if (!GetMenuItemInfoW(hMenu
, uID
, FALSE
, &mi
))
1933 /*************************************************************************
1936 * Get the color depth of the primary display.
1942 * The color depth of the primary display.
1944 DWORD WINAPI
SHGetCurColorRes(void)
1952 ret
= GetDeviceCaps(hdc
, BITSPIXEL
) * GetDeviceCaps(hdc
, PLANES
);
1957 /*************************************************************************
1960 * Wait for a message to arrive, with a timeout.
1963 * hand [I] Handle to query
1964 * dwTimeout [I] Timeout in ticks or INFINITE to never timeout
1967 * STATUS_TIMEOUT if no message is received before dwTimeout ticks passes.
1968 * Otherwise returns the value from MsgWaitForMultipleObjectsEx when a
1969 * message is available.
1971 DWORD WINAPI
SHWaitForSendMessageThread(HANDLE hand
, DWORD dwTimeout
)
1973 DWORD dwEndTicks
= GetTickCount() + dwTimeout
;
1976 while ((dwRet
= MsgWaitForMultipleObjectsEx(1, &hand
, dwTimeout
, QS_SENDMESSAGE
, 0)) == 1)
1980 PeekMessageW(&msg
, NULL
, 0, 0, PM_NOREMOVE
);
1982 if (dwTimeout
!= INFINITE
)
1984 if ((int)(dwTimeout
= dwEndTicks
- GetTickCount()) <= 0)
1985 return WAIT_TIMEOUT
;
1992 /*************************************************************************
1995 * Determine if a shell folder can be expanded.
1998 * lpFolder [I] Parent folder containing the object to test.
1999 * pidl [I] Id of the object to test.
2002 * Success: S_OK, if the object is expandable, S_FALSE otherwise.
2003 * Failure: E_INVALIDARG, if any argument is invalid.
2006 * If the object to be tested does not expose the IQueryInfo() interface it
2007 * will not be identified as an expandable folder.
2009 HRESULT WINAPI
SHIsExpandableFolder(LPSHELLFOLDER lpFolder
, LPCITEMIDLIST pidl
)
2011 HRESULT hRet
= E_INVALIDARG
;
2014 if (lpFolder
&& pidl
)
2016 hRet
= IShellFolder_GetUIObjectOf(lpFolder
, NULL
, 1, &pidl
, &IID_IQueryInfo
,
2017 NULL
, (void**)&lpInfo
);
2019 hRet
= S_FALSE
; /* Doesn't expose IQueryInfo */
2024 /* MSDN states of IQueryInfo_GetInfoFlags() that "This method is not
2025 * currently used". Really? You wouldn't be holding out on me would you?
2027 hRet
= IQueryInfo_GetInfoFlags(lpInfo
, &dwFlags
);
2029 if (SUCCEEDED(hRet
))
2031 /* 0x2 is an undocumented flag apparently indicating expandability */
2032 hRet
= dwFlags
& 0x2 ? S_OK
: S_FALSE
;
2035 IQueryInfo_Release(lpInfo
);
2041 /*************************************************************************
2044 * Blank out a region of text by drawing the background only.
2047 * hDC [I] Device context to draw in
2048 * pRect [I] Area to draw in
2049 * cRef [I] Color to draw in
2054 DWORD WINAPI
SHFillRectClr(HDC hDC
, LPCRECT pRect
, COLORREF cRef
)
2056 COLORREF cOldColor
= SetBkColor(hDC
, cRef
);
2057 ExtTextOutA(hDC
, 0, 0, ETO_OPAQUE
, pRect
, 0, 0, 0);
2058 SetBkColor(hDC
, cOldColor
);
2062 /*************************************************************************
2065 * Return the value associated with a key in a map.
2068 * lpKeys [I] A list of keys of length iLen
2069 * lpValues [I] A list of values associated with lpKeys, of length iLen
2070 * iLen [I] Length of both lpKeys and lpValues
2071 * iKey [I] The key value to look up in lpKeys
2074 * The value in lpValues associated with iKey, or -1 if iKey is not
2078 * - If two elements in the map share the same key, this function returns
2079 * the value closest to the start of the map
2080 * - The native version of this function crashes if lpKeys or lpValues is NULL.
2082 int WINAPI
SHSearchMapInt(const int *lpKeys
, const int *lpValues
, int iLen
, int iKey
)
2084 if (lpKeys
&& lpValues
)
2090 if (lpKeys
[i
] == iKey
)
2091 return lpValues
[i
]; /* Found */
2095 return -1; /* Not found */
2099 /*************************************************************************
2102 * Copy an interface pointer
2105 * lppDest [O] Destination for copy
2106 * lpUnknown [I] Source for copy
2111 VOID WINAPI
IUnknown_Set(IUnknown
**lppDest
, IUnknown
*lpUnknown
)
2113 TRACE("(%p,%p)\n", lppDest
, lpUnknown
);
2115 IUnknown_AtomicRelease(lppDest
);
2119 IUnknown_AddRef(lpUnknown
);
2120 *lppDest
= lpUnknown
;
2124 /*************************************************************************
2128 HRESULT WINAPI
MayQSForward(IUnknown
* lpUnknown
, PVOID lpReserved
,
2129 REFGUID riidCmdGrp
, ULONG cCmds
,
2130 OLECMD
*prgCmds
, OLECMDTEXT
* pCmdText
)
2132 FIXME("(%p,%p,%p,%d,%p,%p) - stub\n",
2133 lpUnknown
, lpReserved
, riidCmdGrp
, cCmds
, prgCmds
, pCmdText
);
2135 /* FIXME: Calls IsQSForward & IUnknown_QueryStatus */
2136 return DRAGDROP_E_NOTREGISTERED
;
2139 /*************************************************************************
2143 HRESULT WINAPI
MayExecForward(IUnknown
* lpUnknown
, INT iUnk
, REFGUID pguidCmdGroup
,
2144 DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
* pvaIn
,
2147 FIXME("(%p,%d,%p,%d,%d,%p,%p) - stub!\n", lpUnknown
, iUnk
, pguidCmdGroup
,
2148 nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2149 return DRAGDROP_E_NOTREGISTERED
;
2152 /*************************************************************************
2156 HRESULT WINAPI
IsQSForward(REFGUID pguidCmdGroup
,ULONG cCmds
, OLECMD
*prgCmds
)
2158 FIXME("(%p,%d,%p) - stub!\n", pguidCmdGroup
, cCmds
, prgCmds
);
2159 return DRAGDROP_E_NOTREGISTERED
;
2162 /*************************************************************************
2165 * Determine if a window is not a child of another window.
2168 * hParent [I] Suspected parent window
2169 * hChild [I] Suspected child window
2172 * TRUE: If hChild is a child window of hParent
2173 * FALSE: If hChild is not a child window of hParent, or they are equal
2175 BOOL WINAPI
SHIsChildOrSelf(HWND hParent
, HWND hChild
)
2177 TRACE("(%p,%p)\n", hParent
, hChild
);
2179 if (!hParent
|| !hChild
)
2181 else if(hParent
== hChild
)
2183 return !IsChild(hParent
, hChild
);
2186 /*************************************************************************
2187 * FDSA functions. Manage a dynamic array of fixed size memory blocks.
2192 DWORD num_items
; /* Number of elements inserted */
2193 void *mem
; /* Ptr to array */
2194 DWORD blocks_alloced
; /* Number of elements allocated */
2195 BYTE inc
; /* Number of elements to grow by when we need to expand */
2196 BYTE block_size
; /* Size in bytes of an element */
2197 BYTE flags
; /* Flags */
2200 #define FDSA_FLAG_INTERNAL_ALLOC 0x01 /* When set we have allocated mem internally */
2202 /*************************************************************************
2205 * Initialize an FDSA array.
2207 BOOL WINAPI
FDSA_Initialize(DWORD block_size
, DWORD inc
, FDSA_info
*info
, void *mem
,
2210 TRACE("(0x%08x 0x%08x %p %p 0x%08x)\n", block_size
, inc
, info
, mem
, init_blocks
);
2216 memset(mem
, 0, block_size
* init_blocks
);
2218 info
->num_items
= 0;
2221 info
->blocks_alloced
= init_blocks
;
2222 info
->block_size
= block_size
;
2228 /*************************************************************************
2231 * Destroy an FDSA array
2233 BOOL WINAPI
FDSA_Destroy(FDSA_info
*info
)
2235 TRACE("(%p)\n", info
);
2237 if(info
->flags
& FDSA_FLAG_INTERNAL_ALLOC
)
2239 HeapFree(GetProcessHeap(), 0, info
->mem
);
2246 /*************************************************************************
2249 * Insert element into an FDSA array
2251 DWORD WINAPI
FDSA_InsertItem(FDSA_info
*info
, DWORD where
, const void *block
)
2253 TRACE("(%p 0x%08x %p)\n", info
, where
, block
);
2254 if(where
> info
->num_items
)
2255 where
= info
->num_items
;
2257 if(info
->num_items
>= info
->blocks_alloced
)
2259 DWORD size
= (info
->blocks_alloced
+ info
->inc
) * info
->block_size
;
2260 if(info
->flags
& 0x1)
2261 info
->mem
= HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, info
->mem
, size
);
2264 void *old_mem
= info
->mem
;
2265 info
->mem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
2266 memcpy(info
->mem
, old_mem
, info
->blocks_alloced
* info
->block_size
);
2268 info
->blocks_alloced
+= info
->inc
;
2272 if(where
< info
->num_items
)
2274 memmove((char*)info
->mem
+ (where
+ 1) * info
->block_size
,
2275 (char*)info
->mem
+ where
* info
->block_size
,
2276 (info
->num_items
- where
) * info
->block_size
);
2278 memcpy((char*)info
->mem
+ where
* info
->block_size
, block
, info
->block_size
);
2284 /*************************************************************************
2287 * Delete an element from an FDSA array.
2289 BOOL WINAPI
FDSA_DeleteItem(FDSA_info
*info
, DWORD where
)
2291 TRACE("(%p 0x%08x)\n", info
, where
);
2293 if(where
>= info
->num_items
)
2296 if(where
< info
->num_items
- 1)
2298 memmove((char*)info
->mem
+ where
* info
->block_size
,
2299 (char*)info
->mem
+ (where
+ 1) * info
->block_size
,
2300 (info
->num_items
- where
- 1) * info
->block_size
);
2302 memset((char*)info
->mem
+ (info
->num_items
- 1) * info
->block_size
,
2303 0, info
->block_size
);
2308 /*************************************************************************
2311 * Call IUnknown_QueryInterface() on a table of objects.
2315 * Failure: E_POINTER or E_NOINTERFACE.
2317 HRESULT WINAPI
QISearch(
2318 void *base
, /* [in] Table of interfaces */
2319 const QITAB
*table
, /* [in] Array of REFIIDs and indexes into the table */
2320 REFIID riid
, /* [in] REFIID to get interface for */
2321 void **ppv
) /* [out] Destination for interface pointer */
2327 TRACE("(%p %p %s %p)\n", base
, table
, debugstr_guid(riid
), ppv
);
2330 while (xmove
->piid
) {
2331 TRACE("trying (offset %d) %s\n", xmove
->dwOffset
, debugstr_guid(xmove
->piid
));
2332 if (IsEqualIID(riid
, xmove
->piid
)) {
2333 a_vtbl
= (IUnknown
*)(xmove
->dwOffset
+ (LPBYTE
)base
);
2334 TRACE("matched, returning (%p)\n", a_vtbl
);
2336 IUnknown_AddRef(a_vtbl
);
2342 if (IsEqualIID(riid
, &IID_IUnknown
)) {
2343 a_vtbl
= (IUnknown
*)(table
->dwOffset
+ (LPBYTE
)base
);
2344 TRACE("returning first for IUnknown (%p)\n", a_vtbl
);
2346 IUnknown_AddRef(a_vtbl
);
2350 ret
= E_NOINTERFACE
;
2354 TRACE("-- 0x%08x\n", ret
);
2358 /*************************************************************************
2361 * Set the Font for a window and the "PropDlgFont" property of the parent window.
2364 * hWnd [I] Parent Window to set the property
2365 * id [I] Index of child Window to set the Font
2371 HRESULT WINAPI
SHSetDefaultDialogFont(HWND hWnd
, INT id
)
2373 FIXME("(%p, %d) stub\n", hWnd
, id
);
2377 /*************************************************************************
2380 * Remove the "PropDlgFont" property from a window.
2383 * hWnd [I] Window to remove the property from
2386 * A handle to the removed property, or NULL if it did not exist.
2388 HANDLE WINAPI
SHRemoveDefaultDialogFont(HWND hWnd
)
2392 TRACE("(%p)\n", hWnd
);
2394 hProp
= GetPropA(hWnd
, "PropDlgFont");
2398 DeleteObject(hProp
);
2399 hProp
= RemovePropA(hWnd
, "PropDlgFont");
2404 /*************************************************************************
2407 * Load the in-process server of a given GUID.
2410 * refiid [I] GUID of the server to load.
2413 * Success: A handle to the loaded server dll.
2414 * Failure: A NULL handle.
2416 HMODULE WINAPI
SHPinDllOfCLSID(REFIID refiid
)
2420 CHAR value
[MAX_PATH
], string
[MAX_PATH
];
2422 strcpy(string
, "CLSID\\");
2423 SHStringFromGUIDA(refiid
, string
+ 6, sizeof(string
)/sizeof(char) - 6);
2424 strcat(string
, "\\InProcServer32");
2427 RegOpenKeyExA(HKEY_CLASSES_ROOT
, string
, 0, 1, &newkey
);
2428 RegQueryValueExA(newkey
, 0, 0, &type
, (PBYTE
)value
, &count
);
2429 RegCloseKey(newkey
);
2430 return LoadLibraryExA(value
, 0, 0);
2433 /*************************************************************************
2436 * Unicode version of SHLWAPI_183.
2438 DWORD WINAPI
SHRegisterClassW(WNDCLASSW
* lpWndClass
)
2442 TRACE("(%p %s)\n",lpWndClass
->hInstance
, debugstr_w(lpWndClass
->lpszClassName
));
2444 if (GetClassInfoW(lpWndClass
->hInstance
, lpWndClass
->lpszClassName
, &WndClass
))
2446 return RegisterClassW(lpWndClass
);
2449 /*************************************************************************
2452 * Unregister a list of classes.
2455 * hInst [I] Application instance that registered the classes
2456 * lppClasses [I] List of class names
2457 * iCount [I] Number of names in lppClasses
2462 void WINAPI
SHUnregisterClassesA(HINSTANCE hInst
, LPCSTR
*lppClasses
, INT iCount
)
2466 TRACE("(%p,%p,%d)\n", hInst
, lppClasses
, iCount
);
2470 if (GetClassInfoA(hInst
, *lppClasses
, &WndClass
))
2471 UnregisterClassA(*lppClasses
, hInst
);
2477 /*************************************************************************
2480 * Unicode version of SHUnregisterClassesA.
2482 void WINAPI
SHUnregisterClassesW(HINSTANCE hInst
, LPCWSTR
*lppClasses
, INT iCount
)
2486 TRACE("(%p,%p,%d)\n", hInst
, lppClasses
, iCount
);
2490 if (GetClassInfoW(hInst
, *lppClasses
, &WndClass
))
2491 UnregisterClassW(*lppClasses
, hInst
);
2497 /*************************************************************************
2500 * Call The correct (Ascii/Unicode) default window procedure for a window.
2503 * hWnd [I] Window to call the default procedure for
2504 * uMessage [I] Message ID
2505 * wParam [I] WPARAM of message
2506 * lParam [I] LPARAM of message
2509 * The result of calling DefWindowProcA() or DefWindowProcW().
2511 LRESULT CALLBACK
SHDefWindowProc(HWND hWnd
, UINT uMessage
, WPARAM wParam
, LPARAM lParam
)
2513 if (IsWindowUnicode(hWnd
))
2514 return DefWindowProcW(hWnd
, uMessage
, wParam
, lParam
);
2515 return DefWindowProcA(hWnd
, uMessage
, wParam
, lParam
);
2518 /*************************************************************************
2521 HRESULT WINAPI
IUnknown_GetSite(LPUNKNOWN lpUnknown
, REFIID iid
, PVOID
*lppSite
)
2523 HRESULT hRet
= E_INVALIDARG
;
2524 LPOBJECTWITHSITE lpSite
= NULL
;
2526 TRACE("(%p,%s,%p)\n", lpUnknown
, debugstr_guid(iid
), lppSite
);
2528 if (lpUnknown
&& iid
&& lppSite
)
2530 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IObjectWithSite
,
2532 if (SUCCEEDED(hRet
) && lpSite
)
2534 hRet
= IObjectWithSite_GetSite(lpSite
, iid
, lppSite
);
2535 IObjectWithSite_Release(lpSite
);
2541 /*************************************************************************
2544 * Create a worker window using CreateWindowExA().
2547 * wndProc [I] Window procedure
2548 * hWndParent [I] Parent window
2549 * dwExStyle [I] Extra style flags
2550 * dwStyle [I] Style flags
2551 * hMenu [I] Window menu
2552 * wnd_extra [I] Window extra bytes value
2555 * Success: The window handle of the newly created window.
2559 HWND WINAPI
SHCreateWorkerWindowA(LONG wndProc
, HWND hWndParent
, DWORD dwExStyle
,
2560 DWORD dwStyle
, HMENU hMenu
, LONG_PTR wnd_extra
)
2562 HWND WINAPI
SHCreateWorkerWindowA(WNDPROC wndProc
, HWND hWndParent
, DWORD dwExStyle
,
2563 DWORD dwStyle
, HMENU hMenu
, LONG_PTR wnd_extra
)
2566 static const char szClass
[] = "WorkerA";
2570 TRACE("(0x%08x, %p, 0x%08x, 0x%08x, %p, 0x%08lx)\n",
2571 wndProc
, hWndParent
, dwExStyle
, dwStyle
, hMenu
, wnd_extra
);
2573 /* Create Window class */
2575 wc
.lpfnWndProc
= DefWindowProcA
;
2577 wc
.cbWndExtra
= sizeof(LONG_PTR
);
2578 wc
.hInstance
= shlwapi_hInstance
;
2580 wc
.hCursor
= LoadCursorA(NULL
, (LPSTR
)IDC_ARROW
);
2581 wc
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
2582 wc
.lpszMenuName
= NULL
;
2583 wc
.lpszClassName
= szClass
;
2585 SHRegisterClassA(&wc
);
2587 hWnd
= CreateWindowExA(dwExStyle
, szClass
, 0, dwStyle
, 0, 0, 0, 0,
2588 hWndParent
, hMenu
, shlwapi_hInstance
, 0);
2591 SetWindowLongPtrW(hWnd
, 0, wnd_extra
);
2594 if (wndProc
) SetWindowLongPtrA(hWnd
, GWLP_WNDPROC
, wndProc
);
2596 if (wndProc
) SetWindowLongPtrA(hWnd
, GWLP_WNDPROC
, (LONG_PTR
)wndProc
);
2603 typedef struct tagPOLICYDATA
2605 DWORD policy
; /* flags value passed to SHRestricted */
2606 LPCWSTR appstr
; /* application str such as "Explorer" */
2607 LPCWSTR keystr
; /* name of the actual registry key / policy */
2608 } POLICYDATA
, *LPPOLICYDATA
;
2610 #define SHELL_NO_POLICY 0xffffffff
2612 /* default shell policy registry key */
2613 static const WCHAR strRegistryPolicyW
[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o',
2614 's','o','f','t','\\','W','i','n','d','o','w','s','\\',
2615 'C','u','r','r','e','n','t','V','e','r','s','i','o','n',
2616 '\\','P','o','l','i','c','i','e','s',0};
2618 /*************************************************************************
2621 * Retrieve a policy value from the registry.
2624 * lpSubKey [I] registry key name
2625 * lpSubName [I] subname of registry key
2626 * lpValue [I] value name of registry value
2629 * the value associated with the registry key or 0 if not found
2631 DWORD WINAPI
SHGetRestriction(LPCWSTR lpSubKey
, LPCWSTR lpSubName
, LPCWSTR lpValue
)
2633 DWORD retval
, datsize
= sizeof(retval
);
2637 lpSubKey
= strRegistryPolicyW
;
2639 retval
= RegOpenKeyW(HKEY_LOCAL_MACHINE
, lpSubKey
, &hKey
);
2640 if (retval
!= ERROR_SUCCESS
)
2641 retval
= RegOpenKeyW(HKEY_CURRENT_USER
, lpSubKey
, &hKey
);
2642 if (retval
!= ERROR_SUCCESS
)
2645 SHGetValueW(hKey
, lpSubName
, lpValue
, NULL
, &retval
, &datsize
);
2650 /*************************************************************************
2653 * Helper function to retrieve the possibly cached value for a specific policy
2656 * policy [I] The policy to look for
2657 * initial [I] Main registry key to open, if NULL use default
2658 * polTable [I] Table of known policies, 0 terminated
2659 * polArr [I] Cache array of policy values
2662 * The retrieved policy value or 0 if not successful
2665 * This function is used by the native SHRestricted function to search for the
2666 * policy and cache it once retrieved. The current Wine implementation uses a
2667 * different POLICYDATA structure and implements a similar algorithm adapted to
2670 DWORD WINAPI
SHRestrictionLookup(
2673 LPPOLICYDATA polTable
,
2676 TRACE("(0x%08x %s %p %p)\n", policy
, debugstr_w(initial
), polTable
, polArr
);
2678 if (!polTable
|| !polArr
)
2681 for (;polTable
->policy
; polTable
++, polArr
++)
2683 if (policy
== polTable
->policy
)
2685 /* we have a known policy */
2687 /* check if this policy has been cached */
2688 if (*polArr
== SHELL_NO_POLICY
)
2689 *polArr
= SHGetRestriction(initial
, polTable
->appstr
, polTable
->keystr
);
2693 /* we don't know this policy, return 0 */
2694 TRACE("unknown policy: (%08x)\n", policy
);
2698 /*************************************************************************
2701 * Get an interface from an object.
2704 * Success: S_OK. ppv contains the requested interface.
2705 * Failure: An HRESULT error code.
2708 * This QueryInterface asks the inner object for an interface. In case
2709 * of aggregation this request would be forwarded by the inner to the
2710 * outer object. This function asks the inner object directly for the
2711 * interface circumventing the forwarding to the outer object.
2713 HRESULT WINAPI
SHWeakQueryInterface(
2714 IUnknown
* pUnk
, /* [in] Outer object */
2715 IUnknown
* pInner
, /* [in] Inner object */
2716 IID
* riid
, /* [in] Interface GUID to query for */
2717 LPVOID
* ppv
) /* [out] Destination for queried interface */
2719 HRESULT hret
= E_NOINTERFACE
;
2720 TRACE("(pUnk=%p pInner=%p\n\tIID: %s %p)\n",pUnk
,pInner
,debugstr_guid(riid
), ppv
);
2723 if(pUnk
&& pInner
) {
2724 hret
= IUnknown_QueryInterface(pInner
, riid
, ppv
);
2725 if (SUCCEEDED(hret
)) IUnknown_Release(pUnk
);
2727 TRACE("-- 0x%08x\n", hret
);
2731 /*************************************************************************
2734 * Move a reference from one interface to another.
2737 * lpDest [O] Destination to receive the reference
2738 * lppUnknown [O] Source to give up the reference to lpDest
2743 VOID WINAPI
SHWeakReleaseInterface(IUnknown
*lpDest
, IUnknown
**lppUnknown
)
2745 TRACE("(%p,%p)\n", lpDest
, lppUnknown
);
2750 IUnknown_AddRef(lpDest
);
2751 IUnknown_AtomicRelease(lppUnknown
); /* Release existing interface */
2755 /*************************************************************************
2758 * Convert an ASCII string of a CLSID into a CLSID.
2761 * idstr [I] String representing a CLSID in registry format
2762 * id [O] Destination for the converted CLSID
2765 * Success: TRUE. id contains the converted CLSID.
2768 BOOL WINAPI
GUIDFromStringA(LPCSTR idstr
, CLSID
*id
)
2771 MultiByteToWideChar(CP_ACP
, 0, idstr
, -1, wClsid
, sizeof(wClsid
)/sizeof(WCHAR
));
2772 return SUCCEEDED(CLSIDFromString(wClsid
, id
));
2775 /*************************************************************************
2778 * Unicode version of GUIDFromStringA.
2780 BOOL WINAPI
GUIDFromStringW(LPCWSTR idstr
, CLSID
*id
)
2782 return SUCCEEDED(CLSIDFromString((LPCOLESTR
)idstr
, id
));
2785 /*************************************************************************
2788 * Determine if the browser is integrated into the shell, and set a registry
2795 * 1, If the browser is not integrated.
2796 * 2, If the browser is integrated.
2799 * The key "HKLM\Software\Microsoft\Internet Explorer\IntegratedBrowser" is
2800 * either set to TRUE, or removed depending on whether the browser is deemed
2803 DWORD WINAPI
WhichPlatform(void)
2805 static const char szIntegratedBrowser
[] = "IntegratedBrowser";
2806 static DWORD dwState
= 0;
2808 DWORD dwRet
, dwData
, dwSize
;
2814 /* If shell32 exports DllGetVersion(), the browser is integrated */
2816 hshell32
= LoadLibraryA("shell32.dll");
2819 FARPROC pDllGetVersion
;
2820 pDllGetVersion
= GetProcAddress(hshell32
, "DllGetVersion");
2821 dwState
= pDllGetVersion
? 2 : 1;
2822 FreeLibrary(hshell32
);
2825 /* Set or delete the key accordingly */
2826 dwRet
= RegOpenKeyExA(HKEY_LOCAL_MACHINE
,
2827 "Software\\Microsoft\\Internet Explorer", 0,
2828 KEY_ALL_ACCESS
, &hKey
);
2831 dwRet
= RegQueryValueExA(hKey
, szIntegratedBrowser
, 0, 0,
2832 (LPBYTE
)&dwData
, &dwSize
);
2834 if (!dwRet
&& dwState
== 1)
2836 /* Value exists but browser is not integrated */
2837 RegDeleteValueA(hKey
, szIntegratedBrowser
);
2839 else if (dwRet
&& dwState
== 2)
2841 /* Browser is integrated but value does not exist */
2843 RegSetValueExA(hKey
, szIntegratedBrowser
, 0, REG_DWORD
,
2844 (LPBYTE
)&dwData
, sizeof(dwData
));
2851 /*************************************************************************
2854 * Unicode version of SHCreateWorkerWindowA.
2857 HWND WINAPI
SHCreateWorkerWindowW(LONG wndProc
, HWND hWndParent
, DWORD dwExStyle
,
2858 DWORD dwStyle
, HMENU hMenu
, LONG msg_result
)
2860 HWND WINAPI
SHCreateWorkerWindowW(WNDPROC wndProc
, HWND hWndParent
, DWORD dwExStyle
,
2861 DWORD dwStyle
, HMENU hMenu
, LONG_PTR wnd_extra
)
2864 static const WCHAR szClass
[] = { 'W', 'o', 'r', 'k', 'e', 'r', 'W', 0 };
2868 TRACE("(0x%08x, %p, 0x%08x, 0x%08x, %p, 0x%08x)\n",
2870 wndProc
, hWndParent
, dwExStyle
, dwStyle
, hMenu
, msg_result
);
2872 wndProc
, hWndParent
, dwExStyle
, dwStyle
, hMenu
, wnd_extra
);
2875 /* If our OS is natively ANSI, use the ANSI version */
2876 if (GetVersion() & 0x80000000) /* not NT */
2878 TRACE("fallback to ANSI, ver 0x%08x\n", GetVersion());
2880 return SHCreateWorkerWindowA(wndProc
, hWndParent
, dwExStyle
, dwStyle
, hMenu
, msg_result
);
2882 return SHCreateWorkerWindowA(wndProc
, hWndParent
, dwExStyle
, dwStyle
, hMenu
, wnd_extra
);
2886 /* Create Window class */
2888 wc
.lpfnWndProc
= DefWindowProcW
;
2893 wc
.cbWndExtra
= sizeof(LONG_PTR
);
2895 wc
.hInstance
= shlwapi_hInstance
;
2897 wc
.hCursor
= LoadCursorW(NULL
, (LPWSTR
)IDC_ARROW
);
2898 wc
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
2899 wc
.lpszMenuName
= NULL
;
2900 wc
.lpszClassName
= szClass
;
2902 SHRegisterClassW(&wc
);
2904 hWnd
= CreateWindowExW(dwExStyle
, szClass
, 0, dwStyle
, 0, 0, 0, 0,
2905 hWndParent
, hMenu
, shlwapi_hInstance
, 0);
2909 SetWindowLongPtrW(hWnd
, DWLP_MSGRESULT
, msg_result
);
2911 if (wndProc
) SetWindowLongPtrW(hWnd
, GWLP_WNDPROC
, wndProc
);
2913 SetWindowLongPtrW(hWnd
, 0, wnd_extra
);
2914 if (wndProc
) SetWindowLongPtrW(hWnd
, GWLP_WNDPROC
, (LONG_PTR
)wndProc
);
2921 /*************************************************************************
2924 * Get and show a context menu from a shell folder.
2927 * hWnd [I] Window displaying the shell folder
2928 * lpFolder [I] IShellFolder interface
2929 * lpApidl [I] Id for the particular folder desired
2933 * Failure: An HRESULT error code indicating the error.
2935 HRESULT WINAPI
SHInvokeDefaultCommand(HWND hWnd
, IShellFolder
* lpFolder
, LPCITEMIDLIST lpApidl
)
2937 TRACE("%p %p %p\n", hWnd
, lpFolder
, lpApidl
);
2938 return SHInvokeCommand(hWnd
, lpFolder
, lpApidl
, 0);
2941 /*************************************************************************
2944 * _SHPackDispParamsV
2946 HRESULT WINAPI
SHPackDispParamsV(DISPPARAMS
*params
, VARIANTARG
*args
, UINT cnt
, __ms_va_list valist
)
2950 TRACE("(%p %p %u ...)\n", params
, args
, cnt
);
2952 params
->rgvarg
= args
;
2953 params
->rgdispidNamedArgs
= NULL
;
2954 params
->cArgs
= cnt
;
2955 params
->cNamedArgs
= 0;
2959 while(iter
-- > args
) {
2960 V_VT(iter
) = va_arg(valist
, enum VARENUM
);
2962 TRACE("vt=%d\n", V_VT(iter
));
2964 if(V_VT(iter
) & VT_BYREF
) {
2965 V_BYREF(iter
) = va_arg(valist
, LPVOID
);
2967 switch(V_VT(iter
)) {
2969 V_I4(iter
) = va_arg(valist
, LONG
);
2972 V_BSTR(iter
) = va_arg(valist
, BSTR
);
2975 V_DISPATCH(iter
) = va_arg(valist
, IDispatch
*);
2978 V_BOOL(iter
) = va_arg(valist
, int);
2981 V_UNKNOWN(iter
) = va_arg(valist
, IUnknown
*);
2985 V_I4(iter
) = va_arg(valist
, LONG
);
2993 /*************************************************************************
2998 HRESULT WINAPIV
SHPackDispParams(DISPPARAMS
*params
, VARIANTARG
*args
, UINT cnt
, ...)
3000 __ms_va_list valist
;
3003 __ms_va_start(valist
, cnt
);
3004 hres
= SHPackDispParamsV(params
, args
, cnt
, valist
);
3005 __ms_va_end(valist
);
3009 /*************************************************************************
3010 * SHLWAPI_InvokeByIID
3012 * This helper function calls IDispatch::Invoke for each sink
3013 * which implements given iid or IDispatch.
3016 static HRESULT
SHLWAPI_InvokeByIID(
3017 IConnectionPoint
* iCP
,
3020 DISPPARAMS
* dispParams
)
3022 IEnumConnections
*enumerator
;
3024 static DISPPARAMS empty
= {NULL
, NULL
, 0, 0};
3025 DISPPARAMS
* params
= dispParams
;
3027 HRESULT result
= IConnectionPoint_EnumConnections(iCP
, &enumerator
);
3031 /* Invoke is never happening with an NULL dispParams */
3035 while(IEnumConnections_Next(enumerator
, 1, &rgcd
, NULL
)==S_OK
)
3037 IDispatch
*dispIface
;
3038 if ((iid
&& SUCCEEDED(IUnknown_QueryInterface(rgcd
.pUnk
, iid
, (LPVOID
*)&dispIface
))) ||
3039 SUCCEEDED(IUnknown_QueryInterface(rgcd
.pUnk
, &IID_IDispatch
, (LPVOID
*)&dispIface
)))
3041 IDispatch_Invoke(dispIface
, dispId
, &IID_NULL
, 0, DISPATCH_METHOD
, params
, NULL
, NULL
, NULL
);
3042 IDispatch_Release(dispIface
);
3044 IUnknown_Release(rgcd
.pUnk
);
3047 IEnumConnections_Release(enumerator
);
3052 /*************************************************************************
3053 * IConnectionPoint_InvokeWithCancel [SHLWAPI.283]
3055 HRESULT WINAPI
IConnectionPoint_InvokeWithCancel( IConnectionPoint
* iCP
,
3056 DISPID dispId
, DISPPARAMS
* dispParams
,
3057 DWORD unknown1
, DWORD unknown2
)
3062 FIXME("(%p)->(0x%x %p %x %x) partial stub\n", iCP
, dispId
, dispParams
, unknown1
, unknown2
);
3064 result
= IConnectionPoint_GetConnectionInterface(iCP
, &iid
);
3065 if (SUCCEEDED(result
))
3066 result
= SHLWAPI_InvokeByIID(iCP
, &iid
, dispId
, dispParams
);
3068 result
= SHLWAPI_InvokeByIID(iCP
, NULL
, dispId
, dispParams
);
3074 /*************************************************************************
3077 * IConnectionPoint_SimpleInvoke
3079 HRESULT WINAPI
IConnectionPoint_SimpleInvoke(
3080 IConnectionPoint
* iCP
,
3082 DISPPARAMS
* dispParams
)
3087 TRACE("(%p)->(0x%x %p)\n",iCP
,dispId
,dispParams
);
3089 result
= IConnectionPoint_GetConnectionInterface(iCP
, &iid
);
3090 if (SUCCEEDED(result
))
3091 result
= SHLWAPI_InvokeByIID(iCP
, &iid
, dispId
, dispParams
);
3093 result
= SHLWAPI_InvokeByIID(iCP
, NULL
, dispId
, dispParams
);
3098 /*************************************************************************
3101 * Notify an IConnectionPoint object of changes.
3104 * lpCP [I] Object to notify
3109 * Failure: E_NOINTERFACE, if lpCP is NULL or does not support the
3110 * IConnectionPoint interface.
3112 HRESULT WINAPI
IConnectionPoint_OnChanged(IConnectionPoint
* lpCP
, DISPID dispID
)
3114 IEnumConnections
*lpEnum
;
3115 HRESULT hRet
= E_NOINTERFACE
;
3117 TRACE("(%p,0x%8X)\n", lpCP
, dispID
);
3119 /* Get an enumerator for the connections */
3121 hRet
= IConnectionPoint_EnumConnections(lpCP
, &lpEnum
);
3123 if (SUCCEEDED(hRet
))
3125 IPropertyNotifySink
*lpSink
;
3126 CONNECTDATA connData
;
3129 /* Call OnChanged() for every notify sink in the connection point */
3130 while (IEnumConnections_Next(lpEnum
, 1, &connData
, &ulFetched
) == S_OK
)
3132 if (SUCCEEDED(IUnknown_QueryInterface(connData
.pUnk
, &IID_IPropertyNotifySink
, (void**)&lpSink
)) &&
3135 IPropertyNotifySink_OnChanged(lpSink
, dispID
);
3136 IPropertyNotifySink_Release(lpSink
);
3138 IUnknown_Release(connData
.pUnk
);
3141 IEnumConnections_Release(lpEnum
);
3146 /*************************************************************************
3149 * IUnknown_CPContainerInvokeParam
3151 HRESULT WINAPIV
IUnknown_CPContainerInvokeParam(
3152 IUnknown
*container
,
3159 IConnectionPoint
*iCP
;
3160 IConnectionPointContainer
*iCPC
;
3161 DISPPARAMS dispParams
= {buffer
, NULL
, cParams
, 0};
3162 __ms_va_list valist
;
3165 return E_NOINTERFACE
;
3167 result
= IUnknown_QueryInterface(container
, &IID_IConnectionPointContainer
,(LPVOID
*) &iCPC
);
3171 result
= IConnectionPointContainer_FindConnectionPoint(iCPC
, riid
, &iCP
);
3172 IConnectionPointContainer_Release(iCPC
);
3176 __ms_va_start(valist
, cParams
);
3177 SHPackDispParamsV(&dispParams
, buffer
, cParams
, valist
);
3178 __ms_va_end(valist
);
3180 result
= SHLWAPI_InvokeByIID(iCP
, riid
, dispId
, &dispParams
);
3181 IConnectionPoint_Release(iCP
);
3186 /*************************************************************************
3189 * Notify an IConnectionPointContainer object of changes.
3192 * lpUnknown [I] Object to notify
3197 * Failure: E_NOINTERFACE, if lpUnknown is NULL or does not support the
3198 * IConnectionPointContainer interface.
3200 HRESULT WINAPI
IUnknown_CPContainerOnChanged(IUnknown
*lpUnknown
, DISPID dispID
)
3202 IConnectionPointContainer
* lpCPC
= NULL
;
3203 HRESULT hRet
= E_NOINTERFACE
;
3205 TRACE("(%p,0x%8X)\n", lpUnknown
, dispID
);
3208 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IConnectionPointContainer
, (void**)&lpCPC
);
3210 if (SUCCEEDED(hRet
))
3212 IConnectionPoint
* lpCP
;
3214 hRet
= IConnectionPointContainer_FindConnectionPoint(lpCPC
, &IID_IPropertyNotifySink
, &lpCP
);
3215 IConnectionPointContainer_Release(lpCPC
);
3217 hRet
= IConnectionPoint_OnChanged(lpCP
, dispID
);
3218 IConnectionPoint_Release(lpCP
);
3223 /*************************************************************************
3228 BOOL WINAPI
PlaySoundWrapW(LPCWSTR pszSound
, HMODULE hmod
, DWORD fdwSound
)
3230 return PlaySoundW(pszSound
, hmod
, fdwSound
);
3233 /*************************************************************************
3236 * Retrieve a key value from an INI file. See GetPrivateProfileString for
3240 * appName [I] The section in the INI file that contains the key
3241 * keyName [I] The key to be retrieved
3242 * out [O] The buffer into which the key's value will be copied
3243 * outLen [I] The length of the `out' buffer
3244 * filename [I] The location of the INI file
3247 * Length of string copied into `out'.
3249 DWORD WINAPI
SHGetIniStringW(LPCWSTR appName
, LPCWSTR keyName
, LPWSTR out
,
3250 DWORD outLen
, LPCWSTR filename
)
3255 TRACE("(%s,%s,%p,%08x,%s)\n", debugstr_w(appName
), debugstr_w(keyName
),
3256 out
, outLen
, debugstr_w(filename
));
3261 buf
= HeapAlloc(GetProcessHeap(), 0, outLen
* sizeof(WCHAR
));
3267 ret
= GetPrivateProfileStringW(appName
, keyName
, NULL
, buf
, outLen
, filename
);
3273 HeapFree(GetProcessHeap(), 0, buf
);
3275 return strlenW(out
);
3278 /*************************************************************************
3281 * Set a key value in an INI file. See WritePrivateProfileString for
3285 * appName [I] The section in the INI file that contains the key
3286 * keyName [I] The key to be set
3287 * str [O] The value of the key
3288 * filename [I] The location of the INI file
3294 BOOL WINAPI
SHSetIniStringW(LPCWSTR appName
, LPCWSTR keyName
, LPCWSTR str
,
3297 TRACE("(%s, %p, %s, %s)\n", debugstr_w(appName
), keyName
, debugstr_w(str
),
3298 debugstr_w(filename
));
3300 return WritePrivateProfileStringW(appName
, keyName
, str
, filename
);
3303 /*************************************************************************
3306 * See SHGetFileInfoW.
3308 DWORD WINAPI
SHGetFileInfoWrapW(LPCWSTR path
, DWORD dwFileAttributes
,
3309 SHFILEINFOW
*psfi
, UINT sizeofpsfi
, UINT flags
)
3311 return SHGetFileInfoW(path
, dwFileAttributes
, psfi
, sizeofpsfi
, flags
);
3314 /*************************************************************************
3317 * See DragQueryFileW.
3319 UINT WINAPI
DragQueryFileWrapW(HDROP hDrop
, UINT lFile
, LPWSTR lpszFile
, UINT lLength
)
3321 return DragQueryFileW(hDrop
, lFile
, lpszFile
, lLength
);
3324 /*************************************************************************
3327 * See SHBrowseForFolderW.
3329 LPITEMIDLIST WINAPI
SHBrowseForFolderWrapW(LPBROWSEINFOW lpBi
)
3331 return SHBrowseForFolderW(lpBi
);
3334 /*************************************************************************
3337 * See SHGetPathFromIDListW.
3339 BOOL WINAPI
SHGetPathFromIDListWrapW(LPCITEMIDLIST pidl
,LPWSTR pszPath
)
3341 return SHGetPathFromIDListW(pidl
, pszPath
);
3344 /*************************************************************************
3347 * See ShellExecuteExW.
3349 BOOL WINAPI
ShellExecuteExWrapW(LPSHELLEXECUTEINFOW lpExecInfo
)
3351 return ShellExecuteExW(lpExecInfo
);
3354 /*************************************************************************
3357 * See SHFileOperationW.
3359 INT WINAPI
SHFileOperationWrapW(LPSHFILEOPSTRUCTW lpFileOp
)
3361 return SHFileOperationW(lpFileOp
);
3364 /*************************************************************************
3368 PVOID WINAPI
SHInterlockedCompareExchange( PVOID
*dest
, PVOID xchg
, PVOID compare
)
3370 return InterlockedCompareExchangePointer( dest
, xchg
, compare
);
3373 /*************************************************************************
3376 * See GetFileVersionInfoSizeW.
3378 DWORD WINAPI
GetFileVersionInfoSizeWrapW( LPCWSTR filename
, LPDWORD handle
)
3380 return GetFileVersionInfoSizeW( filename
, handle
);
3383 /*************************************************************************
3386 * See GetFileVersionInfoW.
3388 BOOL WINAPI
GetFileVersionInfoWrapW( LPCWSTR filename
, DWORD handle
,
3389 DWORD datasize
, LPVOID data
)
3391 return GetFileVersionInfoW( filename
, handle
, datasize
, data
);
3394 /*************************************************************************
3397 * See VerQueryValueW.
3399 WORD WINAPI
VerQueryValueWrapW( LPVOID pBlock
, LPCWSTR lpSubBlock
,
3400 LPVOID
*lplpBuffer
, UINT
*puLen
)
3402 return VerQueryValueW( pBlock
, lpSubBlock
, lplpBuffer
, puLen
);
3405 #define IsIface(type) SUCCEEDED((hRet = IUnknown_QueryInterface(lpUnknown, &IID_##type, (void**)&lpObj)))
3406 #define IShellBrowser_EnableModeless IShellBrowser_EnableModelessSB
3407 #define EnableModeless(type) type##_EnableModeless((type*)lpObj, bModeless)
3409 /*************************************************************************
3412 * Change the modality of a shell object.
3415 * lpUnknown [I] Object to make modeless
3416 * bModeless [I] TRUE=Make modeless, FALSE=Make modal
3419 * Success: S_OK. The modality lpUnknown is changed.
3420 * Failure: An HRESULT error code indicating the error.
3423 * lpUnknown must support the IOleInPlaceFrame interface, the
3424 * IInternetSecurityMgrSite interface, the IShellBrowser interface
3425 * the IDocHostUIHandler interface, or the IOleInPlaceActiveObject interface,
3426 * or this call will fail.
3428 HRESULT WINAPI
IUnknown_EnableModeless(IUnknown
*lpUnknown
, BOOL bModeless
)
3433 TRACE("(%p,%d)\n", lpUnknown
, bModeless
);
3438 if (IsIface(IOleInPlaceActiveObject
))
3439 EnableModeless(IOleInPlaceActiveObject
);
3440 else if (IsIface(IOleInPlaceFrame
))
3441 EnableModeless(IOleInPlaceFrame
);
3442 else if (IsIface(IShellBrowser
))
3443 EnableModeless(IShellBrowser
);
3444 else if (IsIface(IInternetSecurityMgrSite
))
3445 EnableModeless(IInternetSecurityMgrSite
);
3446 else if (IsIface(IDocHostUIHandler
))
3447 EnableModeless(IDocHostUIHandler
);
3451 IUnknown_Release(lpObj
);
3455 /*************************************************************************
3458 * See SHGetNewLinkInfoW.
3460 BOOL WINAPI
SHGetNewLinkInfoWrapW(LPCWSTR pszLinkTo
, LPCWSTR pszDir
, LPWSTR pszName
,
3461 BOOL
*pfMustCopy
, UINT uFlags
)
3463 return SHGetNewLinkInfoW(pszLinkTo
, pszDir
, pszName
, pfMustCopy
, uFlags
);
3466 /*************************************************************************
3469 * See SHDefExtractIconW.
3471 UINT WINAPI
SHDefExtractIconWrapW(LPCWSTR pszIconFile
, int iIndex
, UINT uFlags
, HICON
* phiconLarge
,
3472 HICON
* phiconSmall
, UINT nIconSize
)
3474 return SHDefExtractIconW(pszIconFile
, iIndex
, uFlags
, phiconLarge
, phiconSmall
, nIconSize
);
3477 /*************************************************************************
3480 * Get and show a context menu from a shell folder.
3483 * hWnd [I] Window displaying the shell folder
3484 * lpFolder [I] IShellFolder interface
3485 * lpApidl [I] Id for the particular folder desired
3486 * dwCommandId [I] The command ID to invoke (0=invoke default)
3489 * Success: S_OK. If bInvokeDefault is TRUE, the default menu action was
3491 * Failure: An HRESULT error code indicating the error.
3493 HRESULT WINAPI
SHInvokeCommand(HWND hWnd
, IShellFolder
* lpFolder
, LPCITEMIDLIST lpApidl
, DWORD dwCommandId
)
3495 IContextMenu
*iContext
;
3498 TRACE("(%p, %p, %p, %u)\n", hWnd
, lpFolder
, lpApidl
, dwCommandId
);
3503 /* Get the context menu from the shell folder */
3504 hRet
= IShellFolder_GetUIObjectOf(lpFolder
, hWnd
, 1, &lpApidl
,
3505 &IID_IContextMenu
, 0, (void**)&iContext
);
3506 if (SUCCEEDED(hRet
))
3509 if ((hMenu
= CreatePopupMenu()))
3513 /* Add the context menu entries to the popup */
3514 hQuery
= IContextMenu_QueryContextMenu(iContext
, hMenu
, 0, 1, 0x7FFF,
3515 dwCommandId
? CMF_NORMAL
: CMF_DEFAULTONLY
);
3517 if (SUCCEEDED(hQuery
))
3520 dwCommandId
= GetMenuDefaultItem(hMenu
, 0, 0);
3521 if (dwCommandId
!= (UINT
)-1)
3523 CMINVOKECOMMANDINFO cmIci
;
3524 /* Invoke the default item */
3525 memset(&cmIci
,0,sizeof(cmIci
));
3526 cmIci
.cbSize
= sizeof(cmIci
);
3527 cmIci
.fMask
= CMIC_MASK_ASYNCOK
;
3529 #ifdef __REACTOS__ /* r75561 */
3530 cmIci
.lpVerb
= MAKEINTRESOURCEA(dwCommandId
- 1);
3532 cmIci
.lpVerb
= MAKEINTRESOURCEA(dwCommandId
);
3534 cmIci
.nShow
= SW_SHOWNORMAL
;
3536 hRet
= IContextMenu_InvokeCommand(iContext
, &cmIci
);
3541 IContextMenu_Release(iContext
);
3546 /*************************************************************************
3551 HICON WINAPI
ExtractIconWrapW(HINSTANCE hInstance
, LPCWSTR lpszExeFileName
,
3554 return ExtractIconW(hInstance
, lpszExeFileName
, nIconIndex
);
3557 /*************************************************************************
3560 * Load a library from the directory of a particular process.
3563 * new_mod [I] Library name
3564 * inst_hwnd [I] Module whose directory is to be used
3565 * dwCrossCodePage [I] Should be FALSE (currently ignored)
3568 * Success: A handle to the loaded module
3569 * Failure: A NULL handle.
3571 HMODULE WINAPI
MLLoadLibraryA(LPCSTR new_mod
, HMODULE inst_hwnd
, DWORD dwCrossCodePage
)
3573 /* FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for
3575 * FIXME: Native shows calls to:
3576 * SHRegGetUSValue for "Software\Microsoft\Internet Explorer\International"
3578 * RegOpenKeyExA for "HKLM\Software\Microsoft\Internet Explorer"
3579 * RegQueryValueExA for "LPKInstalled"
3581 * RegOpenKeyExA for "HKCU\Software\Microsoft\Internet Explorer\International"
3582 * RegQueryValueExA for "ResourceLocale"
3584 * RegOpenKeyExA for "HKLM\Software\Microsoft\Active Setup\Installed Components\{guid}"
3585 * RegQueryValueExA for "Locale"
3587 * and then tests the Locale ("en" for me).
3589 * after the code then a DPA_Create (first time) and DPA_InsertPtr are done.
3591 CHAR mod_path
[2*MAX_PATH
];
3595 FIXME("(%s,%p,%d) semi-stub!\n", debugstr_a(new_mod
), inst_hwnd
, dwCrossCodePage
);
3596 len
= GetModuleFileNameA(inst_hwnd
, mod_path
, sizeof(mod_path
));
3597 if (!len
|| len
>= sizeof(mod_path
)) return NULL
;
3599 ptr
= strrchr(mod_path
, '\\');
3601 strcpy(ptr
+1, new_mod
);
3602 TRACE("loading %s\n", debugstr_a(mod_path
));
3603 return LoadLibraryA(mod_path
);
3608 /*************************************************************************
3611 * Unicode version of MLLoadLibraryA.
3613 HMODULE WINAPI
MLLoadLibraryW(LPCWSTR new_mod
, HMODULE inst_hwnd
, DWORD dwCrossCodePage
)
3615 WCHAR mod_path
[2*MAX_PATH
];
3619 FIXME("(%s,%p,%d) semi-stub!\n", debugstr_w(new_mod
), inst_hwnd
, dwCrossCodePage
);
3620 len
= GetModuleFileNameW(inst_hwnd
, mod_path
, sizeof(mod_path
) / sizeof(WCHAR
));
3621 if (!len
|| len
>= sizeof(mod_path
) / sizeof(WCHAR
)) return NULL
;
3623 ptr
= strrchrW(mod_path
, '\\');
3625 strcpyW(ptr
+1, new_mod
);
3626 TRACE("loading %s\n", debugstr_w(mod_path
));
3627 return LoadLibraryW(mod_path
);
3632 /*************************************************************************
3633 * ColorAdjustLuma [SHLWAPI.@]
3635 * Adjust the luminosity of a color
3638 * cRGB [I] RGB value to convert
3639 * dwLuma [I] Luma adjustment
3640 * bUnknown [I] Unknown
3643 * The adjusted RGB color.
3645 COLORREF WINAPI
ColorAdjustLuma(COLORREF cRGB
, int dwLuma
, BOOL bUnknown
)
3647 TRACE("(0x%8x,%d,%d)\n", cRGB
, dwLuma
, bUnknown
);
3653 ColorRGBToHLS(cRGB
, &wH
, &wL
, &wS
);
3655 FIXME("Ignoring luma adjustment\n");
3657 /* FIXME: The adjustment is not linear */
3659 cRGB
= ColorHLSToRGB(wH
, wL
, wS
);
3664 /*************************************************************************
3667 * See GetSaveFileNameW.
3669 BOOL WINAPI
GetSaveFileNameWrapW(LPOPENFILENAMEW ofn
)
3671 return GetSaveFileNameW(ofn
);
3674 /*************************************************************************
3677 * See WNetRestoreConnectionW.
3679 DWORD WINAPI
WNetRestoreConnectionWrapW(HWND hwndOwner
, LPWSTR lpszDevice
)
3681 return WNetRestoreConnectionW(hwndOwner
, lpszDevice
);
3684 /*************************************************************************
3687 * See WNetGetLastErrorW.
3689 DWORD WINAPI
WNetGetLastErrorWrapW(LPDWORD lpError
, LPWSTR lpErrorBuf
, DWORD nErrorBufSize
,
3690 LPWSTR lpNameBuf
, DWORD nNameBufSize
)
3692 return WNetGetLastErrorW(lpError
, lpErrorBuf
, nErrorBufSize
, lpNameBuf
, nNameBufSize
);
3695 /*************************************************************************
3698 * See PageSetupDlgW.
3700 BOOL WINAPI
PageSetupDlgWrapW(LPPAGESETUPDLGW pagedlg
)
3702 return PageSetupDlgW(pagedlg
);
3705 /*************************************************************************
3710 BOOL WINAPI
PrintDlgWrapW(LPPRINTDLGW printdlg
)
3712 return PrintDlgW(printdlg
);
3715 /*************************************************************************
3718 * See GetOpenFileNameW.
3720 BOOL WINAPI
GetOpenFileNameWrapW(LPOPENFILENAMEW ofn
)
3722 return GetOpenFileNameW(ofn
);
3725 /*************************************************************************
3728 HRESULT WINAPI
SHIShellFolder_EnumObjects(LPSHELLFOLDER lpFolder
, HWND hwnd
, SHCONTF flags
, IEnumIDList
**ppenum
)
3730 /* Windows attempts to get an IPersist interface and, if that fails, an
3731 * IPersistFolder interface on the folder passed-in here. If one of those
3732 * interfaces is available, it then calls GetClassID on the folder... and
3733 * then calls IShellFolder_EnumObjects no matter what, even crashing if
3734 * lpFolder isn't actually an IShellFolder object. The purpose of getting
3735 * the ClassID is unknown, so we don't do it here.
3737 * For discussion and detailed tests, see:
3738 * "shlwapi: Be less strict on which type of IShellFolder can be enumerated"
3739 * wine-devel mailing list, 3 Jun 2010
3742 return IShellFolder_EnumObjects(lpFolder
, hwnd
, flags
, ppenum
);
3745 /* INTERNAL: Map from HLS color space to RGB */
3746 static WORD
ConvertHue(int wHue
, WORD wMid1
, WORD wMid2
)
3748 wHue
= wHue
> 240 ? wHue
- 240 : wHue
< 0 ? wHue
+ 240 : wHue
;
3752 else if (wHue
> 120)
3757 return ((wHue
* (wMid2
- wMid1
) + 20) / 40) + wMid1
;
3760 /* Convert to RGB and scale into RGB range (0..255) */
3761 #define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240
3763 /*************************************************************************
3764 * ColorHLSToRGB [SHLWAPI.@]
3766 * Convert from hls color space into an rgb COLORREF.
3769 * wHue [I] Hue amount
3770 * wLuminosity [I] Luminosity amount
3771 * wSaturation [I] Saturation amount
3774 * A COLORREF representing the converted color.
3777 * Input hls values are constrained to the range (0..240).
3779 COLORREF WINAPI
ColorHLSToRGB(WORD wHue
, WORD wLuminosity
, WORD wSaturation
)
3785 WORD wGreen
, wBlue
, wMid1
, wMid2
;
3787 if (wLuminosity
> 120)
3788 wMid2
= wSaturation
+ wLuminosity
- (wSaturation
* wLuminosity
+ 120) / 240;
3790 wMid2
= ((wSaturation
+ 240) * wLuminosity
+ 120) / 240;
3792 wMid1
= wLuminosity
* 2 - wMid2
;
3794 wRed
= GET_RGB(wHue
+ 80);
3795 wGreen
= GET_RGB(wHue
);
3796 wBlue
= GET_RGB(wHue
- 80);
3798 return RGB(wRed
, wGreen
, wBlue
);
3801 wRed
= wLuminosity
* 255 / 240;
3802 return RGB(wRed
, wRed
, wRed
);
3805 /*************************************************************************
3808 * Get the current docking status of the system.
3811 * dwFlags [I] DOCKINFO_ flags from "winbase.h", unused
3814 * One of DOCKINFO_UNDOCKED, DOCKINFO_UNDOCKED, or 0 if the system is not
3817 DWORD WINAPI
SHGetMachineInfo(DWORD dwFlags
)
3819 HW_PROFILE_INFOA hwInfo
;
3821 TRACE("(0x%08x)\n", dwFlags
);
3823 GetCurrentHwProfileA(&hwInfo
);
3824 switch (hwInfo
.dwDockInfo
& (DOCKINFO_DOCKED
|DOCKINFO_UNDOCKED
))
3826 case DOCKINFO_DOCKED
:
3827 case DOCKINFO_UNDOCKED
:
3828 return hwInfo
.dwDockInfo
& (DOCKINFO_DOCKED
|DOCKINFO_UNDOCKED
);
3834 /*************************************************************************
3838 DWORD WINAPI
SHWinHelpOnDemandW(HWND hwnd
, LPCWSTR helpfile
, DWORD flags1
, VOID
*ptr1
, DWORD flags2
)
3841 FIXME("(%p, %s, 0x%x, %p, %d)\n", hwnd
, debugstr_w(helpfile
), flags1
, ptr1
, flags2
);
3845 /*************************************************************************
3849 DWORD WINAPI
SHWinHelpOnDemandA(HWND hwnd
, LPCSTR helpfile
, DWORD flags1
, VOID
*ptr1
, DWORD flags2
)
3852 FIXME("(%p, %s, 0x%x, %p, %d)\n", hwnd
, debugstr_a(helpfile
), flags1
, ptr1
, flags2
);
3856 /*************************************************************************
3859 * Function seems to do FreeLibrary plus other things.
3861 * FIXME native shows the following calls:
3862 * RtlEnterCriticalSection
3864 * GetProcAddress(Comctl32??, 150L)
3866 * RtlLeaveCriticalSection
3867 * followed by the FreeLibrary.
3868 * The above code may be related to .377 above.
3870 BOOL WINAPI
MLFreeLibrary(HMODULE hModule
)
3872 FIXME("(%p) semi-stub\n", hModule
);
3873 return FreeLibrary(hModule
);
3876 /*************************************************************************
3879 BOOL WINAPI
SHFlushSFCacheWrap(void) {
3884 /*************************************************************************
3886 * FIXME I have no idea what this function does or what its arguments are.
3888 BOOL WINAPI
MLIsMLHInstance(HINSTANCE hInst
)
3890 FIXME("(%p) stub\n", hInst
);
3895 /*************************************************************************
3898 DWORD WINAPI
MLSetMLHInstance(HINSTANCE hInst
, HANDLE hHeap
)
3900 FIXME("(%p,%p) stub\n", hInst
, hHeap
);
3901 return E_FAIL
; /* This is what is used if shlwapi not loaded */
3904 /*************************************************************************
3907 DWORD WINAPI
MLClearMLHInstance(DWORD x
)
3909 FIXME("(0x%08x)stub\n", x
);
3913 /*************************************************************************
3916 * See SHSendMessageBroadcastW
3919 DWORD WINAPI
SHSendMessageBroadcastA(UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3921 return SendMessageTimeoutA(HWND_BROADCAST
, uMsg
, wParam
, lParam
,
3922 SMTO_ABORTIFHUNG
, 2000, NULL
);
3925 /*************************************************************************
3928 * A wrapper for sending Broadcast Messages to all top level Windows
3931 DWORD WINAPI
SHSendMessageBroadcastW(UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3933 return SendMessageTimeoutW(HWND_BROADCAST
, uMsg
, wParam
, lParam
,
3934 SMTO_ABORTIFHUNG
, 2000, NULL
);
3937 /*************************************************************************
3940 * Convert a Unicode string CLSID into a CLSID.
3943 * idstr [I] string containing a CLSID in text form
3944 * id [O] CLSID extracted from the string
3947 * S_OK on success or E_INVALIDARG on failure
3949 HRESULT WINAPI
CLSIDFromStringWrap(LPCWSTR idstr
, CLSID
*id
)
3951 return CLSIDFromString((LPCOLESTR
)idstr
, id
);
3954 /*************************************************************************
3957 * Determine if the OS supports a given feature.
3960 * dwFeature [I] Feature requested (undocumented)
3963 * TRUE If the feature is available.
3964 * FALSE If the feature is not available.
3966 BOOL WINAPI
IsOS(DWORD feature
)
3968 OSVERSIONINFOA osvi
;
3969 DWORD platform
, majorv
, minorv
;
3971 osvi
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFOA
);
3972 if(!GetVersionExA(&osvi
)) {
3973 ERR("GetVersionEx failed\n");
3977 majorv
= osvi
.dwMajorVersion
;
3978 minorv
= osvi
.dwMinorVersion
;
3979 platform
= osvi
.dwPlatformId
;
3981 #define ISOS_RETURN(x) \
3982 TRACE("(0x%x) ret=%d\n",feature,(x)); \
3986 case OS_WIN32SORGREATER
:
3987 ISOS_RETURN(platform
== VER_PLATFORM_WIN32s
3988 || platform
== VER_PLATFORM_WIN32_WINDOWS
)
3990 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3991 case OS_WIN95ORGREATER
:
3992 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
)
3993 case OS_NT4ORGREATER
:
3994 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 4)
3995 case OS_WIN2000ORGREATER_ALT
:
3996 case OS_WIN2000ORGREATER
:
3997 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5)
3998 case OS_WIN98ORGREATER
:
3999 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
&& minorv
>= 10)
4001 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
&& minorv
== 10)
4003 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5)
4004 case OS_WIN2000SERVER
:
4005 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& (minorv
== 0 || minorv
== 1))
4006 case OS_WIN2000ADVSERVER
:
4007 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& (minorv
== 0 || minorv
== 1))
4008 case OS_WIN2000DATACENTER
:
4009 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& (minorv
== 0 || minorv
== 1))
4010 case OS_WIN2000TERMINAL
:
4011 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& (minorv
== 0 || minorv
== 1))
4013 FIXME("(OS_EMBEDDED) What should we return here?\n");
4015 case OS_TERMINALCLIENT
:
4016 FIXME("(OS_TERMINALCLIENT) What should we return here?\n");
4018 case OS_TERMINALREMOTEADMIN
:
4019 FIXME("(OS_TERMINALREMOTEADMIN) What should we return here?\n");
4022 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
&& minorv
== 0)
4023 case OS_MEORGREATER
:
4024 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
&& minorv
>= 90)
4025 case OS_XPORGREATER
:
4026 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5 && minorv
>= 1)
4028 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5 && minorv
>= 1)
4029 case OS_PROFESSIONAL
:
4030 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
4032 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
4034 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5)
4036 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
4037 case OS_TERMINALSERVER
:
4038 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
4039 case OS_PERSONALTERMINALSERVER
:
4040 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& minorv
>= 1 && majorv
>= 5)
4041 case OS_FASTUSERSWITCHING
:
4042 FIXME("(OS_FASTUSERSWITCHING) What should we return here?\n");
4044 case OS_WELCOMELOGONUI
:
4045 FIXME("(OS_WELCOMELOGONUI) What should we return here?\n");
4047 case OS_DOMAINMEMBER
:
4048 FIXME("(OS_DOMAINMEMBER) What should we return here?\n");
4051 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
4055 IsWow64Process(GetCurrentProcess(), &is_wow64
);
4059 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
4060 case OS_SMALLBUSINESSSERVER
:
4061 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
4063 FIXME("(OS_TABLETPC) What should we return here?\n");
4065 case OS_SERVERADMINUI
:
4066 FIXME("(OS_SERVERADMINUI) What should we return here?\n");
4068 case OS_MEDIACENTER
:
4069 FIXME("(OS_MEDIACENTER) What should we return here?\n");
4072 FIXME("(OS_APPLIANCE) What should we return here?\n");
4074 case 0x25: /*OS_VISTAORGREATER*/
4075 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 6)
4080 WARN("(0x%x) unknown parameter\n",feature
);
4085 /*************************************************************************
4088 HRESULT WINAPI
SHLoadRegUIStringW(HKEY hkey
, LPCWSTR value
, LPWSTR buf
, DWORD size
)
4090 DWORD type
, sz
= size
;
4092 if(RegQueryValueExW(hkey
, value
, NULL
, &type
, (LPBYTE
)buf
, &sz
) != ERROR_SUCCESS
)
4095 return SHLoadIndirectString(buf
, buf
, size
, NULL
);
4098 /*************************************************************************
4101 * Call IInputObject_TranslateAcceleratorIO() on an object.
4104 * lpUnknown [I] Object supporting the IInputObject interface.
4105 * lpMsg [I] Key message to be processed.
4109 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
4111 HRESULT WINAPI
IUnknown_TranslateAcceleratorIO(IUnknown
*lpUnknown
, LPMSG lpMsg
)
4113 IInputObject
* lpInput
= NULL
;
4114 HRESULT hRet
= E_INVALIDARG
;
4116 TRACE("(%p,%p)\n", lpUnknown
, lpMsg
);
4119 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IInputObject
,
4121 if (SUCCEEDED(hRet
) && lpInput
)
4123 hRet
= IInputObject_TranslateAcceleratorIO(lpInput
, lpMsg
);
4124 IInputObject_Release(lpInput
);
4130 /*************************************************************************
4133 * Call IInputObject_HasFocusIO() on an object.
4136 * lpUnknown [I] Object supporting the IInputObject interface.
4139 * Success: S_OK, if lpUnknown is an IInputObject object and has the focus,
4140 * or S_FALSE otherwise.
4141 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
4143 HRESULT WINAPI
IUnknown_HasFocusIO(IUnknown
*lpUnknown
)
4145 IInputObject
* lpInput
= NULL
;
4146 HRESULT hRet
= E_INVALIDARG
;
4148 TRACE("(%p)\n", lpUnknown
);
4151 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IInputObject
,
4153 if (SUCCEEDED(hRet
) && lpInput
)
4155 hRet
= IInputObject_HasFocusIO(lpInput
);
4156 IInputObject_Release(lpInput
);
4162 /*************************************************************************
4163 * ColorRGBToHLS [SHLWAPI.@]
4165 * Convert an rgb COLORREF into the hls color space.
4168 * cRGB [I] Source rgb value
4169 * pwHue [O] Destination for converted hue
4170 * pwLuminance [O] Destination for converted luminance
4171 * pwSaturation [O] Destination for converted saturation
4174 * Nothing. pwHue, pwLuminance and pwSaturation are set to the converted
4178 * Output HLS values are constrained to the range (0..240).
4179 * For Achromatic conversions, Hue is set to 160.
4181 VOID WINAPI
ColorRGBToHLS(COLORREF cRGB
, LPWORD pwHue
,
4182 LPWORD pwLuminance
, LPWORD pwSaturation
)
4184 int wR
, wG
, wB
, wMax
, wMin
, wHue
, wLuminosity
, wSaturation
;
4186 TRACE("(%08x,%p,%p,%p)\n", cRGB
, pwHue
, pwLuminance
, pwSaturation
);
4188 wR
= GetRValue(cRGB
);
4189 wG
= GetGValue(cRGB
);
4190 wB
= GetBValue(cRGB
);
4192 wMax
= max(wR
, max(wG
, wB
));
4193 wMin
= min(wR
, min(wG
, wB
));
4196 wLuminosity
= ((wMax
+ wMin
) * 240 + 255) / 510;
4200 /* Achromatic case */
4202 /* Hue is now unrepresentable, but this is what native returns... */
4207 /* Chromatic case */
4208 int wDelta
= wMax
- wMin
, wRNorm
, wGNorm
, wBNorm
;
4211 if (wLuminosity
<= 120)
4212 wSaturation
= ((wMax
+ wMin
)/2 + wDelta
* 240) / (wMax
+ wMin
);
4214 wSaturation
= ((510 - wMax
- wMin
)/2 + wDelta
* 240) / (510 - wMax
- wMin
);
4217 wRNorm
= (wDelta
/2 + wMax
* 40 - wR
* 40) / wDelta
;
4218 wGNorm
= (wDelta
/2 + wMax
* 40 - wG
* 40) / wDelta
;
4219 wBNorm
= (wDelta
/2 + wMax
* 40 - wB
* 40) / wDelta
;
4222 wHue
= wBNorm
- wGNorm
;
4223 else if (wG
== wMax
)
4224 wHue
= 80 + wRNorm
- wBNorm
;
4226 wHue
= 160 + wGNorm
- wRNorm
;
4229 else if (wHue
> 240)
4235 *pwLuminance
= wLuminosity
;
4237 *pwSaturation
= wSaturation
;
4240 /*************************************************************************
4241 * SHCreateShellPalette [SHLWAPI.@]
4243 HPALETTE WINAPI
SHCreateShellPalette(HDC hdc
)
4246 return CreateHalftonePalette(hdc
);
4249 /*************************************************************************
4250 * SHGetInverseCMAP (SHLWAPI.@)
4252 * Get an inverse color map table.
4255 * lpCmap [O] Destination for color map
4256 * dwSize [I] Size of memory pointed to by lpCmap
4260 * Failure: E_POINTER, If lpCmap is invalid.
4261 * E_INVALIDARG, If dwFlags is invalid
4262 * E_OUTOFMEMORY, If there is no memory available
4265 * dwSize may only be CMAP_PTR_SIZE (4) or CMAP_SIZE (8192).
4266 * If dwSize = CMAP_PTR_SIZE, *lpCmap is set to the address of this DLL's
4268 * If dwSize = CMAP_SIZE, lpCmap is filled with a copy of the data from
4269 * this DLL's internal CMap.
4271 HRESULT WINAPI
SHGetInverseCMAP(LPDWORD dest
, DWORD dwSize
)
4274 FIXME(" - returning bogus address for SHGetInverseCMAP\n");
4275 *dest
= (DWORD
)0xabba1249;
4278 FIXME("(%p, %#x) stub\n", dest
, dwSize
);
4282 /*************************************************************************
4283 * SHIsLowMemoryMachine [SHLWAPI.@]
4285 * Determine if the current computer has low memory.
4291 * TRUE if the users machine has 16 Megabytes of memory or less,
4294 BOOL WINAPI
SHIsLowMemoryMachine (DWORD x
)
4296 FIXME("(0x%08x) stub\n", x
);
4300 /*************************************************************************
4301 * GetMenuPosFromID [SHLWAPI.@]
4303 * Return the position of a menu item from its Id.
4306 * hMenu [I] Menu containing the item
4307 * wID [I] Id of the menu item
4310 * Success: The index of the menu item in hMenu.
4311 * Failure: -1, If the item is not found.
4313 INT WINAPI
GetMenuPosFromID(HMENU hMenu
, UINT wID
)
4316 INT nCount
= GetMenuItemCount(hMenu
), nIter
= 0;
4318 TRACE("%p %u\n", hMenu
, wID
);
4320 while (nIter
< nCount
)
4322 mi
.cbSize
= sizeof(mi
);
4324 if (GetMenuItemInfoW(hMenu
, nIter
, TRUE
, &mi
) && mi
.wID
== wID
)
4326 TRACE("ret %d\n", nIter
);
4335 /*************************************************************************
4338 * Same as SHLWAPI.GetMenuPosFromID
4340 DWORD WINAPI
SHMenuIndexFromID(HMENU hMenu
, UINT uID
)
4342 TRACE("%p %u\n", hMenu
, uID
);
4343 return GetMenuPosFromID(hMenu
, uID
);
4347 /*************************************************************************
4350 VOID WINAPI
FixSlashesAndColonW(LPWSTR lpwstr
)
4361 /*************************************************************************
4364 DWORD WINAPI
SHGetAppCompatFlags(DWORD dwUnknown
)
4366 FIXME("(0x%08x) stub\n", dwUnknown
);
4371 /*************************************************************************
4374 HRESULT WINAPI
SHCoCreateInstanceAC(REFCLSID rclsid
, LPUNKNOWN pUnkOuter
,
4375 DWORD dwClsContext
, REFIID iid
, LPVOID
*ppv
)
4377 return CoCreateInstance(rclsid
, pUnkOuter
, dwClsContext
, iid
, ppv
);
4380 /*************************************************************************
4381 * SHSkipJunction [SHLWAPI.@]
4383 * Determine if a bind context can be bound to an object
4386 * pbc [I] Bind context to check
4387 * pclsid [I] CLSID of object to be bound to
4390 * TRUE: If it is safe to bind
4391 * FALSE: If pbc is invalid or binding would not be safe
4394 BOOL WINAPI
SHSkipJunction(IBindCtx
*pbc
, const CLSID
*pclsid
)
4396 static WCHAR szSkipBinding
[] = { 'S','k','i','p',' ',
4397 'B','i','n','d','i','n','g',' ','C','L','S','I','D','\0' };
4404 if (SUCCEEDED(IBindCtx_GetObjectParam(pbc
, szSkipBinding
, &lpUnk
)))
4408 if (SUCCEEDED(IUnknown_GetClassID(lpUnk
, &clsid
)) &&
4409 IsEqualGUID(pclsid
, &clsid
))
4412 IUnknown_Release(lpUnk
);
4418 /***********************************************************************
4419 * SHGetShellKey (SHLWAPI.491)
4421 HKEY WINAPI
SHGetShellKey(DWORD flags
, LPCWSTR sub_key
, BOOL create
)
4423 enum _shellkey_flags
{
4424 SHKEY_Root_HKCU
= 0x1,
4425 SHKEY_Root_HKLM
= 0x2,
4426 SHKEY_Key_Explorer
= 0x00,
4427 SHKEY_Key_Shell
= 0x10,
4428 SHKEY_Key_ShellNoRoam
= 0x20,
4429 SHKEY_Key_Classes
= 0x30,
4430 SHKEY_Subkey_Default
= 0x0000,
4431 SHKEY_Subkey_ResourceName
= 0x1000,
4432 SHKEY_Subkey_Handlers
= 0x2000,
4433 SHKEY_Subkey_Associations
= 0x3000,
4434 SHKEY_Subkey_Volatile
= 0x4000,
4435 SHKEY_Subkey_MUICache
= 0x5000,
4436 SHKEY_Subkey_FileExts
= 0x6000
4439 static const WCHAR explorerW
[] = {'S','o','f','t','w','a','r','e','\\',
4440 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
4441 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
4442 'E','x','p','l','o','r','e','r','\\'};
4443 static const WCHAR shellW
[] = {'S','o','f','t','w','a','r','e','\\',
4444 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
4445 'S','h','e','l','l','\\'};
4446 static const WCHAR shell_no_roamW
[] = {'S','o','f','t','w','a','r','e','\\',
4447 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
4448 'S','h','e','l','l','N','o','R','o','a','m','\\'};
4449 static const WCHAR classesW
[] = {'S','o','f','t','w','a','r','e','\\',
4450 'C','l','a','s','s','e','s','\\'};
4452 static const WCHAR localized_resource_nameW
[] = {'L','o','c','a','l','i','z','e','d',
4453 'R','e','s','o','u','r','c','e','N','a','m','e','\\'};
4454 static const WCHAR handlersW
[] = {'H','a','n','d','l','e','r','s','\\'};
4455 static const WCHAR associationsW
[] = {'A','s','s','o','c','i','a','t','i','o','n','s','\\'};
4456 static const WCHAR volatileW
[] = {'V','o','l','a','t','i','l','e','\\'};
4457 static const WCHAR mui_cacheW
[] = {'M','U','I','C','a','c','h','e','\\'};
4458 static const WCHAR file_extsW
[] = {'F','i','l','e','E','x','t','s','\\'};
4461 const WCHAR
*key
, *subkey
;
4462 int size_key
, size_subkey
, size_user
;
4465 TRACE("(0x%08x, %s, %d)\n", flags
, debugstr_w(sub_key
), create
);
4467 /* For compatibility with Vista+ */
4468 if(flags
== 0x1ffff)
4471 switch(flags
&0xff0) {
4472 case SHKEY_Key_Explorer
:
4474 size_key
= sizeof(explorerW
);
4476 case SHKEY_Key_Shell
:
4478 size_key
= sizeof(shellW
);
4480 case SHKEY_Key_ShellNoRoam
:
4481 key
= shell_no_roamW
;
4482 size_key
= sizeof(shell_no_roamW
);
4484 case SHKEY_Key_Classes
:
4486 size_key
= sizeof(classesW
);
4489 FIXME("unsupported flags (0x%08x)\n", flags
);
4493 switch(flags
&0xff000) {
4494 case SHKEY_Subkey_Default
:
4498 case SHKEY_Subkey_ResourceName
:
4499 subkey
= localized_resource_nameW
;
4500 size_subkey
= sizeof(localized_resource_nameW
);
4502 case SHKEY_Subkey_Handlers
:
4504 size_subkey
= sizeof(handlersW
);
4506 case SHKEY_Subkey_Associations
:
4507 subkey
= associationsW
;
4508 size_subkey
= sizeof(associationsW
);
4510 case SHKEY_Subkey_Volatile
:
4512 size_subkey
= sizeof(volatileW
);
4514 case SHKEY_Subkey_MUICache
:
4515 subkey
= mui_cacheW
;
4516 size_subkey
= sizeof(mui_cacheW
);
4518 case SHKEY_Subkey_FileExts
:
4519 subkey
= file_extsW
;
4520 size_subkey
= sizeof(file_extsW
);
4523 FIXME("unsupported flags (0x%08x)\n", flags
);
4528 size_user
= lstrlenW(sub_key
)*sizeof(WCHAR
);
4532 path
= HeapAlloc(GetProcessHeap(), 0, size_key
+size_subkey
+size_user
+sizeof(WCHAR
));
4534 ERR("Out of memory\n");
4538 memcpy(path
, key
, size_key
);
4540 memcpy(path
+size_key
/sizeof(WCHAR
), subkey
, size_subkey
);
4542 memcpy(path
+(size_key
+size_subkey
)/sizeof(WCHAR
), sub_key
, size_user
);
4543 path
[(size_key
+size_subkey
+size_user
)/sizeof(WCHAR
)] = '\0';
4546 RegCreateKeyExW((flags
&0xf)==SHKEY_Root_HKLM
?HKEY_LOCAL_MACHINE
:HKEY_CURRENT_USER
,
4547 path
, 0, NULL
, 0, MAXIMUM_ALLOWED
, NULL
, &hkey
, NULL
);
4549 RegOpenKeyExW((flags
&0xf)==SHKEY_Root_HKLM
?HKEY_LOCAL_MACHINE
:HKEY_CURRENT_USER
,
4550 path
, 0, MAXIMUM_ALLOWED
, &hkey
);
4552 HeapFree(GetProcessHeap(), 0, path
);
4556 /***********************************************************************
4557 * SHQueueUserWorkItem (SHLWAPI.@)
4559 BOOL WINAPI
SHQueueUserWorkItem(LPTHREAD_START_ROUTINE pfnCallback
,
4560 LPVOID pContext
, LONG lPriority
, DWORD_PTR dwTag
,
4561 DWORD_PTR
*pdwId
, LPCSTR pszModule
, DWORD dwFlags
)
4563 TRACE("(%p, %p, %d, %lx, %p, %s, %08x)\n", pfnCallback
, pContext
,
4564 lPriority
, dwTag
, pdwId
, debugstr_a(pszModule
), dwFlags
);
4566 if(lPriority
|| dwTag
|| pdwId
|| pszModule
|| dwFlags
)
4567 FIXME("Unsupported arguments\n");
4569 return QueueUserWorkItem(pfnCallback
, pContext
, 0);
4572 /***********************************************************************
4573 * SHSetTimerQueueTimer (SHLWAPI.263)
4575 HANDLE WINAPI
SHSetTimerQueueTimer(HANDLE hQueue
,
4576 WAITORTIMERCALLBACK pfnCallback
, LPVOID pContext
, DWORD dwDueTime
,
4577 DWORD dwPeriod
, LPCSTR lpszLibrary
, DWORD dwFlags
)
4581 /* SHSetTimerQueueTimer flags -> CreateTimerQueueTimer flags */
4582 if (dwFlags
& TPS_LONGEXECTIME
) {
4583 dwFlags
&= ~TPS_LONGEXECTIME
;
4584 dwFlags
|= WT_EXECUTELONGFUNCTION
;
4586 if (dwFlags
& TPS_EXECUTEIO
) {
4587 dwFlags
&= ~TPS_EXECUTEIO
;
4588 dwFlags
|= WT_EXECUTEINIOTHREAD
;
4591 if (!CreateTimerQueueTimer(&hNewTimer
, hQueue
, pfnCallback
, pContext
,
4592 dwDueTime
, dwPeriod
, dwFlags
))
4598 /***********************************************************************
4599 * IUnknown_OnFocusChangeIS (SHLWAPI.@)
4601 HRESULT WINAPI
IUnknown_OnFocusChangeIS(LPUNKNOWN lpUnknown
, LPUNKNOWN pFocusObject
, BOOL bFocus
)
4603 IInputObjectSite
*pIOS
= NULL
;
4604 HRESULT hRet
= E_INVALIDARG
;
4606 TRACE("(%p, %p, %s)\n", lpUnknown
, pFocusObject
, bFocus
? "TRUE" : "FALSE");
4610 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IInputObjectSite
,
4612 if (SUCCEEDED(hRet
) && pIOS
)
4614 hRet
= IInputObjectSite_OnFocusChangeIS(pIOS
, pFocusObject
, bFocus
);
4615 IInputObjectSite_Release(pIOS
);
4621 /***********************************************************************
4622 * SKAllocValueW (SHLWAPI.519)
4624 HRESULT WINAPI
SKAllocValueW(DWORD flags
, LPCWSTR subkey
, LPCWSTR value
, DWORD
*type
,
4625 LPVOID
*data
, DWORD
*count
)
4630 TRACE("(0x%x, %s, %s, %p, %p, %p)\n", flags
, debugstr_w(subkey
),
4631 debugstr_w(value
), type
, data
, count
);
4633 hkey
= SHGetShellKey(flags
, subkey
, FALSE
);
4635 return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
);
4637 ret
= SHQueryValueExW(hkey
, value
, NULL
, type
, NULL
, &size
);
4640 return HRESULT_FROM_WIN32(ret
);
4644 *data
= LocalAlloc(0, size
);
4647 return E_OUTOFMEMORY
;
4650 ret
= SHQueryValueExW(hkey
, value
, NULL
, type
, *data
, &size
);
4655 return HRESULT_FROM_WIN32(ret
);
4658 /***********************************************************************
4659 * SKDeleteValueW (SHLWAPI.518)
4661 HRESULT WINAPI
SKDeleteValueW(DWORD flags
, LPCWSTR subkey
, LPCWSTR value
)
4666 TRACE("(0x%x, %s %s)\n", flags
, debugstr_w(subkey
), debugstr_w(value
));
4668 hkey
= SHGetShellKey(flags
, subkey
, FALSE
);
4670 return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
);
4672 ret
= RegDeleteValueW(hkey
, value
);
4675 return HRESULT_FROM_WIN32(ret
);
4678 /***********************************************************************
4679 * SKGetValueW (SHLWAPI.516)
4681 HRESULT WINAPI
SKGetValueW(DWORD flags
, LPCWSTR subkey
, LPCWSTR value
, DWORD
*type
,
4682 void *data
, DWORD
*count
)
4687 TRACE("(0x%x, %s, %s, %p, %p, %p)\n", flags
, debugstr_w(subkey
),
4688 debugstr_w(value
), type
, data
, count
);
4690 hkey
= SHGetShellKey(flags
, subkey
, FALSE
);
4692 return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
);
4694 ret
= SHQueryValueExW(hkey
, value
, NULL
, type
, data
, count
);
4697 return HRESULT_FROM_WIN32(ret
);
4700 /***********************************************************************
4701 * SKSetValueW (SHLWAPI.516)
4703 HRESULT WINAPI
SKSetValueW(DWORD flags
, LPCWSTR subkey
, LPCWSTR value
,
4704 DWORD type
, void *data
, DWORD count
)
4709 TRACE("(0x%x, %s, %s, %x, %p, %d)\n", flags
, debugstr_w(subkey
),
4710 debugstr_w(value
), type
, data
, count
);
4712 hkey
= SHGetShellKey(flags
, subkey
, TRUE
);
4714 return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
);
4716 ret
= RegSetValueExW(hkey
, value
, 0, type
, data
, count
);
4719 return HRESULT_FROM_WIN32(ret
);
4722 typedef HRESULT (WINAPI
*DllGetVersion_func
)(DLLVERSIONINFO
*);
4724 /***********************************************************************
4725 * GetUIVersion (SHLWAPI.452)
4727 DWORD WINAPI
GetUIVersion(void)
4729 static DWORD version
;
4733 DllGetVersion_func pDllGetVersion
;
4734 HMODULE dll
= LoadLibraryA("shell32.dll");
4737 pDllGetVersion
= (DllGetVersion_func
)GetProcAddress(dll
, "DllGetVersion");
4741 dvi
.cbSize
= sizeof(DLLVERSIONINFO
);
4742 if (pDllGetVersion(&dvi
) == S_OK
) version
= dvi
.dwMajorVersion
;
4745 if (!version
) version
= 3; /* old shell dlls don't have DllGetVersion */
4750 /***********************************************************************
4751 * ShellMessageBoxWrapW [SHLWAPI.388]
4753 * See shell32.ShellMessageBoxW
4756 * shlwapi.ShellMessageBoxWrapW is a duplicate of shell32.ShellMessageBoxW
4757 * because we can't forward to it in the .spec file since it's exported by
4758 * ordinal. If you change the implementation here please update the code in
4761 INT WINAPIV
ShellMessageBoxWrapW(HINSTANCE hInstance
, HWND hWnd
, LPCWSTR lpText
,
4762 LPCWSTR lpCaption
, UINT uType
, ...)
4764 WCHAR
*szText
= NULL
, szTitle
[100];
4765 LPCWSTR pszText
, pszTitle
= szTitle
;
4770 __ms_va_start(args
, uType
);
4772 TRACE("(%p,%p,%p,%p,%08x)\n", hInstance
, hWnd
, lpText
, lpCaption
, uType
);
4774 if (IS_INTRESOURCE(lpCaption
))
4775 LoadStringW(hInstance
, LOWORD(lpCaption
), szTitle
, sizeof(szTitle
)/sizeof(szTitle
[0]));
4777 pszTitle
= lpCaption
;
4779 if (IS_INTRESOURCE(lpText
))
4782 UINT len
= LoadStringW(hInstance
, LOWORD(lpText
), (LPWSTR
)&ptr
, 0);
4786 szText
= HeapAlloc(GetProcessHeap(), 0, (len
+ 1) * sizeof(WCHAR
));
4787 if (szText
) LoadStringW(hInstance
, LOWORD(lpText
), szText
, len
+ 1);
4791 WARN("Failed to load id %d\n", LOWORD(lpText
));
4799 FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_STRING
,
4800 pszText
, 0, 0, (LPWSTR
)&pszTemp
, 0, &args
);
4804 ret
= MessageBoxW(hWnd
, pszTemp
, pszTitle
, uType
);
4806 HeapFree(GetProcessHeap(), 0, szText
);
4811 /***********************************************************************
4812 * ZoneComputePaneSize [SHLWAPI.382]
4814 UINT WINAPI
ZoneComputePaneSize(HWND hwnd
)
4820 /***********************************************************************
4821 * SHChangeNotifyWrap [SHLWAPI.394]
4823 void WINAPI
SHChangeNotifyWrap(LONG wEventId
, UINT uFlags
, LPCVOID dwItem1
, LPCVOID dwItem2
)
4825 SHChangeNotify(wEventId
, uFlags
, dwItem1
, dwItem2
);
4828 typedef struct SHELL_USER_SID
{ /* according to MSDN this should be in shlobj.h... */
4829 SID_IDENTIFIER_AUTHORITY sidAuthority
;
4830 DWORD dwUserGroupID
;
4832 } SHELL_USER_SID
, *PSHELL_USER_SID
;
4834 typedef struct SHELL_USER_PERMISSION
{ /* ...and this should be in shlwapi.h */
4835 SHELL_USER_SID susID
;
4839 DWORD dwInheritMask
;
4840 DWORD dwInheritAccessMask
;
4841 } SHELL_USER_PERMISSION
, *PSHELL_USER_PERMISSION
;
4843 /***********************************************************************
4844 * GetShellSecurityDescriptor [SHLWAPI.475]
4846 * prepares SECURITY_DESCRIPTOR from a set of ACEs
4849 * apUserPerm [I] array of pointers to SHELL_USER_PERMISSION structures,
4850 * each of which describes permissions to apply
4851 * cUserPerm [I] number of entries in apUserPerm array
4854 * success: pointer to SECURITY_DESCRIPTOR
4858 * Call should free returned descriptor with LocalFree
4860 PSECURITY_DESCRIPTOR WINAPI
GetShellSecurityDescriptor(const PSHELL_USER_PERMISSION
*apUserPerm
, int cUserPerm
)
4863 PSID cur_user
= NULL
;
4867 PSECURITY_DESCRIPTOR psd
= NULL
;
4869 TRACE("%p %d\n", apUserPerm
, cUserPerm
);
4871 if (apUserPerm
== NULL
|| cUserPerm
<= 0)
4874 sidlist
= HeapAlloc(GetProcessHeap(), 0, cUserPerm
* sizeof(PSID
));
4878 acl_size
= sizeof(ACL
);
4880 for(sid_count
= 0; sid_count
< cUserPerm
; sid_count
++)
4882 static SHELL_USER_SID null_sid
= {{SECURITY_NULL_SID_AUTHORITY
}, 0, 0};
4883 PSHELL_USER_PERMISSION perm
= apUserPerm
[sid_count
];
4884 PSHELL_USER_SID sid
= &perm
->susID
;
4888 if (!memcmp((void*)sid
, (void*)&null_sid
, sizeof(SHELL_USER_SID
)))
4889 { /* current user's SID */
4893 DWORD bufsize
= sizeof(tuUser
);
4895 ret
= OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY
, &Token
);
4898 ret
= GetTokenInformation(Token
, TokenUser
, (void*)tuUser
, bufsize
, &bufsize
);
4900 cur_user
= ((PTOKEN_USER
)tuUser
)->User
.Sid
;
4905 } else if (sid
->dwUserID
==0) /* one sub-authority */
4906 ret
= AllocateAndInitializeSid(&sid
->sidAuthority
, 1, sid
->dwUserGroupID
, 0,
4907 0, 0, 0, 0, 0, 0, &pSid
);
4909 ret
= AllocateAndInitializeSid(&sid
->sidAuthority
, 2, sid
->dwUserGroupID
, sid
->dwUserID
,
4910 0, 0, 0, 0, 0, 0, &pSid
);
4914 sidlist
[sid_count
] = pSid
;
4915 /* increment acl_size (1 ACE for non-inheritable and 2 ACEs for inheritable records */
4916 acl_size
+= (sizeof(ACCESS_ALLOWED_ACE
)-sizeof(DWORD
) + GetLengthSid(pSid
)) * (perm
->fInherit
? 2 : 1);
4919 psd
= LocalAlloc(0, sizeof(SECURITY_DESCRIPTOR
) + acl_size
);
4923 PACL pAcl
= (PACL
)(((BYTE
*)psd
)+sizeof(SECURITY_DESCRIPTOR
));
4925 if (!InitializeSecurityDescriptor(psd
, SECURITY_DESCRIPTOR_REVISION
))
4928 if (!InitializeAcl(pAcl
, acl_size
, ACL_REVISION
))
4931 for(i
= 0; i
< sid_count
; i
++)
4933 PSHELL_USER_PERMISSION sup
= apUserPerm
[i
];
4934 PSID sid
= sidlist
[i
];
4936 switch(sup
->dwAccessType
)
4938 case ACCESS_ALLOWED_ACE_TYPE
:
4939 if (!AddAccessAllowedAce(pAcl
, ACL_REVISION
, sup
->dwAccessMask
, sid
))
4941 if (sup
->fInherit
&& !AddAccessAllowedAceEx(pAcl
, ACL_REVISION
,
4942 (BYTE
)sup
->dwInheritMask
, sup
->dwInheritAccessMask
, sid
))
4945 case ACCESS_DENIED_ACE_TYPE
:
4946 if (!AddAccessDeniedAce(pAcl
, ACL_REVISION
, sup
->dwAccessMask
, sid
))
4948 if (sup
->fInherit
&& !AddAccessDeniedAceEx(pAcl
, ACL_REVISION
,
4949 (BYTE
)sup
->dwInheritMask
, sup
->dwInheritAccessMask
, sid
))
4957 if (!SetSecurityDescriptorDacl(psd
, TRUE
, pAcl
, FALSE
))
4966 for(i
= 0; i
< sid_count
; i
++)
4968 if (!cur_user
|| sidlist
[i
] != cur_user
)
4969 FreeSid(sidlist
[i
]);
4971 HeapFree(GetProcessHeap(), 0, sidlist
);
4976 /***********************************************************************
4977 * SHCreatePropertyBagOnRegKey [SHLWAPI.471]
4979 * Creates a property bag from a registry key
4982 * hKey [I] Handle to the desired registry key
4983 * subkey [I] Name of desired subkey, or NULL to open hKey directly
4984 * grfMode [I] Optional flags
4985 * riid [I] IID of requested property bag interface
4986 * ppv [O] Address to receive pointer to the new interface
4990 * failure: error code
4993 HRESULT WINAPI
SHCreatePropertyBagOnRegKey (HKEY hKey
, LPCWSTR subkey
,
4994 DWORD grfMode
, REFIID riid
, void **ppv
)
4996 FIXME("%p %s %d %s %p STUB\n", hKey
, debugstr_w(subkey
), grfMode
,
4997 debugstr_guid(riid
), ppv
);
5002 /***********************************************************************
5003 * SHGetViewStatePropertyBag [SHLWAPI.515]
5005 * Retrieves a property bag in which the view state information of a folder
5009 * pidl [I] PIDL of the folder requested
5010 * bag_name [I] Name of the property bag requested
5011 * flags [I] Optional flags
5012 * riid [I] IID of requested property bag interface
5013 * ppv [O] Address to receive pointer to the new interface
5017 * failure: error code
5020 HRESULT WINAPI
SHGetViewStatePropertyBag(LPCITEMIDLIST pidl
, LPWSTR bag_name
,
5021 DWORD flags
, REFIID riid
, void **ppv
)
5023 FIXME("%p %s %d %s %p STUB\n", pidl
, debugstr_w(bag_name
), flags
,
5024 debugstr_guid(riid
), ppv
);
5029 /***********************************************************************
5030 * SHFormatDateTimeW [SHLWAPI.354]
5032 * Produces a string representation of a time.
5035 * fileTime [I] Pointer to FILETIME structure specifying the time
5036 * flags [I] Flags specifying the desired output
5037 * buf [O] Pointer to buffer for output
5038 * size [I] Number of characters that can be contained in buffer
5041 * success: number of characters written to the buffer
5045 INT WINAPI
SHFormatDateTimeW(const FILETIME UNALIGNED
*fileTime
, DWORD
*flags
,
5046 LPWSTR buf
, UINT size
)
5048 #define SHFORMATDT_UNSUPPORTED_FLAGS (FDTF_RELATIVE | FDTF_LTRDATE | FDTF_RTLDATE | FDTF_NOAUTOREADINGORDER)
5049 DWORD fmt_flags
= flags
? *flags
: FDTF_DEFAULT
;
5054 TRACE("%p %p %p %u\n", fileTime
, flags
, buf
, size
);
5059 if (fmt_flags
& SHFORMATDT_UNSUPPORTED_FLAGS
)
5060 FIXME("ignoring some flags - 0x%08x\n", fmt_flags
& SHFORMATDT_UNSUPPORTED_FLAGS
);
5062 FileTimeToLocalFileTime(fileTime
, &ft
);
5063 FileTimeToSystemTime(&ft
, &st
);
5065 /* first of all date */
5066 if (fmt_flags
& (FDTF_LONGDATE
| FDTF_SHORTDATE
))
5068 static const WCHAR sep1
[] = {',',' ',0};
5069 static const WCHAR sep2
[] = {' ',0};
5071 DWORD date
= fmt_flags
& FDTF_LONGDATE
? DATE_LONGDATE
: DATE_SHORTDATE
;
5072 ret
= GetDateFormatW(LOCALE_USER_DEFAULT
, date
, &st
, NULL
, buf
, size
);
5073 if (ret
>= size
) return ret
;
5076 if (ret
< size
&& (fmt_flags
& (FDTF_LONGTIME
| FDTF_SHORTTIME
)))
5078 if ((fmt_flags
& FDTF_LONGDATE
) && (ret
< size
+ 2))
5080 lstrcatW(&buf
[ret
-1], sep1
);
5085 lstrcatW(&buf
[ret
-1], sep2
);
5091 if (fmt_flags
& (FDTF_LONGTIME
| FDTF_SHORTTIME
))
5093 DWORD time
= fmt_flags
& FDTF_LONGTIME
? 0 : TIME_NOSECONDS
;
5096 ret
+= GetTimeFormatW(LOCALE_USER_DEFAULT
, time
, &st
, NULL
, &buf
[ret
], size
- ret
);
5101 #undef SHFORMATDT_UNSUPPORTED_FLAGS
5104 /***********************************************************************
5105 * SHFormatDateTimeA [SHLWAPI.353]
5107 * See SHFormatDateTimeW.
5110 INT WINAPI
SHFormatDateTimeA(const FILETIME UNALIGNED
*fileTime
, DWORD
*flags
,
5111 LPSTR buf
, UINT size
)
5119 bufW
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
) * size
);
5120 retval
= SHFormatDateTimeW(fileTime
, flags
, bufW
, size
);
5123 WideCharToMultiByte(CP_ACP
, 0, bufW
, -1, buf
, size
, NULL
, NULL
);
5125 HeapFree(GetProcessHeap(), 0, bufW
);
5129 /***********************************************************************
5130 * ZoneCheckUrlExW [SHLWAPI.231]
5132 * Checks the details of the security zone for the supplied site. (?)
5136 * szURL [I] Pointer to the URL to check
5138 * Other parameters currently unknown.
5144 INT WINAPI
ZoneCheckUrlExW(LPWSTR szURL
, PVOID pUnknown
, DWORD dwUnknown2
,
5145 DWORD dwUnknown3
, DWORD dwUnknown4
, DWORD dwUnknown5
, DWORD dwUnknown6
,
5148 FIXME("(%s,%p,%x,%x,%x,%x,%x,%x) STUB\n", debugstr_w(szURL
), pUnknown
, dwUnknown2
,
5149 dwUnknown3
, dwUnknown4
, dwUnknown5
, dwUnknown6
, dwUnknown7
);
5154 /***********************************************************************
5155 * SHVerbExistsNA [SHLWAPI.196]
5160 * verb [I] a string, often appears to be an extension.
5162 * Other parameters currently unknown.
5167 INT WINAPI
SHVerbExistsNA(LPSTR verb
, PVOID pUnknown
, PVOID pUnknown2
, DWORD dwUnknown3
)
5169 FIXME("(%s, %p, %p, %i) STUB\n",verb
, pUnknown
, pUnknown2
, dwUnknown3
);
5173 /*************************************************************************
5176 * Undocumented: Implementation guessed at via Name and behavior
5179 * lpUnknown [I] Object to get an IServiceProvider interface from
5180 * riid [I] Function requested for QueryService call
5181 * lppOut [O] Destination for the service interface pointer
5184 * Success: S_OK. lppOut contains an object providing the requested service
5185 * Failure: An HRESULT error code
5188 * lpUnknown is expected to support the IServiceProvider interface.
5190 HRESULT WINAPI
IUnknown_QueryServiceForWebBrowserApp(IUnknown
* lpUnknown
,
5191 REFGUID riid
, LPVOID
*lppOut
)
5193 FIXME("%p %s %p semi-STUB\n", lpUnknown
, debugstr_guid(riid
), lppOut
);
5194 return IUnknown_QueryService(lpUnknown
,&IID_IWebBrowserApp
,riid
,lppOut
);
5197 /**************************************************************************
5198 * SHPropertyBag_ReadLONG (SHLWAPI.496)
5200 * This function asks a property bag to read a named property as a LONG.
5203 * ppb: a IPropertyBag interface
5204 * pszPropName: Unicode string that names the property
5205 * pValue: address to receive the property value as a 32-bit signed integer
5210 HRESULT WINAPI
SHPropertyBag_ReadLONG(IPropertyBag
*ppb
, LPCWSTR pszPropName
, LPLONG pValue
)
5214 TRACE("%p %s %p\n", ppb
,debugstr_w(pszPropName
),pValue
);
5215 if (!pszPropName
|| !ppb
|| !pValue
)
5216 return E_INVALIDARG
;
5218 hr
= IPropertyBag_Read(ppb
, pszPropName
, &var
, NULL
);
5221 if (V_VT(&var
) == VT_I4
)
5222 *pValue
= V_I4(&var
);
5224 hr
= DISP_E_BADVARTYPE
;
5230 /**************************************************************************
5231 * SHPropertyBag_WriteLONG (SHLWAPI.497)
5233 * This function asks a property bag to write a named property as a LONG.
5236 * ppb: a IPropertyBag interface
5237 * pszPropName: Unicode string that names the property
5238 * lValue: address to receive the property value as a 32-bit signed integer
5243 HRESULT WINAPI
SHPropertyBag_WriteLONG(IPropertyBag
*ppb
, LPCWSTR pszPropName
, LONG lValue
)
5249 /**************************************************************************
5250 * SHPropertyBag_WriteStr (SHLWAPI.495)
5252 * This function asks a property bag to write a string as the value of a named property.
5255 * ppb: a IPropertyBag interface
5256 * pszPropName: Unicode string that names the property
5257 * pValue: address to write the property value
5262 HRESULT WINAPI
SHPropertyBag_WriteStr(IPropertyBag
*ppb
, LPCWSTR pszPropName
, LPCWSTR pszValue
)
5269 /* return flags for SHGetObjectCompatFlags, names derived from registry value names */
5270 #define OBJCOMPAT_OTNEEDSSFCACHE 0x00000001
5271 #define OBJCOMPAT_NO_WEBVIEW 0x00000002
5272 #define OBJCOMPAT_UNBINDABLE 0x00000004
5273 #define OBJCOMPAT_PINDLL 0x00000008
5274 #define OBJCOMPAT_NEEDSFILESYSANCESTOR 0x00000010
5275 #define OBJCOMPAT_NOTAFILESYSTEM 0x00000020
5276 #define OBJCOMPAT_CTXMENU_NOVERBS 0x00000040
5277 #define OBJCOMPAT_CTXMENU_LIMITEDQI 0x00000080
5278 #define OBJCOMPAT_COCREATESHELLFOLDERONLY 0x00000100
5279 #define OBJCOMPAT_NEEDSSTORAGEANCESTOR 0x00000200
5280 #define OBJCOMPAT_NOLEGACYWEBVIEW 0x00000400
5281 #define OBJCOMPAT_CTXMENU_XPQCMFLAGS 0x00001000
5282 #define OBJCOMPAT_NOIPROPERTYSTORE 0x00002000
5284 /* a search table for compatibility flags */
5285 struct objcompat_entry
{
5286 const WCHAR name
[30];
5290 /* expected to be sorted by name */
5291 static const struct objcompat_entry objcompat_table
[] = {
5292 { {'C','O','C','R','E','A','T','E','S','H','E','L','L','F','O','L','D','E','R','O','N','L','Y',0},
5293 OBJCOMPAT_COCREATESHELLFOLDERONLY
},
5294 { {'C','T','X','M','E','N','U','_','L','I','M','I','T','E','D','Q','I',0},
5295 OBJCOMPAT_CTXMENU_LIMITEDQI
},
5296 { {'C','T','X','M','E','N','U','_','N','O','V','E','R','B','S',0},
5297 OBJCOMPAT_CTXMENU_LIMITEDQI
},
5298 { {'C','T','X','M','E','N','U','_','X','P','Q','C','M','F','L','A','G','S',0},
5299 OBJCOMPAT_CTXMENU_XPQCMFLAGS
},
5300 { {'N','E','E','D','S','F','I','L','E','S','Y','S','A','N','C','E','S','T','O','R',0},
5301 OBJCOMPAT_NEEDSFILESYSANCESTOR
},
5302 { {'N','E','E','D','S','S','T','O','R','A','G','E','A','N','C','E','S','T','O','R',0},
5303 OBJCOMPAT_NEEDSSTORAGEANCESTOR
},
5304 { {'N','O','I','P','R','O','P','E','R','T','Y','S','T','O','R','E',0},
5305 OBJCOMPAT_NOIPROPERTYSTORE
},
5306 { {'N','O','L','E','G','A','C','Y','W','E','B','V','I','E','W',0},
5307 OBJCOMPAT_NOLEGACYWEBVIEW
},
5308 { {'N','O','T','A','F','I','L','E','S','Y','S','T','E','M',0},
5309 OBJCOMPAT_NOTAFILESYSTEM
},
5310 { {'N','O','_','W','E','B','V','I','E','W',0},
5311 OBJCOMPAT_NO_WEBVIEW
},
5312 { {'O','T','N','E','E','D','S','S','F','C','A','C','H','E',0},
5313 OBJCOMPAT_OTNEEDSSFCACHE
},
5314 { {'P','I','N','D','L','L',0},
5316 { {'U','N','B','I','N','D','A','B','L','E',0},
5317 OBJCOMPAT_UNBINDABLE
}
5320 /**************************************************************************
5321 * SHGetObjectCompatFlags (SHLWAPI.476)
5323 * Function returns an integer representation of compatibility flags stored
5324 * in registry for CLSID under ShellCompatibility subkey.
5327 * pUnk: pointer to object IUnknown interface, idetifies CLSID
5328 * clsid: pointer to CLSID to retrieve data for
5331 * 0 on failure, flags set on success
5333 DWORD WINAPI
SHGetObjectCompatFlags(IUnknown
*pUnk
, const CLSID
*clsid
)
5335 static const WCHAR compatpathW
[] =
5336 {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
5337 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
5338 'S','h','e','l','l','C','o','m','p','a','t','i','b','i','l','i','t','y','\\',
5339 'O','b','j','e','c','t','s','\\','%','s',0};
5340 WCHAR strW
[sizeof(compatpathW
)/sizeof(WCHAR
) + 38 /* { CLSID } */];
5341 DWORD ret
, length
= sizeof(strW
)/sizeof(WCHAR
);
5346 TRACE("%p %s\n", pUnk
, debugstr_guid(clsid
));
5348 if (!pUnk
&& !clsid
) return 0;
5352 FIXME("iface not handled\n");
5356 StringFromCLSID(clsid
, &clsid_str
);
5357 sprintfW(strW
, compatpathW
, clsid_str
);
5358 CoTaskMemFree(clsid_str
);
5360 ret
= RegOpenKeyW(HKEY_LOCAL_MACHINE
, strW
, &key
);
5361 if (ret
!= ERROR_SUCCESS
) return 0;
5363 /* now collect flag values */
5365 for (i
= 0; RegEnumValueW(key
, i
, strW
, &length
, NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
; i
++)
5367 INT left
, right
, res
, x
;
5369 /* search in table */
5371 right
= sizeof(objcompat_table
) / sizeof(struct objcompat_entry
) - 1;
5373 while (right
>= left
) {
5374 x
= (left
+ right
) / 2;
5375 res
= strcmpW(strW
, objcompat_table
[x
].name
);
5378 ret
|= objcompat_table
[x
].value
;
5387 length
= sizeof(strW
)/sizeof(WCHAR
);