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
,
83 TRACE("Returning handle NULL\n");
87 /* Get dest process handle */
88 if (dwDstProcId
== dwMyProcId
)
89 hDst
= GetCurrentProcess();
91 hDst
= OpenProcess(PROCESS_DUP_HANDLE
, 0, dwDstProcId
);
95 /* Get src process handle */
96 if (dwSrcProcId
== dwMyProcId
)
97 hSrc
= GetCurrentProcess();
99 hSrc
= OpenProcess(PROCESS_DUP_HANDLE
, 0, dwSrcProcId
);
103 /* Make handle available to dest process */
104 if (!DuplicateHandle(hSrc
, hShared
, hDst
, &hRet
,
105 dwAccess
, 0, dwOptions
| DUPLICATE_SAME_ACCESS
))
108 if (dwSrcProcId
!= dwMyProcId
)
112 if (dwDstProcId
!= dwMyProcId
)
116 TRACE("Returning handle %p\n", hRet
);
120 /*************************************************************************
123 * Create a block of sharable memory and initialise it with data.
126 * lpvData [I] Pointer to data to write
127 * dwSize [I] Size of data
128 * dwProcId [I] ID of process owning data
131 * Success: A shared memory handle
135 * Ordinals 7-11 provide a set of calls to create shared memory between a
136 * group of processes. The shared memory is treated opaquely in that its size
137 * is not exposed to clients who map it. This is accomplished by storing
138 * the size of the map as the first DWORD of mapped data, and then offsetting
139 * the view pointer returned by this size.
142 HANDLE WINAPI
SHAllocShared(LPCVOID lpvData
, DWORD dwSize
, DWORD dwProcId
)
148 TRACE("(%p,%d,%d)\n", lpvData
, dwSize
, dwProcId
);
150 /* Create file mapping of the correct length */
151 hMap
= CreateFileMappingA(INVALID_HANDLE_VALUE
, NULL
, FILE_MAP_READ
, 0,
152 dwSize
+ sizeof(dwSize
), NULL
);
156 /* Get a view in our process address space */
157 pMapped
= MapViewOfFile(hMap
, FILE_MAP_READ
| FILE_MAP_WRITE
, 0, 0, 0);
161 /* Write size of data, followed by the data, to the view */
162 *((DWORD
*)pMapped
) = dwSize
;
164 memcpy((char *) pMapped
+ sizeof(dwSize
), lpvData
, dwSize
);
166 /* Release view. All further views mapped will be opaque */
167 UnmapViewOfFile(pMapped
);
168 hRet
= SHMapHandle(hMap
, GetCurrentProcessId(), dwProcId
,
169 FILE_MAP_ALL_ACCESS
, DUPLICATE_SAME_ACCESS
);
176 /*************************************************************************
179 * Get a pointer to a block of shared memory from a shared memory handle.
182 * hShared [I] Shared memory handle
183 * dwProcId [I] ID of process owning hShared
186 * Success: A pointer to the shared memory
190 PVOID WINAPI
SHLockShared(HANDLE hShared
, DWORD dwProcId
)
195 TRACE("(%p %d)\n", hShared
, dwProcId
);
197 /* Get handle to shared memory for current process */
198 hDup
= SHMapHandle(hShared
, dwProcId
, GetCurrentProcessId(), FILE_MAP_ALL_ACCESS
, 0);
201 pMapped
= MapViewOfFile(hDup
, FILE_MAP_READ
| FILE_MAP_WRITE
, 0, 0, 0);
205 return (char *) pMapped
+ sizeof(DWORD
); /* Hide size */
209 /*************************************************************************
212 * Release a pointer to a block of shared memory.
215 * lpView [I] Shared memory pointer
222 BOOL WINAPI
SHUnlockShared(LPVOID lpView
)
224 TRACE("(%p)\n", lpView
);
225 return UnmapViewOfFile((char *) lpView
- sizeof(DWORD
)); /* Include size */
228 /*************************************************************************
231 * Destroy a block of sharable memory.
234 * hShared [I] Shared memory handle
235 * dwProcId [I] ID of process owning hShared
242 BOOL WINAPI
SHFreeShared(HANDLE hShared
, DWORD dwProcId
)
246 TRACE("(%p %d)\n", hShared
, dwProcId
);
251 /* Get a copy of the handle for our process, closing the source handle */
252 hClose
= SHMapHandle(hShared
, dwProcId
, GetCurrentProcessId(),
253 FILE_MAP_ALL_ACCESS
,DUPLICATE_CLOSE_SOURCE
);
254 /* Close local copy */
255 return CloseHandle(hClose
);
258 /*************************************************************************
261 * Create and register a clipboard enumerator for a web browser.
264 * lpBC [I] Binding context
265 * lpUnknown [I] An object exposing the IWebBrowserApp interface
269 * Failure: An HRESULT error code.
272 * The enumerator is stored as a property of the web browser. If it does not
273 * yet exist, it is created and set before being registered.
275 HRESULT WINAPI
RegisterDefaultAcceptHeaders(LPBC lpBC
, IUnknown
*lpUnknown
)
277 static const WCHAR szProperty
[] = { '{','D','0','F','C','A','4','2','0',
278 '-','D','3','F','5','-','1','1','C','F', '-','B','2','1','1','-','0',
279 '0','A','A','0','0','4','A','E','8','3','7','}','\0' };
281 IEnumFORMATETC
* pIEnumFormatEtc
= NULL
;
284 IWebBrowserApp
* pBrowser
;
286 TRACE("(%p, %p)\n", lpBC
, lpUnknown
);
288 hr
= IUnknown_QueryService(lpUnknown
, &IID_IWebBrowserApp
, &IID_IWebBrowserApp
, (void**)&pBrowser
);
292 V_VT(&var
) = VT_EMPTY
;
294 /* The property we get is the browsers clipboard enumerator */
295 property
= SysAllocString(szProperty
);
296 hr
= IWebBrowserApp_GetProperty(pBrowser
, property
, &var
);
297 SysFreeString(property
);
298 if (FAILED(hr
)) goto exit
;
300 if (V_VT(&var
) == VT_EMPTY
)
302 /* Iterate through accepted documents and RegisterClipBoardFormatA() them */
303 char szKeyBuff
[128], szValueBuff
[128];
304 DWORD dwKeySize
, dwValueSize
, dwRet
= 0, dwCount
= 0, dwNumValues
, dwType
;
305 FORMATETC
* formatList
, *format
;
308 TRACE("Registering formats and creating IEnumFORMATETC instance\n");
310 if (!RegOpenKeyA(HKEY_LOCAL_MACHINE
, "Software\\Microsoft\\Windows\\Current"
311 "Version\\Internet Settings\\Accepted Documents", &hDocs
))
317 /* Get count of values in key */
320 dwKeySize
= sizeof(szKeyBuff
);
321 dwRet
= RegEnumValueA(hDocs
,dwCount
,szKeyBuff
,&dwKeySize
,0,&dwType
,0,0);
325 dwNumValues
= dwCount
;
327 /* Note: dwCount = number of items + 1; The extra item is the end node */
328 format
= formatList
= HeapAlloc(GetProcessHeap(), 0, dwCount
* sizeof(FORMATETC
));
343 /* Register clipboard formats for the values and populate format list */
344 while(!dwRet
&& dwCount
< dwNumValues
)
346 dwKeySize
= sizeof(szKeyBuff
);
347 dwValueSize
= sizeof(szValueBuff
);
348 dwRet
= RegEnumValueA(hDocs
, dwCount
, szKeyBuff
, &dwKeySize
, 0, &dwType
,
349 (PBYTE
)szValueBuff
, &dwValueSize
);
352 HeapFree(GetProcessHeap(), 0, formatList
);
358 format
->cfFormat
= RegisterClipboardFormatA(szValueBuff
);
360 format
->dwAspect
= 1;
371 /* Terminate the (maybe empty) list, last entry has a cfFormat of 0 */
372 format
->cfFormat
= 0;
374 format
->dwAspect
= 1;
378 /* Create a clipboard enumerator */
379 hr
= CreateFormatEnumerator(dwNumValues
, formatList
, &pIEnumFormatEtc
);
380 HeapFree(GetProcessHeap(), 0, formatList
);
381 if (FAILED(hr
)) goto exit
;
383 /* Set our enumerator as the browsers property */
384 V_VT(&var
) = VT_UNKNOWN
;
385 V_UNKNOWN(&var
) = (IUnknown
*)pIEnumFormatEtc
;
387 property
= SysAllocString(szProperty
);
388 hr
= IWebBrowserApp_PutProperty(pBrowser
, property
, var
);
389 SysFreeString(property
);
392 IEnumFORMATETC_Release(pIEnumFormatEtc
);
397 if (V_VT(&var
) == VT_UNKNOWN
)
399 /* Our variant is holding the clipboard enumerator */
400 IUnknown
* pIUnknown
= V_UNKNOWN(&var
);
401 IEnumFORMATETC
* pClone
= NULL
;
403 TRACE("Retrieved IEnumFORMATETC property\n");
405 /* Get an IEnumFormatEtc interface from the variants value */
406 pIEnumFormatEtc
= NULL
;
407 hr
= IUnknown_QueryInterface(pIUnknown
, &IID_IEnumFORMATETC
, (void**)&pIEnumFormatEtc
);
408 if (hr
== S_OK
&& pIEnumFormatEtc
)
410 /* Clone and register the enumerator */
411 hr
= IEnumFORMATETC_Clone(pIEnumFormatEtc
, &pClone
);
412 if (hr
== S_OK
&& pClone
)
414 RegisterFormatEnumerator(lpBC
, pClone
, 0);
416 IEnumFORMATETC_Release(pClone
);
419 IUnknown_Release(pIUnknown
);
421 IUnknown_Release(V_UNKNOWN(&var
));
425 IWebBrowserApp_Release(pBrowser
);
429 /*************************************************************************
432 * Get Explorers "AcceptLanguage" setting.
435 * langbuf [O] Destination for language string
436 * buflen [I] Length of langbuf in characters
437 * [0] Success: used length of langbuf
440 * Success: S_OK. langbuf is set to the language string found.
441 * Failure: E_FAIL, If any arguments are invalid, error occurred, or Explorer
442 * does not contain the setting.
443 * E_NOT_SUFFICIENT_BUFFER, If the buffer is not big enough
445 HRESULT WINAPI
GetAcceptLanguagesW( LPWSTR langbuf
, LPDWORD buflen
)
447 static const WCHAR szkeyW
[] = {
448 'S','o','f','t','w','a','r','e','\\',
449 'M','i','c','r','o','s','o','f','t','\\',
450 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
451 'I','n','t','e','r','n','a','t','i','o','n','a','l',0};
452 static const WCHAR valueW
[] = {
453 'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0};
454 DWORD mystrlen
, mytype
;
461 TRACE("(%p, %p) *%p: %d\n", langbuf
, buflen
, buflen
, buflen
? *buflen
: -1);
463 if(!langbuf
|| !buflen
|| !*buflen
)
466 mystrlen
= (*buflen
> 20) ? *buflen
: 20 ;
467 len
= mystrlen
* sizeof(WCHAR
);
468 mystr
= HeapAlloc(GetProcessHeap(), 0, len
);
470 RegOpenKeyW(HKEY_CURRENT_USER
, szkeyW
, &mykey
);
471 lres
= RegQueryValueExW(mykey
, valueW
, 0, &mytype
, (PBYTE
)mystr
, &len
);
473 len
= lstrlenW(mystr
);
475 if (!lres
&& (*buflen
> len
)) {
476 lstrcpyW(langbuf
, mystr
);
478 HeapFree(GetProcessHeap(), 0, mystr
);
482 /* Did not find a value in the registry or the user buffer is too small */
483 mylcid
= GetUserDefaultLCID();
484 LcidToRfc1766W(mylcid
, mystr
, mystrlen
);
485 len
= lstrlenW(mystr
);
487 memcpy( langbuf
, mystr
, min(*buflen
, len
+1)*sizeof(WCHAR
) );
488 HeapFree(GetProcessHeap(), 0, mystr
);
496 return E_NOT_SUFFICIENT_BUFFER
;
499 /*************************************************************************
502 * Ascii version of GetAcceptLanguagesW.
504 HRESULT WINAPI
GetAcceptLanguagesA( LPSTR langbuf
, LPDWORD buflen
)
507 DWORD buflenW
, convlen
;
510 TRACE("(%p, %p) *%p: %d\n", langbuf
, buflen
, buflen
, buflen
? *buflen
: -1);
512 if(!langbuf
|| !buflen
|| !*buflen
) return E_FAIL
;
515 langbufW
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
) * buflenW
);
516 retval
= GetAcceptLanguagesW(langbufW
, &buflenW
);
520 convlen
= WideCharToMultiByte(CP_ACP
, 0, langbufW
, -1, langbuf
, *buflen
, NULL
, NULL
);
521 convlen
--; /* do not count the terminating 0 */
523 else /* copy partial string anyway */
525 convlen
= WideCharToMultiByte(CP_ACP
, 0, langbufW
, *buflen
, langbuf
, *buflen
, NULL
, NULL
);
526 if (convlen
< *buflen
)
528 langbuf
[convlen
] = 0;
529 convlen
--; /* do not count the terminating 0 */
536 *buflen
= buflenW
? convlen
: 0;
538 HeapFree(GetProcessHeap(), 0, langbufW
);
542 /*************************************************************************
545 * Convert a GUID to a string.
548 * guid [I] GUID to convert
549 * lpszDest [O] Destination for string
550 * cchMax [I] Length of output buffer
553 * The length of the string created.
555 INT WINAPI
SHStringFromGUIDA(REFGUID guid
, LPSTR lpszDest
, INT cchMax
)
560 TRACE("(%s,%p,%d)\n", debugstr_guid(guid
), lpszDest
, cchMax
);
562 sprintf(xguid
, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
563 guid
->Data1
, guid
->Data2
, guid
->Data3
,
564 guid
->Data4
[0], guid
->Data4
[1], guid
->Data4
[2], guid
->Data4
[3],
565 guid
->Data4
[4], guid
->Data4
[5], guid
->Data4
[6], guid
->Data4
[7]);
567 iLen
= strlen(xguid
) + 1;
571 memcpy(lpszDest
, xguid
, iLen
);
575 /*************************************************************************
578 * Convert a GUID to a string.
581 * guid [I] GUID to convert
582 * str [O] Destination for string
583 * cmax [I] Length of output buffer
586 * The length of the string created.
588 INT WINAPI
SHStringFromGUIDW(REFGUID guid
, LPWSTR lpszDest
, INT cchMax
)
592 static const WCHAR wszFormat
[] = {'{','%','0','8','l','X','-','%','0','4','X','-','%','0','4','X','-',
593 '%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','%','0','2','X','%','0','2',
594 'X','%','0','2','X','%','0','2','X','}',0};
596 TRACE("(%s,%p,%d)\n", debugstr_guid(guid
), lpszDest
, cchMax
);
598 sprintfW(xguid
, wszFormat
, guid
->Data1
, guid
->Data2
, guid
->Data3
,
599 guid
->Data4
[0], guid
->Data4
[1], guid
->Data4
[2], guid
->Data4
[3],
600 guid
->Data4
[4], guid
->Data4
[5], guid
->Data4
[6], guid
->Data4
[7]);
602 iLen
= strlenW(xguid
) + 1;
606 memcpy(lpszDest
, xguid
, iLen
*sizeof(WCHAR
));
610 /*************************************************************************
613 * Determine if a Unicode character is a blank.
616 * wc [I] Character to check.
619 * TRUE, if wc is a blank,
623 BOOL WINAPI
IsCharBlankW(WCHAR wc
)
627 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_BLANK
);
630 /*************************************************************************
633 * Determine if a Unicode character is punctuation.
636 * wc [I] Character to check.
639 * TRUE, if wc is punctuation,
642 BOOL WINAPI
IsCharPunctW(WCHAR wc
)
646 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_PUNCT
);
649 /*************************************************************************
652 * Determine if a Unicode character is a control character.
655 * wc [I] Character to check.
658 * TRUE, if wc is a control character,
661 BOOL WINAPI
IsCharCntrlW(WCHAR wc
)
665 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_CNTRL
);
668 /*************************************************************************
671 * Determine if a Unicode character is a digit.
674 * wc [I] Character to check.
677 * TRUE, if wc is a digit,
680 BOOL WINAPI
IsCharDigitW(WCHAR wc
)
684 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_DIGIT
);
687 /*************************************************************************
690 * Determine if a Unicode character is a hex digit.
693 * wc [I] Character to check.
696 * TRUE, if wc is a hex digit,
699 BOOL WINAPI
IsCharXDigitW(WCHAR wc
)
703 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_XDIGIT
);
706 /*************************************************************************
710 BOOL WINAPI
GetStringType3ExW(LPWSTR src
, INT count
, LPWORD type
)
712 return GetStringTypeW(CT_CTYPE3
, src
, count
, type
);
715 /*************************************************************************
718 * Compare two Ascii strings up to a given length.
721 * lpszSrc [I] Source string
722 * lpszCmp [I] String to compare to lpszSrc
723 * len [I] Maximum length
726 * A number greater than, less than or equal to 0 depending on whether
727 * lpszSrc is greater than, less than or equal to lpszCmp.
729 DWORD WINAPI
StrCmpNCA(LPCSTR lpszSrc
, LPCSTR lpszCmp
, INT len
)
731 return StrCmpNA(lpszSrc
, lpszCmp
, len
);
734 /*************************************************************************
737 * Unicode version of StrCmpNCA.
739 DWORD WINAPI
StrCmpNCW(LPCWSTR lpszSrc
, LPCWSTR lpszCmp
, INT len
)
741 return StrCmpNW(lpszSrc
, lpszCmp
, len
);
744 /*************************************************************************
747 * Compare two Ascii strings up to a given length, ignoring case.
750 * lpszSrc [I] Source string
751 * lpszCmp [I] String to compare to lpszSrc
752 * len [I] Maximum length
755 * A number greater than, less than or equal to 0 depending on whether
756 * lpszSrc is greater than, less than or equal to lpszCmp.
758 DWORD WINAPI
StrCmpNICA(LPCSTR lpszSrc
, LPCSTR lpszCmp
, DWORD len
)
760 return StrCmpNIA(lpszSrc
, lpszCmp
, len
);
763 /*************************************************************************
766 * Unicode version of StrCmpNICA.
768 DWORD WINAPI
StrCmpNICW(LPCWSTR lpszSrc
, LPCWSTR lpszCmp
, DWORD len
)
770 return StrCmpNIW(lpszSrc
, lpszCmp
, len
);
773 /*************************************************************************
776 * Compare two Ascii strings.
779 * lpszSrc [I] Source string
780 * lpszCmp [I] String to compare to lpszSrc
783 * A number greater than, less than or equal to 0 depending on whether
784 * lpszSrc is greater than, less than or equal to lpszCmp.
786 DWORD WINAPI
StrCmpCA(LPCSTR lpszSrc
, LPCSTR lpszCmp
)
788 return lstrcmpA(lpszSrc
, lpszCmp
);
791 /*************************************************************************
794 * Unicode version of StrCmpCA.
796 DWORD WINAPI
StrCmpCW(LPCWSTR lpszSrc
, LPCWSTR lpszCmp
)
798 return lstrcmpW(lpszSrc
, lpszCmp
);
801 /*************************************************************************
804 * Compare two Ascii strings, ignoring case.
807 * lpszSrc [I] Source string
808 * lpszCmp [I] String to compare to lpszSrc
811 * A number greater than, less than or equal to 0 depending on whether
812 * lpszSrc is greater than, less than or equal to lpszCmp.
814 DWORD WINAPI
StrCmpICA(LPCSTR lpszSrc
, LPCSTR lpszCmp
)
816 return lstrcmpiA(lpszSrc
, lpszCmp
);
819 /*************************************************************************
822 * Unicode version of StrCmpICA.
824 DWORD WINAPI
StrCmpICW(LPCWSTR lpszSrc
, LPCWSTR lpszCmp
)
826 return lstrcmpiW(lpszSrc
, lpszCmp
);
829 /*************************************************************************
832 * Get an identification string for the OS and explorer.
835 * lpszDest [O] Destination for Id string
836 * dwDestLen [I] Length of lpszDest
839 * TRUE, If the string was created successfully
842 BOOL WINAPI
SHAboutInfoA(LPSTR lpszDest
, DWORD dwDestLen
)
846 TRACE("(%p,%d)\n", lpszDest
, dwDestLen
);
848 if (lpszDest
&& SHAboutInfoW(buff
, dwDestLen
))
850 WideCharToMultiByte(CP_ACP
, 0, buff
, -1, lpszDest
, dwDestLen
, NULL
, NULL
);
856 /*************************************************************************
859 * Unicode version of SHAboutInfoA.
861 BOOL WINAPI
SHAboutInfoW(LPWSTR lpszDest
, DWORD dwDestLen
)
863 static const WCHAR szIEKey
[] = { 'S','O','F','T','W','A','R','E','\\',
864 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
865 ' ','E','x','p','l','o','r','e','r','\0' };
866 static const WCHAR szWinNtKey
[] = { 'S','O','F','T','W','A','R','E','\\',
867 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s',' ',
868 'N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
869 static const WCHAR szWinKey
[] = { 'S','O','F','T','W','A','R','E','\\',
870 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
871 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
872 static const WCHAR szRegKey
[] = { 'S','O','F','T','W','A','R','E','\\',
873 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
874 ' ','E','x','p','l','o','r','e','r','\\',
875 'R','e','g','i','s','t','r','a','t','i','o','n','\0' };
876 static const WCHAR szVersion
[] = { 'V','e','r','s','i','o','n','\0' };
877 static const WCHAR szCustomized
[] = { 'C','u','s','t','o','m','i','z','e','d',
878 'V','e','r','s','i','o','n','\0' };
879 static const WCHAR szOwner
[] = { 'R','e','g','i','s','t','e','r','e','d',
880 'O','w','n','e','r','\0' };
881 static const WCHAR szOrg
[] = { 'R','e','g','i','s','t','e','r','e','d',
882 'O','r','g','a','n','i','z','a','t','i','o','n','\0' };
883 static const WCHAR szProduct
[] = { 'P','r','o','d','u','c','t','I','d','\0' };
884 static const WCHAR szUpdate
[] = { 'I','E','A','K',
885 'U','p','d','a','t','e','U','r','l','\0' };
886 static const WCHAR szHelp
[] = { 'I','E','A','K',
887 'H','e','l','p','S','t','r','i','n','g','\0' };
892 TRACE("(%p,%d)\n", lpszDest
, dwDestLen
);
899 /* Try the NT key first, followed by 95/98 key */
900 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szWinNtKey
, 0, KEY_READ
, &hReg
) &&
901 RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szWinKey
, 0, KEY_READ
, &hReg
))
907 if (!SHGetValueW(HKEY_LOCAL_MACHINE
, szIEKey
, szVersion
, &dwType
, buff
, &dwLen
))
909 DWORD dwStrLen
= strlenW(buff
);
910 dwLen
= 30 - dwStrLen
;
911 SHGetValueW(HKEY_LOCAL_MACHINE
, szIEKey
,
912 szCustomized
, &dwType
, buff
+dwStrLen
, &dwLen
);
914 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
916 /* ~Registered Owner */
919 if (SHGetValueW(hReg
, szOwner
, 0, &dwType
, buff
+1, &dwLen
))
921 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
923 /* ~Registered Organization */
925 if (SHGetValueW(hReg
, szOrg
, 0, &dwType
, buff
+1, &dwLen
))
927 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
929 /* FIXME: Not sure where this number comes from */
933 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
937 if (SHGetValueW(HKEY_LOCAL_MACHINE
, szRegKey
, szProduct
, &dwType
, buff
+1, &dwLen
))
939 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
943 if(SHGetValueW(HKEY_LOCAL_MACHINE
, szWinKey
, szUpdate
, &dwType
, buff
+1, &dwLen
))
945 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
947 /* ~IE Help String */
949 if(SHGetValueW(hReg
, szHelp
, 0, &dwType
, buff
+1, &dwLen
))
951 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
957 /*************************************************************************
960 * Call IOleCommandTarget_QueryStatus() on an object.
963 * lpUnknown [I] Object supporting the IOleCommandTarget interface
964 * pguidCmdGroup [I] GUID for the command group
966 * prgCmds [O] Commands
967 * pCmdText [O] Command text
971 * Failure: E_FAIL, if lpUnknown is NULL.
972 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
973 * Otherwise, an error code from IOleCommandTarget_QueryStatus().
975 HRESULT WINAPI
IUnknown_QueryStatus(IUnknown
* lpUnknown
, REFGUID pguidCmdGroup
,
976 ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
* pCmdText
)
978 HRESULT hRet
= E_FAIL
;
980 TRACE("(%p,%p,%d,%p,%p)\n",lpUnknown
, pguidCmdGroup
, cCmds
, prgCmds
, pCmdText
);
984 IOleCommandTarget
* lpOle
;
986 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleCommandTarget
,
989 if (SUCCEEDED(hRet
) && lpOle
)
991 hRet
= IOleCommandTarget_QueryStatus(lpOle
, pguidCmdGroup
, cCmds
,
993 IOleCommandTarget_Release(lpOle
);
999 /*************************************************************************
1002 * Call IOleCommandTarget_Exec() on an object.
1005 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1006 * pguidCmdGroup [I] GUID for the command group
1010 * Failure: E_FAIL, if lpUnknown is NULL.
1011 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1012 * Otherwise, an error code from IOleCommandTarget_Exec().
1014 HRESULT WINAPI
IUnknown_Exec(IUnknown
* lpUnknown
, REFGUID pguidCmdGroup
,
1015 DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
* pvaIn
,
1018 HRESULT hRet
= E_FAIL
;
1020 TRACE("(%p,%p,%d,%d,%p,%p)\n",lpUnknown
, pguidCmdGroup
, nCmdID
,
1021 nCmdexecopt
, pvaIn
, pvaOut
);
1025 IOleCommandTarget
* lpOle
;
1027 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleCommandTarget
,
1029 if (SUCCEEDED(hRet
) && lpOle
)
1031 hRet
= IOleCommandTarget_Exec(lpOle
, pguidCmdGroup
, nCmdID
,
1032 nCmdexecopt
, pvaIn
, pvaOut
);
1033 IOleCommandTarget_Release(lpOle
);
1039 /*************************************************************************
1042 * Retrieve, modify, and re-set a value from a window.
1045 * hWnd [I] Window to get value from
1046 * offset [I] Offset of value
1047 * mask [I] Mask for flags
1048 * flags [I] Bits to set in window value
1051 * The new value as it was set, or 0 if any parameter is invalid.
1054 * Only bits specified in mask are affected - set if present in flags and
1057 LONG WINAPI
SHSetWindowBits(HWND hwnd
, INT offset
, UINT mask
, UINT flags
)
1059 LONG ret
= GetWindowLongW(hwnd
, offset
);
1060 LONG new_flags
= (flags
& mask
) | (ret
& ~mask
);
1062 TRACE("%p %d %x %x\n", hwnd
, offset
, mask
, flags
);
1064 if (new_flags
!= ret
)
1065 ret
= SetWindowLongW(hwnd
, offset
, new_flags
);
1069 /*************************************************************************
1072 * Change a window's parent.
1075 * hWnd [I] Window to change parent of
1076 * hWndParent [I] New parent window
1079 * The old parent of hWnd.
1082 * If hWndParent is NULL (desktop), the window style is changed to WS_POPUP.
1083 * If hWndParent is NOT NULL then we set the WS_CHILD style.
1085 HWND WINAPI
SHSetParentHwnd(HWND hWnd
, HWND hWndParent
)
1087 TRACE("%p, %p\n", hWnd
, hWndParent
);
1089 if(GetParent(hWnd
) == hWndParent
)
1093 SHSetWindowBits(hWnd
, GWL_STYLE
, WS_CHILD
| WS_POPUP
, WS_CHILD
);
1095 SHSetWindowBits(hWnd
, GWL_STYLE
, WS_CHILD
| WS_POPUP
, WS_POPUP
);
1097 return hWndParent
? SetParent(hWnd
, hWndParent
) : NULL
;
1100 /*************************************************************************
1103 * Locate and advise a connection point in an IConnectionPointContainer object.
1106 * lpUnkSink [I] Sink for the connection point advise call
1107 * riid [I] REFIID of connection point to advise
1108 * fConnect [I] TRUE = Connection being establisted, FALSE = broken
1109 * lpUnknown [I] Object supporting the IConnectionPointContainer interface
1110 * lpCookie [O] Pointer to connection point cookie
1111 * lppCP [O] Destination for the IConnectionPoint found
1114 * Success: S_OK. If lppCP is non-NULL, it is filled with the IConnectionPoint
1115 * that was advised. The caller is responsible for releasing it.
1116 * Failure: E_FAIL, if any arguments are invalid.
1117 * E_NOINTERFACE, if lpUnknown isn't an IConnectionPointContainer,
1118 * Or an HRESULT error code if any call fails.
1120 HRESULT WINAPI
ConnectToConnectionPoint(IUnknown
* lpUnkSink
, REFIID riid
, BOOL fConnect
,
1121 IUnknown
* lpUnknown
, LPDWORD lpCookie
,
1122 IConnectionPoint
**lppCP
)
1125 IConnectionPointContainer
* lpContainer
;
1126 IConnectionPoint
*lpCP
;
1128 if(!lpUnknown
|| (fConnect
&& !lpUnkSink
))
1134 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IConnectionPointContainer
,
1135 (void**)&lpContainer
);
1136 if (SUCCEEDED(hRet
))
1138 hRet
= IConnectionPointContainer_FindConnectionPoint(lpContainer
, riid
, &lpCP
);
1140 if (SUCCEEDED(hRet
))
1143 hRet
= IConnectionPoint_Unadvise(lpCP
, *lpCookie
);
1145 hRet
= IConnectionPoint_Advise(lpCP
, lpUnkSink
, lpCookie
);
1150 if (lppCP
&& SUCCEEDED(hRet
))
1151 *lppCP
= lpCP
; /* Caller keeps the interface */
1153 IConnectionPoint_Release(lpCP
); /* Release it */
1156 IConnectionPointContainer_Release(lpContainer
);
1161 /*************************************************************************
1164 * Release an interface and zero a supplied pointer.
1167 * lpUnknown [I] Object to release
1172 void WINAPI
IUnknown_AtomicRelease(IUnknown
** lpUnknown
)
1174 TRACE("(%p)\n", lpUnknown
);
1176 if(!lpUnknown
|| !*lpUnknown
) return;
1178 TRACE("doing Release\n");
1180 IUnknown_Release(*lpUnknown
);
1184 /*************************************************************************
1187 * Skip '//' if present in a string.
1190 * lpszSrc [I] String to check for '//'
1193 * Success: The next character after the '//' or the string if not present
1194 * Failure: NULL, if lpszStr is NULL.
1196 LPCSTR WINAPI
PathSkipLeadingSlashesA(LPCSTR lpszSrc
)
1198 if (lpszSrc
&& lpszSrc
[0] == '/' && lpszSrc
[1] == '/')
1203 /*************************************************************************
1206 * Check if two interfaces come from the same object.
1209 * lpInt1 [I] Interface to check against lpInt2.
1210 * lpInt2 [I] Interface to check against lpInt1.
1213 * TRUE, If the interfaces come from the same object.
1216 BOOL WINAPI
SHIsSameObject(IUnknown
* lpInt1
, IUnknown
* lpInt2
)
1218 IUnknown
*lpUnknown1
, *lpUnknown2
;
1221 TRACE("(%p %p)\n", lpInt1
, lpInt2
);
1223 if (!lpInt1
|| !lpInt2
)
1226 if (lpInt1
== lpInt2
)
1229 if (IUnknown_QueryInterface(lpInt1
, &IID_IUnknown
, (void**)&lpUnknown1
) != S_OK
)
1232 if (IUnknown_QueryInterface(lpInt2
, &IID_IUnknown
, (void**)&lpUnknown2
) != S_OK
)
1234 IUnknown_Release(lpUnknown1
);
1238 ret
= lpUnknown1
== lpUnknown2
;
1240 IUnknown_Release(lpUnknown1
);
1241 IUnknown_Release(lpUnknown2
);
1246 /*************************************************************************
1249 * Get the window handle of an object.
1252 * lpUnknown [I] Object to get the window handle of
1253 * lphWnd [O] Destination for window handle
1256 * Success: S_OK. lphWnd contains the objects window handle.
1257 * Failure: An HRESULT error code.
1260 * lpUnknown is expected to support one of the following interfaces:
1261 * IOleWindow(), IInternetSecurityMgrSite(), or IShellView().
1263 HRESULT WINAPI
IUnknown_GetWindow(IUnknown
*lpUnknown
, HWND
*lphWnd
)
1266 HRESULT hRet
= E_FAIL
;
1268 TRACE("(%p,%p)\n", lpUnknown
, lphWnd
);
1273 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleWindow
, (void**)&lpOle
);
1277 hRet
= IUnknown_QueryInterface(lpUnknown
,&IID_IShellView
, (void**)&lpOle
);
1281 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IInternetSecurityMgrSite
,
1286 if (SUCCEEDED(hRet
))
1288 /* Laziness here - Since GetWindow() is the first method for the above 3
1289 * interfaces, we use the same call for them all.
1291 hRet
= IOleWindow_GetWindow((IOleWindow
*)lpOle
, lphWnd
);
1292 IUnknown_Release(lpOle
);
1294 TRACE("Returning HWND=%p\n", *lphWnd
);
1300 /*************************************************************************
1303 * Call a SetOwner method of IShellService from specified object.
1306 * iface [I] Object that supports IShellService
1307 * pUnk [I] Argument for the SetOwner call
1310 * Corresponding return value from last call or E_FAIL for null input
1312 HRESULT WINAPI
IUnknown_SetOwner(IUnknown
*iface
, IUnknown
*pUnk
)
1314 IShellService
*service
;
1317 TRACE("(%p, %p)\n", iface
, pUnk
);
1319 if (!iface
) return E_FAIL
;
1321 hr
= IUnknown_QueryInterface(iface
, &IID_IShellService
, (void**)&service
);
1324 hr
= IShellService_SetOwner(service
, pUnk
);
1325 IShellService_Release(service
);
1331 /*************************************************************************
1334 * Call either IObjectWithSite_SetSite() or IInternetSecurityManager_SetSecuritySite() on
1338 HRESULT WINAPI
IUnknown_SetSite(
1339 IUnknown
*obj
, /* [in] OLE object */
1340 IUnknown
*site
) /* [in] Site interface */
1343 IObjectWithSite
*iobjwithsite
;
1344 IInternetSecurityManager
*isecmgr
;
1346 if (!obj
) return E_FAIL
;
1348 hr
= IUnknown_QueryInterface(obj
, &IID_IObjectWithSite
, (LPVOID
*)&iobjwithsite
);
1349 TRACE("IID_IObjectWithSite QI ret=%08x, %p\n", hr
, iobjwithsite
);
1352 hr
= IObjectWithSite_SetSite(iobjwithsite
, site
);
1353 TRACE("done IObjectWithSite_SetSite ret=%08x\n", hr
);
1354 IObjectWithSite_Release(iobjwithsite
);
1358 hr
= IUnknown_QueryInterface(obj
, &IID_IInternetSecurityManager
, (LPVOID
*)&isecmgr
);
1359 TRACE("IID_IInternetSecurityManager QI ret=%08x, %p\n", hr
, isecmgr
);
1360 if (FAILED(hr
)) return hr
;
1362 hr
= IInternetSecurityManager_SetSecuritySite(isecmgr
, (IInternetSecurityMgrSite
*)site
);
1363 TRACE("done IInternetSecurityManager_SetSecuritySite ret=%08x\n", hr
);
1364 IInternetSecurityManager_Release(isecmgr
);
1369 /*************************************************************************
1372 * Call IPersist_GetClassID() on an object.
1375 * lpUnknown [I] Object supporting the IPersist interface
1376 * clsid [O] Destination for Class Id
1379 * Success: S_OK. lpClassId contains the Class Id requested.
1380 * Failure: E_FAIL, If lpUnknown is NULL,
1381 * E_NOINTERFACE If lpUnknown does not support IPersist,
1382 * Or an HRESULT error code.
1384 HRESULT WINAPI
IUnknown_GetClassID(IUnknown
*lpUnknown
, CLSID
*clsid
)
1389 TRACE("(%p, %p)\n", lpUnknown
, clsid
);
1393 memset(clsid
, 0, sizeof(*clsid
));
1397 hr
= IUnknown_QueryInterface(lpUnknown
, &IID_IPersist
, (void**)&persist
);
1400 hr
= IUnknown_QueryInterface(lpUnknown
, &IID_IPersistFolder
, (void**)&persist
);
1405 hr
= IPersist_GetClassID(persist
, clsid
);
1406 IPersist_Release(persist
);
1410 /*************************************************************************
1413 * Retrieve a Service Interface from an object.
1416 * lpUnknown [I] Object to get an IServiceProvider interface from
1417 * sid [I] Service ID for IServiceProvider_QueryService() call
1418 * riid [I] Function requested for QueryService call
1419 * lppOut [O] Destination for the service interface pointer
1422 * Success: S_OK. lppOut contains an object providing the requested service
1423 * Failure: An HRESULT error code
1426 * lpUnknown is expected to support the IServiceProvider interface.
1428 HRESULT WINAPI
IUnknown_QueryService(IUnknown
* lpUnknown
, REFGUID sid
, REFIID riid
,
1431 IServiceProvider
* pService
= NULL
;
1442 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IServiceProvider
,
1443 (LPVOID
*)&pService
);
1445 if (hRet
== S_OK
&& pService
)
1447 TRACE("QueryInterface returned (IServiceProvider*)%p\n", pService
);
1449 /* Get a Service interface from the object */
1450 hRet
= IServiceProvider_QueryService(pService
, sid
, riid
, lppOut
);
1452 TRACE("(IServiceProvider*)%p returned (IUnknown*)%p\n", pService
, *lppOut
);
1454 IServiceProvider_Release(pService
);
1459 /*************************************************************************
1462 * Calls IOleCommandTarget::Exec() for specified service object.
1465 * lpUnknown [I] Object to get an IServiceProvider interface from
1466 * service [I] Service ID for IServiceProvider_QueryService() call
1467 * group [I] Group ID for IOleCommandTarget::Exec() call
1468 * cmdId [I] Command ID for IOleCommandTarget::Exec() call
1469 * cmdOpt [I] Options flags for command
1470 * pIn [I] Input arguments for command
1471 * pOut [O] Output arguments for command
1474 * Success: S_OK. lppOut contains an object providing the requested service
1475 * Failure: An HRESULT error code
1478 * lpUnknown is expected to support the IServiceProvider interface.
1480 HRESULT WINAPI
IUnknown_QueryServiceExec(IUnknown
*lpUnknown
, REFIID service
,
1481 const GUID
*group
, DWORD cmdId
, DWORD cmdOpt
, VARIANT
*pIn
, VARIANT
*pOut
)
1483 IOleCommandTarget
*target
;
1486 TRACE("%p %s %s %d %08x %p %p\n", lpUnknown
, debugstr_guid(service
),
1487 debugstr_guid(group
), cmdId
, cmdOpt
, pIn
, pOut
);
1489 hr
= IUnknown_QueryService(lpUnknown
, service
, &IID_IOleCommandTarget
, (void**)&target
);
1492 hr
= IOleCommandTarget_Exec(target
, group
, cmdId
, cmdOpt
, pIn
, pOut
);
1493 IOleCommandTarget_Release(target
);
1496 TRACE("<-- hr=0x%08x\n", hr
);
1501 /*************************************************************************
1504 * Calls IProfferService methods to proffer/revoke specified service.
1507 * lpUnknown [I] Object to get an IServiceProvider interface from
1508 * service [I] Service ID for IProfferService::Proffer/Revoke calls
1509 * pService [I] Service to proffer. If NULL ::Revoke is called
1510 * pCookie [IO] Group ID for IOleCommandTarget::Exec() call
1513 * Success: S_OK. IProffer method returns S_OK
1514 * Failure: An HRESULT error code
1517 * lpUnknown is expected to support the IServiceProvider interface.
1519 HRESULT WINAPI
IUnknown_ProfferService(IUnknown
*lpUnknown
, REFGUID service
, IServiceProvider
*pService
, DWORD
*pCookie
)
1521 IProfferService
*proffer
;
1524 TRACE("%p %s %p %p\n", lpUnknown
, debugstr_guid(service
), pService
, pCookie
);
1526 hr
= IUnknown_QueryService(lpUnknown
, &IID_IProfferService
, &IID_IProfferService
, (void**)&proffer
);
1530 hr
= IProfferService_ProfferService(proffer
, service
, pService
, pCookie
);
1533 hr
= IProfferService_RevokeService(proffer
, *pCookie
);
1537 IProfferService_Release(proffer
);
1543 /*************************************************************************
1546 * Call an object's UIActivateIO method.
1549 * unknown [I] Object to call the UIActivateIO method on
1550 * activate [I] Parameter for UIActivateIO call
1551 * msg [I] Parameter for UIActivateIO call
1554 * Success: Value of UI_ActivateIO call
1555 * Failure: An HRESULT error code
1558 * unknown is expected to support the IInputObject interface.
1560 HRESULT WINAPI
IUnknown_UIActivateIO(IUnknown
*unknown
, BOOL activate
, LPMSG msg
)
1562 IInputObject
* object
= NULL
;
1568 /* Get an IInputObject interface from the object */
1569 ret
= IUnknown_QueryInterface(unknown
, &IID_IInputObject
, (LPVOID
*) &object
);
1573 ret
= IInputObject_UIActivateIO(object
, activate
, msg
);
1574 IInputObject_Release(object
);
1580 /*************************************************************************
1583 * Loads a popup menu.
1586 * hInst [I] Instance handle
1587 * szName [I] Menu name
1593 BOOL WINAPI
SHLoadMenuPopup(HINSTANCE hInst
, LPCWSTR szName
)
1597 TRACE("%p %s\n", hInst
, debugstr_w(szName
));
1599 if ((hMenu
= LoadMenuW(hInst
, szName
)))
1601 if (GetSubMenu(hMenu
, 0))
1602 RemoveMenu(hMenu
, 0, MF_BYPOSITION
);
1610 typedef struct _enumWndData
1615 LRESULT (WINAPI
*pfnPost
)(HWND
,UINT
,WPARAM
,LPARAM
);
1618 /* Callback for SHLWAPI_178 */
1619 static BOOL CALLBACK
SHLWAPI_EnumChildProc(HWND hWnd
, LPARAM lParam
)
1621 enumWndData
*data
= (enumWndData
*)lParam
;
1623 TRACE("(%p,%p)\n", hWnd
, data
);
1624 data
->pfnPost(hWnd
, data
->uiMsgId
, data
->wParam
, data
->lParam
);
1628 /*************************************************************************
1631 * Send or post a message to every child of a window.
1634 * hWnd [I] Window whose children will get the messages
1635 * uiMsgId [I] Message Id
1636 * wParam [I] WPARAM of message
1637 * lParam [I] LPARAM of message
1638 * bSend [I] TRUE = Use SendMessageA(), FALSE = Use PostMessageA()
1644 * The appropriate ASCII or Unicode function is called for the window.
1646 void WINAPI
SHPropagateMessage(HWND hWnd
, UINT uiMsgId
, WPARAM wParam
, LPARAM lParam
, BOOL bSend
)
1650 TRACE("(%p,%u,%ld,%ld,%d)\n", hWnd
, uiMsgId
, wParam
, lParam
, bSend
);
1654 data
.uiMsgId
= uiMsgId
;
1655 data
.wParam
= wParam
;
1656 data
.lParam
= lParam
;
1659 data
.pfnPost
= IsWindowUnicode(hWnd
) ? (void*)SendMessageW
: (void*)SendMessageA
;
1661 data
.pfnPost
= IsWindowUnicode(hWnd
) ? (void*)PostMessageW
: (void*)PostMessageA
;
1663 EnumChildWindows(hWnd
, SHLWAPI_EnumChildProc
, (LPARAM
)&data
);
1667 /*************************************************************************
1670 * Remove all sub-menus from a menu.
1673 * hMenu [I] Menu to remove sub-menus from
1676 * Success: 0. All sub-menus under hMenu are removed
1677 * Failure: -1, if any parameter is invalid
1679 DWORD WINAPI
SHRemoveAllSubMenus(HMENU hMenu
)
1681 int iItemCount
= GetMenuItemCount(hMenu
) - 1;
1683 TRACE("%p\n", hMenu
);
1685 while (iItemCount
>= 0)
1687 HMENU hSubMenu
= GetSubMenu(hMenu
, iItemCount
);
1689 RemoveMenu(hMenu
, iItemCount
, MF_BYPOSITION
);
1695 /*************************************************************************
1698 * Enable or disable a menu item.
1701 * hMenu [I] Menu holding menu item
1702 * uID [I] ID of menu item to enable/disable
1703 * bEnable [I] Whether to enable (TRUE) or disable (FALSE) the item.
1706 * The return code from EnableMenuItem.
1708 UINT WINAPI
SHEnableMenuItem(HMENU hMenu
, UINT wItemID
, BOOL bEnable
)
1710 TRACE("%p, %u, %d\n", hMenu
, wItemID
, bEnable
);
1711 return EnableMenuItem(hMenu
, wItemID
, bEnable
? MF_ENABLED
: MF_GRAYED
);
1714 /*************************************************************************
1717 * Check or uncheck a menu item.
1720 * hMenu [I] Menu holding menu item
1721 * uID [I] ID of menu item to check/uncheck
1722 * bCheck [I] Whether to check (TRUE) or uncheck (FALSE) the item.
1725 * The return code from CheckMenuItem.
1727 DWORD WINAPI
SHCheckMenuItem(HMENU hMenu
, UINT uID
, BOOL bCheck
)
1729 TRACE("%p, %u, %d\n", hMenu
, uID
, bCheck
);
1730 return CheckMenuItem(hMenu
, uID
, bCheck
? MF_CHECKED
: MF_UNCHECKED
);
1733 /*************************************************************************
1736 * Register a window class if it isn't already.
1739 * lpWndClass [I] Window class to register
1742 * The result of the RegisterClassA call.
1744 DWORD WINAPI
SHRegisterClassA(WNDCLASSA
*wndclass
)
1747 if (GetClassInfoA(wndclass
->hInstance
, wndclass
->lpszClassName
, &wca
))
1749 return (DWORD
)RegisterClassA(wndclass
);
1752 /*************************************************************************
1755 BOOL WINAPI
SHSimulateDrop(IDropTarget
*pDrop
, IDataObject
*pDataObj
,
1756 DWORD grfKeyState
, PPOINTL lpPt
, DWORD
* pdwEffect
)
1758 DWORD dwEffect
= DROPEFFECT_LINK
| DROPEFFECT_MOVE
| DROPEFFECT_COPY
;
1759 POINTL pt
= { 0, 0 };
1761 TRACE("%p %p 0x%08x %p %p\n", pDrop
, pDataObj
, grfKeyState
, lpPt
, pdwEffect
);
1767 pdwEffect
= &dwEffect
;
1769 IDropTarget_DragEnter(pDrop
, pDataObj
, grfKeyState
, *lpPt
, pdwEffect
);
1771 if (*pdwEffect
!= DROPEFFECT_NONE
)
1772 return IDropTarget_Drop(pDrop
, pDataObj
, grfKeyState
, *lpPt
, pdwEffect
);
1774 IDropTarget_DragLeave(pDrop
);
1778 /*************************************************************************
1781 * Call IPersistPropertyBag_Load() on an object.
1784 * lpUnknown [I] Object supporting the IPersistPropertyBag interface
1785 * lpPropBag [O] Destination for loaded IPropertyBag
1789 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1791 DWORD WINAPI
SHLoadFromPropertyBag(IUnknown
*lpUnknown
, IPropertyBag
* lpPropBag
)
1793 IPersistPropertyBag
* lpPPBag
;
1794 HRESULT hRet
= E_FAIL
;
1796 TRACE("(%p,%p)\n", lpUnknown
, lpPropBag
);
1800 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IPersistPropertyBag
,
1802 if (SUCCEEDED(hRet
) && lpPPBag
)
1804 hRet
= IPersistPropertyBag_Load(lpPPBag
, lpPropBag
, NULL
);
1805 IPersistPropertyBag_Release(lpPPBag
);
1811 /*************************************************************************
1814 * Call IOleControlSite_TranslateAccelerator() on an object.
1817 * lpUnknown [I] Object supporting the IOleControlSite interface.
1818 * lpMsg [I] Key message to be processed.
1819 * dwModifiers [I] Flags containing the state of the modifier keys.
1823 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
1825 HRESULT WINAPI
IUnknown_TranslateAcceleratorOCS(IUnknown
*lpUnknown
, LPMSG lpMsg
, DWORD dwModifiers
)
1827 IOleControlSite
* lpCSite
= NULL
;
1828 HRESULT hRet
= E_INVALIDARG
;
1830 TRACE("(%p,%p,0x%08x)\n", lpUnknown
, lpMsg
, dwModifiers
);
1833 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleControlSite
,
1835 if (SUCCEEDED(hRet
) && lpCSite
)
1837 hRet
= IOleControlSite_TranslateAccelerator(lpCSite
, lpMsg
, dwModifiers
);
1838 IOleControlSite_Release(lpCSite
);
1845 /*************************************************************************
1848 * Call IOleControlSite_OnFocus() on an object.
1851 * lpUnknown [I] Object supporting the IOleControlSite interface.
1852 * fGotFocus [I] Whether focus was gained (TRUE) or lost (FALSE).
1856 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1858 HRESULT WINAPI
IUnknown_OnFocusOCS(IUnknown
*lpUnknown
, BOOL fGotFocus
)
1860 IOleControlSite
* lpCSite
= NULL
;
1861 HRESULT hRet
= E_FAIL
;
1863 TRACE("(%p, %d)\n", lpUnknown
, fGotFocus
);
1866 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleControlSite
,
1868 if (SUCCEEDED(hRet
) && lpCSite
)
1870 hRet
= IOleControlSite_OnFocus(lpCSite
, fGotFocus
);
1871 IOleControlSite_Release(lpCSite
);
1877 /*************************************************************************
1880 HRESULT WINAPI
IUnknown_HandleIRestrict(LPUNKNOWN lpUnknown
, PVOID lpArg1
,
1881 PVOID lpArg2
, PVOID lpArg3
, PVOID lpArg4
)
1883 /* FIXME: {D12F26B2-D90A-11D0-830D-00AA005B4383} - What object does this represent? */
1884 static const DWORD service_id
[] = { 0xd12f26b2, 0x11d0d90a, 0xaa000d83, 0x83435b00 };
1885 /* FIXME: {D12F26B1-D90A-11D0-830D-00AA005B4383} - Also Unknown/undocumented */
1886 static const DWORD function_id
[] = { 0xd12f26b1, 0x11d0d90a, 0xaa000d83, 0x83435b00 };
1887 HRESULT hRet
= E_INVALIDARG
;
1888 LPUNKNOWN lpUnkInner
= NULL
; /* FIXME: Real type is unknown */
1890 TRACE("(%p,%p,%p,%p,%p)\n", lpUnknown
, lpArg1
, lpArg2
, lpArg3
, lpArg4
);
1892 if (lpUnknown
&& lpArg4
)
1894 hRet
= IUnknown_QueryService(lpUnknown
, (REFGUID
)service_id
,
1895 (REFGUID
)function_id
, (void**)&lpUnkInner
);
1897 if (SUCCEEDED(hRet
) && lpUnkInner
)
1899 /* FIXME: The type of service object requested is unknown, however
1900 * testing shows that its first method is called with 4 parameters.
1901 * Fake this by using IParseDisplayName_ParseDisplayName since the
1902 * signature and position in the vtable matches our unknown object type.
1904 hRet
= IParseDisplayName_ParseDisplayName((LPPARSEDISPLAYNAME
)lpUnkInner
,
1905 lpArg1
, lpArg2
, lpArg3
, lpArg4
);
1906 IUnknown_Release(lpUnkInner
);
1912 /*************************************************************************
1915 * Get a sub-menu from a menu item.
1918 * hMenu [I] Menu to get sub-menu from
1919 * uID [I] ID of menu item containing sub-menu
1922 * The sub-menu of the item, or a NULL handle if any parameters are invalid.
1924 HMENU WINAPI
SHGetMenuFromID(HMENU hMenu
, UINT uID
)
1928 TRACE("(%p,%u)\n", hMenu
, uID
);
1930 mi
.cbSize
= sizeof(mi
);
1931 mi
.fMask
= MIIM_SUBMENU
;
1933 if (!GetMenuItemInfoW(hMenu
, uID
, FALSE
, &mi
))
1939 /*************************************************************************
1942 * Get the color depth of the primary display.
1948 * The color depth of the primary display.
1950 DWORD WINAPI
SHGetCurColorRes(void)
1958 ret
= GetDeviceCaps(hdc
, BITSPIXEL
) * GetDeviceCaps(hdc
, PLANES
);
1963 /*************************************************************************
1966 * Wait for a message to arrive, with a timeout.
1969 * hand [I] Handle to query
1970 * dwTimeout [I] Timeout in ticks or INFINITE to never timeout
1973 * STATUS_TIMEOUT if no message is received before dwTimeout ticks passes.
1974 * Otherwise returns the value from MsgWaitForMultipleObjectsEx when a
1975 * message is available.
1977 DWORD WINAPI
SHWaitForSendMessageThread(HANDLE hand
, DWORD dwTimeout
)
1979 DWORD dwEndTicks
= GetTickCount() + dwTimeout
;
1982 while ((dwRet
= MsgWaitForMultipleObjectsEx(1, &hand
, dwTimeout
, QS_SENDMESSAGE
, 0)) == 1)
1986 PeekMessageW(&msg
, NULL
, 0, 0, PM_NOREMOVE
);
1988 if (dwTimeout
!= INFINITE
)
1990 if ((int)(dwTimeout
= dwEndTicks
- GetTickCount()) <= 0)
1991 return WAIT_TIMEOUT
;
1998 /*************************************************************************
2001 * Determine if a shell folder can be expanded.
2004 * lpFolder [I] Parent folder containing the object to test.
2005 * pidl [I] Id of the object to test.
2008 * Success: S_OK, if the object is expandable, S_FALSE otherwise.
2009 * Failure: E_INVALIDARG, if any argument is invalid.
2012 * If the object to be tested does not expose the IQueryInfo() interface it
2013 * will not be identified as an expandable folder.
2015 HRESULT WINAPI
SHIsExpandableFolder(LPSHELLFOLDER lpFolder
, LPCITEMIDLIST pidl
)
2017 HRESULT hRet
= E_INVALIDARG
;
2020 if (lpFolder
&& pidl
)
2022 hRet
= IShellFolder_GetUIObjectOf(lpFolder
, NULL
, 1, &pidl
, &IID_IQueryInfo
,
2023 NULL
, (void**)&lpInfo
);
2025 hRet
= S_FALSE
; /* Doesn't expose IQueryInfo */
2030 /* MSDN states of IQueryInfo_GetInfoFlags() that "This method is not
2031 * currently used". Really? You wouldn't be holding out on me would you?
2033 hRet
= IQueryInfo_GetInfoFlags(lpInfo
, &dwFlags
);
2035 if (SUCCEEDED(hRet
))
2037 /* 0x2 is an undocumented flag apparently indicating expandability */
2038 hRet
= dwFlags
& 0x2 ? S_OK
: S_FALSE
;
2041 IQueryInfo_Release(lpInfo
);
2047 /*************************************************************************
2050 * Blank out a region of text by drawing the background only.
2053 * hDC [I] Device context to draw in
2054 * pRect [I] Area to draw in
2055 * cRef [I] Color to draw in
2060 DWORD WINAPI
SHFillRectClr(HDC hDC
, LPCRECT pRect
, COLORREF cRef
)
2062 COLORREF cOldColor
= SetBkColor(hDC
, cRef
);
2063 ExtTextOutA(hDC
, 0, 0, ETO_OPAQUE
, pRect
, 0, 0, 0);
2064 SetBkColor(hDC
, cOldColor
);
2068 /*************************************************************************
2071 * Return the value associated with a key in a map.
2074 * lpKeys [I] A list of keys of length iLen
2075 * lpValues [I] A list of values associated with lpKeys, of length iLen
2076 * iLen [I] Length of both lpKeys and lpValues
2077 * iKey [I] The key value to look up in lpKeys
2080 * The value in lpValues associated with iKey, or -1 if iKey is not
2084 * - If two elements in the map share the same key, this function returns
2085 * the value closest to the start of the map
2086 * - The native version of this function crashes if lpKeys or lpValues is NULL.
2088 int WINAPI
SHSearchMapInt(const int *lpKeys
, const int *lpValues
, int iLen
, int iKey
)
2090 if (lpKeys
&& lpValues
)
2096 if (lpKeys
[i
] == iKey
)
2097 return lpValues
[i
]; /* Found */
2101 return -1; /* Not found */
2105 /*************************************************************************
2108 * Copy an interface pointer
2111 * lppDest [O] Destination for copy
2112 * lpUnknown [I] Source for copy
2117 VOID WINAPI
IUnknown_Set(IUnknown
**lppDest
, IUnknown
*lpUnknown
)
2119 TRACE("(%p,%p)\n", lppDest
, lpUnknown
);
2121 IUnknown_AtomicRelease(lppDest
);
2125 IUnknown_AddRef(lpUnknown
);
2126 *lppDest
= lpUnknown
;
2130 /*************************************************************************
2134 HRESULT WINAPI
MayQSForward(IUnknown
* lpUnknown
, PVOID lpReserved
,
2135 REFGUID riidCmdGrp
, ULONG cCmds
,
2136 OLECMD
*prgCmds
, OLECMDTEXT
* pCmdText
)
2138 FIXME("(%p,%p,%p,%d,%p,%p) - stub\n",
2139 lpUnknown
, lpReserved
, riidCmdGrp
, cCmds
, prgCmds
, pCmdText
);
2141 /* FIXME: Calls IsQSForward & IUnknown_QueryStatus */
2142 return DRAGDROP_E_NOTREGISTERED
;
2145 /*************************************************************************
2149 HRESULT WINAPI
MayExecForward(IUnknown
* lpUnknown
, INT iUnk
, REFGUID pguidCmdGroup
,
2150 DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
* pvaIn
,
2153 FIXME("(%p,%d,%p,%d,%d,%p,%p) - stub!\n", lpUnknown
, iUnk
, pguidCmdGroup
,
2154 nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2155 return DRAGDROP_E_NOTREGISTERED
;
2158 /*************************************************************************
2162 HRESULT WINAPI
IsQSForward(REFGUID pguidCmdGroup
,ULONG cCmds
, OLECMD
*prgCmds
)
2164 FIXME("(%p,%d,%p) - stub!\n", pguidCmdGroup
, cCmds
, prgCmds
);
2165 return DRAGDROP_E_NOTREGISTERED
;
2168 /*************************************************************************
2171 * Determine if a window is not a child of another window.
2174 * hParent [I] Suspected parent window
2175 * hChild [I] Suspected child window
2178 * TRUE: If hChild is a child window of hParent
2179 * FALSE: If hChild is not a child window of hParent, or they are equal
2181 BOOL WINAPI
SHIsChildOrSelf(HWND hParent
, HWND hChild
)
2183 TRACE("(%p,%p)\n", hParent
, hChild
);
2185 if (!hParent
|| !hChild
)
2187 else if(hParent
== hChild
)
2189 return !IsChild(hParent
, hChild
);
2192 /*************************************************************************
2193 * FDSA functions. Manage a dynamic array of fixed size memory blocks.
2198 DWORD num_items
; /* Number of elements inserted */
2199 void *mem
; /* Ptr to array */
2200 DWORD blocks_alloced
; /* Number of elements allocated */
2201 BYTE inc
; /* Number of elements to grow by when we need to expand */
2202 BYTE block_size
; /* Size in bytes of an element */
2203 BYTE flags
; /* Flags */
2206 #define FDSA_FLAG_INTERNAL_ALLOC 0x01 /* When set we have allocated mem internally */
2208 /*************************************************************************
2211 * Initialize an FDSA array.
2213 BOOL WINAPI
FDSA_Initialize(DWORD block_size
, DWORD inc
, FDSA_info
*info
, void *mem
,
2216 TRACE("(0x%08x 0x%08x %p %p 0x%08x)\n", block_size
, inc
, info
, mem
, init_blocks
);
2222 memset(mem
, 0, block_size
* init_blocks
);
2224 info
->num_items
= 0;
2227 info
->blocks_alloced
= init_blocks
;
2228 info
->block_size
= block_size
;
2234 /*************************************************************************
2237 * Destroy an FDSA array
2239 BOOL WINAPI
FDSA_Destroy(FDSA_info
*info
)
2241 TRACE("(%p)\n", info
);
2243 if(info
->flags
& FDSA_FLAG_INTERNAL_ALLOC
)
2245 HeapFree(GetProcessHeap(), 0, info
->mem
);
2252 /*************************************************************************
2255 * Insert element into an FDSA array
2257 DWORD WINAPI
FDSA_InsertItem(FDSA_info
*info
, DWORD where
, const void *block
)
2259 TRACE("(%p 0x%08x %p)\n", info
, where
, block
);
2260 if(where
> info
->num_items
)
2261 where
= info
->num_items
;
2263 if(info
->num_items
>= info
->blocks_alloced
)
2265 DWORD size
= (info
->blocks_alloced
+ info
->inc
) * info
->block_size
;
2266 if(info
->flags
& 0x1)
2267 info
->mem
= HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, info
->mem
, size
);
2270 void *old_mem
= info
->mem
;
2271 info
->mem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
2272 memcpy(info
->mem
, old_mem
, info
->blocks_alloced
* info
->block_size
);
2274 info
->blocks_alloced
+= info
->inc
;
2278 if(where
< info
->num_items
)
2280 memmove((char*)info
->mem
+ (where
+ 1) * info
->block_size
,
2281 (char*)info
->mem
+ where
* info
->block_size
,
2282 (info
->num_items
- where
) * info
->block_size
);
2284 memcpy((char*)info
->mem
+ where
* info
->block_size
, block
, info
->block_size
);
2290 /*************************************************************************
2293 * Delete an element from an FDSA array.
2295 BOOL WINAPI
FDSA_DeleteItem(FDSA_info
*info
, DWORD where
)
2297 TRACE("(%p 0x%08x)\n", info
, where
);
2299 if(where
>= info
->num_items
)
2302 if(where
< info
->num_items
- 1)
2304 memmove((char*)info
->mem
+ where
* info
->block_size
,
2305 (char*)info
->mem
+ (where
+ 1) * info
->block_size
,
2306 (info
->num_items
- where
- 1) * info
->block_size
);
2308 memset((char*)info
->mem
+ (info
->num_items
- 1) * info
->block_size
,
2309 0, info
->block_size
);
2314 /*************************************************************************
2317 * Call IUnknown_QueryInterface() on a table of objects.
2321 * Failure: E_POINTER or E_NOINTERFACE.
2323 HRESULT WINAPI
QISearch(
2324 void *base
, /* [in] Table of interfaces */
2325 const QITAB
*table
, /* [in] Array of REFIIDs and indexes into the table */
2326 REFIID riid
, /* [in] REFIID to get interface for */
2327 void **ppv
) /* [out] Destination for interface pointer */
2333 TRACE("(%p %p %s %p)\n", base
, table
, debugstr_guid(riid
), ppv
);
2336 while (xmove
->piid
) {
2337 TRACE("trying (offset %d) %s\n", xmove
->dwOffset
, debugstr_guid(xmove
->piid
));
2338 if (IsEqualIID(riid
, xmove
->piid
)) {
2339 a_vtbl
= (IUnknown
*)(xmove
->dwOffset
+ (LPBYTE
)base
);
2340 TRACE("matched, returning (%p)\n", a_vtbl
);
2342 IUnknown_AddRef(a_vtbl
);
2348 if (IsEqualIID(riid
, &IID_IUnknown
)) {
2349 a_vtbl
= (IUnknown
*)(table
->dwOffset
+ (LPBYTE
)base
);
2350 TRACE("returning first for IUnknown (%p)\n", a_vtbl
);
2352 IUnknown_AddRef(a_vtbl
);
2356 ret
= E_NOINTERFACE
;
2360 TRACE("-- 0x%08x\n", ret
);
2364 /*************************************************************************
2367 * Set the Font for a window and the "PropDlgFont" property of the parent window.
2370 * hWnd [I] Parent Window to set the property
2371 * id [I] Index of child Window to set the Font
2377 HRESULT WINAPI
SHSetDefaultDialogFont(HWND hWnd
, INT id
)
2379 FIXME("(%p, %d) stub\n", hWnd
, id
);
2383 /*************************************************************************
2386 * Remove the "PropDlgFont" property from a window.
2389 * hWnd [I] Window to remove the property from
2392 * A handle to the removed property, or NULL if it did not exist.
2394 HANDLE WINAPI
SHRemoveDefaultDialogFont(HWND hWnd
)
2398 TRACE("(%p)\n", hWnd
);
2400 hProp
= GetPropA(hWnd
, "PropDlgFont");
2404 DeleteObject(hProp
);
2405 hProp
= RemovePropA(hWnd
, "PropDlgFont");
2410 /*************************************************************************
2413 * Load the in-process server of a given GUID.
2416 * refiid [I] GUID of the server to load.
2419 * Success: A handle to the loaded server dll.
2420 * Failure: A NULL handle.
2422 HMODULE WINAPI
SHPinDllOfCLSID(REFIID refiid
)
2426 CHAR value
[MAX_PATH
], string
[MAX_PATH
];
2428 strcpy(string
, "CLSID\\");
2429 SHStringFromGUIDA(refiid
, string
+ 6, sizeof(string
)/sizeof(char) - 6);
2430 strcat(string
, "\\InProcServer32");
2433 RegOpenKeyExA(HKEY_CLASSES_ROOT
, string
, 0, 1, &newkey
);
2434 RegQueryValueExA(newkey
, 0, 0, &type
, (PBYTE
)value
, &count
);
2435 RegCloseKey(newkey
);
2436 return LoadLibraryExA(value
, 0, 0);
2439 /*************************************************************************
2442 * Unicode version of SHLWAPI_183.
2444 DWORD WINAPI
SHRegisterClassW(WNDCLASSW
* lpWndClass
)
2448 TRACE("(%p %s)\n",lpWndClass
->hInstance
, debugstr_w(lpWndClass
->lpszClassName
));
2450 if (GetClassInfoW(lpWndClass
->hInstance
, lpWndClass
->lpszClassName
, &WndClass
))
2452 return RegisterClassW(lpWndClass
);
2455 /*************************************************************************
2458 * Unregister a list of classes.
2461 * hInst [I] Application instance that registered the classes
2462 * lppClasses [I] List of class names
2463 * iCount [I] Number of names in lppClasses
2468 void WINAPI
SHUnregisterClassesA(HINSTANCE hInst
, LPCSTR
*lppClasses
, INT iCount
)
2472 TRACE("(%p,%p,%d)\n", hInst
, lppClasses
, iCount
);
2476 if (GetClassInfoA(hInst
, *lppClasses
, &WndClass
))
2477 UnregisterClassA(*lppClasses
, hInst
);
2483 /*************************************************************************
2486 * Unicode version of SHUnregisterClassesA.
2488 void WINAPI
SHUnregisterClassesW(HINSTANCE hInst
, LPCWSTR
*lppClasses
, INT iCount
)
2492 TRACE("(%p,%p,%d)\n", hInst
, lppClasses
, iCount
);
2496 if (GetClassInfoW(hInst
, *lppClasses
, &WndClass
))
2497 UnregisterClassW(*lppClasses
, hInst
);
2503 /*************************************************************************
2506 * Call The correct (Ascii/Unicode) default window procedure for a window.
2509 * hWnd [I] Window to call the default procedure for
2510 * uMessage [I] Message ID
2511 * wParam [I] WPARAM of message
2512 * lParam [I] LPARAM of message
2515 * The result of calling DefWindowProcA() or DefWindowProcW().
2517 LRESULT CALLBACK
SHDefWindowProc(HWND hWnd
, UINT uMessage
, WPARAM wParam
, LPARAM lParam
)
2519 if (IsWindowUnicode(hWnd
))
2520 return DefWindowProcW(hWnd
, uMessage
, wParam
, lParam
);
2521 return DefWindowProcA(hWnd
, uMessage
, wParam
, lParam
);
2524 /*************************************************************************
2527 HRESULT WINAPI
IUnknown_GetSite(LPUNKNOWN lpUnknown
, REFIID iid
, PVOID
*lppSite
)
2529 HRESULT hRet
= E_INVALIDARG
;
2530 LPOBJECTWITHSITE lpSite
= NULL
;
2532 TRACE("(%p,%s,%p)\n", lpUnknown
, debugstr_guid(iid
), lppSite
);
2534 if (lpUnknown
&& iid
&& lppSite
)
2536 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IObjectWithSite
,
2538 if (SUCCEEDED(hRet
) && lpSite
)
2540 hRet
= IObjectWithSite_GetSite(lpSite
, iid
, lppSite
);
2541 IObjectWithSite_Release(lpSite
);
2547 /*************************************************************************
2550 * Create a worker window using CreateWindowExA().
2553 * wndProc [I] Window procedure
2554 * hWndParent [I] Parent window
2555 * dwExStyle [I] Extra style flags
2556 * dwStyle [I] Style flags
2557 * hMenu [I] Window menu
2558 * wnd_extra [I] Window extra bytes value
2561 * Success: The window handle of the newly created window.
2564 HWND WINAPI
SHCreateWorkerWindowA(LONG wndProc
, HWND hWndParent
, DWORD dwExStyle
,
2565 DWORD dwStyle
, HMENU hMenu
, LONG_PTR wnd_extra
)
2567 static const char szClass
[] = "WorkerA";
2571 TRACE("(0x%08x, %p, 0x%08x, 0x%08x, %p, 0x%08lx)\n",
2572 wndProc
, hWndParent
, dwExStyle
, dwStyle
, hMenu
, wnd_extra
);
2574 /* Create Window class */
2576 wc
.lpfnWndProc
= DefWindowProcA
;
2578 wc
.cbWndExtra
= sizeof(LONG_PTR
);
2579 wc
.hInstance
= shlwapi_hInstance
;
2581 wc
.hCursor
= LoadCursorA(NULL
, (LPSTR
)IDC_ARROW
);
2582 wc
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
2583 wc
.lpszMenuName
= NULL
;
2584 wc
.lpszClassName
= szClass
;
2586 SHRegisterClassA(&wc
);
2588 hWnd
= CreateWindowExA(dwExStyle
, szClass
, 0, dwStyle
, 0, 0, 0, 0,
2589 hWndParent
, hMenu
, shlwapi_hInstance
, 0);
2592 SetWindowLongPtrW(hWnd
, 0, wnd_extra
);
2594 if (wndProc
) SetWindowLongPtrA(hWnd
, GWLP_WNDPROC
, wndProc
);
2600 typedef struct tagPOLICYDATA
2602 DWORD policy
; /* flags value passed to SHRestricted */
2603 LPCWSTR appstr
; /* application str such as "Explorer" */
2604 LPCWSTR keystr
; /* name of the actual registry key / policy */
2605 } POLICYDATA
, *LPPOLICYDATA
;
2607 #define SHELL_NO_POLICY 0xffffffff
2609 /* default shell policy registry key */
2610 static const WCHAR strRegistryPolicyW
[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o',
2611 's','o','f','t','\\','W','i','n','d','o','w','s','\\',
2612 'C','u','r','r','e','n','t','V','e','r','s','i','o','n',
2613 '\\','P','o','l','i','c','i','e','s',0};
2615 /*************************************************************************
2618 * Retrieve a policy value from the registry.
2621 * lpSubKey [I] registry key name
2622 * lpSubName [I] subname of registry key
2623 * lpValue [I] value name of registry value
2626 * the value associated with the registry key or 0 if not found
2628 DWORD WINAPI
SHGetRestriction(LPCWSTR lpSubKey
, LPCWSTR lpSubName
, LPCWSTR lpValue
)
2630 DWORD retval
, datsize
= sizeof(retval
);
2634 lpSubKey
= strRegistryPolicyW
;
2636 retval
= RegOpenKeyW(HKEY_LOCAL_MACHINE
, lpSubKey
, &hKey
);
2637 if (retval
!= ERROR_SUCCESS
)
2638 retval
= RegOpenKeyW(HKEY_CURRENT_USER
, lpSubKey
, &hKey
);
2639 if (retval
!= ERROR_SUCCESS
)
2642 SHGetValueW(hKey
, lpSubName
, lpValue
, NULL
, &retval
, &datsize
);
2647 /*************************************************************************
2650 * Helper function to retrieve the possibly cached value for a specific policy
2653 * policy [I] The policy to look for
2654 * initial [I] Main registry key to open, if NULL use default
2655 * polTable [I] Table of known policies, 0 terminated
2656 * polArr [I] Cache array of policy values
2659 * The retrieved policy value or 0 if not successful
2662 * This function is used by the native SHRestricted function to search for the
2663 * policy and cache it once retrieved. The current Wine implementation uses a
2664 * different POLICYDATA structure and implements a similar algorithm adapted to
2667 DWORD WINAPI
SHRestrictionLookup(
2670 LPPOLICYDATA polTable
,
2673 TRACE("(0x%08x %s %p %p)\n", policy
, debugstr_w(initial
), polTable
, polArr
);
2675 if (!polTable
|| !polArr
)
2678 for (;polTable
->policy
; polTable
++, polArr
++)
2680 if (policy
== polTable
->policy
)
2682 /* we have a known policy */
2684 /* check if this policy has been cached */
2685 if (*polArr
== SHELL_NO_POLICY
)
2686 *polArr
= SHGetRestriction(initial
, polTable
->appstr
, polTable
->keystr
);
2690 /* we don't know this policy, return 0 */
2691 TRACE("unknown policy: (%08x)\n", policy
);
2695 /*************************************************************************
2698 * Get an interface from an object.
2701 * Success: S_OK. ppv contains the requested interface.
2702 * Failure: An HRESULT error code.
2705 * This QueryInterface asks the inner object for an interface. In case
2706 * of aggregation this request would be forwarded by the inner to the
2707 * outer object. This function asks the inner object directly for the
2708 * interface circumventing the forwarding to the outer object.
2710 HRESULT WINAPI
SHWeakQueryInterface(
2711 IUnknown
* pUnk
, /* [in] Outer object */
2712 IUnknown
* pInner
, /* [in] Inner object */
2713 IID
* riid
, /* [in] Interface GUID to query for */
2714 LPVOID
* ppv
) /* [out] Destination for queried interface */
2716 HRESULT hret
= E_NOINTERFACE
;
2717 TRACE("(pUnk=%p pInner=%p\n\tIID: %s %p)\n",pUnk
,pInner
,debugstr_guid(riid
), ppv
);
2720 if(pUnk
&& pInner
) {
2721 hret
= IUnknown_QueryInterface(pInner
, riid
, ppv
);
2722 if (SUCCEEDED(hret
)) IUnknown_Release(pUnk
);
2724 TRACE("-- 0x%08x\n", hret
);
2728 /*************************************************************************
2731 * Move a reference from one interface to another.
2734 * lpDest [O] Destination to receive the reference
2735 * lppUnknown [O] Source to give up the reference to lpDest
2740 VOID WINAPI
SHWeakReleaseInterface(IUnknown
*lpDest
, IUnknown
**lppUnknown
)
2742 TRACE("(%p,%p)\n", lpDest
, lppUnknown
);
2747 IUnknown_AddRef(lpDest
);
2748 IUnknown_AtomicRelease(lppUnknown
); /* Release existing interface */
2752 /*************************************************************************
2755 * Convert an ASCII string of a CLSID into a CLSID.
2758 * idstr [I] String representing a CLSID in registry format
2759 * id [O] Destination for the converted CLSID
2762 * Success: TRUE. id contains the converted CLSID.
2765 BOOL WINAPI
GUIDFromStringA(LPCSTR idstr
, CLSID
*id
)
2768 MultiByteToWideChar(CP_ACP
, 0, idstr
, -1, wClsid
, sizeof(wClsid
)/sizeof(WCHAR
));
2769 return SUCCEEDED(CLSIDFromString(wClsid
, id
));
2772 /*************************************************************************
2775 * Unicode version of GUIDFromStringA.
2777 BOOL WINAPI
GUIDFromStringW(LPCWSTR idstr
, CLSID
*id
)
2779 return SUCCEEDED(CLSIDFromString((LPCOLESTR
)idstr
, id
));
2782 /*************************************************************************
2785 * Determine if the browser is integrated into the shell, and set a registry
2792 * 1, If the browser is not integrated.
2793 * 2, If the browser is integrated.
2796 * The key "HKLM\Software\Microsoft\Internet Explorer\IntegratedBrowser" is
2797 * either set to TRUE, or removed depending on whether the browser is deemed
2800 DWORD WINAPI
WhichPlatform(void)
2802 static const char szIntegratedBrowser
[] = "IntegratedBrowser";
2803 static DWORD dwState
= 0;
2805 DWORD dwRet
, dwData
, dwSize
;
2811 /* If shell32 exports DllGetVersion(), the browser is integrated */
2813 hshell32
= LoadLibraryA("shell32.dll");
2816 FARPROC pDllGetVersion
;
2817 pDllGetVersion
= GetProcAddress(hshell32
, "DllGetVersion");
2818 dwState
= pDllGetVersion
? 2 : 1;
2819 FreeLibrary(hshell32
);
2822 /* Set or delete the key accordingly */
2823 dwRet
= RegOpenKeyExA(HKEY_LOCAL_MACHINE
,
2824 "Software\\Microsoft\\Internet Explorer", 0,
2825 KEY_ALL_ACCESS
, &hKey
);
2828 dwRet
= RegQueryValueExA(hKey
, szIntegratedBrowser
, 0, 0,
2829 (LPBYTE
)&dwData
, &dwSize
);
2831 if (!dwRet
&& dwState
== 1)
2833 /* Value exists but browser is not integrated */
2834 RegDeleteValueA(hKey
, szIntegratedBrowser
);
2836 else if (dwRet
&& dwState
== 2)
2838 /* Browser is integrated but value does not exist */
2840 RegSetValueExA(hKey
, szIntegratedBrowser
, 0, REG_DWORD
,
2841 (LPBYTE
)&dwData
, sizeof(dwData
));
2848 /*************************************************************************
2851 * Unicode version of SHCreateWorkerWindowA.
2853 HWND WINAPI
SHCreateWorkerWindowW(LONG wndProc
, HWND hWndParent
, DWORD dwExStyle
,
2854 DWORD dwStyle
, HMENU hMenu
, LONG msg_result
)
2856 static const WCHAR szClass
[] = { 'W', 'o', 'r', 'k', 'e', 'r', 'W', 0 };
2860 TRACE("(0x%08x, %p, 0x%08x, 0x%08x, %p, 0x%08x)\n",
2861 wndProc
, hWndParent
, dwExStyle
, dwStyle
, hMenu
, msg_result
);
2863 /* If our OS is natively ANSI, use the ANSI version */
2864 if (GetVersion() & 0x80000000) /* not NT */
2866 TRACE("fallback to ANSI, ver 0x%08x\n", GetVersion());
2867 return SHCreateWorkerWindowA(wndProc
, hWndParent
, dwExStyle
, dwStyle
, hMenu
, msg_result
);
2870 /* Create Window class */
2872 wc
.lpfnWndProc
= DefWindowProcW
;
2875 wc
.hInstance
= shlwapi_hInstance
;
2877 wc
.hCursor
= LoadCursorW(NULL
, (LPWSTR
)IDC_ARROW
);
2878 wc
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
2879 wc
.lpszMenuName
= NULL
;
2880 wc
.lpszClassName
= szClass
;
2882 SHRegisterClassW(&wc
);
2884 hWnd
= CreateWindowExW(dwExStyle
, szClass
, 0, dwStyle
, 0, 0, 0, 0,
2885 hWndParent
, hMenu
, shlwapi_hInstance
, 0);
2888 SetWindowLongPtrW(hWnd
, DWLP_MSGRESULT
, msg_result
);
2890 if (wndProc
) SetWindowLongPtrW(hWnd
, GWLP_WNDPROC
, wndProc
);
2896 /*************************************************************************
2899 * Get and show a context menu from a shell folder.
2902 * hWnd [I] Window displaying the shell folder
2903 * lpFolder [I] IShellFolder interface
2904 * lpApidl [I] Id for the particular folder desired
2908 * Failure: An HRESULT error code indicating the error.
2910 HRESULT WINAPI
SHInvokeDefaultCommand(HWND hWnd
, IShellFolder
* lpFolder
, LPCITEMIDLIST lpApidl
)
2912 TRACE("%p %p %p\n", hWnd
, lpFolder
, lpApidl
);
2913 return SHInvokeCommand(hWnd
, lpFolder
, lpApidl
, 0);
2916 /*************************************************************************
2919 * _SHPackDispParamsV
2921 HRESULT WINAPI
SHPackDispParamsV(DISPPARAMS
*params
, VARIANTARG
*args
, UINT cnt
, __ms_va_list valist
)
2925 TRACE("(%p %p %u ...)\n", params
, args
, cnt
);
2927 params
->rgvarg
= args
;
2928 params
->rgdispidNamedArgs
= NULL
;
2929 params
->cArgs
= cnt
;
2930 params
->cNamedArgs
= 0;
2934 while(iter
-- > args
) {
2935 V_VT(iter
) = va_arg(valist
, enum VARENUM
);
2937 TRACE("vt=%d\n", V_VT(iter
));
2939 if(V_VT(iter
) & VT_BYREF
) {
2940 V_BYREF(iter
) = va_arg(valist
, LPVOID
);
2942 switch(V_VT(iter
)) {
2944 V_I4(iter
) = va_arg(valist
, LONG
);
2947 V_BSTR(iter
) = va_arg(valist
, BSTR
);
2950 V_DISPATCH(iter
) = va_arg(valist
, IDispatch
*);
2953 V_BOOL(iter
) = va_arg(valist
, int);
2956 V_UNKNOWN(iter
) = va_arg(valist
, IUnknown
*);
2960 V_I4(iter
) = va_arg(valist
, LONG
);
2968 /*************************************************************************
2973 HRESULT WINAPIV
SHPackDispParams(DISPPARAMS
*params
, VARIANTARG
*args
, UINT cnt
, ...)
2975 __ms_va_list valist
;
2978 __ms_va_start(valist
, cnt
);
2979 hres
= SHPackDispParamsV(params
, args
, cnt
, valist
);
2980 __ms_va_end(valist
);
2984 /*************************************************************************
2985 * SHLWAPI_InvokeByIID
2987 * This helper function calls IDispatch::Invoke for each sink
2988 * which implements given iid or IDispatch.
2991 static HRESULT
SHLWAPI_InvokeByIID(
2992 IConnectionPoint
* iCP
,
2995 DISPPARAMS
* dispParams
)
2997 IEnumConnections
*enumerator
;
2999 static DISPPARAMS empty
= {NULL
, NULL
, 0, 0};
3000 DISPPARAMS
* params
= dispParams
;
3002 HRESULT result
= IConnectionPoint_EnumConnections(iCP
, &enumerator
);
3006 /* Invoke is never happening with an NULL dispParams */
3010 while(IEnumConnections_Next(enumerator
, 1, &rgcd
, NULL
)==S_OK
)
3012 IDispatch
*dispIface
;
3013 if ((iid
&& SUCCEEDED(IUnknown_QueryInterface(rgcd
.pUnk
, iid
, (LPVOID
*)&dispIface
))) ||
3014 SUCCEEDED(IUnknown_QueryInterface(rgcd
.pUnk
, &IID_IDispatch
, (LPVOID
*)&dispIface
)))
3016 IDispatch_Invoke(dispIface
, dispId
, &IID_NULL
, 0, DISPATCH_METHOD
, params
, NULL
, NULL
, NULL
);
3017 IDispatch_Release(dispIface
);
3019 IUnknown_Release(rgcd
.pUnk
);
3022 IEnumConnections_Release(enumerator
);
3027 /*************************************************************************
3028 * IConnectionPoint_InvokeWithCancel [SHLWAPI.283]
3030 HRESULT WINAPI
IConnectionPoint_InvokeWithCancel( IConnectionPoint
* iCP
,
3031 DISPID dispId
, DISPPARAMS
* dispParams
,
3032 DWORD unknown1
, DWORD unknown2
)
3037 FIXME("(%p)->(0x%x %p %x %x) partial stub\n", iCP
, dispId
, dispParams
, unknown1
, unknown2
);
3039 result
= IConnectionPoint_GetConnectionInterface(iCP
, &iid
);
3040 if (SUCCEEDED(result
))
3041 result
= SHLWAPI_InvokeByIID(iCP
, &iid
, dispId
, dispParams
);
3043 result
= SHLWAPI_InvokeByIID(iCP
, NULL
, dispId
, dispParams
);
3049 /*************************************************************************
3052 * IConnectionPoint_SimpleInvoke
3054 HRESULT WINAPI
IConnectionPoint_SimpleInvoke(
3055 IConnectionPoint
* iCP
,
3057 DISPPARAMS
* dispParams
)
3062 TRACE("(%p)->(0x%x %p)\n",iCP
,dispId
,dispParams
);
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
);
3073 /*************************************************************************
3076 * Notify an IConnectionPoint object of changes.
3079 * lpCP [I] Object to notify
3084 * Failure: E_NOINTERFACE, if lpCP is NULL or does not support the
3085 * IConnectionPoint interface.
3087 HRESULT WINAPI
IConnectionPoint_OnChanged(IConnectionPoint
* lpCP
, DISPID dispID
)
3089 IEnumConnections
*lpEnum
;
3090 HRESULT hRet
= E_NOINTERFACE
;
3092 TRACE("(%p,0x%8X)\n", lpCP
, dispID
);
3094 /* Get an enumerator for the connections */
3096 hRet
= IConnectionPoint_EnumConnections(lpCP
, &lpEnum
);
3098 if (SUCCEEDED(hRet
))
3100 IPropertyNotifySink
*lpSink
;
3101 CONNECTDATA connData
;
3104 /* Call OnChanged() for every notify sink in the connection point */
3105 while (IEnumConnections_Next(lpEnum
, 1, &connData
, &ulFetched
) == S_OK
)
3107 if (SUCCEEDED(IUnknown_QueryInterface(connData
.pUnk
, &IID_IPropertyNotifySink
, (void**)&lpSink
)) &&
3110 IPropertyNotifySink_OnChanged(lpSink
, dispID
);
3111 IPropertyNotifySink_Release(lpSink
);
3113 IUnknown_Release(connData
.pUnk
);
3116 IEnumConnections_Release(lpEnum
);
3121 /*************************************************************************
3124 * IUnknown_CPContainerInvokeParam
3126 HRESULT WINAPIV
IUnknown_CPContainerInvokeParam(
3127 IUnknown
*container
,
3134 IConnectionPoint
*iCP
;
3135 IConnectionPointContainer
*iCPC
;
3136 DISPPARAMS dispParams
= {buffer
, NULL
, cParams
, 0};
3137 __ms_va_list valist
;
3140 return E_NOINTERFACE
;
3142 result
= IUnknown_QueryInterface(container
, &IID_IConnectionPointContainer
,(LPVOID
*) &iCPC
);
3146 result
= IConnectionPointContainer_FindConnectionPoint(iCPC
, riid
, &iCP
);
3147 IConnectionPointContainer_Release(iCPC
);
3151 __ms_va_start(valist
, cParams
);
3152 SHPackDispParamsV(&dispParams
, buffer
, cParams
, valist
);
3153 __ms_va_end(valist
);
3155 result
= SHLWAPI_InvokeByIID(iCP
, riid
, dispId
, &dispParams
);
3156 IConnectionPoint_Release(iCP
);
3161 /*************************************************************************
3164 * Notify an IConnectionPointContainer object of changes.
3167 * lpUnknown [I] Object to notify
3172 * Failure: E_NOINTERFACE, if lpUnknown is NULL or does not support the
3173 * IConnectionPointContainer interface.
3175 HRESULT WINAPI
IUnknown_CPContainerOnChanged(IUnknown
*lpUnknown
, DISPID dispID
)
3177 IConnectionPointContainer
* lpCPC
= NULL
;
3178 HRESULT hRet
= E_NOINTERFACE
;
3180 TRACE("(%p,0x%8X)\n", lpUnknown
, dispID
);
3183 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IConnectionPointContainer
, (void**)&lpCPC
);
3185 if (SUCCEEDED(hRet
))
3187 IConnectionPoint
* lpCP
;
3189 hRet
= IConnectionPointContainer_FindConnectionPoint(lpCPC
, &IID_IPropertyNotifySink
, &lpCP
);
3190 IConnectionPointContainer_Release(lpCPC
);
3192 hRet
= IConnectionPoint_OnChanged(lpCP
, dispID
);
3193 IConnectionPoint_Release(lpCP
);
3198 /*************************************************************************
3203 BOOL WINAPI
PlaySoundWrapW(LPCWSTR pszSound
, HMODULE hmod
, DWORD fdwSound
)
3205 return PlaySoundW(pszSound
, hmod
, fdwSound
);
3208 /*************************************************************************
3211 * Retrieve a key value from an INI file. See GetPrivateProfileString for
3215 * appName [I] The section in the INI file that contains the key
3216 * keyName [I] The key to be retrieved
3217 * out [O] The buffer into which the key's value will be copied
3218 * outLen [I] The length of the `out' buffer
3219 * filename [I] The location of the INI file
3222 * Length of string copied into `out'.
3224 DWORD WINAPI
SHGetIniStringW(LPCWSTR appName
, LPCWSTR keyName
, LPWSTR out
,
3225 DWORD outLen
, LPCWSTR filename
)
3230 TRACE("(%s,%s,%p,%08x,%s)\n", debugstr_w(appName
), debugstr_w(keyName
),
3231 out
, outLen
, debugstr_w(filename
));
3236 buf
= HeapAlloc(GetProcessHeap(), 0, outLen
* sizeof(WCHAR
));
3242 ret
= GetPrivateProfileStringW(appName
, keyName
, NULL
, buf
, outLen
, filename
);
3248 HeapFree(GetProcessHeap(), 0, buf
);
3250 return strlenW(out
);
3253 /*************************************************************************
3256 * Set a key value in an INI file. See WritePrivateProfileString for
3260 * appName [I] The section in the INI file that contains the key
3261 * keyName [I] The key to be set
3262 * str [O] The value of the key
3263 * filename [I] The location of the INI file
3269 BOOL WINAPI
SHSetIniStringW(LPCWSTR appName
, LPCWSTR keyName
, LPCWSTR str
,
3272 TRACE("(%s, %p, %s, %s)\n", debugstr_w(appName
), keyName
, debugstr_w(str
),
3273 debugstr_w(filename
));
3275 return WritePrivateProfileStringW(appName
, keyName
, str
, filename
);
3278 /*************************************************************************
3281 * See SHGetFileInfoW.
3283 DWORD WINAPI
SHGetFileInfoWrapW(LPCWSTR path
, DWORD dwFileAttributes
,
3284 SHFILEINFOW
*psfi
, UINT sizeofpsfi
, UINT flags
)
3286 return SHGetFileInfoW(path
, dwFileAttributes
, psfi
, sizeofpsfi
, flags
);
3289 /*************************************************************************
3292 * See DragQueryFileW.
3294 UINT WINAPI
DragQueryFileWrapW(HDROP hDrop
, UINT lFile
, LPWSTR lpszFile
, UINT lLength
)
3296 return DragQueryFileW(hDrop
, lFile
, lpszFile
, lLength
);
3299 /*************************************************************************
3302 * See SHBrowseForFolderW.
3304 LPITEMIDLIST WINAPI
SHBrowseForFolderWrapW(LPBROWSEINFOW lpBi
)
3306 return SHBrowseForFolderW(lpBi
);
3309 /*************************************************************************
3312 * See SHGetPathFromIDListW.
3314 BOOL WINAPI
SHGetPathFromIDListWrapW(LPCITEMIDLIST pidl
,LPWSTR pszPath
)
3316 return SHGetPathFromIDListW(pidl
, pszPath
);
3319 /*************************************************************************
3322 * See ShellExecuteExW.
3324 BOOL WINAPI
ShellExecuteExWrapW(LPSHELLEXECUTEINFOW lpExecInfo
)
3326 return ShellExecuteExW(lpExecInfo
);
3329 /*************************************************************************
3332 * See SHFileOperationW.
3334 INT WINAPI
SHFileOperationWrapW(LPSHFILEOPSTRUCTW lpFileOp
)
3336 return SHFileOperationW(lpFileOp
);
3339 /*************************************************************************
3343 PVOID WINAPI
SHInterlockedCompareExchange( PVOID
*dest
, PVOID xchg
, PVOID compare
)
3345 return InterlockedCompareExchangePointer( dest
, xchg
, compare
);
3348 /*************************************************************************
3351 * See GetFileVersionInfoSizeW.
3353 DWORD WINAPI
GetFileVersionInfoSizeWrapW( LPCWSTR filename
, LPDWORD handle
)
3355 return GetFileVersionInfoSizeW( filename
, handle
);
3358 /*************************************************************************
3361 * See GetFileVersionInfoW.
3363 BOOL WINAPI
GetFileVersionInfoWrapW( LPCWSTR filename
, DWORD handle
,
3364 DWORD datasize
, LPVOID data
)
3366 return GetFileVersionInfoW( filename
, handle
, datasize
, data
);
3369 /*************************************************************************
3372 * See VerQueryValueW.
3374 WORD WINAPI
VerQueryValueWrapW( LPVOID pBlock
, LPCWSTR lpSubBlock
,
3375 LPVOID
*lplpBuffer
, UINT
*puLen
)
3377 return VerQueryValueW( pBlock
, lpSubBlock
, lplpBuffer
, puLen
);
3380 #define IsIface(type) SUCCEEDED((hRet = IUnknown_QueryInterface(lpUnknown, &IID_##type, (void**)&lpObj)))
3381 #define IShellBrowser_EnableModeless IShellBrowser_EnableModelessSB
3382 #define EnableModeless(type) type##_EnableModeless((type*)lpObj, bModeless)
3384 /*************************************************************************
3387 * Change the modality of a shell object.
3390 * lpUnknown [I] Object to make modeless
3391 * bModeless [I] TRUE=Make modeless, FALSE=Make modal
3394 * Success: S_OK. The modality lpUnknown is changed.
3395 * Failure: An HRESULT error code indicating the error.
3398 * lpUnknown must support the IOleInPlaceFrame interface, the
3399 * IInternetSecurityMgrSite interface, the IShellBrowser interface
3400 * the IDocHostUIHandler interface, or the IOleInPlaceActiveObject interface,
3401 * or this call will fail.
3403 HRESULT WINAPI
IUnknown_EnableModeless(IUnknown
*lpUnknown
, BOOL bModeless
)
3408 TRACE("(%p,%d)\n", lpUnknown
, bModeless
);
3413 if (IsIface(IOleInPlaceActiveObject
))
3414 EnableModeless(IOleInPlaceActiveObject
);
3415 else if (IsIface(IOleInPlaceFrame
))
3416 EnableModeless(IOleInPlaceFrame
);
3417 else if (IsIface(IShellBrowser
))
3418 EnableModeless(IShellBrowser
);
3419 else if (IsIface(IInternetSecurityMgrSite
))
3420 EnableModeless(IInternetSecurityMgrSite
);
3421 else if (IsIface(IDocHostUIHandler
))
3422 EnableModeless(IDocHostUIHandler
);
3426 IUnknown_Release(lpObj
);
3430 /*************************************************************************
3433 * See SHGetNewLinkInfoW.
3435 BOOL WINAPI
SHGetNewLinkInfoWrapW(LPCWSTR pszLinkTo
, LPCWSTR pszDir
, LPWSTR pszName
,
3436 BOOL
*pfMustCopy
, UINT uFlags
)
3438 return SHGetNewLinkInfoW(pszLinkTo
, pszDir
, pszName
, pfMustCopy
, uFlags
);
3441 /*************************************************************************
3444 * See SHDefExtractIconW.
3446 UINT WINAPI
SHDefExtractIconWrapW(LPCWSTR pszIconFile
, int iIndex
, UINT uFlags
, HICON
* phiconLarge
,
3447 HICON
* phiconSmall
, UINT nIconSize
)
3449 return SHDefExtractIconW(pszIconFile
, iIndex
, uFlags
, phiconLarge
, phiconSmall
, nIconSize
);
3452 /*************************************************************************
3455 * Get and show a context menu from a shell folder.
3458 * hWnd [I] Window displaying the shell folder
3459 * lpFolder [I] IShellFolder interface
3460 * lpApidl [I] Id for the particular folder desired
3461 * dwCommandId [I] The command ID to invoke (0=invoke default)
3464 * Success: S_OK. If bInvokeDefault is TRUE, the default menu action was
3466 * Failure: An HRESULT error code indicating the error.
3468 HRESULT WINAPI
SHInvokeCommand(HWND hWnd
, IShellFolder
* lpFolder
, LPCITEMIDLIST lpApidl
, DWORD dwCommandId
)
3470 IContextMenu
*iContext
;
3473 TRACE("(%p, %p, %p, %u)\n", hWnd
, lpFolder
, lpApidl
, dwCommandId
);
3478 /* Get the context menu from the shell folder */
3479 hRet
= IShellFolder_GetUIObjectOf(lpFolder
, hWnd
, 1, &lpApidl
,
3480 &IID_IContextMenu
, 0, (void**)&iContext
);
3481 if (SUCCEEDED(hRet
))
3484 if ((hMenu
= CreatePopupMenu()))
3488 /* Add the context menu entries to the popup */
3489 hQuery
= IContextMenu_QueryContextMenu(iContext
, hMenu
, 0, 1, 0x7FFF,
3490 dwCommandId
? CMF_NORMAL
: CMF_DEFAULTONLY
);
3492 if (SUCCEEDED(hQuery
))
3495 dwCommandId
= GetMenuDefaultItem(hMenu
, 0, 0);
3496 if (dwCommandId
!= (UINT
)-1)
3498 CMINVOKECOMMANDINFO cmIci
;
3499 /* Invoke the default item */
3500 memset(&cmIci
,0,sizeof(cmIci
));
3501 cmIci
.cbSize
= sizeof(cmIci
);
3502 cmIci
.fMask
= CMIC_MASK_ASYNCOK
;
3504 #ifdef __REACTOS__ /* r75561 */
3505 cmIci
.lpVerb
= MAKEINTRESOURCEA(dwCommandId
- 1);
3507 cmIci
.lpVerb
= MAKEINTRESOURCEA(dwCommandId
);
3509 cmIci
.nShow
= SW_SHOWNORMAL
;
3511 hRet
= IContextMenu_InvokeCommand(iContext
, &cmIci
);
3516 IContextMenu_Release(iContext
);
3521 /*************************************************************************
3526 HICON WINAPI
ExtractIconWrapW(HINSTANCE hInstance
, LPCWSTR lpszExeFileName
,
3529 return ExtractIconW(hInstance
, lpszExeFileName
, nIconIndex
);
3532 /*************************************************************************
3535 * Load a library from the directory of a particular process.
3538 * new_mod [I] Library name
3539 * inst_hwnd [I] Module whose directory is to be used
3540 * dwCrossCodePage [I] Should be FALSE (currently ignored)
3543 * Success: A handle to the loaded module
3544 * Failure: A NULL handle.
3546 HMODULE WINAPI
MLLoadLibraryA(LPCSTR new_mod
, HMODULE inst_hwnd
, DWORD dwCrossCodePage
)
3548 /* FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for
3550 * FIXME: Native shows calls to:
3551 * SHRegGetUSValue for "Software\Microsoft\Internet Explorer\International"
3553 * RegOpenKeyExA for "HKLM\Software\Microsoft\Internet Explorer"
3554 * RegQueryValueExA for "LPKInstalled"
3556 * RegOpenKeyExA for "HKCU\Software\Microsoft\Internet Explorer\International"
3557 * RegQueryValueExA for "ResourceLocale"
3559 * RegOpenKeyExA for "HKLM\Software\Microsoft\Active Setup\Installed Components\{guid}"
3560 * RegQueryValueExA for "Locale"
3562 * and then tests the Locale ("en" for me).
3564 * after the code then a DPA_Create (first time) and DPA_InsertPtr are done.
3566 CHAR mod_path
[2*MAX_PATH
];
3570 FIXME("(%s,%p,%d) semi-stub!\n", debugstr_a(new_mod
), inst_hwnd
, dwCrossCodePage
);
3571 len
= GetModuleFileNameA(inst_hwnd
, mod_path
, sizeof(mod_path
));
3572 if (!len
|| len
>= sizeof(mod_path
)) return NULL
;
3574 ptr
= strrchr(mod_path
, '\\');
3576 strcpy(ptr
+1, new_mod
);
3577 TRACE("loading %s\n", debugstr_a(mod_path
));
3578 return LoadLibraryA(mod_path
);
3583 /*************************************************************************
3586 * Unicode version of MLLoadLibraryA.
3588 HMODULE WINAPI
MLLoadLibraryW(LPCWSTR new_mod
, HMODULE inst_hwnd
, DWORD dwCrossCodePage
)
3590 WCHAR mod_path
[2*MAX_PATH
];
3594 FIXME("(%s,%p,%d) semi-stub!\n", debugstr_w(new_mod
), inst_hwnd
, dwCrossCodePage
);
3595 len
= GetModuleFileNameW(inst_hwnd
, mod_path
, sizeof(mod_path
) / sizeof(WCHAR
));
3596 if (!len
|| len
>= sizeof(mod_path
) / sizeof(WCHAR
)) return NULL
;
3598 ptr
= strrchrW(mod_path
, '\\');
3600 strcpyW(ptr
+1, new_mod
);
3601 TRACE("loading %s\n", debugstr_w(mod_path
));
3602 return LoadLibraryW(mod_path
);
3607 /*************************************************************************
3608 * ColorAdjustLuma [SHLWAPI.@]
3610 * Adjust the luminosity of a color
3613 * cRGB [I] RGB value to convert
3614 * dwLuma [I] Luma adjustment
3615 * bUnknown [I] Unknown
3618 * The adjusted RGB color.
3620 COLORREF WINAPI
ColorAdjustLuma(COLORREF cRGB
, int dwLuma
, BOOL bUnknown
)
3622 TRACE("(0x%8x,%d,%d)\n", cRGB
, dwLuma
, bUnknown
);
3628 ColorRGBToHLS(cRGB
, &wH
, &wL
, &wS
);
3630 FIXME("Ignoring luma adjustment\n");
3632 /* FIXME: The adjustment is not linear */
3634 cRGB
= ColorHLSToRGB(wH
, wL
, wS
);
3639 /*************************************************************************
3642 * See GetSaveFileNameW.
3644 BOOL WINAPI
GetSaveFileNameWrapW(LPOPENFILENAMEW ofn
)
3646 return GetSaveFileNameW(ofn
);
3649 /*************************************************************************
3652 * See WNetRestoreConnectionW.
3654 DWORD WINAPI
WNetRestoreConnectionWrapW(HWND hwndOwner
, LPWSTR lpszDevice
)
3656 return WNetRestoreConnectionW(hwndOwner
, lpszDevice
);
3659 /*************************************************************************
3662 * See WNetGetLastErrorW.
3664 DWORD WINAPI
WNetGetLastErrorWrapW(LPDWORD lpError
, LPWSTR lpErrorBuf
, DWORD nErrorBufSize
,
3665 LPWSTR lpNameBuf
, DWORD nNameBufSize
)
3667 return WNetGetLastErrorW(lpError
, lpErrorBuf
, nErrorBufSize
, lpNameBuf
, nNameBufSize
);
3670 /*************************************************************************
3673 * See PageSetupDlgW.
3675 BOOL WINAPI
PageSetupDlgWrapW(LPPAGESETUPDLGW pagedlg
)
3677 return PageSetupDlgW(pagedlg
);
3680 /*************************************************************************
3685 BOOL WINAPI
PrintDlgWrapW(LPPRINTDLGW printdlg
)
3687 return PrintDlgW(printdlg
);
3690 /*************************************************************************
3693 * See GetOpenFileNameW.
3695 BOOL WINAPI
GetOpenFileNameWrapW(LPOPENFILENAMEW ofn
)
3697 return GetOpenFileNameW(ofn
);
3700 /*************************************************************************
3703 HRESULT WINAPI
SHIShellFolder_EnumObjects(LPSHELLFOLDER lpFolder
, HWND hwnd
, SHCONTF flags
, IEnumIDList
**ppenum
)
3705 /* Windows attempts to get an IPersist interface and, if that fails, an
3706 * IPersistFolder interface on the folder passed-in here. If one of those
3707 * interfaces is available, it then calls GetClassID on the folder... and
3708 * then calls IShellFolder_EnumObjects no matter what, even crashing if
3709 * lpFolder isn't actually an IShellFolder object. The purpose of getting
3710 * the ClassID is unknown, so we don't do it here.
3712 * For discussion and detailed tests, see:
3713 * "shlwapi: Be less strict on which type of IShellFolder can be enumerated"
3714 * wine-devel mailing list, 3 Jun 2010
3717 return IShellFolder_EnumObjects(lpFolder
, hwnd
, flags
, ppenum
);
3720 /* INTERNAL: Map from HLS color space to RGB */
3721 static WORD
ConvertHue(int wHue
, WORD wMid1
, WORD wMid2
)
3723 wHue
= wHue
> 240 ? wHue
- 240 : wHue
< 0 ? wHue
+ 240 : wHue
;
3727 else if (wHue
> 120)
3732 return ((wHue
* (wMid2
- wMid1
) + 20) / 40) + wMid1
;
3735 /* Convert to RGB and scale into RGB range (0..255) */
3736 #define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240
3738 /*************************************************************************
3739 * ColorHLSToRGB [SHLWAPI.@]
3741 * Convert from hls color space into an rgb COLORREF.
3744 * wHue [I] Hue amount
3745 * wLuminosity [I] Luminosity amount
3746 * wSaturation [I] Saturation amount
3749 * A COLORREF representing the converted color.
3752 * Input hls values are constrained to the range (0..240).
3754 COLORREF WINAPI
ColorHLSToRGB(WORD wHue
, WORD wLuminosity
, WORD wSaturation
)
3760 WORD wGreen
, wBlue
, wMid1
, wMid2
;
3762 if (wLuminosity
> 120)
3763 wMid2
= wSaturation
+ wLuminosity
- (wSaturation
* wLuminosity
+ 120) / 240;
3765 wMid2
= ((wSaturation
+ 240) * wLuminosity
+ 120) / 240;
3767 wMid1
= wLuminosity
* 2 - wMid2
;
3769 wRed
= GET_RGB(wHue
+ 80);
3770 wGreen
= GET_RGB(wHue
);
3771 wBlue
= GET_RGB(wHue
- 80);
3773 return RGB(wRed
, wGreen
, wBlue
);
3776 wRed
= wLuminosity
* 255 / 240;
3777 return RGB(wRed
, wRed
, wRed
);
3780 /*************************************************************************
3783 * Get the current docking status of the system.
3786 * dwFlags [I] DOCKINFO_ flags from "winbase.h", unused
3789 * One of DOCKINFO_UNDOCKED, DOCKINFO_UNDOCKED, or 0 if the system is not
3792 DWORD WINAPI
SHGetMachineInfo(DWORD dwFlags
)
3794 HW_PROFILE_INFOA hwInfo
;
3796 TRACE("(0x%08x)\n", dwFlags
);
3798 GetCurrentHwProfileA(&hwInfo
);
3799 switch (hwInfo
.dwDockInfo
& (DOCKINFO_DOCKED
|DOCKINFO_UNDOCKED
))
3801 case DOCKINFO_DOCKED
:
3802 case DOCKINFO_UNDOCKED
:
3803 return hwInfo
.dwDockInfo
& (DOCKINFO_DOCKED
|DOCKINFO_UNDOCKED
);
3809 /*************************************************************************
3813 DWORD WINAPI
SHWinHelpOnDemandW(HWND hwnd
, LPCWSTR helpfile
, DWORD flags1
, VOID
*ptr1
, DWORD flags2
)
3816 FIXME("(%p, %s, 0x%x, %p, %d)\n", hwnd
, debugstr_w(helpfile
), flags1
, ptr1
, flags2
);
3820 /*************************************************************************
3824 DWORD WINAPI
SHWinHelpOnDemandA(HWND hwnd
, LPCSTR helpfile
, DWORD flags1
, VOID
*ptr1
, DWORD flags2
)
3827 FIXME("(%p, %s, 0x%x, %p, %d)\n", hwnd
, debugstr_a(helpfile
), flags1
, ptr1
, flags2
);
3831 /*************************************************************************
3834 * Function seems to do FreeLibrary plus other things.
3836 * FIXME native shows the following calls:
3837 * RtlEnterCriticalSection
3839 * GetProcAddress(Comctl32??, 150L)
3841 * RtlLeaveCriticalSection
3842 * followed by the FreeLibrary.
3843 * The above code may be related to .377 above.
3845 BOOL WINAPI
MLFreeLibrary(HMODULE hModule
)
3847 FIXME("(%p) semi-stub\n", hModule
);
3848 return FreeLibrary(hModule
);
3851 /*************************************************************************
3854 BOOL WINAPI
SHFlushSFCacheWrap(void) {
3859 /*************************************************************************
3861 * FIXME I have no idea what this function does or what its arguments are.
3863 BOOL WINAPI
MLIsMLHInstance(HINSTANCE hInst
)
3865 FIXME("(%p) stub\n", hInst
);
3870 /*************************************************************************
3873 DWORD WINAPI
MLSetMLHInstance(HINSTANCE hInst
, HANDLE hHeap
)
3875 FIXME("(%p,%p) stub\n", hInst
, hHeap
);
3876 return E_FAIL
; /* This is what is used if shlwapi not loaded */
3879 /*************************************************************************
3882 DWORD WINAPI
MLClearMLHInstance(DWORD x
)
3884 FIXME("(0x%08x)stub\n", x
);
3888 /*************************************************************************
3891 * See SHSendMessageBroadcastW
3894 DWORD WINAPI
SHSendMessageBroadcastA(UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3896 return SendMessageTimeoutA(HWND_BROADCAST
, uMsg
, wParam
, lParam
,
3897 SMTO_ABORTIFHUNG
, 2000, NULL
);
3900 /*************************************************************************
3903 * A wrapper for sending Broadcast Messages to all top level Windows
3906 DWORD WINAPI
SHSendMessageBroadcastW(UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3908 return SendMessageTimeoutW(HWND_BROADCAST
, uMsg
, wParam
, lParam
,
3909 SMTO_ABORTIFHUNG
, 2000, NULL
);
3912 /*************************************************************************
3915 * Convert a Unicode string CLSID into a CLSID.
3918 * idstr [I] string containing a CLSID in text form
3919 * id [O] CLSID extracted from the string
3922 * S_OK on success or E_INVALIDARG on failure
3924 HRESULT WINAPI
CLSIDFromStringWrap(LPCWSTR idstr
, CLSID
*id
)
3926 return CLSIDFromString((LPCOLESTR
)idstr
, id
);
3929 /*************************************************************************
3932 * Determine if the OS supports a given feature.
3935 * dwFeature [I] Feature requested (undocumented)
3938 * TRUE If the feature is available.
3939 * FALSE If the feature is not available.
3941 BOOL WINAPI
IsOS(DWORD feature
)
3943 OSVERSIONINFOA osvi
;
3944 DWORD platform
, majorv
, minorv
;
3946 osvi
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFOA
);
3947 if(!GetVersionExA(&osvi
)) {
3948 ERR("GetVersionEx failed\n");
3952 majorv
= osvi
.dwMajorVersion
;
3953 minorv
= osvi
.dwMinorVersion
;
3954 platform
= osvi
.dwPlatformId
;
3956 #define ISOS_RETURN(x) \
3957 TRACE("(0x%x) ret=%d\n",feature,(x)); \
3961 case OS_WIN32SORGREATER
:
3962 ISOS_RETURN(platform
== VER_PLATFORM_WIN32s
3963 || platform
== VER_PLATFORM_WIN32_WINDOWS
)
3965 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3966 case OS_WIN95ORGREATER
:
3967 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
)
3968 case OS_NT4ORGREATER
:
3969 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 4)
3970 case OS_WIN2000ORGREATER_ALT
:
3971 case OS_WIN2000ORGREATER
:
3972 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5)
3973 case OS_WIN98ORGREATER
:
3974 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
&& minorv
>= 10)
3976 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
&& minorv
== 10)
3978 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5)
3979 case OS_WIN2000SERVER
:
3980 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& (minorv
== 0 || minorv
== 1))
3981 case OS_WIN2000ADVSERVER
:
3982 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& (minorv
== 0 || minorv
== 1))
3983 case OS_WIN2000DATACENTER
:
3984 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& (minorv
== 0 || minorv
== 1))
3985 case OS_WIN2000TERMINAL
:
3986 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& (minorv
== 0 || minorv
== 1))
3988 FIXME("(OS_EMBEDDED) What should we return here?\n");
3990 case OS_TERMINALCLIENT
:
3991 FIXME("(OS_TERMINALCLIENT) What should we return here?\n");
3993 case OS_TERMINALREMOTEADMIN
:
3994 FIXME("(OS_TERMINALREMOTEADMIN) What should we return here?\n");
3997 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
&& minorv
== 0)
3998 case OS_MEORGREATER
:
3999 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
&& minorv
>= 90)
4000 case OS_XPORGREATER
:
4001 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5 && minorv
>= 1)
4003 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5 && minorv
>= 1)
4004 case OS_PROFESSIONAL
:
4005 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
4007 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
4009 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5)
4011 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
4012 case OS_TERMINALSERVER
:
4013 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
4014 case OS_PERSONALTERMINALSERVER
:
4015 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& minorv
>= 1 && majorv
>= 5)
4016 case OS_FASTUSERSWITCHING
:
4017 FIXME("(OS_FASTUSERSWITCHING) What should we return here?\n");
4019 case OS_WELCOMELOGONUI
:
4020 FIXME("(OS_WELCOMELOGONUI) What should we return here?\n");
4022 case OS_DOMAINMEMBER
:
4023 FIXME("(OS_DOMAINMEMBER) What should we return here?\n");
4026 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
4030 IsWow64Process(GetCurrentProcess(), &is_wow64
);
4034 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
4035 case OS_SMALLBUSINESSSERVER
:
4036 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
4038 FIXME("(OS_TABLETPC) What should we return here?\n");
4040 case OS_SERVERADMINUI
:
4041 FIXME("(OS_SERVERADMINUI) What should we return here?\n");
4043 case OS_MEDIACENTER
:
4044 FIXME("(OS_MEDIACENTER) What should we return here?\n");
4047 FIXME("(OS_APPLIANCE) What should we return here?\n");
4049 case 0x25: /*OS_VISTAORGREATER*/
4050 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 6)
4055 WARN("(0x%x) unknown parameter\n",feature
);
4060 /*************************************************************************
4063 HRESULT WINAPI
SHLoadRegUIStringW(HKEY hkey
, LPCWSTR value
, LPWSTR buf
, DWORD size
)
4065 DWORD type
, sz
= size
;
4067 if(RegQueryValueExW(hkey
, value
, NULL
, &type
, (LPBYTE
)buf
, &sz
) != ERROR_SUCCESS
)
4070 return SHLoadIndirectString(buf
, buf
, size
, NULL
);
4073 /*************************************************************************
4076 * Call IInputObject_TranslateAcceleratorIO() on an object.
4079 * lpUnknown [I] Object supporting the IInputObject interface.
4080 * lpMsg [I] Key message to be processed.
4084 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
4086 HRESULT WINAPI
IUnknown_TranslateAcceleratorIO(IUnknown
*lpUnknown
, LPMSG lpMsg
)
4088 IInputObject
* lpInput
= NULL
;
4089 HRESULT hRet
= E_INVALIDARG
;
4091 TRACE("(%p,%p)\n", lpUnknown
, lpMsg
);
4094 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IInputObject
,
4096 if (SUCCEEDED(hRet
) && lpInput
)
4098 hRet
= IInputObject_TranslateAcceleratorIO(lpInput
, lpMsg
);
4099 IInputObject_Release(lpInput
);
4105 /*************************************************************************
4108 * Call IInputObject_HasFocusIO() on an object.
4111 * lpUnknown [I] Object supporting the IInputObject interface.
4114 * Success: S_OK, if lpUnknown is an IInputObject object and has the focus,
4115 * or S_FALSE otherwise.
4116 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
4118 HRESULT WINAPI
IUnknown_HasFocusIO(IUnknown
*lpUnknown
)
4120 IInputObject
* lpInput
= NULL
;
4121 HRESULT hRet
= E_INVALIDARG
;
4123 TRACE("(%p)\n", lpUnknown
);
4126 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IInputObject
,
4128 if (SUCCEEDED(hRet
) && lpInput
)
4130 hRet
= IInputObject_HasFocusIO(lpInput
);
4131 IInputObject_Release(lpInput
);
4137 /*************************************************************************
4138 * ColorRGBToHLS [SHLWAPI.@]
4140 * Convert an rgb COLORREF into the hls color space.
4143 * cRGB [I] Source rgb value
4144 * pwHue [O] Destination for converted hue
4145 * pwLuminance [O] Destination for converted luminance
4146 * pwSaturation [O] Destination for converted saturation
4149 * Nothing. pwHue, pwLuminance and pwSaturation are set to the converted
4153 * Output HLS values are constrained to the range (0..240).
4154 * For Achromatic conversions, Hue is set to 160.
4156 VOID WINAPI
ColorRGBToHLS(COLORREF cRGB
, LPWORD pwHue
,
4157 LPWORD pwLuminance
, LPWORD pwSaturation
)
4159 int wR
, wG
, wB
, wMax
, wMin
, wHue
, wLuminosity
, wSaturation
;
4161 TRACE("(%08x,%p,%p,%p)\n", cRGB
, pwHue
, pwLuminance
, pwSaturation
);
4163 wR
= GetRValue(cRGB
);
4164 wG
= GetGValue(cRGB
);
4165 wB
= GetBValue(cRGB
);
4167 wMax
= max(wR
, max(wG
, wB
));
4168 wMin
= min(wR
, min(wG
, wB
));
4171 wLuminosity
= ((wMax
+ wMin
) * 240 + 255) / 510;
4175 /* Achromatic case */
4177 /* Hue is now unrepresentable, but this is what native returns... */
4182 /* Chromatic case */
4183 int wDelta
= wMax
- wMin
, wRNorm
, wGNorm
, wBNorm
;
4186 if (wLuminosity
<= 120)
4187 wSaturation
= ((wMax
+ wMin
)/2 + wDelta
* 240) / (wMax
+ wMin
);
4189 wSaturation
= ((510 - wMax
- wMin
)/2 + wDelta
* 240) / (510 - wMax
- wMin
);
4192 wRNorm
= (wDelta
/2 + wMax
* 40 - wR
* 40) / wDelta
;
4193 wGNorm
= (wDelta
/2 + wMax
* 40 - wG
* 40) / wDelta
;
4194 wBNorm
= (wDelta
/2 + wMax
* 40 - wB
* 40) / wDelta
;
4197 wHue
= wBNorm
- wGNorm
;
4198 else if (wG
== wMax
)
4199 wHue
= 80 + wRNorm
- wBNorm
;
4201 wHue
= 160 + wGNorm
- wRNorm
;
4204 else if (wHue
> 240)
4210 *pwLuminance
= wLuminosity
;
4212 *pwSaturation
= wSaturation
;
4215 /*************************************************************************
4216 * SHCreateShellPalette [SHLWAPI.@]
4218 HPALETTE WINAPI
SHCreateShellPalette(HDC hdc
)
4221 return CreateHalftonePalette(hdc
);
4224 /*************************************************************************
4225 * SHGetInverseCMAP (SHLWAPI.@)
4227 * Get an inverse color map table.
4230 * lpCmap [O] Destination for color map
4231 * dwSize [I] Size of memory pointed to by lpCmap
4235 * Failure: E_POINTER, If lpCmap is invalid.
4236 * E_INVALIDARG, If dwFlags is invalid
4237 * E_OUTOFMEMORY, If there is no memory available
4240 * dwSize may only be CMAP_PTR_SIZE (4) or CMAP_SIZE (8192).
4241 * If dwSize = CMAP_PTR_SIZE, *lpCmap is set to the address of this DLL's
4243 * If dwSize = CMAP_SIZE, lpCmap is filled with a copy of the data from
4244 * this DLL's internal CMap.
4246 HRESULT WINAPI
SHGetInverseCMAP(LPDWORD dest
, DWORD dwSize
)
4249 FIXME(" - returning bogus address for SHGetInverseCMAP\n");
4250 *dest
= (DWORD
)0xabba1249;
4253 FIXME("(%p, %#x) stub\n", dest
, dwSize
);
4257 /*************************************************************************
4258 * SHIsLowMemoryMachine [SHLWAPI.@]
4260 * Determine if the current computer has low memory.
4266 * TRUE if the users machine has 16 Megabytes of memory or less,
4269 BOOL WINAPI
SHIsLowMemoryMachine (DWORD x
)
4271 FIXME("(0x%08x) stub\n", x
);
4275 /*************************************************************************
4276 * GetMenuPosFromID [SHLWAPI.@]
4278 * Return the position of a menu item from its Id.
4281 * hMenu [I] Menu containing the item
4282 * wID [I] Id of the menu item
4285 * Success: The index of the menu item in hMenu.
4286 * Failure: -1, If the item is not found.
4288 INT WINAPI
GetMenuPosFromID(HMENU hMenu
, UINT wID
)
4291 INT nCount
= GetMenuItemCount(hMenu
), nIter
= 0;
4293 TRACE("%p %u\n", hMenu
, wID
);
4295 while (nIter
< nCount
)
4297 mi
.cbSize
= sizeof(mi
);
4299 if (GetMenuItemInfoW(hMenu
, nIter
, TRUE
, &mi
) && mi
.wID
== wID
)
4301 TRACE("ret %d\n", nIter
);
4310 /*************************************************************************
4313 * Same as SHLWAPI.GetMenuPosFromID
4315 DWORD WINAPI
SHMenuIndexFromID(HMENU hMenu
, UINT uID
)
4317 TRACE("%p %u\n", hMenu
, uID
);
4318 return GetMenuPosFromID(hMenu
, uID
);
4322 /*************************************************************************
4325 VOID WINAPI
FixSlashesAndColonW(LPWSTR lpwstr
)
4336 /*************************************************************************
4339 DWORD WINAPI
SHGetAppCompatFlags(DWORD dwUnknown
)
4341 FIXME("(0x%08x) stub\n", dwUnknown
);
4346 /*************************************************************************
4349 HRESULT WINAPI
SHCoCreateInstanceAC(REFCLSID rclsid
, LPUNKNOWN pUnkOuter
,
4350 DWORD dwClsContext
, REFIID iid
, LPVOID
*ppv
)
4352 return CoCreateInstance(rclsid
, pUnkOuter
, dwClsContext
, iid
, ppv
);
4355 /*************************************************************************
4356 * SHSkipJunction [SHLWAPI.@]
4358 * Determine if a bind context can be bound to an object
4361 * pbc [I] Bind context to check
4362 * pclsid [I] CLSID of object to be bound to
4365 * TRUE: If it is safe to bind
4366 * FALSE: If pbc is invalid or binding would not be safe
4369 BOOL WINAPI
SHSkipJunction(IBindCtx
*pbc
, const CLSID
*pclsid
)
4371 static WCHAR szSkipBinding
[] = { 'S','k','i','p',' ',
4372 'B','i','n','d','i','n','g',' ','C','L','S','I','D','\0' };
4379 if (SUCCEEDED(IBindCtx_GetObjectParam(pbc
, szSkipBinding
, &lpUnk
)))
4383 if (SUCCEEDED(IUnknown_GetClassID(lpUnk
, &clsid
)) &&
4384 IsEqualGUID(pclsid
, &clsid
))
4387 IUnknown_Release(lpUnk
);
4393 /***********************************************************************
4394 * SHGetShellKey (SHLWAPI.491)
4396 HKEY WINAPI
SHGetShellKey(DWORD flags
, LPCWSTR sub_key
, BOOL create
)
4398 enum _shellkey_flags
{
4399 SHKEY_Root_HKCU
= 0x1,
4400 SHKEY_Root_HKLM
= 0x2,
4401 SHKEY_Key_Explorer
= 0x00,
4402 SHKEY_Key_Shell
= 0x10,
4403 SHKEY_Key_ShellNoRoam
= 0x20,
4404 SHKEY_Key_Classes
= 0x30,
4405 SHKEY_Subkey_Default
= 0x0000,
4406 SHKEY_Subkey_ResourceName
= 0x1000,
4407 SHKEY_Subkey_Handlers
= 0x2000,
4408 SHKEY_Subkey_Associations
= 0x3000,
4409 SHKEY_Subkey_Volatile
= 0x4000,
4410 SHKEY_Subkey_MUICache
= 0x5000,
4411 SHKEY_Subkey_FileExts
= 0x6000
4414 static const WCHAR explorerW
[] = {'S','o','f','t','w','a','r','e','\\',
4415 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
4416 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
4417 'E','x','p','l','o','r','e','r','\\'};
4418 static const WCHAR shellW
[] = {'S','o','f','t','w','a','r','e','\\',
4419 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
4420 'S','h','e','l','l','\\'};
4421 static const WCHAR shell_no_roamW
[] = {'S','o','f','t','w','a','r','e','\\',
4422 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
4423 'S','h','e','l','l','N','o','R','o','a','m','\\'};
4424 static const WCHAR classesW
[] = {'S','o','f','t','w','a','r','e','\\',
4425 'C','l','a','s','s','e','s','\\'};
4427 static const WCHAR localized_resource_nameW
[] = {'L','o','c','a','l','i','z','e','d',
4428 'R','e','s','o','u','r','c','e','N','a','m','e','\\'};
4429 static const WCHAR handlersW
[] = {'H','a','n','d','l','e','r','s','\\'};
4430 static const WCHAR associationsW
[] = {'A','s','s','o','c','i','a','t','i','o','n','s','\\'};
4431 static const WCHAR volatileW
[] = {'V','o','l','a','t','i','l','e','\\'};
4432 static const WCHAR mui_cacheW
[] = {'M','U','I','C','a','c','h','e','\\'};
4433 static const WCHAR file_extsW
[] = {'F','i','l','e','E','x','t','s','\\'};
4436 const WCHAR
*key
, *subkey
;
4437 int size_key
, size_subkey
, size_user
;
4440 TRACE("(0x%08x, %s, %d)\n", flags
, debugstr_w(sub_key
), create
);
4442 /* For compatibility with Vista+ */
4443 if(flags
== 0x1ffff)
4446 switch(flags
&0xff0) {
4447 case SHKEY_Key_Explorer
:
4449 size_key
= sizeof(explorerW
);
4451 case SHKEY_Key_Shell
:
4453 size_key
= sizeof(shellW
);
4455 case SHKEY_Key_ShellNoRoam
:
4456 key
= shell_no_roamW
;
4457 size_key
= sizeof(shell_no_roamW
);
4459 case SHKEY_Key_Classes
:
4461 size_key
= sizeof(classesW
);
4464 FIXME("unsupported flags (0x%08x)\n", flags
);
4468 switch(flags
&0xff000) {
4469 case SHKEY_Subkey_Default
:
4473 case SHKEY_Subkey_ResourceName
:
4474 subkey
= localized_resource_nameW
;
4475 size_subkey
= sizeof(localized_resource_nameW
);
4477 case SHKEY_Subkey_Handlers
:
4479 size_subkey
= sizeof(handlersW
);
4481 case SHKEY_Subkey_Associations
:
4482 subkey
= associationsW
;
4483 size_subkey
= sizeof(associationsW
);
4485 case SHKEY_Subkey_Volatile
:
4487 size_subkey
= sizeof(volatileW
);
4489 case SHKEY_Subkey_MUICache
:
4490 subkey
= mui_cacheW
;
4491 size_subkey
= sizeof(mui_cacheW
);
4493 case SHKEY_Subkey_FileExts
:
4494 subkey
= file_extsW
;
4495 size_subkey
= sizeof(file_extsW
);
4498 FIXME("unsupported flags (0x%08x)\n", flags
);
4503 size_user
= lstrlenW(sub_key
)*sizeof(WCHAR
);
4507 path
= HeapAlloc(GetProcessHeap(), 0, size_key
+size_subkey
+size_user
+sizeof(WCHAR
));
4509 ERR("Out of memory\n");
4513 memcpy(path
, key
, size_key
);
4515 memcpy(path
+size_key
/sizeof(WCHAR
), subkey
, size_subkey
);
4517 memcpy(path
+(size_key
+size_subkey
)/sizeof(WCHAR
), sub_key
, size_user
);
4518 path
[(size_key
+size_subkey
+size_user
)/sizeof(WCHAR
)] = '\0';
4521 RegCreateKeyExW((flags
&0xf)==SHKEY_Root_HKLM
?HKEY_LOCAL_MACHINE
:HKEY_CURRENT_USER
,
4522 path
, 0, NULL
, 0, MAXIMUM_ALLOWED
, NULL
, &hkey
, NULL
);
4524 RegOpenKeyExW((flags
&0xf)==SHKEY_Root_HKLM
?HKEY_LOCAL_MACHINE
:HKEY_CURRENT_USER
,
4525 path
, 0, MAXIMUM_ALLOWED
, &hkey
);
4527 HeapFree(GetProcessHeap(), 0, path
);
4531 /***********************************************************************
4532 * SHQueueUserWorkItem (SHLWAPI.@)
4534 BOOL WINAPI
SHQueueUserWorkItem(LPTHREAD_START_ROUTINE pfnCallback
,
4535 LPVOID pContext
, LONG lPriority
, DWORD_PTR dwTag
,
4536 DWORD_PTR
*pdwId
, LPCSTR pszModule
, DWORD dwFlags
)
4538 TRACE("(%p, %p, %d, %lx, %p, %s, %08x)\n", pfnCallback
, pContext
,
4539 lPriority
, dwTag
, pdwId
, debugstr_a(pszModule
), dwFlags
);
4541 if(lPriority
|| dwTag
|| pdwId
|| pszModule
|| dwFlags
)
4542 FIXME("Unsupported arguments\n");
4544 return QueueUserWorkItem(pfnCallback
, pContext
, 0);
4547 /***********************************************************************
4548 * SHSetTimerQueueTimer (SHLWAPI.263)
4550 HANDLE WINAPI
SHSetTimerQueueTimer(HANDLE hQueue
,
4551 WAITORTIMERCALLBACK pfnCallback
, LPVOID pContext
, DWORD dwDueTime
,
4552 DWORD dwPeriod
, LPCSTR lpszLibrary
, DWORD dwFlags
)
4556 /* SHSetTimerQueueTimer flags -> CreateTimerQueueTimer flags */
4557 if (dwFlags
& TPS_LONGEXECTIME
) {
4558 dwFlags
&= ~TPS_LONGEXECTIME
;
4559 dwFlags
|= WT_EXECUTELONGFUNCTION
;
4561 if (dwFlags
& TPS_EXECUTEIO
) {
4562 dwFlags
&= ~TPS_EXECUTEIO
;
4563 dwFlags
|= WT_EXECUTEINIOTHREAD
;
4566 if (!CreateTimerQueueTimer(&hNewTimer
, hQueue
, pfnCallback
, pContext
,
4567 dwDueTime
, dwPeriod
, dwFlags
))
4573 /***********************************************************************
4574 * IUnknown_OnFocusChangeIS (SHLWAPI.@)
4576 HRESULT WINAPI
IUnknown_OnFocusChangeIS(LPUNKNOWN lpUnknown
, LPUNKNOWN pFocusObject
, BOOL bFocus
)
4578 IInputObjectSite
*pIOS
= NULL
;
4579 HRESULT hRet
= E_INVALIDARG
;
4581 TRACE("(%p, %p, %s)\n", lpUnknown
, pFocusObject
, bFocus
? "TRUE" : "FALSE");
4585 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IInputObjectSite
,
4587 if (SUCCEEDED(hRet
) && pIOS
)
4589 hRet
= IInputObjectSite_OnFocusChangeIS(pIOS
, pFocusObject
, bFocus
);
4590 IInputObjectSite_Release(pIOS
);
4596 /***********************************************************************
4597 * SKAllocValueW (SHLWAPI.519)
4599 HRESULT WINAPI
SKAllocValueW(DWORD flags
, LPCWSTR subkey
, LPCWSTR value
, DWORD
*type
,
4600 LPVOID
*data
, DWORD
*count
)
4605 TRACE("(0x%x, %s, %s, %p, %p, %p)\n", flags
, debugstr_w(subkey
),
4606 debugstr_w(value
), type
, data
, count
);
4608 hkey
= SHGetShellKey(flags
, subkey
, FALSE
);
4610 return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
);
4612 ret
= SHQueryValueExW(hkey
, value
, NULL
, type
, NULL
, &size
);
4615 return HRESULT_FROM_WIN32(ret
);
4619 *data
= LocalAlloc(0, size
);
4622 return E_OUTOFMEMORY
;
4625 ret
= SHQueryValueExW(hkey
, value
, NULL
, type
, *data
, &size
);
4630 return HRESULT_FROM_WIN32(ret
);
4633 /***********************************************************************
4634 * SKDeleteValueW (SHLWAPI.518)
4636 HRESULT WINAPI
SKDeleteValueW(DWORD flags
, LPCWSTR subkey
, LPCWSTR value
)
4641 TRACE("(0x%x, %s %s)\n", flags
, debugstr_w(subkey
), debugstr_w(value
));
4643 hkey
= SHGetShellKey(flags
, subkey
, FALSE
);
4645 return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
);
4647 ret
= RegDeleteValueW(hkey
, value
);
4650 return HRESULT_FROM_WIN32(ret
);
4653 /***********************************************************************
4654 * SKGetValueW (SHLWAPI.516)
4656 HRESULT WINAPI
SKGetValueW(DWORD flags
, LPCWSTR subkey
, LPCWSTR value
, DWORD
*type
,
4657 void *data
, DWORD
*count
)
4662 TRACE("(0x%x, %s, %s, %p, %p, %p)\n", flags
, debugstr_w(subkey
),
4663 debugstr_w(value
), type
, data
, count
);
4665 hkey
= SHGetShellKey(flags
, subkey
, FALSE
);
4667 return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
);
4669 ret
= SHQueryValueExW(hkey
, value
, NULL
, type
, data
, count
);
4672 return HRESULT_FROM_WIN32(ret
);
4675 /***********************************************************************
4676 * SKSetValueW (SHLWAPI.516)
4678 HRESULT WINAPI
SKSetValueW(DWORD flags
, LPCWSTR subkey
, LPCWSTR value
,
4679 DWORD type
, void *data
, DWORD count
)
4684 TRACE("(0x%x, %s, %s, %x, %p, %d)\n", flags
, debugstr_w(subkey
),
4685 debugstr_w(value
), type
, data
, count
);
4687 hkey
= SHGetShellKey(flags
, subkey
, TRUE
);
4689 return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
);
4691 ret
= RegSetValueExW(hkey
, value
, 0, type
, data
, count
);
4694 return HRESULT_FROM_WIN32(ret
);
4697 typedef HRESULT (WINAPI
*DllGetVersion_func
)(DLLVERSIONINFO
*);
4699 /***********************************************************************
4700 * GetUIVersion (SHLWAPI.452)
4702 DWORD WINAPI
GetUIVersion(void)
4704 static DWORD version
;
4708 DllGetVersion_func pDllGetVersion
;
4709 HMODULE dll
= LoadLibraryA("shell32.dll");
4712 pDllGetVersion
= (DllGetVersion_func
)GetProcAddress(dll
, "DllGetVersion");
4716 dvi
.cbSize
= sizeof(DLLVERSIONINFO
);
4717 if (pDllGetVersion(&dvi
) == S_OK
) version
= dvi
.dwMajorVersion
;
4720 if (!version
) version
= 3; /* old shell dlls don't have DllGetVersion */
4725 /***********************************************************************
4726 * ShellMessageBoxWrapW [SHLWAPI.388]
4728 * See shell32.ShellMessageBoxW
4731 * shlwapi.ShellMessageBoxWrapW is a duplicate of shell32.ShellMessageBoxW
4732 * because we can't forward to it in the .spec file since it's exported by
4733 * ordinal. If you change the implementation here please update the code in
4736 INT WINAPIV
ShellMessageBoxWrapW(HINSTANCE hInstance
, HWND hWnd
, LPCWSTR lpText
,
4737 LPCWSTR lpCaption
, UINT uType
, ...)
4739 WCHAR
*szText
= NULL
, szTitle
[100];
4740 LPCWSTR pszText
, pszTitle
= szTitle
;
4745 __ms_va_start(args
, uType
);
4747 TRACE("(%p,%p,%p,%p,%08x)\n", hInstance
, hWnd
, lpText
, lpCaption
, uType
);
4749 if (IS_INTRESOURCE(lpCaption
))
4750 LoadStringW(hInstance
, LOWORD(lpCaption
), szTitle
, sizeof(szTitle
)/sizeof(szTitle
[0]));
4752 pszTitle
= lpCaption
;
4754 if (IS_INTRESOURCE(lpText
))
4757 UINT len
= LoadStringW(hInstance
, LOWORD(lpText
), (LPWSTR
)&ptr
, 0);
4761 szText
= HeapAlloc(GetProcessHeap(), 0, (len
+ 1) * sizeof(WCHAR
));
4762 if (szText
) LoadStringW(hInstance
, LOWORD(lpText
), szText
, len
+ 1);
4766 WARN("Failed to load id %d\n", LOWORD(lpText
));
4774 FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_STRING
,
4775 pszText
, 0, 0, (LPWSTR
)&pszTemp
, 0, &args
);
4779 ret
= MessageBoxW(hWnd
, pszTemp
, pszTitle
, uType
);
4781 HeapFree(GetProcessHeap(), 0, szText
);
4786 /***********************************************************************
4787 * ZoneComputePaneSize [SHLWAPI.382]
4789 UINT WINAPI
ZoneComputePaneSize(HWND hwnd
)
4795 /***********************************************************************
4796 * SHChangeNotifyWrap [SHLWAPI.394]
4798 void WINAPI
SHChangeNotifyWrap(LONG wEventId
, UINT uFlags
, LPCVOID dwItem1
, LPCVOID dwItem2
)
4800 SHChangeNotify(wEventId
, uFlags
, dwItem1
, dwItem2
);
4803 typedef struct SHELL_USER_SID
{ /* according to MSDN this should be in shlobj.h... */
4804 SID_IDENTIFIER_AUTHORITY sidAuthority
;
4805 DWORD dwUserGroupID
;
4807 } SHELL_USER_SID
, *PSHELL_USER_SID
;
4809 typedef struct SHELL_USER_PERMISSION
{ /* ...and this should be in shlwapi.h */
4810 SHELL_USER_SID susID
;
4814 DWORD dwInheritMask
;
4815 DWORD dwInheritAccessMask
;
4816 } SHELL_USER_PERMISSION
, *PSHELL_USER_PERMISSION
;
4818 /***********************************************************************
4819 * GetShellSecurityDescriptor [SHLWAPI.475]
4821 * prepares SECURITY_DESCRIPTOR from a set of ACEs
4824 * apUserPerm [I] array of pointers to SHELL_USER_PERMISSION structures,
4825 * each of which describes permissions to apply
4826 * cUserPerm [I] number of entries in apUserPerm array
4829 * success: pointer to SECURITY_DESCRIPTOR
4833 * Call should free returned descriptor with LocalFree
4835 PSECURITY_DESCRIPTOR WINAPI
GetShellSecurityDescriptor(const PSHELL_USER_PERMISSION
*apUserPerm
, int cUserPerm
)
4838 PSID cur_user
= NULL
;
4842 PSECURITY_DESCRIPTOR psd
= NULL
;
4844 TRACE("%p %d\n", apUserPerm
, cUserPerm
);
4846 if (apUserPerm
== NULL
|| cUserPerm
<= 0)
4849 sidlist
= HeapAlloc(GetProcessHeap(), 0, cUserPerm
* sizeof(PSID
));
4853 acl_size
= sizeof(ACL
);
4855 for(sid_count
= 0; sid_count
< cUserPerm
; sid_count
++)
4857 static SHELL_USER_SID null_sid
= {{SECURITY_NULL_SID_AUTHORITY
}, 0, 0};
4858 PSHELL_USER_PERMISSION perm
= apUserPerm
[sid_count
];
4859 PSHELL_USER_SID sid
= &perm
->susID
;
4863 if (!memcmp((void*)sid
, (void*)&null_sid
, sizeof(SHELL_USER_SID
)))
4864 { /* current user's SID */
4868 DWORD bufsize
= sizeof(tuUser
);
4870 ret
= OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY
, &Token
);
4873 ret
= GetTokenInformation(Token
, TokenUser
, (void*)tuUser
, bufsize
, &bufsize
);
4875 cur_user
= ((PTOKEN_USER
)tuUser
)->User
.Sid
;
4880 } else if (sid
->dwUserID
==0) /* one sub-authority */
4881 ret
= AllocateAndInitializeSid(&sid
->sidAuthority
, 1, sid
->dwUserGroupID
, 0,
4882 0, 0, 0, 0, 0, 0, &pSid
);
4884 ret
= AllocateAndInitializeSid(&sid
->sidAuthority
, 2, sid
->dwUserGroupID
, sid
->dwUserID
,
4885 0, 0, 0, 0, 0, 0, &pSid
);
4889 sidlist
[sid_count
] = pSid
;
4890 /* increment acl_size (1 ACE for non-inheritable and 2 ACEs for inheritable records */
4891 acl_size
+= (sizeof(ACCESS_ALLOWED_ACE
)-sizeof(DWORD
) + GetLengthSid(pSid
)) * (perm
->fInherit
? 2 : 1);
4894 psd
= LocalAlloc(0, sizeof(SECURITY_DESCRIPTOR
) + acl_size
);
4898 PACL pAcl
= (PACL
)(((BYTE
*)psd
)+sizeof(SECURITY_DESCRIPTOR
));
4900 if (!InitializeSecurityDescriptor(psd
, SECURITY_DESCRIPTOR_REVISION
))
4903 if (!InitializeAcl(pAcl
, acl_size
, ACL_REVISION
))
4906 for(i
= 0; i
< sid_count
; i
++)
4908 PSHELL_USER_PERMISSION sup
= apUserPerm
[i
];
4909 PSID sid
= sidlist
[i
];
4911 switch(sup
->dwAccessType
)
4913 case ACCESS_ALLOWED_ACE_TYPE
:
4914 if (!AddAccessAllowedAce(pAcl
, ACL_REVISION
, sup
->dwAccessMask
, sid
))
4916 if (sup
->fInherit
&& !AddAccessAllowedAceEx(pAcl
, ACL_REVISION
,
4917 (BYTE
)sup
->dwInheritMask
, sup
->dwInheritAccessMask
, sid
))
4920 case ACCESS_DENIED_ACE_TYPE
:
4921 if (!AddAccessDeniedAce(pAcl
, ACL_REVISION
, sup
->dwAccessMask
, sid
))
4923 if (sup
->fInherit
&& !AddAccessDeniedAceEx(pAcl
, ACL_REVISION
,
4924 (BYTE
)sup
->dwInheritMask
, sup
->dwInheritAccessMask
, sid
))
4932 if (!SetSecurityDescriptorDacl(psd
, TRUE
, pAcl
, FALSE
))
4941 for(i
= 0; i
< sid_count
; i
++)
4943 if (!cur_user
|| sidlist
[i
] != cur_user
)
4944 FreeSid(sidlist
[i
]);
4946 HeapFree(GetProcessHeap(), 0, sidlist
);
4951 /***********************************************************************
4952 * SHCreatePropertyBagOnRegKey [SHLWAPI.471]
4954 * Creates a property bag from a registry key
4957 * hKey [I] Handle to the desired registry key
4958 * subkey [I] Name of desired subkey, or NULL to open hKey directly
4959 * grfMode [I] Optional flags
4960 * riid [I] IID of requested property bag interface
4961 * ppv [O] Address to receive pointer to the new interface
4965 * failure: error code
4968 HRESULT WINAPI
SHCreatePropertyBagOnRegKey (HKEY hKey
, LPCWSTR subkey
,
4969 DWORD grfMode
, REFIID riid
, void **ppv
)
4971 FIXME("%p %s %d %s %p STUB\n", hKey
, debugstr_w(subkey
), grfMode
,
4972 debugstr_guid(riid
), ppv
);
4977 /***********************************************************************
4978 * SHGetViewStatePropertyBag [SHLWAPI.515]
4980 * Retrieves a property bag in which the view state information of a folder
4984 * pidl [I] PIDL of the folder requested
4985 * bag_name [I] Name of the property bag requested
4986 * flags [I] Optional flags
4987 * riid [I] IID of requested property bag interface
4988 * ppv [O] Address to receive pointer to the new interface
4992 * failure: error code
4995 HRESULT WINAPI
SHGetViewStatePropertyBag(LPCITEMIDLIST pidl
, LPWSTR bag_name
,
4996 DWORD flags
, REFIID riid
, void **ppv
)
4998 FIXME("%p %s %d %s %p STUB\n", pidl
, debugstr_w(bag_name
), flags
,
4999 debugstr_guid(riid
), ppv
);
5004 /***********************************************************************
5005 * SHFormatDateTimeW [SHLWAPI.354]
5007 * Produces a string representation of a time.
5010 * fileTime [I] Pointer to FILETIME structure specifying the time
5011 * flags [I] Flags specifying the desired output
5012 * buf [O] Pointer to buffer for output
5013 * size [I] Number of characters that can be contained in buffer
5016 * success: number of characters written to the buffer
5020 INT WINAPI
SHFormatDateTimeW(const FILETIME UNALIGNED
*fileTime
, DWORD
*flags
,
5021 LPWSTR buf
, UINT size
)
5023 #define SHFORMATDT_UNSUPPORTED_FLAGS (FDTF_RELATIVE | FDTF_LTRDATE | FDTF_RTLDATE | FDTF_NOAUTOREADINGORDER)
5024 DWORD fmt_flags
= flags
? *flags
: FDTF_DEFAULT
;
5029 TRACE("%p %p %p %u\n", fileTime
, flags
, buf
, size
);
5034 if (fmt_flags
& SHFORMATDT_UNSUPPORTED_FLAGS
)
5035 FIXME("ignoring some flags - 0x%08x\n", fmt_flags
& SHFORMATDT_UNSUPPORTED_FLAGS
);
5037 FileTimeToLocalFileTime(fileTime
, &ft
);
5038 FileTimeToSystemTime(&ft
, &st
);
5040 /* first of all date */
5041 if (fmt_flags
& (FDTF_LONGDATE
| FDTF_SHORTDATE
))
5043 static const WCHAR sep1
[] = {',',' ',0};
5044 static const WCHAR sep2
[] = {' ',0};
5046 DWORD date
= fmt_flags
& FDTF_LONGDATE
? DATE_LONGDATE
: DATE_SHORTDATE
;
5047 ret
= GetDateFormatW(LOCALE_USER_DEFAULT
, date
, &st
, NULL
, buf
, size
);
5048 if (ret
>= size
) return ret
;
5051 if (ret
< size
&& (fmt_flags
& (FDTF_LONGTIME
| FDTF_SHORTTIME
)))
5053 if ((fmt_flags
& FDTF_LONGDATE
) && (ret
< size
+ 2))
5055 lstrcatW(&buf
[ret
-1], sep1
);
5060 lstrcatW(&buf
[ret
-1], sep2
);
5066 if (fmt_flags
& (FDTF_LONGTIME
| FDTF_SHORTTIME
))
5068 DWORD time
= fmt_flags
& FDTF_LONGTIME
? 0 : TIME_NOSECONDS
;
5071 ret
+= GetTimeFormatW(LOCALE_USER_DEFAULT
, time
, &st
, NULL
, &buf
[ret
], size
- ret
);
5076 #undef SHFORMATDT_UNSUPPORTED_FLAGS
5079 /***********************************************************************
5080 * SHFormatDateTimeA [SHLWAPI.353]
5082 * See SHFormatDateTimeW.
5085 INT WINAPI
SHFormatDateTimeA(const FILETIME UNALIGNED
*fileTime
, DWORD
*flags
,
5086 LPSTR buf
, UINT size
)
5094 bufW
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
) * size
);
5095 retval
= SHFormatDateTimeW(fileTime
, flags
, bufW
, size
);
5098 WideCharToMultiByte(CP_ACP
, 0, bufW
, -1, buf
, size
, NULL
, NULL
);
5100 HeapFree(GetProcessHeap(), 0, bufW
);
5104 /***********************************************************************
5105 * ZoneCheckUrlExW [SHLWAPI.231]
5107 * Checks the details of the security zone for the supplied site. (?)
5111 * szURL [I] Pointer to the URL to check
5113 * Other parameters currently unknown.
5119 INT WINAPI
ZoneCheckUrlExW(LPWSTR szURL
, PVOID pUnknown
, DWORD dwUnknown2
,
5120 DWORD dwUnknown3
, DWORD dwUnknown4
, DWORD dwUnknown5
, DWORD dwUnknown6
,
5123 FIXME("(%s,%p,%x,%x,%x,%x,%x,%x) STUB\n", debugstr_w(szURL
), pUnknown
, dwUnknown2
,
5124 dwUnknown3
, dwUnknown4
, dwUnknown5
, dwUnknown6
, dwUnknown7
);
5129 /***********************************************************************
5130 * SHVerbExistsNA [SHLWAPI.196]
5135 * verb [I] a string, often appears to be an extension.
5137 * Other parameters currently unknown.
5142 INT WINAPI
SHVerbExistsNA(LPSTR verb
, PVOID pUnknown
, PVOID pUnknown2
, DWORD dwUnknown3
)
5144 FIXME("(%s, %p, %p, %i) STUB\n",verb
, pUnknown
, pUnknown2
, dwUnknown3
);
5148 /*************************************************************************
5151 * Undocumented: Implementation guessed at via Name and behavior
5154 * lpUnknown [I] Object to get an IServiceProvider interface from
5155 * riid [I] Function requested for QueryService call
5156 * lppOut [O] Destination for the service interface pointer
5159 * Success: S_OK. lppOut contains an object providing the requested service
5160 * Failure: An HRESULT error code
5163 * lpUnknown is expected to support the IServiceProvider interface.
5165 HRESULT WINAPI
IUnknown_QueryServiceForWebBrowserApp(IUnknown
* lpUnknown
,
5166 REFGUID riid
, LPVOID
*lppOut
)
5168 FIXME("%p %s %p semi-STUB\n", lpUnknown
, debugstr_guid(riid
), lppOut
);
5169 return IUnknown_QueryService(lpUnknown
,&IID_IWebBrowserApp
,riid
,lppOut
);
5172 /**************************************************************************
5173 * SHPropertyBag_ReadLONG (SHLWAPI.496)
5175 * This function asks a property bag to read a named property as a LONG.
5178 * ppb: a IPropertyBag interface
5179 * pszPropName: Unicode string that names the property
5180 * pValue: address to receive the property value as a 32-bit signed integer
5185 HRESULT WINAPI
SHPropertyBag_ReadLONG(IPropertyBag
*ppb
, LPCWSTR pszPropName
, LPLONG pValue
)
5189 TRACE("%p %s %p\n", ppb
,debugstr_w(pszPropName
),pValue
);
5190 if (!pszPropName
|| !ppb
|| !pValue
)
5191 return E_INVALIDARG
;
5193 hr
= IPropertyBag_Read(ppb
, pszPropName
, &var
, NULL
);
5196 if (V_VT(&var
) == VT_I4
)
5197 *pValue
= V_I4(&var
);
5199 hr
= DISP_E_BADVARTYPE
;
5205 /**************************************************************************
5206 * SHPropertyBag_WriteLONG (SHLWAPI.497)
5208 * This function asks a property bag to write a named property as a LONG.
5211 * ppb: a IPropertyBag interface
5212 * pszPropName: Unicode string that names the property
5213 * lValue: address to receive the property value as a 32-bit signed integer
5218 HRESULT WINAPI
SHPropertyBag_WriteLONG(IPropertyBag
*ppb
, LPCWSTR pszPropName
, LONG lValue
)
5224 /**************************************************************************
5225 * SHPropertyBag_WriteStr (SHLWAPI.495)
5227 * This function asks a property bag to write a string as the value of a named property.
5230 * ppb: a IPropertyBag interface
5231 * pszPropName: Unicode string that names the property
5232 * pValue: address to write the property value
5237 HRESULT WINAPI
SHPropertyBag_WriteStr(IPropertyBag
*ppb
, LPCWSTR pszPropName
, LPCWSTR pszValue
)
5244 /* return flags for SHGetObjectCompatFlags, names derived from registry value names */
5245 #define OBJCOMPAT_OTNEEDSSFCACHE 0x00000001
5246 #define OBJCOMPAT_NO_WEBVIEW 0x00000002
5247 #define OBJCOMPAT_UNBINDABLE 0x00000004
5248 #define OBJCOMPAT_PINDLL 0x00000008
5249 #define OBJCOMPAT_NEEDSFILESYSANCESTOR 0x00000010
5250 #define OBJCOMPAT_NOTAFILESYSTEM 0x00000020
5251 #define OBJCOMPAT_CTXMENU_NOVERBS 0x00000040
5252 #define OBJCOMPAT_CTXMENU_LIMITEDQI 0x00000080
5253 #define OBJCOMPAT_COCREATESHELLFOLDERONLY 0x00000100
5254 #define OBJCOMPAT_NEEDSSTORAGEANCESTOR 0x00000200
5255 #define OBJCOMPAT_NOLEGACYWEBVIEW 0x00000400
5256 #define OBJCOMPAT_CTXMENU_XPQCMFLAGS 0x00001000
5257 #define OBJCOMPAT_NOIPROPERTYSTORE 0x00002000
5259 /* a search table for compatibility flags */
5260 struct objcompat_entry
{
5261 const WCHAR name
[30];
5265 /* expected to be sorted by name */
5266 static const struct objcompat_entry objcompat_table
[] = {
5267 { {'C','O','C','R','E','A','T','E','S','H','E','L','L','F','O','L','D','E','R','O','N','L','Y',0},
5268 OBJCOMPAT_COCREATESHELLFOLDERONLY
},
5269 { {'C','T','X','M','E','N','U','_','L','I','M','I','T','E','D','Q','I',0},
5270 OBJCOMPAT_CTXMENU_LIMITEDQI
},
5271 { {'C','T','X','M','E','N','U','_','N','O','V','E','R','B','S',0},
5272 OBJCOMPAT_CTXMENU_LIMITEDQI
},
5273 { {'C','T','X','M','E','N','U','_','X','P','Q','C','M','F','L','A','G','S',0},
5274 OBJCOMPAT_CTXMENU_XPQCMFLAGS
},
5275 { {'N','E','E','D','S','F','I','L','E','S','Y','S','A','N','C','E','S','T','O','R',0},
5276 OBJCOMPAT_NEEDSFILESYSANCESTOR
},
5277 { {'N','E','E','D','S','S','T','O','R','A','G','E','A','N','C','E','S','T','O','R',0},
5278 OBJCOMPAT_NEEDSSTORAGEANCESTOR
},
5279 { {'N','O','I','P','R','O','P','E','R','T','Y','S','T','O','R','E',0},
5280 OBJCOMPAT_NOIPROPERTYSTORE
},
5281 { {'N','O','L','E','G','A','C','Y','W','E','B','V','I','E','W',0},
5282 OBJCOMPAT_NOLEGACYWEBVIEW
},
5283 { {'N','O','T','A','F','I','L','E','S','Y','S','T','E','M',0},
5284 OBJCOMPAT_NOTAFILESYSTEM
},
5285 { {'N','O','_','W','E','B','V','I','E','W',0},
5286 OBJCOMPAT_NO_WEBVIEW
},
5287 { {'O','T','N','E','E','D','S','S','F','C','A','C','H','E',0},
5288 OBJCOMPAT_OTNEEDSSFCACHE
},
5289 { {'P','I','N','D','L','L',0},
5291 { {'U','N','B','I','N','D','A','B','L','E',0},
5292 OBJCOMPAT_UNBINDABLE
}
5295 /**************************************************************************
5296 * SHGetObjectCompatFlags (SHLWAPI.476)
5298 * Function returns an integer representation of compatibility flags stored
5299 * in registry for CLSID under ShellCompatibility subkey.
5302 * pUnk: pointer to object IUnknown interface, idetifies CLSID
5303 * clsid: pointer to CLSID to retrieve data for
5306 * 0 on failure, flags set on success
5308 DWORD WINAPI
SHGetObjectCompatFlags(IUnknown
*pUnk
, const CLSID
*clsid
)
5310 static const WCHAR compatpathW
[] =
5311 {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
5312 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
5313 'S','h','e','l','l','C','o','m','p','a','t','i','b','i','l','i','t','y','\\',
5314 'O','b','j','e','c','t','s','\\','%','s',0};
5315 WCHAR strW
[sizeof(compatpathW
)/sizeof(WCHAR
) + 38 /* { CLSID } */];
5316 DWORD ret
, length
= sizeof(strW
)/sizeof(WCHAR
);
5321 TRACE("%p %s\n", pUnk
, debugstr_guid(clsid
));
5323 if (!pUnk
&& !clsid
) return 0;
5327 FIXME("iface not handled\n");
5331 StringFromCLSID(clsid
, &clsid_str
);
5332 sprintfW(strW
, compatpathW
, clsid_str
);
5333 CoTaskMemFree(clsid_str
);
5335 ret
= RegOpenKeyW(HKEY_LOCAL_MACHINE
, strW
, &key
);
5336 if (ret
!= ERROR_SUCCESS
) return 0;
5338 /* now collect flag values */
5340 for (i
= 0; RegEnumValueW(key
, i
, strW
, &length
, NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
; i
++)
5342 INT left
, right
, res
, x
;
5344 /* search in table */
5346 right
= sizeof(objcompat_table
) / sizeof(struct objcompat_entry
) - 1;
5348 while (right
>= left
) {
5349 x
= (left
+ right
) / 2;
5350 res
= strcmpW(strW
, objcompat_table
[x
].name
);
5353 ret
|= objcompat_table
[x
].value
;
5362 length
= sizeof(strW
)/sizeof(WCHAR
);