2 * SHLWAPI ordinal functions
4 * Copyright 1997 Marcus Meissner
6 * 2001-2003 Jon Griffiths
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "wine/port.h"
31 #define NONAMELESSUNION
32 #define NONAMELESSSTRUCT
51 #include "wine/unicode.h"
52 #include "wine/debug.h"
55 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
57 /* DLL handles for late bound calls */
58 extern HINSTANCE shlwapi_hInstance
;
59 extern DWORD SHLWAPI_ThreadRef_index
;
61 HRESULT WINAPI
IUnknown_QueryService(IUnknown
*,REFGUID
,REFIID
,LPVOID
*);
62 HRESULT WINAPI
SHInvokeCommand(HWND
,IShellFolder
*,LPCITEMIDLIST
,BOOL
);
63 BOOL WINAPI
SHAboutInfoW(LPWSTR
,DWORD
);
66 NOTES: Most functions exported by ordinal seem to be superfluous.
67 The reason for these functions to be there is to provide a wrapper
68 for unicode functions to provide these functions on systems without
69 unicode functions eg. win95/win98. Since we have such functions we just
70 call these. If running Wine with native DLLs, some late bound calls may
71 fail. However, it is better to implement the functions in the forward DLL
72 and recommend the builtin rather than reimplementing the calls here!
75 /*************************************************************************
76 * SHLWAPI_DupSharedHandle
78 * Internal implemetation of SHLWAPI_11.
80 static HANDLE
SHLWAPI_DupSharedHandle(HANDLE hShared
, DWORD dwDstProcId
,
81 DWORD dwSrcProcId
, DWORD dwAccess
,
85 DWORD dwMyProcId
= GetCurrentProcessId();
88 TRACE("(%p,%d,%d,%08x,%08x)\n", hShared
, dwDstProcId
, dwSrcProcId
,
91 /* Get dest process handle */
92 if (dwDstProcId
== dwMyProcId
)
93 hDst
= GetCurrentProcess();
95 hDst
= OpenProcess(PROCESS_DUP_HANDLE
, 0, dwDstProcId
);
99 /* Get src process handle */
100 if (dwSrcProcId
== dwMyProcId
)
101 hSrc
= GetCurrentProcess();
103 hSrc
= OpenProcess(PROCESS_DUP_HANDLE
, 0, dwSrcProcId
);
107 /* Make handle available to dest process */
108 if (!DuplicateHandle(hDst
, hShared
, hSrc
, &hRet
,
109 dwAccess
, 0, dwOptions
| DUPLICATE_SAME_ACCESS
))
112 if (dwSrcProcId
!= dwMyProcId
)
116 if (dwDstProcId
!= dwMyProcId
)
120 TRACE("Returning handle %p\n", hRet
);
124 /*************************************************************************
127 * Create a block of sharable memory and initialise it with data.
130 * lpvData [I] Pointer to data to write
131 * dwSize [I] Size of data
132 * dwProcId [I] ID of process owning data
135 * Success: A shared memory handle
139 * Ordinals 7-11 provide a set of calls to create shared memory between a
140 * group of processes. The shared memory is treated opaquely in that its size
141 * is not exposed to clients who map it. This is accomplished by storing
142 * the size of the map as the first DWORD of mapped data, and then offsetting
143 * the view pointer returned by this size.
146 HANDLE WINAPI
SHAllocShared(LPCVOID lpvData
, DWORD dwSize
, DWORD dwProcId
)
152 TRACE("(%p,%d,%d)\n", lpvData
, dwSize
, dwProcId
);
154 /* Create file mapping of the correct length */
155 hMap
= CreateFileMappingA(INVALID_HANDLE_VALUE
, NULL
, FILE_MAP_READ
, 0,
156 dwSize
+ sizeof(dwSize
), NULL
);
160 /* Get a view in our process address space */
161 pMapped
= MapViewOfFile(hMap
, FILE_MAP_READ
| FILE_MAP_WRITE
, 0, 0, 0);
165 /* Write size of data, followed by the data, to the view */
166 *((DWORD
*)pMapped
) = dwSize
;
168 memcpy((char *) pMapped
+ sizeof(dwSize
), lpvData
, dwSize
);
170 /* Release view. All further views mapped will be opaque */
171 UnmapViewOfFile(pMapped
);
172 hRet
= SHLWAPI_DupSharedHandle(hMap
, dwProcId
,
173 GetCurrentProcessId(), FILE_MAP_ALL_ACCESS
,
174 DUPLICATE_SAME_ACCESS
);
181 /*************************************************************************
184 * Get a pointer to a block of shared memory from a shared memory handle.
187 * hShared [I] Shared memory handle
188 * dwProcId [I] ID of process owning hShared
191 * Success: A pointer to the shared memory
195 PVOID WINAPI
SHLockShared(HANDLE hShared
, DWORD dwProcId
)
200 TRACE("(%p %d)\n", hShared
, dwProcId
);
202 /* Get handle to shared memory for current process */
203 hDup
= SHLWAPI_DupSharedHandle(hShared
, dwProcId
, GetCurrentProcessId(),
204 FILE_MAP_ALL_ACCESS
, 0);
206 pMapped
= MapViewOfFile(hDup
, FILE_MAP_READ
| FILE_MAP_WRITE
, 0, 0, 0);
210 return (char *) pMapped
+ sizeof(DWORD
); /* Hide size */
214 /*************************************************************************
217 * Release a pointer to a block of shared memory.
220 * lpView [I] Shared memory pointer
227 BOOL WINAPI
SHUnlockShared(LPVOID lpView
)
229 TRACE("(%p)\n", lpView
);
230 return UnmapViewOfFile((char *) lpView
- sizeof(DWORD
)); /* Include size */
233 /*************************************************************************
236 * Destroy a block of sharable memory.
239 * hShared [I] Shared memory handle
240 * dwProcId [I] ID of process owning hShared
247 BOOL WINAPI
SHFreeShared(HANDLE hShared
, DWORD dwProcId
)
251 TRACE("(%p %d)\n", hShared
, dwProcId
);
253 /* Get a copy of the handle for our process, closing the source handle */
254 hClose
= SHLWAPI_DupSharedHandle(hShared
, dwProcId
, GetCurrentProcessId(),
255 FILE_MAP_ALL_ACCESS
,DUPLICATE_CLOSE_SOURCE
);
256 /* Close local copy */
257 return CloseHandle(hClose
);
260 /*************************************************************************
263 * Copy a sharable memory handle from one process to another.
266 * hShared [I] Shared memory handle to duplicate
267 * dwDstProcId [I] ID of the process wanting the duplicated handle
268 * dwSrcProcId [I] ID of the process owning hShared
269 * dwAccess [I] Desired DuplicateHandle() access
270 * dwOptions [I] Desired DuplicateHandle() options
273 * Success: A handle suitable for use by the dwDstProcId process.
274 * Failure: A NULL handle.
277 HANDLE WINAPI
SHMapHandle(HANDLE hShared
, DWORD dwDstProcId
, DWORD dwSrcProcId
,
278 DWORD dwAccess
, DWORD dwOptions
)
282 hRet
= SHLWAPI_DupSharedHandle(hShared
, dwDstProcId
, dwSrcProcId
,
283 dwAccess
, dwOptions
);
287 /*************************************************************************
290 * Create and register a clipboard enumerator for a web browser.
293 * lpBC [I] Binding context
294 * lpUnknown [I] An object exposing the IWebBrowserApp interface
298 * Failure: An HRESULT error code.
301 * The enumerator is stored as a property of the web browser. If it does not
302 * yet exist, it is created and set before being registered.
304 HRESULT WINAPI
RegisterDefaultAcceptHeaders(LPBC lpBC
, IUnknown
*lpUnknown
)
306 static const WCHAR szProperty
[] = { '{','D','0','F','C','A','4','2','0',
307 '-','D','3','F','5','-','1','1','C','F', '-','B','2','1','1','-','0',
308 '0','A','A','0','0','4','A','E','8','3','7','}','\0' };
310 IEnumFORMATETC
* pIEnumFormatEtc
= NULL
;
313 IWebBrowserApp
* pBrowser
;
315 TRACE("(%p, %p)\n", lpBC
, lpUnknown
);
317 hr
= IUnknown_QueryService(lpUnknown
, &IID_IWebBrowserApp
, &IID_IWebBrowserApp
, (void**)&pBrowser
);
321 V_VT(&var
) = VT_EMPTY
;
323 /* The property we get is the browsers clipboard enumerator */
324 property
= SysAllocString(szProperty
);
325 hr
= IWebBrowserApp_GetProperty(pBrowser
, property
, &var
);
326 SysFreeString(property
);
327 if (FAILED(hr
)) goto exit
;
329 if (V_VT(&var
) == VT_EMPTY
)
331 /* Iterate through accepted documents and RegisterClipBoardFormatA() them */
332 char szKeyBuff
[128], szValueBuff
[128];
333 DWORD dwKeySize
, dwValueSize
, dwRet
= 0, dwCount
= 0, dwNumValues
, dwType
;
334 FORMATETC
* formatList
, *format
;
337 TRACE("Registering formats and creating IEnumFORMATETC instance\n");
339 if (!RegOpenKeyA(HKEY_LOCAL_MACHINE
, "Software\\Microsoft\\Windows\\Current"
340 "Version\\Internet Settings\\Accepted Documents", &hDocs
))
346 /* Get count of values in key */
349 dwKeySize
= sizeof(szKeyBuff
);
350 dwRet
= RegEnumValueA(hDocs
,dwCount
,szKeyBuff
,&dwKeySize
,0,&dwType
,0,0);
354 dwNumValues
= dwCount
;
356 /* Note: dwCount = number of items + 1; The extra item is the end node */
357 format
= formatList
= HeapAlloc(GetProcessHeap(), 0, dwCount
* sizeof(FORMATETC
));
372 /* Register clipboard formats for the values and populate format list */
373 while(!dwRet
&& dwCount
< dwNumValues
)
375 dwKeySize
= sizeof(szKeyBuff
);
376 dwValueSize
= sizeof(szValueBuff
);
377 dwRet
= RegEnumValueA(hDocs
, dwCount
, szKeyBuff
, &dwKeySize
, 0, &dwType
,
378 (PBYTE
)szValueBuff
, &dwValueSize
);
381 HeapFree(GetProcessHeap(), 0, formatList
);
387 format
->cfFormat
= RegisterClipboardFormatA(szValueBuff
);
389 format
->dwAspect
= 1;
400 /* Terminate the (maybe empty) list, last entry has a cfFormat of 0 */
401 format
->cfFormat
= 0;
403 format
->dwAspect
= 1;
407 /* Create a clipboard enumerator */
408 hr
= CreateFormatEnumerator(dwNumValues
, formatList
, &pIEnumFormatEtc
);
409 HeapFree(GetProcessHeap(), 0, formatList
);
410 if (FAILED(hr
)) goto exit
;
412 /* Set our enumerator as the browsers property */
413 V_VT(&var
) = VT_UNKNOWN
;
414 V_UNKNOWN(&var
) = (IUnknown
*)pIEnumFormatEtc
;
416 property
= SysAllocString(szProperty
);
417 hr
= IWebBrowserApp_PutProperty(pBrowser
, property
, var
);
418 SysFreeString(property
);
421 IEnumFORMATETC_Release(pIEnumFormatEtc
);
426 if (V_VT(&var
) == VT_UNKNOWN
)
428 /* Our variant is holding the clipboard enumerator */
429 IUnknown
* pIUnknown
= V_UNKNOWN(&var
);
430 IEnumFORMATETC
* pClone
= NULL
;
432 TRACE("Retrieved IEnumFORMATETC property\n");
434 /* Get an IEnumFormatEtc interface from the variants value */
435 pIEnumFormatEtc
= NULL
;
436 hr
= IUnknown_QueryInterface(pIUnknown
, &IID_IEnumFORMATETC
, (void**)&pIEnumFormatEtc
);
437 if (hr
== S_OK
&& pIEnumFormatEtc
)
439 /* Clone and register the enumerator */
440 hr
= IEnumFORMATETC_Clone(pIEnumFormatEtc
, &pClone
);
441 if (hr
== S_OK
&& pClone
)
443 RegisterFormatEnumerator(lpBC
, pClone
, 0);
445 IEnumFORMATETC_Release(pClone
);
448 IEnumFORMATETC_Release(pIUnknown
);
450 IUnknown_Release(V_UNKNOWN(&var
));
454 IWebBrowserApp_Release(pBrowser
);
458 /*************************************************************************
461 * Get Explorers "AcceptLanguage" setting.
464 * langbuf [O] Destination for language string
465 * buflen [I] Length of langbuf in characters
466 * [0] Success: used length of langbuf
469 * Success: S_OK. langbuf is set to the language string found.
470 * Failure: E_FAIL, If any arguments are invalid, error occurred, or Explorer
471 * does not contain the setting.
472 * HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), If the buffer is not big enough
474 HRESULT WINAPI
GetAcceptLanguagesW( LPWSTR langbuf
, LPDWORD buflen
)
476 static const WCHAR szkeyW
[] = {
477 'S','o','f','t','w','a','r','e','\\',
478 'M','i','c','r','o','s','o','f','t','\\',
479 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
480 'I','n','t','e','r','n','a','t','i','o','n','a','l',0};
481 static const WCHAR valueW
[] = {
482 'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0};
483 DWORD mystrlen
, mytype
;
491 TRACE("(%p, %p) *%p: %d\n", langbuf
, buflen
, buflen
, buflen
? *buflen
: -1);
493 if(!langbuf
|| !buflen
|| !*buflen
)
496 mystrlen
= (*buflen
> 20) ? *buflen
: 20 ;
497 len
= mystrlen
* sizeof(WCHAR
);
498 mystr
= HeapAlloc(GetProcessHeap(), 0, len
);
500 RegOpenKeyW(HKEY_CURRENT_USER
, szkeyW
, &mykey
);
501 lres
= RegQueryValueExW(mykey
, valueW
, 0, &mytype
, (PBYTE
)mystr
, &len
);
503 len
= lstrlenW(mystr
);
505 if (!lres
&& (*buflen
> len
)) {
506 lstrcpyW(langbuf
, mystr
);
508 HeapFree(GetProcessHeap(), 0, mystr
);
512 /* Did not find a value in the registry or the user buffer is too small */
513 mylcid
= GetUserDefaultLCID();
514 retval
= LcidToRfc1766W(mylcid
, mystr
, mystrlen
);
515 len
= lstrlenW(mystr
);
517 memcpy( langbuf
, mystr
, min(*buflen
, len
+1)*sizeof(WCHAR
) );
518 HeapFree(GetProcessHeap(), 0, mystr
);
526 return __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER
);
529 /*************************************************************************
532 * Ascii version of GetAcceptLanguagesW.
534 HRESULT WINAPI
GetAcceptLanguagesA( LPSTR langbuf
, LPDWORD buflen
)
537 DWORD buflenW
, convlen
;
540 TRACE("(%p, %p) *%p: %d\n", langbuf
, buflen
, buflen
, buflen
? *buflen
: -1);
542 if(!langbuf
|| !buflen
|| !*buflen
) return E_FAIL
;
545 langbufW
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
) * buflenW
);
546 retval
= GetAcceptLanguagesW(langbufW
, &buflenW
);
550 convlen
= WideCharToMultiByte(CP_ACP
, 0, langbufW
, -1, langbuf
, *buflen
, NULL
, NULL
);
551 convlen
--; /* do not count the terminating 0 */
553 else /* copy partial string anyway */
555 convlen
= WideCharToMultiByte(CP_ACP
, 0, langbufW
, *buflen
, langbuf
, *buflen
, NULL
, NULL
);
556 if (convlen
< *buflen
)
558 langbuf
[convlen
] = 0;
559 convlen
--; /* do not count the terminating 0 */
566 *buflen
= buflenW
? convlen
: 0;
568 HeapFree(GetProcessHeap(), 0, langbufW
);
572 /*************************************************************************
575 * Convert a GUID to a string.
578 * guid [I] GUID to convert
579 * lpszDest [O] Destination for string
580 * cchMax [I] Length of output buffer
583 * The length of the string created.
585 INT WINAPI
SHStringFromGUIDA(REFGUID guid
, LPSTR lpszDest
, INT cchMax
)
590 TRACE("(%s,%p,%d)\n", debugstr_guid(guid
), lpszDest
, cchMax
);
592 sprintf(xguid
, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
593 guid
->Data1
, guid
->Data2
, guid
->Data3
,
594 guid
->Data4
[0], guid
->Data4
[1], guid
->Data4
[2], guid
->Data4
[3],
595 guid
->Data4
[4], guid
->Data4
[5], guid
->Data4
[6], guid
->Data4
[7]);
597 iLen
= strlen(xguid
) + 1;
601 memcpy(lpszDest
, xguid
, iLen
);
605 /*************************************************************************
608 * Convert a GUID to a string.
611 * guid [I] GUID to convert
612 * str [O] Destination for string
613 * cmax [I] Length of output buffer
616 * The length of the string created.
618 INT WINAPI
SHStringFromGUIDW(REFGUID guid
, LPWSTR lpszDest
, INT cchMax
)
622 static const WCHAR wszFormat
[] = {'{','%','0','8','l','X','-','%','0','4','X','-','%','0','4','X','-',
623 '%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','%','0','2','X','%','0','2',
624 'X','%','0','2','X','%','0','2','X','}',0};
626 TRACE("(%s,%p,%d)\n", debugstr_guid(guid
), lpszDest
, cchMax
);
628 sprintfW(xguid
, wszFormat
, guid
->Data1
, guid
->Data2
, guid
->Data3
,
629 guid
->Data4
[0], guid
->Data4
[1], guid
->Data4
[2], guid
->Data4
[3],
630 guid
->Data4
[4], guid
->Data4
[5], guid
->Data4
[6], guid
->Data4
[7]);
632 iLen
= strlenW(xguid
) + 1;
636 memcpy(lpszDest
, xguid
, iLen
*sizeof(WCHAR
));
640 /*************************************************************************
643 * Determine if a Unicode character is a space.
646 * wc [I] Character to check.
649 * TRUE, if wc is a space,
652 BOOL WINAPI
IsCharSpaceW(WCHAR wc
)
656 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_SPACE
);
659 /*************************************************************************
662 * Determine if a Unicode character is a blank.
665 * wc [I] Character to check.
668 * TRUE, if wc is a blank,
672 BOOL WINAPI
IsCharBlankW(WCHAR wc
)
676 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_BLANK
);
679 /*************************************************************************
682 * Determine if a Unicode character is punctuation.
685 * wc [I] Character to check.
688 * TRUE, if wc is punctuation,
691 BOOL WINAPI
IsCharPunctW(WCHAR wc
)
695 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_PUNCT
);
698 /*************************************************************************
701 * Determine if a Unicode character is a control character.
704 * wc [I] Character to check.
707 * TRUE, if wc is a control character,
710 BOOL WINAPI
IsCharCntrlW(WCHAR wc
)
714 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_CNTRL
);
717 /*************************************************************************
720 * Determine if a Unicode character is a digit.
723 * wc [I] Character to check.
726 * TRUE, if wc is a digit,
729 BOOL WINAPI
IsCharDigitW(WCHAR wc
)
733 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_DIGIT
);
736 /*************************************************************************
739 * Determine if a Unicode character is a hex digit.
742 * wc [I] Character to check.
745 * TRUE, if wc is a hex digit,
748 BOOL WINAPI
IsCharXDigitW(WCHAR wc
)
752 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_XDIGIT
);
755 /*************************************************************************
759 BOOL WINAPI
GetStringType3ExW(LPWSTR src
, INT count
, LPWORD type
)
761 return GetStringTypeW(CT_CTYPE3
, src
, count
, type
);
764 /*************************************************************************
767 * Compare two Ascii strings up to a given length.
770 * lpszSrc [I] Source string
771 * lpszCmp [I] String to compare to lpszSrc
772 * len [I] Maximum length
775 * A number greater than, less than or equal to 0 depending on whether
776 * lpszSrc is greater than, less than or equal to lpszCmp.
778 DWORD WINAPI
StrCmpNCA(LPCSTR lpszSrc
, LPCSTR lpszCmp
, INT len
)
780 return StrCmpNA(lpszSrc
, lpszCmp
, len
);
783 /*************************************************************************
786 * Unicode version of StrCmpNCA.
788 DWORD WINAPI
StrCmpNCW(LPCWSTR lpszSrc
, LPCWSTR lpszCmp
, INT len
)
790 return StrCmpNW(lpszSrc
, lpszCmp
, len
);
793 /*************************************************************************
796 * Compare two Ascii strings up to a given length, ignoring case.
799 * lpszSrc [I] Source string
800 * lpszCmp [I] String to compare to lpszSrc
801 * len [I] Maximum length
804 * A number greater than, less than or equal to 0 depending on whether
805 * lpszSrc is greater than, less than or equal to lpszCmp.
807 DWORD WINAPI
StrCmpNICA(LPCSTR lpszSrc
, LPCSTR lpszCmp
, DWORD len
)
809 return StrCmpNIA(lpszSrc
, lpszCmp
, len
);
812 /*************************************************************************
815 * Unicode version of StrCmpNICA.
817 DWORD WINAPI
StrCmpNICW(LPCWSTR lpszSrc
, LPCWSTR lpszCmp
, DWORD len
)
819 return StrCmpNIW(lpszSrc
, lpszCmp
, len
);
822 /*************************************************************************
825 * Compare two Ascii strings.
828 * lpszSrc [I] Source string
829 * lpszCmp [I] String to compare to lpszSrc
832 * A number greater than, less than or equal to 0 depending on whether
833 * lpszSrc is greater than, less than or equal to lpszCmp.
835 DWORD WINAPI
StrCmpCA(LPCSTR lpszSrc
, LPCSTR lpszCmp
)
837 return lstrcmpA(lpszSrc
, lpszCmp
);
840 /*************************************************************************
843 * Unicode version of StrCmpCA.
845 DWORD WINAPI
StrCmpCW(LPCWSTR lpszSrc
, LPCWSTR lpszCmp
)
847 return lstrcmpW(lpszSrc
, lpszCmp
);
850 /*************************************************************************
853 * Compare two Ascii strings, ignoring case.
856 * lpszSrc [I] Source string
857 * lpszCmp [I] String to compare to lpszSrc
860 * A number greater than, less than or equal to 0 depending on whether
861 * lpszSrc is greater than, less than or equal to lpszCmp.
863 DWORD WINAPI
StrCmpICA(LPCSTR lpszSrc
, LPCSTR lpszCmp
)
865 return lstrcmpiA(lpszSrc
, lpszCmp
);
868 /*************************************************************************
871 * Unicode version of StrCmpICA.
873 DWORD WINAPI
StrCmpICW(LPCWSTR lpszSrc
, LPCWSTR lpszCmp
)
875 return lstrcmpiW(lpszSrc
, lpszCmp
);
878 /*************************************************************************
881 * Get an identification string for the OS and explorer.
884 * lpszDest [O] Destination for Id string
885 * dwDestLen [I] Length of lpszDest
888 * TRUE, If the string was created successfully
891 BOOL WINAPI
SHAboutInfoA(LPSTR lpszDest
, DWORD dwDestLen
)
895 TRACE("(%p,%d)\n", lpszDest
, dwDestLen
);
897 if (lpszDest
&& SHAboutInfoW(buff
, dwDestLen
))
899 WideCharToMultiByte(CP_ACP
, 0, buff
, -1, lpszDest
, dwDestLen
, NULL
, NULL
);
905 /*************************************************************************
908 * Unicode version of SHAboutInfoA.
910 BOOL WINAPI
SHAboutInfoW(LPWSTR lpszDest
, DWORD dwDestLen
)
912 static const WCHAR szIEKey
[] = { 'S','O','F','T','W','A','R','E','\\',
913 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
914 ' ','E','x','p','l','o','r','e','r','\0' };
915 static const WCHAR szWinNtKey
[] = { 'S','O','F','T','W','A','R','E','\\',
916 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s',' ',
917 'N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
918 static const WCHAR szWinKey
[] = { 'S','O','F','T','W','A','R','E','\\',
919 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
920 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
921 static const WCHAR szRegKey
[] = { 'S','O','F','T','W','A','R','E','\\',
922 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
923 ' ','E','x','p','l','o','r','e','r','\\',
924 'R','e','g','i','s','t','r','a','t','i','o','n','\0' };
925 static const WCHAR szVersion
[] = { 'V','e','r','s','i','o','n','\0' };
926 static const WCHAR szCustomized
[] = { 'C','u','s','t','o','m','i','z','e','d',
927 'V','e','r','s','i','o','n','\0' };
928 static const WCHAR szOwner
[] = { 'R','e','g','i','s','t','e','r','e','d',
929 'O','w','n','e','r','\0' };
930 static const WCHAR szOrg
[] = { 'R','e','g','i','s','t','e','r','e','d',
931 'O','r','g','a','n','i','z','a','t','i','o','n','\0' };
932 static const WCHAR szProduct
[] = { 'P','r','o','d','u','c','t','I','d','\0' };
933 static const WCHAR szUpdate
[] = { 'I','E','A','K',
934 'U','p','d','a','t','e','U','r','l','\0' };
935 static const WCHAR szHelp
[] = { 'I','E','A','K',
936 'H','e','l','p','S','t','r','i','n','g','\0' };
941 TRACE("(%p,%d)\n", lpszDest
, dwDestLen
);
948 /* Try the NT key first, followed by 95/98 key */
949 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szWinNtKey
, 0, KEY_READ
, &hReg
) &&
950 RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szWinKey
, 0, KEY_READ
, &hReg
))
956 if (!SHGetValueW(HKEY_LOCAL_MACHINE
, szIEKey
, szVersion
, &dwType
, buff
, &dwLen
))
958 DWORD dwStrLen
= strlenW(buff
);
959 dwLen
= 30 - dwStrLen
;
960 SHGetValueW(HKEY_LOCAL_MACHINE
, szIEKey
,
961 szCustomized
, &dwType
, buff
+dwStrLen
, &dwLen
);
963 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
965 /* ~Registered Owner */
968 if (SHGetValueW(hReg
, szOwner
, 0, &dwType
, buff
+1, &dwLen
))
970 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
972 /* ~Registered Organization */
974 if (SHGetValueW(hReg
, szOrg
, 0, &dwType
, buff
+1, &dwLen
))
976 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
978 /* FIXME: Not sure where this number comes from */
982 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
986 if (SHGetValueW(HKEY_LOCAL_MACHINE
, szRegKey
, szProduct
, &dwType
, buff
+1, &dwLen
))
988 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
992 if(SHGetValueW(HKEY_LOCAL_MACHINE
, szWinKey
, szUpdate
, &dwType
, buff
+1, &dwLen
))
994 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
996 /* ~IE Help String */
998 if(SHGetValueW(hReg
, szHelp
, 0, &dwType
, buff
+1, &dwLen
))
1000 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
1006 /*************************************************************************
1009 * Call IOleCommandTarget_QueryStatus() on an object.
1012 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1013 * pguidCmdGroup [I] GUID for the command group
1015 * prgCmds [O] Commands
1016 * pCmdText [O] Command text
1020 * Failure: E_FAIL, if lpUnknown is NULL.
1021 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1022 * Otherwise, an error code from IOleCommandTarget_QueryStatus().
1024 HRESULT WINAPI
IUnknown_QueryStatus(IUnknown
* lpUnknown
, REFGUID pguidCmdGroup
,
1025 ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
* pCmdText
)
1027 HRESULT hRet
= E_FAIL
;
1029 TRACE("(%p,%p,%d,%p,%p)\n",lpUnknown
, pguidCmdGroup
, cCmds
, prgCmds
, pCmdText
);
1033 IOleCommandTarget
* lpOle
;
1035 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleCommandTarget
,
1038 if (SUCCEEDED(hRet
) && lpOle
)
1040 hRet
= IOleCommandTarget_QueryStatus(lpOle
, pguidCmdGroup
, cCmds
,
1042 IOleCommandTarget_Release(lpOle
);
1048 /*************************************************************************
1051 * Call IOleCommandTarget_Exec() on an object.
1054 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1055 * pguidCmdGroup [I] GUID for the command group
1059 * Failure: E_FAIL, if lpUnknown is NULL.
1060 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1061 * Otherwise, an error code from IOleCommandTarget_Exec().
1063 HRESULT WINAPI
IUnknown_Exec(IUnknown
* lpUnknown
, REFGUID pguidCmdGroup
,
1064 DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
* pvaIn
,
1067 HRESULT hRet
= E_FAIL
;
1069 TRACE("(%p,%p,%d,%d,%p,%p)\n",lpUnknown
, pguidCmdGroup
, nCmdID
,
1070 nCmdexecopt
, pvaIn
, pvaOut
);
1074 IOleCommandTarget
* lpOle
;
1076 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleCommandTarget
,
1078 if (SUCCEEDED(hRet
) && lpOle
)
1080 hRet
= IOleCommandTarget_Exec(lpOle
, pguidCmdGroup
, nCmdID
,
1081 nCmdexecopt
, pvaIn
, pvaOut
);
1082 IOleCommandTarget_Release(lpOle
);
1088 /*************************************************************************
1091 * Retrieve, modify, and re-set a value from a window.
1094 * hWnd [I] Window to get value from
1095 * offset [I] Offset of value
1096 * mask [I] Mask for flags
1097 * flags [I] Bits to set in window value
1100 * The new value as it was set, or 0 if any parameter is invalid.
1103 * Only bits specified in mask are affected - set if present in flags and
1106 LONG WINAPI
SHSetWindowBits(HWND hwnd
, INT offset
, UINT mask
, UINT flags
)
1108 LONG ret
= GetWindowLongW(hwnd
, offset
);
1109 LONG new_flags
= (flags
& mask
) | (ret
& ~mask
);
1111 TRACE("%p %d %x %x\n", hwnd
, offset
, mask
, flags
);
1113 if (new_flags
!= ret
)
1114 ret
= SetWindowLongW(hwnd
, offset
, new_flags
);
1118 /*************************************************************************
1121 * Change a window's parent.
1124 * hWnd [I] Window to change parent of
1125 * hWndParent [I] New parent window
1128 * The old parent of hWnd.
1131 * If hWndParent is NULL (desktop), the window style is changed to WS_POPUP.
1132 * If hWndParent is NOT NULL then we set the WS_CHILD style.
1134 HWND WINAPI
SHSetParentHwnd(HWND hWnd
, HWND hWndParent
)
1136 TRACE("%p, %p\n", hWnd
, hWndParent
);
1138 if(GetParent(hWnd
) == hWndParent
)
1142 SHSetWindowBits(hWnd
, GWL_STYLE
, WS_CHILD
, WS_CHILD
);
1144 SHSetWindowBits(hWnd
, GWL_STYLE
, WS_POPUP
, WS_POPUP
);
1146 return SetParent(hWnd
, hWndParent
);
1149 /*************************************************************************
1152 * Locate and advise a connection point in an IConnectionPointContainer object.
1155 * lpUnkSink [I] Sink for the connection point advise call
1156 * riid [I] REFIID of connection point to advise
1157 * fConnect [I] TRUE = Connection being establisted, FALSE = broken
1158 * lpUnknown [I] Object supporting the IConnectionPointContainer interface
1159 * lpCookie [O] Pointer to connection point cookie
1160 * lppCP [O] Destination for the IConnectionPoint found
1163 * Success: S_OK. If lppCP is non-NULL, it is filled with the IConnectionPoint
1164 * that was advised. The caller is responsible for releasing it.
1165 * Failure: E_FAIL, if any arguments are invalid.
1166 * E_NOINTERFACE, if lpUnknown isn't an IConnectionPointContainer,
1167 * Or an HRESULT error code if any call fails.
1169 HRESULT WINAPI
ConnectToConnectionPoint(IUnknown
* lpUnkSink
, REFIID riid
, BOOL fConnect
,
1170 IUnknown
* lpUnknown
, LPDWORD lpCookie
,
1171 IConnectionPoint
**lppCP
)
1174 IConnectionPointContainer
* lpContainer
;
1175 IConnectionPoint
*lpCP
;
1177 if(!lpUnknown
|| (fConnect
&& !lpUnkSink
))
1183 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IConnectionPointContainer
,
1184 (void**)&lpContainer
);
1185 if (SUCCEEDED(hRet
))
1187 hRet
= IConnectionPointContainer_FindConnectionPoint(lpContainer
, riid
, &lpCP
);
1189 if (SUCCEEDED(hRet
))
1192 hRet
= IConnectionPoint_Unadvise(lpCP
, *lpCookie
);
1194 hRet
= IConnectionPoint_Advise(lpCP
, lpUnkSink
, lpCookie
);
1199 if (lppCP
&& SUCCEEDED(hRet
))
1200 *lppCP
= lpCP
; /* Caller keeps the interface */
1202 IConnectionPoint_Release(lpCP
); /* Release it */
1205 IUnknown_Release(lpContainer
);
1210 /*************************************************************************
1213 * Release an interface and zero a supplied pointer.
1216 * lpUnknown [I] Object to release
1221 void WINAPI
IUnknown_AtomicRelease(IUnknown
** lpUnknown
)
1223 TRACE("(%p)\n", lpUnknown
);
1225 if(!lpUnknown
|| !*lpUnknown
) return;
1227 TRACE("doing Release\n");
1229 IUnknown_Release(*lpUnknown
);
1233 /*************************************************************************
1236 * Skip '//' if present in a string.
1239 * lpszSrc [I] String to check for '//'
1242 * Success: The next character after the '//' or the string if not present
1243 * Failure: NULL, if lpszStr is NULL.
1245 LPCSTR WINAPI
PathSkipLeadingSlashesA(LPCSTR lpszSrc
)
1247 if (lpszSrc
&& lpszSrc
[0] == '/' && lpszSrc
[1] == '/')
1252 /*************************************************************************
1255 * Check if two interfaces come from the same object.
1258 * lpInt1 [I] Interface to check against lpInt2.
1259 * lpInt2 [I] Interface to check against lpInt1.
1262 * TRUE, If the interfaces come from the same object.
1265 BOOL WINAPI
SHIsSameObject(IUnknown
* lpInt1
, IUnknown
* lpInt2
)
1267 IUnknown
*lpUnknown1
, *lpUnknown2
;
1270 TRACE("(%p %p)\n", lpInt1
, lpInt2
);
1272 if (!lpInt1
|| !lpInt2
)
1275 if (lpInt1
== lpInt2
)
1278 if (IUnknown_QueryInterface(lpInt1
, &IID_IUnknown
, (void**)&lpUnknown1
) != S_OK
)
1281 if (IUnknown_QueryInterface(lpInt2
, &IID_IUnknown
, (void**)&lpUnknown2
) != S_OK
)
1283 IUnknown_Release(lpUnknown1
);
1287 ret
= lpUnknown1
== lpUnknown2
;
1289 IUnknown_Release(lpUnknown1
);
1290 IUnknown_Release(lpUnknown2
);
1295 /*************************************************************************
1298 * Get the window handle of an object.
1301 * lpUnknown [I] Object to get the window handle of
1302 * lphWnd [O] Destination for window handle
1305 * Success: S_OK. lphWnd contains the objects window handle.
1306 * Failure: An HRESULT error code.
1309 * lpUnknown is expected to support one of the following interfaces:
1310 * IOleWindow(), IInternetSecurityMgrSite(), or IShellView().
1312 HRESULT WINAPI
IUnknown_GetWindow(IUnknown
*lpUnknown
, HWND
*lphWnd
)
1315 HRESULT hRet
= E_FAIL
;
1317 TRACE("(%p,%p)\n", lpUnknown
, lphWnd
);
1322 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleWindow
, (void**)&lpOle
);
1326 hRet
= IUnknown_QueryInterface(lpUnknown
,&IID_IShellView
, (void**)&lpOle
);
1330 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IInternetSecurityMgrSite
,
1335 if (SUCCEEDED(hRet
))
1337 /* Lazyness here - Since GetWindow() is the first method for the above 3
1338 * interfaces, we use the same call for them all.
1340 hRet
= IOleWindow_GetWindow((IOleWindow
*)lpOle
, lphWnd
);
1341 IUnknown_Release(lpOle
);
1343 TRACE("Returning HWND=%p\n", *lphWnd
);
1349 /*************************************************************************
1352 * Call a method on as as yet unidentified object.
1355 * pUnk [I] Object supporting the unidentified interface,
1356 * arg [I] Argument for the call on the object.
1361 HRESULT WINAPI
IUnknown_SetOwner(IUnknown
*pUnk
, ULONG arg
)
1363 static const GUID guid_173
= {
1364 0x5836fb00, 0x8187, 0x11cf, { 0xa1,0x2b,0x00,0xaa,0x00,0x4a,0xe8,0x37 }
1368 TRACE("(%p,%d)\n", pUnk
, arg
);
1370 /* Note: arg may not be a ULONG and pUnk2 is for sure not an IMalloc -
1371 * We use this interface as its vtable entry is compatible with the
1372 * object in question.
1373 * FIXME: Find out what this object is and where it should be defined.
1376 SUCCEEDED(IUnknown_QueryInterface(pUnk
, &guid_173
, (void**)&pUnk2
)))
1378 IMalloc_Alloc(pUnk2
, arg
); /* Faked call!! */
1379 IMalloc_Release(pUnk2
);
1384 /*************************************************************************
1387 * Call either IObjectWithSite_SetSite() or IInternetSecurityManager_SetSecuritySite() on
1391 HRESULT WINAPI
IUnknown_SetSite(
1392 IUnknown
*obj
, /* [in] OLE object */
1393 IUnknown
*site
) /* [in] Site interface */
1396 IObjectWithSite
*iobjwithsite
;
1397 IInternetSecurityManager
*isecmgr
;
1399 if (!obj
) return E_FAIL
;
1401 hr
= IUnknown_QueryInterface(obj
, &IID_IObjectWithSite
, (LPVOID
*)&iobjwithsite
);
1402 TRACE("IID_IObjectWithSite QI ret=%08x, %p\n", hr
, iobjwithsite
);
1405 hr
= IObjectWithSite_SetSite(iobjwithsite
, site
);
1406 TRACE("done IObjectWithSite_SetSite ret=%08x\n", hr
);
1407 IUnknown_Release(iobjwithsite
);
1411 hr
= IUnknown_QueryInterface(obj
, &IID_IInternetSecurityManager
, (LPVOID
*)&isecmgr
);
1412 TRACE("IID_IInternetSecurityManager QI ret=%08x, %p\n", hr
, isecmgr
);
1413 if (FAILED(hr
)) return hr
;
1415 hr
= IInternetSecurityManager_SetSecuritySite(isecmgr
, (IInternetSecurityMgrSite
*)site
);
1416 TRACE("done IInternetSecurityManager_SetSecuritySite ret=%08x\n", hr
);
1417 IUnknown_Release(isecmgr
);
1422 /*************************************************************************
1425 * Call IPersist_GetClassID() on an object.
1428 * lpUnknown [I] Object supporting the IPersist interface
1429 * lpClassId [O] Destination for Class Id
1432 * Success: S_OK. lpClassId contains the Class Id requested.
1433 * Failure: E_FAIL, If lpUnknown is NULL,
1434 * E_NOINTERFACE If lpUnknown does not support IPersist,
1435 * Or an HRESULT error code.
1437 HRESULT WINAPI
IUnknown_GetClassID(IUnknown
*lpUnknown
, CLSID
* lpClassId
)
1439 IPersist
* lpPersist
;
1440 HRESULT hRet
= E_FAIL
;
1442 TRACE("(%p,%p)\n", lpUnknown
, debugstr_guid(lpClassId
));
1446 hRet
= IUnknown_QueryInterface(lpUnknown
,&IID_IPersist
,(void**)&lpPersist
);
1447 if (SUCCEEDED(hRet
))
1449 IPersist_GetClassID(lpPersist
, lpClassId
);
1450 IPersist_Release(lpPersist
);
1456 /*************************************************************************
1459 * Retrieve a Service Interface from an object.
1462 * lpUnknown [I] Object to get an IServiceProvider interface from
1463 * sid [I] Service ID for IServiceProvider_QueryService() call
1464 * riid [I] Function requested for QueryService call
1465 * lppOut [O] Destination for the service interface pointer
1468 * Success: S_OK. lppOut contains an object providing the requested service
1469 * Failure: An HRESULT error code
1472 * lpUnknown is expected to support the IServiceProvider interface.
1474 HRESULT WINAPI
IUnknown_QueryService(IUnknown
* lpUnknown
, REFGUID sid
, REFIID riid
,
1477 IServiceProvider
* pService
= NULL
;
1488 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IServiceProvider
,
1489 (LPVOID
*)&pService
);
1491 if (hRet
== S_OK
&& pService
)
1493 TRACE("QueryInterface returned (IServiceProvider*)%p\n", pService
);
1495 /* Get a Service interface from the object */
1496 hRet
= IServiceProvider_QueryService(pService
, sid
, riid
, lppOut
);
1498 TRACE("(IServiceProvider*)%p returned (IUnknown*)%p\n", pService
, *lppOut
);
1500 IUnknown_Release(pService
);
1505 /*************************************************************************
1508 * Calls IOleCommandTarget::Exec() for specified service object.
1511 * lpUnknown [I] Object to get an IServiceProvider interface from
1512 * service [I] Service ID for IServiceProvider_QueryService() call
1513 * group [I] Group ID for IOleCommandTarget::Exec() call
1514 * cmdId [I] Command ID for IOleCommandTarget::Exec() call
1515 * cmdOpt [I] Options flags for command
1516 * pIn [I] Input arguments for command
1517 * pOut [O] Output arguments for command
1520 * Success: S_OK. lppOut contains an object providing the requested service
1521 * Failure: An HRESULT error code
1524 * lpUnknown is expected to support the IServiceProvider interface.
1526 HRESULT WINAPI
IUnknown_QueryServiceExec(IUnknown
*lpUnknown
, REFIID service
,
1527 const GUID
*group
, DWORD cmdId
, DWORD cmdOpt
, VARIANT
*pIn
, VARIANT
*pOut
)
1529 IOleCommandTarget
*target
;
1532 TRACE("%p %s %s %d %08x %p %p\n", lpUnknown
, debugstr_guid(service
),
1533 debugstr_guid(group
), cmdId
, cmdOpt
, pIn
, pOut
);
1535 hr
= IUnknown_QueryService(lpUnknown
, service
, &IID_IOleCommandTarget
, (void**)&target
);
1538 hr
= IOleCommandTarget_Exec(target
, group
, cmdId
, cmdOpt
, pIn
, pOut
);
1539 IOleCommandTarget_Release(target
);
1542 TRACE("<-- hr=0x%08x\n", hr
);
1547 /*************************************************************************
1550 * Calls IProfferService methods to proffer/revoke specified service.
1553 * lpUnknown [I] Object to get an IServiceProvider interface from
1554 * service [I] Service ID for IProfferService::Proffer/Revoke calls
1555 * pService [I] Service to proffer. If NULL ::Revoke is called
1556 * pCookie [IO] Group ID for IOleCommandTarget::Exec() call
1559 * Success: S_OK. IProffer method returns S_OK
1560 * Failure: An HRESULT error code
1563 * lpUnknown is expected to support the IServiceProvider interface.
1565 HRESULT WINAPI
IUnknown_ProfferService(IUnknown
*lpUnknown
, REFGUID service
, IServiceProvider
*pService
, DWORD
*pCookie
)
1567 IProfferService
*proffer
;
1570 TRACE("%p %s %p %p\n", lpUnknown
, debugstr_guid(service
), pService
, pCookie
);
1572 hr
= IUnknown_QueryService(lpUnknown
, &IID_IProfferService
, &IID_IProfferService
, (void**)&proffer
);
1576 hr
= IProfferService_ProfferService(proffer
, service
, pService
, pCookie
);
1578 hr
= IProfferService_RevokeService(proffer
, *pCookie
);
1580 IProfferService_Release(proffer
);
1586 /*************************************************************************
1589 * Call an object's UIActivateIO method.
1592 * unknown [I] Object to call the UIActivateIO method on
1593 * activate [I] Parameter for UIActivateIO call
1594 * msg [I] Parameter for UIActivateIO call
1597 * Success: Value of UI_ActivateIO call
1598 * Failure: An HRESULT error code
1601 * unknown is expected to support the IInputObject interface.
1603 HRESULT WINAPI
IUnknown_UIActivateIO(IUnknown
*unknown
, BOOL activate
, LPMSG msg
)
1605 IInputObject
* object
= NULL
;
1611 /* Get an IInputObject interface from the object */
1612 ret
= IUnknown_QueryInterface(unknown
, &IID_IInputObject
, (LPVOID
*) &object
);
1616 ret
= IInputObject_UIActivateIO(object
, activate
, msg
);
1617 IUnknown_Release(object
);
1623 /*************************************************************************
1626 * Loads a popup menu.
1629 * hInst [I] Instance handle
1630 * szName [I] Menu name
1636 BOOL WINAPI
SHLoadMenuPopup(HINSTANCE hInst
, LPCWSTR szName
)
1640 if ((hMenu
= LoadMenuW(hInst
, szName
)))
1642 if (GetSubMenu(hMenu
, 0))
1643 RemoveMenu(hMenu
, 0, MF_BYPOSITION
);
1651 typedef struct _enumWndData
1656 LRESULT (WINAPI
*pfnPost
)(HWND
,UINT
,WPARAM
,LPARAM
);
1659 /* Callback for SHLWAPI_178 */
1660 static BOOL CALLBACK
SHLWAPI_EnumChildProc(HWND hWnd
, LPARAM lParam
)
1662 enumWndData
*data
= (enumWndData
*)lParam
;
1664 TRACE("(%p,%p)\n", hWnd
, data
);
1665 data
->pfnPost(hWnd
, data
->uiMsgId
, data
->wParam
, data
->lParam
);
1669 /*************************************************************************
1672 * Send or post a message to every child of a window.
1675 * hWnd [I] Window whose children will get the messages
1676 * uiMsgId [I] Message Id
1677 * wParam [I] WPARAM of message
1678 * lParam [I] LPARAM of message
1679 * bSend [I] TRUE = Use SendMessageA(), FALSE = Use PostMessageA()
1685 * The appropriate ASCII or Unicode function is called for the window.
1687 void WINAPI
SHPropagateMessage(HWND hWnd
, UINT uiMsgId
, WPARAM wParam
, LPARAM lParam
, BOOL bSend
)
1691 TRACE("(%p,%u,%ld,%ld,%d)\n", hWnd
, uiMsgId
, wParam
, lParam
, bSend
);
1695 data
.uiMsgId
= uiMsgId
;
1696 data
.wParam
= wParam
;
1697 data
.lParam
= lParam
;
1700 data
.pfnPost
= IsWindowUnicode(hWnd
) ? (void*)SendMessageW
: (void*)SendMessageA
;
1702 data
.pfnPost
= IsWindowUnicode(hWnd
) ? (void*)PostMessageW
: (void*)PostMessageA
;
1704 EnumChildWindows(hWnd
, SHLWAPI_EnumChildProc
, (LPARAM
)&data
);
1708 /*************************************************************************
1711 * Remove all sub-menus from a menu.
1714 * hMenu [I] Menu to remove sub-menus from
1717 * Success: 0. All sub-menus under hMenu are removed
1718 * Failure: -1, if any parameter is invalid
1720 DWORD WINAPI
SHRemoveAllSubMenus(HMENU hMenu
)
1722 int iItemCount
= GetMenuItemCount(hMenu
) - 1;
1723 while (iItemCount
>= 0)
1725 HMENU hSubMenu
= GetSubMenu(hMenu
, iItemCount
);
1727 RemoveMenu(hMenu
, iItemCount
, MF_BYPOSITION
);
1733 /*************************************************************************
1736 * Enable or disable a menu item.
1739 * hMenu [I] Menu holding menu item
1740 * uID [I] ID of menu item to enable/disable
1741 * bEnable [I] Whether to enable (TRUE) or disable (FALSE) the item.
1744 * The return code from EnableMenuItem.
1746 UINT WINAPI
SHEnableMenuItem(HMENU hMenu
, UINT wItemID
, BOOL bEnable
)
1748 return EnableMenuItem(hMenu
, wItemID
, bEnable
? MF_ENABLED
: MF_GRAYED
);
1751 /*************************************************************************
1754 * Check or uncheck a menu item.
1757 * hMenu [I] Menu holding menu item
1758 * uID [I] ID of menu item to check/uncheck
1759 * bCheck [I] Whether to check (TRUE) or uncheck (FALSE) the item.
1762 * The return code from CheckMenuItem.
1764 DWORD WINAPI
SHCheckMenuItem(HMENU hMenu
, UINT uID
, BOOL bCheck
)
1766 return CheckMenuItem(hMenu
, uID
, bCheck
? MF_CHECKED
: MF_UNCHECKED
);
1769 /*************************************************************************
1772 * Register a window class if it isn't already.
1775 * lpWndClass [I] Window class to register
1778 * The result of the RegisterClassA call.
1780 DWORD WINAPI
SHRegisterClassA(WNDCLASSA
*wndclass
)
1783 if (GetClassInfoA(wndclass
->hInstance
, wndclass
->lpszClassName
, &wca
))
1785 return (DWORD
)RegisterClassA(wndclass
);
1788 /*************************************************************************
1791 BOOL WINAPI
SHSimulateDrop(IDropTarget
*pDrop
, IDataObject
*pDataObj
,
1792 DWORD grfKeyState
, PPOINTL lpPt
, DWORD
* pdwEffect
)
1794 DWORD dwEffect
= DROPEFFECT_LINK
| DROPEFFECT_MOVE
| DROPEFFECT_COPY
;
1795 POINTL pt
= { 0, 0 };
1801 pdwEffect
= &dwEffect
;
1803 IDropTarget_DragEnter(pDrop
, pDataObj
, grfKeyState
, *lpPt
, pdwEffect
);
1806 return IDropTarget_Drop(pDrop
, pDataObj
, grfKeyState
, *lpPt
, pdwEffect
);
1808 IDropTarget_DragLeave(pDrop
);
1812 /*************************************************************************
1815 * Call IPersistPropertyBag_Load() on an object.
1818 * lpUnknown [I] Object supporting the IPersistPropertyBag interface
1819 * lpPropBag [O] Destination for loaded IPropertyBag
1823 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1825 DWORD WINAPI
SHLoadFromPropertyBag(IUnknown
*lpUnknown
, IPropertyBag
* lpPropBag
)
1827 IPersistPropertyBag
* lpPPBag
;
1828 HRESULT hRet
= E_FAIL
;
1830 TRACE("(%p,%p)\n", lpUnknown
, lpPropBag
);
1834 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IPersistPropertyBag
,
1836 if (SUCCEEDED(hRet
) && lpPPBag
)
1838 hRet
= IPersistPropertyBag_Load(lpPPBag
, lpPropBag
, NULL
);
1839 IPersistPropertyBag_Release(lpPPBag
);
1845 /*************************************************************************
1848 * Call IOleControlSite_TranslateAccelerator() on an object.
1851 * lpUnknown [I] Object supporting the IOleControlSite interface.
1852 * lpMsg [I] Key message to be processed.
1853 * dwModifiers [I] Flags containing the state of the modifier keys.
1857 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
1859 HRESULT WINAPI
IUnknown_TranslateAcceleratorOCS(IUnknown
*lpUnknown
, LPMSG lpMsg
, DWORD dwModifiers
)
1861 IOleControlSite
* lpCSite
= NULL
;
1862 HRESULT hRet
= E_INVALIDARG
;
1864 TRACE("(%p,%p,0x%08x)\n", lpUnknown
, lpMsg
, dwModifiers
);
1867 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleControlSite
,
1869 if (SUCCEEDED(hRet
) && lpCSite
)
1871 hRet
= IOleControlSite_TranslateAccelerator(lpCSite
, lpMsg
, dwModifiers
);
1872 IOleControlSite_Release(lpCSite
);
1879 /*************************************************************************
1882 * Call IOleControlSite_OnFocus() on an object.
1885 * lpUnknown [I] Object supporting the IOleControlSite interface.
1886 * fGotFocus [I] Whether focus was gained (TRUE) or lost (FALSE).
1890 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1892 HRESULT WINAPI
IUnknown_OnFocusOCS(IUnknown
*lpUnknown
, BOOL fGotFocus
)
1894 IOleControlSite
* lpCSite
= NULL
;
1895 HRESULT hRet
= E_FAIL
;
1897 TRACE("(%p,%s)\n", lpUnknown
, fGotFocus
? "TRUE" : "FALSE");
1900 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleControlSite
,
1902 if (SUCCEEDED(hRet
) && lpCSite
)
1904 hRet
= IOleControlSite_OnFocus(lpCSite
, fGotFocus
);
1905 IOleControlSite_Release(lpCSite
);
1911 /*************************************************************************
1914 HRESULT WINAPI
IUnknown_HandleIRestrict(LPUNKNOWN lpUnknown
, PVOID lpArg1
,
1915 PVOID lpArg2
, PVOID lpArg3
, PVOID lpArg4
)
1917 /* FIXME: {D12F26B2-D90A-11D0-830D-00AA005B4383} - What object does this represent? */
1918 static const DWORD service_id
[] = { 0xd12f26b2, 0x11d0d90a, 0xaa000d83, 0x83435b00 };
1919 /* FIXME: {D12F26B1-D90A-11D0-830D-00AA005B4383} - Also Unknown/undocumented */
1920 static const DWORD function_id
[] = { 0xd12f26b1, 0x11d0d90a, 0xaa000d83, 0x83435b00 };
1921 HRESULT hRet
= E_INVALIDARG
;
1922 LPUNKNOWN lpUnkInner
= NULL
; /* FIXME: Real type is unknown */
1924 TRACE("(%p,%p,%p,%p,%p)\n", lpUnknown
, lpArg1
, lpArg2
, lpArg3
, lpArg4
);
1926 if (lpUnknown
&& lpArg4
)
1928 hRet
= IUnknown_QueryService(lpUnknown
, (REFGUID
)service_id
,
1929 (REFGUID
)function_id
, (void**)&lpUnkInner
);
1931 if (SUCCEEDED(hRet
) && lpUnkInner
)
1933 /* FIXME: The type of service object requested is unknown, however
1934 * testing shows that its first method is called with 4 parameters.
1935 * Fake this by using IParseDisplayName_ParseDisplayName since the
1936 * signature and position in the vtable matches our unknown object type.
1938 hRet
= IParseDisplayName_ParseDisplayName((LPPARSEDISPLAYNAME
)lpUnkInner
,
1939 lpArg1
, lpArg2
, lpArg3
, lpArg4
);
1940 IUnknown_Release(lpUnkInner
);
1946 /*************************************************************************
1949 * Get a sub-menu from a menu item.
1952 * hMenu [I] Menu to get sub-menu from
1953 * uID [I] ID of menu item containing sub-menu
1956 * The sub-menu of the item, or a NULL handle if any parameters are invalid.
1958 HMENU WINAPI
SHGetMenuFromID(HMENU hMenu
, UINT uID
)
1962 TRACE("(%p,%u)\n", hMenu
, uID
);
1964 mi
.cbSize
= sizeof(mi
);
1965 mi
.fMask
= MIIM_SUBMENU
;
1967 if (!GetMenuItemInfoW(hMenu
, uID
, FALSE
, &mi
))
1973 /*************************************************************************
1976 * Get the color depth of the primary display.
1982 * The color depth of the primary display.
1984 DWORD WINAPI
SHGetCurColorRes(void)
1992 ret
= GetDeviceCaps(hdc
, BITSPIXEL
) * GetDeviceCaps(hdc
, PLANES
);
1997 /*************************************************************************
2000 * Wait for a message to arrive, with a timeout.
2003 * hand [I] Handle to query
2004 * dwTimeout [I] Timeout in ticks or INFINITE to never timeout
2007 * STATUS_TIMEOUT if no message is received before dwTimeout ticks passes.
2008 * Otherwise returns the value from MsgWaitForMultipleObjectsEx when a
2009 * message is available.
2011 DWORD WINAPI
SHWaitForSendMessageThread(HANDLE hand
, DWORD dwTimeout
)
2013 DWORD dwEndTicks
= GetTickCount() + dwTimeout
;
2016 while ((dwRet
= MsgWaitForMultipleObjectsEx(1, &hand
, dwTimeout
, QS_SENDMESSAGE
, 0)) == 1)
2020 PeekMessageW(&msg
, NULL
, 0, 0, PM_NOREMOVE
);
2022 if (dwTimeout
!= INFINITE
)
2024 if ((int)(dwTimeout
= dwEndTicks
- GetTickCount()) <= 0)
2025 return WAIT_TIMEOUT
;
2032 /*************************************************************************
2035 * Determine if a shell folder can be expanded.
2038 * lpFolder [I] Parent folder containing the object to test.
2039 * pidl [I] Id of the object to test.
2042 * Success: S_OK, if the object is expandable, S_FALSE otherwise.
2043 * Failure: E_INVALIDARG, if any argument is invalid.
2046 * If the object to be tested does not expose the IQueryInfo() interface it
2047 * will not be identified as an expandable folder.
2049 HRESULT WINAPI
SHIsExpandableFolder(LPSHELLFOLDER lpFolder
, LPCITEMIDLIST pidl
)
2051 HRESULT hRet
= E_INVALIDARG
;
2054 if (lpFolder
&& pidl
)
2056 hRet
= IShellFolder_GetUIObjectOf(lpFolder
, NULL
, 1, &pidl
, &IID_IQueryInfo
,
2057 NULL
, (void**)&lpInfo
);
2059 hRet
= S_FALSE
; /* Doesn't expose IQueryInfo */
2064 /* MSDN states of IQueryInfo_GetInfoFlags() that "This method is not
2065 * currently used". Really? You wouldn't be holding out on me would you?
2067 hRet
= IQueryInfo_GetInfoFlags(lpInfo
, &dwFlags
);
2069 if (SUCCEEDED(hRet
))
2071 /* 0x2 is an undocumented flag apparently indicating expandability */
2072 hRet
= dwFlags
& 0x2 ? S_OK
: S_FALSE
;
2075 IQueryInfo_Release(lpInfo
);
2081 /*************************************************************************
2084 * Blank out a region of text by drawing the background only.
2087 * hDC [I] Device context to draw in
2088 * pRect [I] Area to draw in
2089 * cRef [I] Color to draw in
2094 DWORD WINAPI
SHFillRectClr(HDC hDC
, LPCRECT pRect
, COLORREF cRef
)
2096 COLORREF cOldColor
= SetBkColor(hDC
, cRef
);
2097 ExtTextOutA(hDC
, 0, 0, ETO_OPAQUE
, pRect
, 0, 0, 0);
2098 SetBkColor(hDC
, cOldColor
);
2102 /*************************************************************************
2105 * Return the value associated with a key in a map.
2108 * lpKeys [I] A list of keys of length iLen
2109 * lpValues [I] A list of values associated with lpKeys, of length iLen
2110 * iLen [I] Length of both lpKeys and lpValues
2111 * iKey [I] The key value to look up in lpKeys
2114 * The value in lpValues associated with iKey, or -1 if iKey is not
2118 * - If two elements in the map share the same key, this function returns
2119 * the value closest to the start of the map
2120 * - The native version of this function crashes if lpKeys or lpValues is NULL.
2122 int WINAPI
SHSearchMapInt(const int *lpKeys
, const int *lpValues
, int iLen
, int iKey
)
2124 if (lpKeys
&& lpValues
)
2130 if (lpKeys
[i
] == iKey
)
2131 return lpValues
[i
]; /* Found */
2135 return -1; /* Not found */
2139 /*************************************************************************
2142 * Copy an interface pointer
2145 * lppDest [O] Destination for copy
2146 * lpUnknown [I] Source for copy
2151 VOID WINAPI
IUnknown_Set(IUnknown
**lppDest
, IUnknown
*lpUnknown
)
2153 TRACE("(%p,%p)\n", lppDest
, lpUnknown
);
2156 IUnknown_AtomicRelease(lppDest
); /* Release existing interface */
2161 IUnknown_AddRef(lpUnknown
);
2162 *lppDest
= lpUnknown
;
2166 /*************************************************************************
2170 HRESULT WINAPI
MayQSForward(IUnknown
* lpUnknown
, PVOID lpReserved
,
2171 REFGUID riidCmdGrp
, ULONG cCmds
,
2172 OLECMD
*prgCmds
, OLECMDTEXT
* pCmdText
)
2174 FIXME("(%p,%p,%p,%d,%p,%p) - stub\n",
2175 lpUnknown
, lpReserved
, riidCmdGrp
, cCmds
, prgCmds
, pCmdText
);
2177 /* FIXME: Calls IsQSForward & IUnknown_QueryStatus */
2178 return DRAGDROP_E_NOTREGISTERED
;
2181 /*************************************************************************
2185 HRESULT WINAPI
MayExecForward(IUnknown
* lpUnknown
, INT iUnk
, REFGUID pguidCmdGroup
,
2186 DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
* pvaIn
,
2189 FIXME("(%p,%d,%p,%d,%d,%p,%p) - stub!\n", lpUnknown
, iUnk
, pguidCmdGroup
,
2190 nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2191 return DRAGDROP_E_NOTREGISTERED
;
2194 /*************************************************************************
2198 HRESULT WINAPI
IsQSForward(REFGUID pguidCmdGroup
,ULONG cCmds
, OLECMD
*prgCmds
)
2200 FIXME("(%p,%d,%p) - stub!\n", pguidCmdGroup
, cCmds
, prgCmds
);
2201 return DRAGDROP_E_NOTREGISTERED
;
2204 /*************************************************************************
2207 * Determine if a window is not a child of another window.
2210 * hParent [I] Suspected parent window
2211 * hChild [I] Suspected child window
2214 * TRUE: If hChild is a child window of hParent
2215 * FALSE: If hChild is not a child window of hParent, or they are equal
2217 BOOL WINAPI
SHIsChildOrSelf(HWND hParent
, HWND hChild
)
2219 TRACE("(%p,%p)\n", hParent
, hChild
);
2221 if (!hParent
|| !hChild
)
2223 else if(hParent
== hChild
)
2225 return !IsChild(hParent
, hChild
);
2228 /*************************************************************************
2229 * FDSA functions. Manage a dynamic array of fixed size memory blocks.
2234 DWORD num_items
; /* Number of elements inserted */
2235 void *mem
; /* Ptr to array */
2236 DWORD blocks_alloced
; /* Number of elements allocated */
2237 BYTE inc
; /* Number of elements to grow by when we need to expand */
2238 BYTE block_size
; /* Size in bytes of an element */
2239 BYTE flags
; /* Flags */
2242 #define FDSA_FLAG_INTERNAL_ALLOC 0x01 /* When set we have allocated mem internally */
2244 /*************************************************************************
2247 * Initialize an FDSA array.
2249 BOOL WINAPI
FDSA_Initialize(DWORD block_size
, DWORD inc
, FDSA_info
*info
, void *mem
,
2252 TRACE("(0x%08x 0x%08x %p %p 0x%08x)\n", block_size
, inc
, info
, mem
, init_blocks
);
2258 memset(mem
, 0, block_size
* init_blocks
);
2260 info
->num_items
= 0;
2263 info
->blocks_alloced
= init_blocks
;
2264 info
->block_size
= block_size
;
2270 /*************************************************************************
2273 * Destroy an FDSA array
2275 BOOL WINAPI
FDSA_Destroy(FDSA_info
*info
)
2277 TRACE("(%p)\n", info
);
2279 if(info
->flags
& FDSA_FLAG_INTERNAL_ALLOC
)
2281 HeapFree(GetProcessHeap(), 0, info
->mem
);
2288 /*************************************************************************
2291 * Insert element into an FDSA array
2293 DWORD WINAPI
FDSA_InsertItem(FDSA_info
*info
, DWORD where
, const void *block
)
2295 TRACE("(%p 0x%08x %p)\n", info
, where
, block
);
2296 if(where
> info
->num_items
)
2297 where
= info
->num_items
;
2299 if(info
->num_items
>= info
->blocks_alloced
)
2301 DWORD size
= (info
->blocks_alloced
+ info
->inc
) * info
->block_size
;
2302 if(info
->flags
& 0x1)
2303 info
->mem
= HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, info
->mem
, size
);
2306 void *old_mem
= info
->mem
;
2307 info
->mem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
2308 memcpy(info
->mem
, old_mem
, info
->blocks_alloced
* info
->block_size
);
2310 info
->blocks_alloced
+= info
->inc
;
2314 if(where
< info
->num_items
)
2316 memmove((char*)info
->mem
+ (where
+ 1) * info
->block_size
,
2317 (char*)info
->mem
+ where
* info
->block_size
,
2318 (info
->num_items
- where
) * info
->block_size
);
2320 memcpy((char*)info
->mem
+ where
* info
->block_size
, block
, info
->block_size
);
2326 /*************************************************************************
2329 * Delete an element from an FDSA array.
2331 BOOL WINAPI
FDSA_DeleteItem(FDSA_info
*info
, DWORD where
)
2333 TRACE("(%p 0x%08x)\n", info
, where
);
2335 if(where
>= info
->num_items
)
2338 if(where
< info
->num_items
- 1)
2340 memmove((char*)info
->mem
+ where
* info
->block_size
,
2341 (char*)info
->mem
+ (where
+ 1) * info
->block_size
,
2342 (info
->num_items
- where
- 1) * info
->block_size
);
2344 memset((char*)info
->mem
+ (info
->num_items
- 1) * info
->block_size
,
2345 0, info
->block_size
);
2356 /*************************************************************************
2359 * Call IUnknown_QueryInterface() on a table of objects.
2363 * Failure: E_POINTER or E_NOINTERFACE.
2365 HRESULT WINAPI
QISearch(
2366 LPVOID w
, /* [in] Table of interfaces */
2367 IFACE_INDEX_TBL
*x
, /* [in] Array of REFIIDs and indexes into the table */
2368 REFIID riid
, /* [in] REFIID to get interface for */
2369 LPVOID
*ppv
) /* [out] Destination for interface pointer */
2373 IFACE_INDEX_TBL
*xmove
;
2375 TRACE("(%p %p %s %p)\n", w
,x
,debugstr_guid(riid
),ppv
);
2378 while (xmove
->refid
) {
2379 TRACE("trying (indx %d) %s\n", xmove
->indx
, debugstr_guid(xmove
->refid
));
2380 if (IsEqualIID(riid
, xmove
->refid
)) {
2381 a_vtbl
= (IUnknown
*)(xmove
->indx
+ (LPBYTE
)w
);
2382 TRACE("matched, returning (%p)\n", a_vtbl
);
2384 IUnknown_AddRef(a_vtbl
);
2390 if (IsEqualIID(riid
, &IID_IUnknown
)) {
2391 a_vtbl
= (IUnknown
*)(x
->indx
+ (LPBYTE
)w
);
2392 TRACE("returning first for IUnknown (%p)\n", a_vtbl
);
2394 IUnknown_AddRef(a_vtbl
);
2398 ret
= E_NOINTERFACE
;
2402 TRACE("-- 0x%08x\n", ret
);
2406 /*************************************************************************
2409 * Set the Font for a window and the "PropDlgFont" property of the parent window.
2412 * hWnd [I] Parent Window to set the property
2413 * id [I] Index of child Window to set the Font
2419 HRESULT WINAPI
SHSetDefaultDialogFont(HWND hWnd
, INT id
)
2421 FIXME("(%p, %d) stub\n", hWnd
, id
);
2425 /*************************************************************************
2428 * Remove the "PropDlgFont" property from a window.
2431 * hWnd [I] Window to remove the property from
2434 * A handle to the removed property, or NULL if it did not exist.
2436 HANDLE WINAPI
SHRemoveDefaultDialogFont(HWND hWnd
)
2440 TRACE("(%p)\n", hWnd
);
2442 hProp
= GetPropA(hWnd
, "PropDlgFont");
2446 DeleteObject(hProp
);
2447 hProp
= RemovePropA(hWnd
, "PropDlgFont");
2452 /*************************************************************************
2455 * Load the in-process server of a given GUID.
2458 * refiid [I] GUID of the server to load.
2461 * Success: A handle to the loaded server dll.
2462 * Failure: A NULL handle.
2464 HMODULE WINAPI
SHPinDllOfCLSID(REFIID refiid
)
2468 CHAR value
[MAX_PATH
], string
[MAX_PATH
];
2470 strcpy(string
, "CLSID\\");
2471 SHStringFromGUIDA(refiid
, string
+ 6, sizeof(string
)/sizeof(char) - 6);
2472 strcat(string
, "\\InProcServer32");
2475 RegOpenKeyExA(HKEY_CLASSES_ROOT
, string
, 0, 1, &newkey
);
2476 RegQueryValueExA(newkey
, 0, 0, &type
, (PBYTE
)value
, &count
);
2477 RegCloseKey(newkey
);
2478 return LoadLibraryExA(value
, 0, 0);
2481 /*************************************************************************
2484 * Unicode version of SHLWAPI_183.
2486 DWORD WINAPI
SHRegisterClassW(WNDCLASSW
* lpWndClass
)
2490 TRACE("(%p %s)\n",lpWndClass
->hInstance
, debugstr_w(lpWndClass
->lpszClassName
));
2492 if (GetClassInfoW(lpWndClass
->hInstance
, lpWndClass
->lpszClassName
, &WndClass
))
2494 return RegisterClassW(lpWndClass
);
2497 /*************************************************************************
2500 * Unregister a list of classes.
2503 * hInst [I] Application instance that registered the classes
2504 * lppClasses [I] List of class names
2505 * iCount [I] Number of names in lppClasses
2510 void WINAPI
SHUnregisterClassesA(HINSTANCE hInst
, LPCSTR
*lppClasses
, INT iCount
)
2514 TRACE("(%p,%p,%d)\n", hInst
, lppClasses
, iCount
);
2518 if (GetClassInfoA(hInst
, *lppClasses
, &WndClass
))
2519 UnregisterClassA(*lppClasses
, hInst
);
2525 /*************************************************************************
2528 * Unicode version of SHUnregisterClassesA.
2530 void WINAPI
SHUnregisterClassesW(HINSTANCE hInst
, LPCWSTR
*lppClasses
, INT iCount
)
2534 TRACE("(%p,%p,%d)\n", hInst
, lppClasses
, iCount
);
2538 if (GetClassInfoW(hInst
, *lppClasses
, &WndClass
))
2539 UnregisterClassW(*lppClasses
, hInst
);
2545 /*************************************************************************
2548 * Call The correct (Ascii/Unicode) default window procedure for a window.
2551 * hWnd [I] Window to call the default procedure for
2552 * uMessage [I] Message ID
2553 * wParam [I] WPARAM of message
2554 * lParam [I] LPARAM of message
2557 * The result of calling DefWindowProcA() or DefWindowProcW().
2559 LRESULT CALLBACK
SHDefWindowProc(HWND hWnd
, UINT uMessage
, WPARAM wParam
, LPARAM lParam
)
2561 if (IsWindowUnicode(hWnd
))
2562 return DefWindowProcW(hWnd
, uMessage
, wParam
, lParam
);
2563 return DefWindowProcA(hWnd
, uMessage
, wParam
, lParam
);
2566 /*************************************************************************
2569 HRESULT WINAPI
IUnknown_GetSite(LPUNKNOWN lpUnknown
, REFIID iid
, PVOID
*lppSite
)
2571 HRESULT hRet
= E_INVALIDARG
;
2572 LPOBJECTWITHSITE lpSite
= NULL
;
2574 TRACE("(%p,%s,%p)\n", lpUnknown
, debugstr_guid(iid
), lppSite
);
2576 if (lpUnknown
&& iid
&& lppSite
)
2578 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IObjectWithSite
,
2580 if (SUCCEEDED(hRet
) && lpSite
)
2582 hRet
= IObjectWithSite_GetSite(lpSite
, iid
, lppSite
);
2583 IObjectWithSite_Release(lpSite
);
2589 /*************************************************************************
2592 * Create a worker window using CreateWindowExA().
2595 * wndProc [I] Window procedure
2596 * hWndParent [I] Parent window
2597 * dwExStyle [I] Extra style flags
2598 * dwStyle [I] Style flags
2599 * hMenu [I] Window menu
2603 * Success: The window handle of the newly created window.
2606 HWND WINAPI
SHCreateWorkerWindowA(LONG wndProc
, HWND hWndParent
, DWORD dwExStyle
,
2607 DWORD dwStyle
, HMENU hMenu
, LONG z
)
2609 static const char szClass
[] = "WorkerA";
2613 TRACE("(0x%08x,%p,0x%08x,0x%08x,%p,0x%08x)\n",
2614 wndProc
, hWndParent
, dwExStyle
, dwStyle
, hMenu
, z
);
2616 /* Create Window class */
2618 wc
.lpfnWndProc
= DefWindowProcA
;
2621 wc
.hInstance
= shlwapi_hInstance
;
2623 wc
.hCursor
= LoadCursorA(NULL
, (LPSTR
)IDC_ARROW
);
2624 wc
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
2625 wc
.lpszMenuName
= NULL
;
2626 wc
.lpszClassName
= szClass
;
2628 SHRegisterClassA(&wc
); /* Register class */
2630 /* FIXME: Set extra bits in dwExStyle */
2632 hWnd
= CreateWindowExA(dwExStyle
, szClass
, 0, dwStyle
, 0, 0, 0, 0,
2633 hWndParent
, hMenu
, shlwapi_hInstance
, 0);
2636 SetWindowLongPtrW(hWnd
, DWLP_MSGRESULT
, z
);
2639 SetWindowLongPtrA(hWnd
, GWLP_WNDPROC
, wndProc
);
2644 typedef struct tagPOLICYDATA
2646 DWORD policy
; /* flags value passed to SHRestricted */
2647 LPCWSTR appstr
; /* application str such as "Explorer" */
2648 LPCWSTR keystr
; /* name of the actual registry key / policy */
2649 } POLICYDATA
, *LPPOLICYDATA
;
2651 #define SHELL_NO_POLICY 0xffffffff
2653 /* default shell policy registry key */
2654 static const WCHAR strRegistryPolicyW
[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o',
2655 's','o','f','t','\\','W','i','n','d','o','w','s','\\',
2656 'C','u','r','r','e','n','t','V','e','r','s','i','o','n',
2657 '\\','P','o','l','i','c','i','e','s',0};
2659 /*************************************************************************
2662 * Retrieve a policy value from the registry.
2665 * lpSubKey [I] registry key name
2666 * lpSubName [I] subname of registry key
2667 * lpValue [I] value name of registry value
2670 * the value associated with the registry key or 0 if not found
2672 DWORD WINAPI
SHGetRestriction(LPCWSTR lpSubKey
, LPCWSTR lpSubName
, LPCWSTR lpValue
)
2674 DWORD retval
, datsize
= sizeof(retval
);
2678 lpSubKey
= strRegistryPolicyW
;
2680 retval
= RegOpenKeyW(HKEY_LOCAL_MACHINE
, lpSubKey
, &hKey
);
2681 if (retval
!= ERROR_SUCCESS
)
2682 retval
= RegOpenKeyW(HKEY_CURRENT_USER
, lpSubKey
, &hKey
);
2683 if (retval
!= ERROR_SUCCESS
)
2686 SHGetValueW(hKey
, lpSubName
, lpValue
, NULL
, &retval
, &datsize
);
2691 /*************************************************************************
2694 * Helper function to retrieve the possibly cached value for a specific policy
2697 * policy [I] The policy to look for
2698 * initial [I] Main registry key to open, if NULL use default
2699 * polTable [I] Table of known policies, 0 terminated
2700 * polArr [I] Cache array of policy values
2703 * The retrieved policy value or 0 if not successful
2706 * This function is used by the native SHRestricted function to search for the
2707 * policy and cache it once retrieved. The current Wine implementation uses a
2708 * different POLICYDATA structure and implements a similar algorithm adapted to
2711 DWORD WINAPI
SHRestrictionLookup(
2714 LPPOLICYDATA polTable
,
2717 TRACE("(0x%08x %s %p %p)\n", policy
, debugstr_w(initial
), polTable
, polArr
);
2719 if (!polTable
|| !polArr
)
2722 for (;polTable
->policy
; polTable
++, polArr
++)
2724 if (policy
== polTable
->policy
)
2726 /* we have a known policy */
2728 /* check if this policy has been cached */
2729 if (*polArr
== SHELL_NO_POLICY
)
2730 *polArr
= SHGetRestriction(initial
, polTable
->appstr
, polTable
->keystr
);
2734 /* we don't know this policy, return 0 */
2735 TRACE("unknown policy: (%08x)\n", policy
);
2739 /*************************************************************************
2742 * Get an interface from an object.
2745 * Success: S_OK. ppv contains the requested interface.
2746 * Failure: An HRESULT error code.
2749 * This QueryInterface asks the inner object for an interface. In case
2750 * of aggregation this request would be forwarded by the inner to the
2751 * outer object. This function asks the inner object directly for the
2752 * interface circumventing the forwarding to the outer object.
2754 HRESULT WINAPI
SHWeakQueryInterface(
2755 IUnknown
* pUnk
, /* [in] Outer object */
2756 IUnknown
* pInner
, /* [in] Inner object */
2757 IID
* riid
, /* [in] Interface GUID to query for */
2758 LPVOID
* ppv
) /* [out] Destination for queried interface */
2760 HRESULT hret
= E_NOINTERFACE
;
2761 TRACE("(pUnk=%p pInner=%p\n\tIID: %s %p)\n",pUnk
,pInner
,debugstr_guid(riid
), ppv
);
2764 if(pUnk
&& pInner
) {
2765 hret
= IUnknown_QueryInterface(pInner
, riid
, ppv
);
2766 if (SUCCEEDED(hret
)) IUnknown_Release(pUnk
);
2768 TRACE("-- 0x%08x\n", hret
);
2772 /*************************************************************************
2775 * Move a reference from one interface to another.
2778 * lpDest [O] Destination to receive the reference
2779 * lppUnknown [O] Source to give up the reference to lpDest
2784 VOID WINAPI
SHWeakReleaseInterface(IUnknown
*lpDest
, IUnknown
**lppUnknown
)
2786 TRACE("(%p,%p)\n", lpDest
, lppUnknown
);
2791 IUnknown_AddRef(lpDest
);
2792 IUnknown_AtomicRelease(lppUnknown
); /* Release existing interface */
2796 /*************************************************************************
2799 * Convert an ASCII string of a CLSID into a CLSID.
2802 * idstr [I] String representing a CLSID in registry format
2803 * id [O] Destination for the converted CLSID
2806 * Success: TRUE. id contains the converted CLSID.
2809 BOOL WINAPI
GUIDFromStringA(LPCSTR idstr
, CLSID
*id
)
2812 MultiByteToWideChar(CP_ACP
, 0, idstr
, -1, wClsid
, sizeof(wClsid
)/sizeof(WCHAR
));
2813 return SUCCEEDED(CLSIDFromString(wClsid
, id
));
2816 /*************************************************************************
2819 * Unicode version of GUIDFromStringA.
2821 BOOL WINAPI
GUIDFromStringW(LPCWSTR idstr
, CLSID
*id
)
2823 return SUCCEEDED(CLSIDFromString((LPOLESTR
)idstr
, id
));
2826 /*************************************************************************
2829 * Determine if the browser is integrated into the shell, and set a registry
2836 * 1, If the browser is not integrated.
2837 * 2, If the browser is integrated.
2840 * The key "HKLM\Software\Microsoft\Internet Explorer\IntegratedBrowser" is
2841 * either set to TRUE, or removed depending on whether the browser is deemed
2844 DWORD WINAPI
WhichPlatform(void)
2846 static const char szIntegratedBrowser
[] = "IntegratedBrowser";
2847 static DWORD dwState
= 0;
2849 DWORD dwRet
, dwData
, dwSize
;
2855 /* If shell32 exports DllGetVersion(), the browser is integrated */
2857 hshell32
= LoadLibraryA("shell32.dll");
2860 FARPROC pDllGetVersion
;
2861 pDllGetVersion
= GetProcAddress(hshell32
, "DllGetVersion");
2862 dwState
= pDllGetVersion
? 2 : 1;
2863 FreeLibrary(hshell32
);
2866 /* Set or delete the key accordingly */
2867 dwRet
= RegOpenKeyExA(HKEY_LOCAL_MACHINE
,
2868 "Software\\Microsoft\\Internet Explorer", 0,
2869 KEY_ALL_ACCESS
, &hKey
);
2872 dwRet
= RegQueryValueExA(hKey
, szIntegratedBrowser
, 0, 0,
2873 (LPBYTE
)&dwData
, &dwSize
);
2875 if (!dwRet
&& dwState
== 1)
2877 /* Value exists but browser is not integrated */
2878 RegDeleteValueA(hKey
, szIntegratedBrowser
);
2880 else if (dwRet
&& dwState
== 2)
2882 /* Browser is integrated but value does not exist */
2884 RegSetValueExA(hKey
, szIntegratedBrowser
, 0, REG_DWORD
,
2885 (LPBYTE
)&dwData
, sizeof(dwData
));
2892 /*************************************************************************
2895 * Unicode version of SHCreateWorkerWindowA.
2897 HWND WINAPI
SHCreateWorkerWindowW(LONG wndProc
, HWND hWndParent
, DWORD dwExStyle
,
2898 DWORD dwStyle
, HMENU hMenu
, LONG z
)
2900 static const WCHAR szClass
[] = { 'W', 'o', 'r', 'k', 'e', 'r', 'W', '\0' };
2904 TRACE("(0x%08x,%p,0x%08x,0x%08x,%p,0x%08x)\n",
2905 wndProc
, hWndParent
, dwExStyle
, dwStyle
, hMenu
, z
);
2907 /* If our OS is natively ASCII, use the ASCII version */
2908 if (!(GetVersion() & 0x80000000)) /* NT */
2909 return SHCreateWorkerWindowA(wndProc
, hWndParent
, dwExStyle
, dwStyle
, hMenu
, z
);
2911 /* Create Window class */
2913 wc
.lpfnWndProc
= DefWindowProcW
;
2916 wc
.hInstance
= shlwapi_hInstance
;
2918 wc
.hCursor
= LoadCursorW(NULL
, (LPWSTR
)IDC_ARROW
);
2919 wc
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
2920 wc
.lpszMenuName
= NULL
;
2921 wc
.lpszClassName
= szClass
;
2923 SHRegisterClassW(&wc
); /* Register class */
2925 /* FIXME: Set extra bits in dwExStyle */
2927 hWnd
= CreateWindowExW(dwExStyle
, szClass
, 0, dwStyle
, 0, 0, 0, 0,
2928 hWndParent
, hMenu
, shlwapi_hInstance
, 0);
2931 SetWindowLongPtrW(hWnd
, DWLP_MSGRESULT
, z
);
2934 SetWindowLongPtrW(hWnd
, GWLP_WNDPROC
, wndProc
);
2939 /*************************************************************************
2942 * Get and show a context menu from a shell folder.
2945 * hWnd [I] Window displaying the shell folder
2946 * lpFolder [I] IShellFolder interface
2947 * lpApidl [I] Id for the particular folder desired
2951 * Failure: An HRESULT error code indicating the error.
2953 HRESULT WINAPI
SHInvokeDefaultCommand(HWND hWnd
, IShellFolder
* lpFolder
, LPCITEMIDLIST lpApidl
)
2955 return SHInvokeCommand(hWnd
, lpFolder
, lpApidl
, FALSE
);
2958 /*************************************************************************
2961 * _SHPackDispParamsV
2963 HRESULT WINAPI
SHPackDispParamsV(DISPPARAMS
*params
, VARIANTARG
*args
, UINT cnt
, __ms_va_list valist
)
2967 TRACE("(%p %p %u ...)\n", params
, args
, cnt
);
2969 params
->rgvarg
= args
;
2970 params
->rgdispidNamedArgs
= NULL
;
2971 params
->cArgs
= cnt
;
2972 params
->cNamedArgs
= 0;
2976 while(iter
-- > args
) {
2977 V_VT(iter
) = va_arg(valist
, enum VARENUM
);
2979 TRACE("vt=%d\n", V_VT(iter
));
2981 if(V_VT(iter
) & VT_BYREF
) {
2982 V_BYREF(iter
) = va_arg(valist
, LPVOID
);
2984 switch(V_VT(iter
)) {
2986 V_I4(iter
) = va_arg(valist
, LONG
);
2989 V_BSTR(iter
) = va_arg(valist
, BSTR
);
2992 V_DISPATCH(iter
) = va_arg(valist
, IDispatch
*);
2995 V_BOOL(iter
) = va_arg(valist
, int);
2998 V_UNKNOWN(iter
) = va_arg(valist
, IUnknown
*);
3002 V_I4(iter
) = va_arg(valist
, LONG
);
3010 /*************************************************************************
3015 HRESULT WINAPIV
SHPackDispParams(DISPPARAMS
*params
, VARIANTARG
*args
, UINT cnt
, ...)
3017 __ms_va_list valist
;
3020 __ms_va_start(valist
, cnt
);
3021 hres
= SHPackDispParamsV(params
, args
, cnt
, valist
);
3022 __ms_va_end(valist
);
3026 /*************************************************************************
3027 * SHLWAPI_InvokeByIID
3029 * This helper function calls IDispatch::Invoke for each sink
3030 * which implements given iid or IDispatch.
3033 static HRESULT
SHLWAPI_InvokeByIID(
3034 IConnectionPoint
* iCP
,
3037 DISPPARAMS
* dispParams
)
3039 IEnumConnections
*enumerator
;
3041 static DISPPARAMS empty
= {NULL
, NULL
, 0, 0};
3042 DISPPARAMS
* params
= dispParams
;
3044 HRESULT result
= IConnectionPoint_EnumConnections(iCP
, &enumerator
);
3048 /* Invoke is never happening with an NULL dispParams */
3052 while(IEnumConnections_Next(enumerator
, 1, &rgcd
, NULL
)==S_OK
)
3054 IDispatch
*dispIface
;
3055 if ((iid
&& SUCCEEDED(IUnknown_QueryInterface(rgcd
.pUnk
, iid
, (LPVOID
*)&dispIface
))) ||
3056 SUCCEEDED(IUnknown_QueryInterface(rgcd
.pUnk
, &IID_IDispatch
, (LPVOID
*)&dispIface
)))
3058 IDispatch_Invoke(dispIface
, dispId
, &IID_NULL
, 0, DISPATCH_METHOD
, params
, NULL
, NULL
, NULL
);
3059 IDispatch_Release(dispIface
);
3061 IUnknown_Release(rgcd
.pUnk
);
3064 IEnumConnections_Release(enumerator
);
3069 /*************************************************************************
3070 * IConnectionPoint_InvokeWithCancel [SHLWAPI.283]
3072 HRESULT WINAPI
IConnectionPoint_InvokeWithCancel( IConnectionPoint
* iCP
,
3073 DISPID dispId
, DISPPARAMS
* dispParams
,
3074 DWORD unknown1
, DWORD unknown2
)
3079 FIXME("(%p)->(0x%x %p %x %x) partial stub\n", iCP
, dispId
, dispParams
, unknown1
, unknown2
);
3081 result
= IConnectionPoint_GetConnectionInterface(iCP
, &iid
);
3082 if (SUCCEEDED(result
))
3083 result
= SHLWAPI_InvokeByIID(iCP
, &iid
, dispId
, dispParams
);
3085 result
= SHLWAPI_InvokeByIID(iCP
, NULL
, dispId
, dispParams
);
3091 /*************************************************************************
3094 * IConnectionPoint_SimpleInvoke
3096 HRESULT WINAPI
IConnectionPoint_SimpleInvoke(
3097 IConnectionPoint
* iCP
,
3099 DISPPARAMS
* dispParams
)
3104 TRACE("(%p)->(0x%x %p)\n",iCP
,dispId
,dispParams
);
3106 result
= IConnectionPoint_GetConnectionInterface(iCP
, &iid
);
3107 if (SUCCEEDED(result
))
3108 result
= SHLWAPI_InvokeByIID(iCP
, &iid
, dispId
, dispParams
);
3110 result
= SHLWAPI_InvokeByIID(iCP
, NULL
, dispId
, dispParams
);
3115 /*************************************************************************
3118 * Notify an IConnectionPoint object of changes.
3121 * lpCP [I] Object to notify
3126 * Failure: E_NOINTERFACE, if lpCP is NULL or does not support the
3127 * IConnectionPoint interface.
3129 HRESULT WINAPI
IConnectionPoint_OnChanged(IConnectionPoint
* lpCP
, DISPID dispID
)
3131 IEnumConnections
*lpEnum
;
3132 HRESULT hRet
= E_NOINTERFACE
;
3134 TRACE("(%p,0x%8X)\n", lpCP
, dispID
);
3136 /* Get an enumerator for the connections */
3138 hRet
= IConnectionPoint_EnumConnections(lpCP
, &lpEnum
);
3140 if (SUCCEEDED(hRet
))
3142 IPropertyNotifySink
*lpSink
;
3143 CONNECTDATA connData
;
3146 /* Call OnChanged() for every notify sink in the connection point */
3147 while (IEnumConnections_Next(lpEnum
, 1, &connData
, &ulFetched
) == S_OK
)
3149 if (SUCCEEDED(IUnknown_QueryInterface(connData
.pUnk
, &IID_IPropertyNotifySink
, (void**)&lpSink
)) &&
3152 IPropertyNotifySink_OnChanged(lpSink
, dispID
);
3153 IPropertyNotifySink_Release(lpSink
);
3155 IUnknown_Release(connData
.pUnk
);
3158 IEnumConnections_Release(lpEnum
);
3163 /*************************************************************************
3166 * IUnknown_CPContainerInvokeParam
3168 HRESULT WINAPIV
IUnknown_CPContainerInvokeParam(
3169 IUnknown
*container
,
3176 IConnectionPoint
*iCP
;
3177 IConnectionPointContainer
*iCPC
;
3178 DISPPARAMS dispParams
= {buffer
, NULL
, cParams
, 0};
3179 __ms_va_list valist
;
3182 return E_NOINTERFACE
;
3184 result
= IUnknown_QueryInterface(container
, &IID_IConnectionPointContainer
,(LPVOID
*) &iCPC
);
3188 result
= IConnectionPointContainer_FindConnectionPoint(iCPC
, riid
, &iCP
);
3189 IConnectionPointContainer_Release(iCPC
);
3193 __ms_va_start(valist
, cParams
);
3194 SHPackDispParamsV(&dispParams
, buffer
, cParams
, valist
);
3195 __ms_va_end(valist
);
3197 result
= SHLWAPI_InvokeByIID(iCP
, riid
, dispId
, &dispParams
);
3198 IConnectionPoint_Release(iCP
);
3203 /*************************************************************************
3206 * Notify an IConnectionPointContainer object of changes.
3209 * lpUnknown [I] Object to notify
3214 * Failure: E_NOINTERFACE, if lpUnknown is NULL or does not support the
3215 * IConnectionPointContainer interface.
3217 HRESULT WINAPI
IUnknown_CPContainerOnChanged(IUnknown
*lpUnknown
, DISPID dispID
)
3219 IConnectionPointContainer
* lpCPC
= NULL
;
3220 HRESULT hRet
= E_NOINTERFACE
;
3222 TRACE("(%p,0x%8X)\n", lpUnknown
, dispID
);
3225 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IConnectionPointContainer
, (void**)&lpCPC
);
3227 if (SUCCEEDED(hRet
))
3229 IConnectionPoint
* lpCP
;
3231 hRet
= IConnectionPointContainer_FindConnectionPoint(lpCPC
, &IID_IPropertyNotifySink
, &lpCP
);
3232 IConnectionPointContainer_Release(lpCPC
);
3234 hRet
= IConnectionPoint_OnChanged(lpCP
, dispID
);
3235 IConnectionPoint_Release(lpCP
);
3240 /*************************************************************************
3245 BOOL WINAPI
PlaySoundWrapW(LPCWSTR pszSound
, HMODULE hmod
, DWORD fdwSound
)
3247 return PlaySoundW(pszSound
, hmod
, fdwSound
);
3250 /*************************************************************************
3253 BOOL WINAPI
SHGetIniStringW(LPCWSTR str1
, LPCWSTR str2
, LPWSTR pStr
, DWORD some_len
, LPCWSTR lpStr2
)
3255 FIXME("(%s,%s,%p,%08x,%s): stub!\n", debugstr_w(str1
), debugstr_w(str2
),
3256 pStr
, some_len
, debugstr_w(lpStr2
));
3260 /*************************************************************************
3263 * Called by ICQ2000b install via SHDOCVW:
3264 * str1: "InternetShortcut"
3265 * x: some unknown pointer
3266 * str2: "http://free.aol.com/tryaolfree/index.adp?139269"
3267 * str3: "C:\\WINDOWS\\Desktop.new2\\Free AOL & Unlimited Internet.url"
3269 * In short: this one maybe creates a desktop link :-)
3271 BOOL WINAPI
SHSetIniStringW(LPWSTR str1
, LPVOID x
, LPWSTR str2
, LPWSTR str3
)
3273 FIXME("(%s, %p, %s, %s), stub.\n", debugstr_w(str1
), x
, debugstr_w(str2
), debugstr_w(str3
));
3277 /*************************************************************************
3280 * See SHGetFileInfoW.
3282 DWORD WINAPI
SHGetFileInfoWrapW(LPCWSTR path
, DWORD dwFileAttributes
,
3283 SHFILEINFOW
*psfi
, UINT sizeofpsfi
, UINT flags
)
3285 return SHGetFileInfoW(path
, dwFileAttributes
, psfi
, sizeofpsfi
, flags
);
3288 /*************************************************************************
3291 * See DragQueryFileW.
3293 UINT WINAPI
DragQueryFileWrapW(HDROP hDrop
, UINT lFile
, LPWSTR lpszFile
, UINT lLength
)
3295 return DragQueryFileW(hDrop
, lFile
, lpszFile
, lLength
);
3298 /*************************************************************************
3301 * See SHBrowseForFolderW.
3303 LPITEMIDLIST WINAPI
SHBrowseForFolderWrapW(LPBROWSEINFOW lpBi
)
3305 return SHBrowseForFolderW(lpBi
);
3308 /*************************************************************************
3311 * See SHGetPathFromIDListW.
3313 BOOL WINAPI
SHGetPathFromIDListWrapW(LPCITEMIDLIST pidl
,LPWSTR pszPath
)
3315 return SHGetPathFromIDListW(pidl
, pszPath
);
3318 /*************************************************************************
3321 * See ShellExecuteExW.
3323 BOOL WINAPI
ShellExecuteExWrapW(LPSHELLEXECUTEINFOW lpExecInfo
)
3325 return ShellExecuteExW(lpExecInfo
);
3328 /*************************************************************************
3331 * See SHFileOperationW.
3333 INT WINAPI
SHFileOperationWrapW(LPSHFILEOPSTRUCTW lpFileOp
)
3335 return SHFileOperationW(lpFileOp
);
3338 /*************************************************************************
3342 PVOID WINAPI
SHInterlockedCompareExchange( PVOID
*dest
, PVOID xchg
, PVOID compare
)
3344 return InterlockedCompareExchangePointer( dest
, xchg
, compare
);
3347 /*************************************************************************
3350 * See GetFileVersionInfoSizeW.
3352 DWORD WINAPI
GetFileVersionInfoSizeWrapW( LPCWSTR filename
, LPDWORD handle
)
3354 return GetFileVersionInfoSizeW( filename
, handle
);
3357 /*************************************************************************
3360 * See GetFileVersionInfoW.
3362 BOOL WINAPI
GetFileVersionInfoWrapW( LPCWSTR filename
, DWORD handle
,
3363 DWORD datasize
, LPVOID data
)
3365 return GetFileVersionInfoW( filename
, handle
, datasize
, data
);
3368 /*************************************************************************
3371 * See VerQueryValueW.
3373 WORD WINAPI
VerQueryValueWrapW( LPVOID pBlock
, LPCWSTR lpSubBlock
,
3374 LPVOID
*lplpBuffer
, UINT
*puLen
)
3376 return VerQueryValueW( pBlock
, lpSubBlock
, lplpBuffer
, puLen
);
3379 #define IsIface(type) SUCCEEDED((hRet = IUnknown_QueryInterface(lpUnknown, &IID_##type, (void**)&lpObj)))
3380 #define IShellBrowser_EnableModeless IShellBrowser_EnableModelessSB
3381 #define EnableModeless(type) type##_EnableModeless((type*)lpObj, bModeless)
3383 /*************************************************************************
3386 * Change the modality of a shell object.
3389 * lpUnknown [I] Object to make modeless
3390 * bModeless [I] TRUE=Make modeless, FALSE=Make modal
3393 * Success: S_OK. The modality lpUnknown is changed.
3394 * Failure: An HRESULT error code indicating the error.
3397 * lpUnknown must support the IOleInPlaceFrame interface, the
3398 * IInternetSecurityMgrSite interface, the IShellBrowser interface
3399 * the IDocHostUIHandler interface, or the IOleInPlaceActiveObject interface,
3400 * or this call will fail.
3402 HRESULT WINAPI
IUnknown_EnableModeless(IUnknown
*lpUnknown
, BOOL bModeless
)
3407 TRACE("(%p,%d)\n", lpUnknown
, bModeless
);
3412 if (IsIface(IOleInPlaceActiveObject
))
3413 EnableModeless(IOleInPlaceActiveObject
);
3414 else if (IsIface(IOleInPlaceFrame
))
3415 EnableModeless(IOleInPlaceFrame
);
3416 else if (IsIface(IShellBrowser
))
3417 EnableModeless(IShellBrowser
);
3418 else if (IsIface(IInternetSecurityMgrSite
))
3419 EnableModeless(IInternetSecurityMgrSite
);
3420 else if (IsIface(IDocHostUIHandler
))
3421 EnableModeless(IDocHostUIHandler
);
3425 IUnknown_Release(lpObj
);
3429 /*************************************************************************
3432 * See SHGetNewLinkInfoW.
3434 BOOL WINAPI
SHGetNewLinkInfoWrapW(LPCWSTR pszLinkTo
, LPCWSTR pszDir
, LPWSTR pszName
,
3435 BOOL
*pfMustCopy
, UINT uFlags
)
3437 return SHGetNewLinkInfoW(pszLinkTo
, pszDir
, pszName
, pfMustCopy
, uFlags
);
3440 /*************************************************************************
3443 * See SHDefExtractIconW.
3445 UINT WINAPI
SHDefExtractIconWrapW(LPCWSTR pszIconFile
, int iIndex
, UINT uFlags
, HICON
* phiconLarge
,
3446 HICON
* phiconSmall
, UINT nIconSize
)
3448 return SHDefExtractIconW(pszIconFile
, iIndex
, uFlags
, phiconLarge
, phiconSmall
, nIconSize
);
3451 /*************************************************************************
3454 * Get and show a context menu from a shell folder.
3457 * hWnd [I] Window displaying the shell folder
3458 * lpFolder [I] IShellFolder interface
3459 * lpApidl [I] Id for the particular folder desired
3460 * bInvokeDefault [I] Whether to invoke the default menu item
3463 * Success: S_OK. If bInvokeDefault is TRUE, the default menu action was
3465 * Failure: An HRESULT error code indicating the error.
3467 HRESULT WINAPI
SHInvokeCommand(HWND hWnd
, IShellFolder
* lpFolder
, LPCITEMIDLIST lpApidl
, BOOL bInvokeDefault
)
3469 IContextMenu
*iContext
;
3470 HRESULT hRet
= E_FAIL
;
3472 TRACE("(%p,%p,%p,%d)\n", hWnd
, lpFolder
, lpApidl
, bInvokeDefault
);
3477 /* Get the context menu from the shell folder */
3478 hRet
= IShellFolder_GetUIObjectOf(lpFolder
, hWnd
, 1, &lpApidl
,
3479 &IID_IContextMenu
, 0, (void**)&iContext
);
3480 if (SUCCEEDED(hRet
))
3483 if ((hMenu
= CreatePopupMenu()))
3486 DWORD dwDefaultId
= 0;
3488 /* Add the context menu entries to the popup */
3489 hQuery
= IContextMenu_QueryContextMenu(iContext
, hMenu
, 0, 1, 0x7FFF,
3490 bInvokeDefault
? CMF_NORMAL
: CMF_DEFAULTONLY
);
3492 if (SUCCEEDED(hQuery
))
3494 if (bInvokeDefault
&&
3495 (dwDefaultId
= GetMenuDefaultItem(hMenu
, 0, 0)) != 0xFFFFFFFF)
3497 CMINVOKECOMMANDINFO cmIci
;
3498 /* Invoke the default item */
3499 memset(&cmIci
,0,sizeof(cmIci
));
3500 cmIci
.cbSize
= sizeof(cmIci
);
3501 cmIci
.fMask
= CMIC_MASK_ASYNCOK
;
3503 cmIci
.lpVerb
= MAKEINTRESOURCEA(dwDefaultId
);
3504 cmIci
.nShow
= SW_SCROLLCHILDREN
;
3506 hRet
= IContextMenu_InvokeCommand(iContext
, &cmIci
);
3511 IContextMenu_Release(iContext
);
3516 /*************************************************************************
3521 HICON WINAPI
ExtractIconWrapW(HINSTANCE hInstance
, LPCWSTR lpszExeFileName
,
3524 return ExtractIconW(hInstance
, lpszExeFileName
, nIconIndex
);
3527 /*************************************************************************
3530 * Load a library from the directory of a particular process.
3533 * new_mod [I] Library name
3534 * inst_hwnd [I] Module whose directory is to be used
3535 * dwCrossCodePage [I] Should be FALSE (currently ignored)
3538 * Success: A handle to the loaded module
3539 * Failure: A NULL handle.
3541 HMODULE WINAPI
MLLoadLibraryA(LPCSTR new_mod
, HMODULE inst_hwnd
, DWORD dwCrossCodePage
)
3543 /* FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for
3545 * FIXME: Native shows calls to:
3546 * SHRegGetUSValue for "Software\Microsoft\Internet Explorer\International"
3548 * RegOpenKeyExA for "HKLM\Software\Microsoft\Internet Explorer"
3549 * RegQueryValueExA for "LPKInstalled"
3551 * RegOpenKeyExA for "HKCU\Software\Microsoft\Internet Explorer\International"
3552 * RegQueryValueExA for "ResourceLocale"
3554 * RegOpenKeyExA for "HKLM\Software\Microsoft\Active Setup\Installed Components\{guid}"
3555 * RegQueryValueExA for "Locale"
3557 * and then tests the Locale ("en" for me).
3559 * after the code then a DPA_Create (first time) and DPA_InsertPtr are done.
3561 CHAR mod_path
[2*MAX_PATH
];
3565 FIXME("(%s,%p,%d) semi-stub!\n", debugstr_a(new_mod
), inst_hwnd
, dwCrossCodePage
);
3566 len
= GetModuleFileNameA(inst_hwnd
, mod_path
, sizeof(mod_path
));
3567 if (!len
|| len
>= sizeof(mod_path
)) return NULL
;
3569 ptr
= strrchr(mod_path
, '\\');
3571 strcpy(ptr
+1, new_mod
);
3572 TRACE("loading %s\n", debugstr_a(mod_path
));
3573 return LoadLibraryA(mod_path
);
3578 /*************************************************************************
3581 * Unicode version of MLLoadLibraryA.
3583 HMODULE WINAPI
MLLoadLibraryW(LPCWSTR new_mod
, HMODULE inst_hwnd
, DWORD dwCrossCodePage
)
3585 WCHAR mod_path
[2*MAX_PATH
];
3589 FIXME("(%s,%p,%d) semi-stub!\n", debugstr_w(new_mod
), inst_hwnd
, dwCrossCodePage
);
3590 len
= GetModuleFileNameW(inst_hwnd
, mod_path
, sizeof(mod_path
) / sizeof(WCHAR
));
3591 if (!len
|| len
>= sizeof(mod_path
) / sizeof(WCHAR
)) return NULL
;
3593 ptr
= strrchrW(mod_path
, '\\');
3595 strcpyW(ptr
+1, new_mod
);
3596 TRACE("loading %s\n", debugstr_w(mod_path
));
3597 return LoadLibraryW(mod_path
);
3602 /*************************************************************************
3603 * ColorAdjustLuma [SHLWAPI.@]
3605 * Adjust the luminosity of a color
3608 * cRGB [I] RGB value to convert
3609 * dwLuma [I] Luma adjustment
3610 * bUnknown [I] Unknown
3613 * The adjusted RGB color.
3615 COLORREF WINAPI
ColorAdjustLuma(COLORREF cRGB
, int dwLuma
, BOOL bUnknown
)
3617 TRACE("(0x%8x,%d,%d)\n", cRGB
, dwLuma
, bUnknown
);
3623 ColorRGBToHLS(cRGB
, &wH
, &wL
, &wS
);
3625 FIXME("Ignoring luma adjustment\n");
3627 /* FIXME: The adjustment is not linear */
3629 cRGB
= ColorHLSToRGB(wH
, wL
, wS
);
3634 /*************************************************************************
3637 * See GetSaveFileNameW.
3639 BOOL WINAPI
GetSaveFileNameWrapW(LPOPENFILENAMEW ofn
)
3641 return GetSaveFileNameW(ofn
);
3644 /*************************************************************************
3647 * See WNetRestoreConnectionW.
3649 DWORD WINAPI
WNetRestoreConnectionWrapW(HWND hwndOwner
, LPWSTR lpszDevice
)
3651 return WNetRestoreConnectionW(hwndOwner
, lpszDevice
);
3654 /*************************************************************************
3657 * See WNetGetLastErrorW.
3659 DWORD WINAPI
WNetGetLastErrorWrapW(LPDWORD lpError
, LPWSTR lpErrorBuf
, DWORD nErrorBufSize
,
3660 LPWSTR lpNameBuf
, DWORD nNameBufSize
)
3662 return WNetGetLastErrorW(lpError
, lpErrorBuf
, nErrorBufSize
, lpNameBuf
, nNameBufSize
);
3665 /*************************************************************************
3668 * See PageSetupDlgW.
3670 BOOL WINAPI
PageSetupDlgWrapW(LPPAGESETUPDLGW pagedlg
)
3672 return PageSetupDlgW(pagedlg
);
3675 /*************************************************************************
3680 BOOL WINAPI
PrintDlgWrapW(LPPRINTDLGW printdlg
)
3682 return PrintDlgW(printdlg
);
3685 /*************************************************************************
3688 * See GetOpenFileNameW.
3690 BOOL WINAPI
GetOpenFileNameWrapW(LPOPENFILENAMEW ofn
)
3692 return GetOpenFileNameW(ofn
);
3695 /*************************************************************************
3698 HRESULT WINAPI
SHIShellFolder_EnumObjects(LPSHELLFOLDER lpFolder
, HWND hwnd
, SHCONTF flags
, IEnumIDList
**ppenum
)
3703 hr
= IShellFolder_QueryInterface(lpFolder
, &IID_IPersist
, (LPVOID
)&persist
);
3707 hr
= IPersist_GetClassID(persist
, &clsid
);
3710 if(IsEqualCLSID(&clsid
, &CLSID_ShellFSFolder
))
3711 hr
= IShellFolder_EnumObjects(lpFolder
, hwnd
, flags
, ppenum
);
3715 IPersist_Release(persist
);
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 /*************************************************************************
3812 * Function seems to do FreeLibrary plus other things.
3814 * FIXME native shows the following calls:
3815 * RtlEnterCriticalSection
3817 * GetProcAddress(Comctl32??, 150L)
3819 * RtlLeaveCriticalSection
3820 * followed by the FreeLibrary.
3821 * The above code may be related to .377 above.
3823 BOOL WINAPI
MLFreeLibrary(HMODULE hModule
)
3825 FIXME("(%p) semi-stub\n", hModule
);
3826 return FreeLibrary(hModule
);
3829 /*************************************************************************
3832 BOOL WINAPI
SHFlushSFCacheWrap(void) {
3837 /*************************************************************************
3839 * FIXME I have no idea what this function does or what its arguments are.
3841 BOOL WINAPI
MLIsMLHInstance(HINSTANCE hInst
)
3843 FIXME("(%p) stub\n", hInst
);
3848 /*************************************************************************
3851 DWORD WINAPI
MLSetMLHInstance(HINSTANCE hInst
, HANDLE hHeap
)
3853 FIXME("(%p,%p) stub\n", hInst
, hHeap
);
3854 return E_FAIL
; /* This is what is used if shlwapi not loaded */
3857 /*************************************************************************
3860 DWORD WINAPI
MLClearMLHInstance(DWORD x
)
3862 FIXME("(0x%08x)stub\n", x
);
3866 /*************************************************************************
3869 * See SHSendMessageBroadcastW
3872 DWORD WINAPI
SHSendMessageBroadcastA(UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3874 return SendMessageTimeoutA(HWND_BROADCAST
, uMsg
, wParam
, lParam
,
3875 SMTO_ABORTIFHUNG
, 2000, NULL
);
3878 /*************************************************************************
3881 * A wrapper for sending Broadcast Messages to all top level Windows
3884 DWORD WINAPI
SHSendMessageBroadcastW(UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3886 return SendMessageTimeoutW(HWND_BROADCAST
, uMsg
, wParam
, lParam
,
3887 SMTO_ABORTIFHUNG
, 2000, NULL
);
3890 /*************************************************************************
3893 * Convert a Unicode string CLSID into a CLSID.
3896 * idstr [I] string containing a CLSID in text form
3897 * id [O] CLSID extracted from the string
3900 * S_OK on success or E_INVALIDARG on failure
3902 HRESULT WINAPI
CLSIDFromStringWrap(LPCWSTR idstr
, CLSID
*id
)
3904 return CLSIDFromString((LPOLESTR
)idstr
, id
);
3907 /*************************************************************************
3910 * Determine if the OS supports a given feature.
3913 * dwFeature [I] Feature requested (undocumented)
3916 * TRUE If the feature is available.
3917 * FALSE If the feature is not available.
3919 BOOL WINAPI
IsOS(DWORD feature
)
3921 OSVERSIONINFOA osvi
;
3922 DWORD platform
, majorv
, minorv
;
3924 osvi
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFOA
);
3925 if(!GetVersionExA(&osvi
)) {
3926 ERR("GetVersionEx failed\n");
3930 majorv
= osvi
.dwMajorVersion
;
3931 minorv
= osvi
.dwMinorVersion
;
3932 platform
= osvi
.dwPlatformId
;
3934 #define ISOS_RETURN(x) \
3935 TRACE("(0x%x) ret=%d\n",feature,(x)); \
3939 case OS_WIN32SORGREATER
:
3940 ISOS_RETURN(platform
== VER_PLATFORM_WIN32s
3941 || platform
== VER_PLATFORM_WIN32_WINDOWS
)
3943 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3944 case OS_WIN95ORGREATER
:
3945 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
)
3946 case OS_NT4ORGREATER
:
3947 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 4)
3948 case OS_WIN2000ORGREATER_ALT
:
3949 case OS_WIN2000ORGREATER
:
3950 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5)
3951 case OS_WIN98ORGREATER
:
3952 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
&& minorv
>= 10)
3954 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
&& minorv
== 10)
3956 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5)
3957 case OS_WIN2000SERVER
:
3958 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& (minorv
== 0 || minorv
== 1))
3959 case OS_WIN2000ADVSERVER
:
3960 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& (minorv
== 0 || minorv
== 1))
3961 case OS_WIN2000DATACENTER
:
3962 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& (minorv
== 0 || minorv
== 1))
3963 case OS_WIN2000TERMINAL
:
3964 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& (minorv
== 0 || minorv
== 1))
3966 FIXME("(OS_EMBEDDED) What should we return here?\n");
3968 case OS_TERMINALCLIENT
:
3969 FIXME("(OS_TERMINALCLIENT) What should we return here?\n");
3971 case OS_TERMINALREMOTEADMIN
:
3972 FIXME("(OS_TERMINALREMOTEADMIN) What should we return here?\n");
3975 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
&& minorv
== 0)
3976 case OS_MEORGREATER
:
3977 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
&& minorv
>= 90)
3978 case OS_XPORGREATER
:
3979 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5 && minorv
>= 1)
3981 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5 && minorv
>= 1)
3982 case OS_PROFESSIONAL
:
3983 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3985 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3987 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5)
3989 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3990 case OS_TERMINALSERVER
:
3991 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3992 case OS_PERSONALTERMINALSERVER
:
3993 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& minorv
>= 1 && majorv
>= 5)
3994 case OS_FASTUSERSWITCHING
:
3995 FIXME("(OS_FASTUSERSWITCHING) What should we return here?\n");
3997 case OS_WELCOMELOGONUI
:
3998 FIXME("(OS_WELCOMELOGONUI) What should we return here?\n");
4000 case OS_DOMAINMEMBER
:
4001 FIXME("(OS_DOMAINMEMBER) What should we return here?\n");
4004 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
4006 FIXME("(OS_WOW6432) Should we check this?\n");
4009 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
4010 case OS_SMALLBUSINESSSERVER
:
4011 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
4013 FIXME("(OS_TABLEPC) What should we return here?\n");
4015 case OS_SERVERADMINUI
:
4016 FIXME("(OS_SERVERADMINUI) What should we return here?\n");
4018 case OS_MEDIACENTER
:
4019 FIXME("(OS_MEDIACENTER) What should we return here?\n");
4022 FIXME("(OS_APPLIANCE) What should we return here?\n");
4024 case 0x25: /*OS_VISTAORGREATER*/
4025 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 6)
4030 WARN("(0x%x) unknown parameter\n",feature
);
4035 /*************************************************************************
4038 HRESULT WINAPI
SHLoadRegUIStringW(HKEY hkey
, LPCWSTR value
, LPWSTR buf
, DWORD size
)
4040 DWORD type
, sz
= size
;
4042 if(RegQueryValueExW(hkey
, value
, NULL
, &type
, (LPBYTE
)buf
, &sz
) != ERROR_SUCCESS
)
4045 return SHLoadIndirectString(buf
, buf
, size
, NULL
);
4048 /*************************************************************************
4051 * Call IInputObject_TranslateAcceleratorIO() on an object.
4054 * lpUnknown [I] Object supporting the IInputObject interface.
4055 * lpMsg [I] Key message to be processed.
4059 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
4061 HRESULT WINAPI
IUnknown_TranslateAcceleratorIO(IUnknown
*lpUnknown
, LPMSG lpMsg
)
4063 IInputObject
* lpInput
= NULL
;
4064 HRESULT hRet
= E_INVALIDARG
;
4066 TRACE("(%p,%p)\n", lpUnknown
, lpMsg
);
4069 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IInputObject
,
4071 if (SUCCEEDED(hRet
) && lpInput
)
4073 hRet
= IInputObject_TranslateAcceleratorIO(lpInput
, lpMsg
);
4074 IInputObject_Release(lpInput
);
4080 /*************************************************************************
4083 * Call IInputObject_HasFocusIO() on an object.
4086 * lpUnknown [I] Object supporting the IInputObject interface.
4089 * Success: S_OK, if lpUnknown is an IInputObject object and has the focus,
4090 * or S_FALSE otherwise.
4091 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
4093 HRESULT WINAPI
IUnknown_HasFocusIO(IUnknown
*lpUnknown
)
4095 IInputObject
* lpInput
= NULL
;
4096 HRESULT hRet
= E_INVALIDARG
;
4098 TRACE("(%p)\n", lpUnknown
);
4101 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IInputObject
,
4103 if (SUCCEEDED(hRet
) && lpInput
)
4105 hRet
= IInputObject_HasFocusIO(lpInput
);
4106 IInputObject_Release(lpInput
);
4112 /*************************************************************************
4113 * ColorRGBToHLS [SHLWAPI.@]
4115 * Convert an rgb COLORREF into the hls color space.
4118 * cRGB [I] Source rgb value
4119 * pwHue [O] Destination for converted hue
4120 * pwLuminance [O] Destination for converted luminance
4121 * pwSaturation [O] Destination for converted saturation
4124 * Nothing. pwHue, pwLuminance and pwSaturation are set to the converted
4128 * Output HLS values are constrained to the range (0..240).
4129 * For Achromatic conversions, Hue is set to 160.
4131 VOID WINAPI
ColorRGBToHLS(COLORREF cRGB
, LPWORD pwHue
,
4132 LPWORD pwLuminance
, LPWORD pwSaturation
)
4134 int wR
, wG
, wB
, wMax
, wMin
, wHue
, wLuminosity
, wSaturation
;
4136 TRACE("(%08x,%p,%p,%p)\n", cRGB
, pwHue
, pwLuminance
, pwSaturation
);
4138 wR
= GetRValue(cRGB
);
4139 wG
= GetGValue(cRGB
);
4140 wB
= GetBValue(cRGB
);
4142 wMax
= max(wR
, max(wG
, wB
));
4143 wMin
= min(wR
, min(wG
, wB
));
4146 wLuminosity
= ((wMax
+ wMin
) * 240 + 255) / 510;
4150 /* Achromatic case */
4152 /* Hue is now unrepresentable, but this is what native returns... */
4157 /* Chromatic case */
4158 int wDelta
= wMax
- wMin
, wRNorm
, wGNorm
, wBNorm
;
4161 if (wLuminosity
<= 120)
4162 wSaturation
= ((wMax
+ wMin
)/2 + wDelta
* 240) / (wMax
+ wMin
);
4164 wSaturation
= ((510 - wMax
- wMin
)/2 + wDelta
* 240) / (510 - wMax
- wMin
);
4167 wRNorm
= (wDelta
/2 + wMax
* 40 - wR
* 40) / wDelta
;
4168 wGNorm
= (wDelta
/2 + wMax
* 40 - wG
* 40) / wDelta
;
4169 wBNorm
= (wDelta
/2 + wMax
* 40 - wB
* 40) / wDelta
;
4172 wHue
= wBNorm
- wGNorm
;
4173 else if (wG
== wMax
)
4174 wHue
= 80 + wRNorm
- wBNorm
;
4176 wHue
= 160 + wGNorm
- wRNorm
;
4179 else if (wHue
> 240)
4185 *pwLuminance
= wLuminosity
;
4187 *pwSaturation
= wSaturation
;
4190 /*************************************************************************
4191 * SHCreateShellPalette [SHLWAPI.@]
4193 HPALETTE WINAPI
SHCreateShellPalette(HDC hdc
)
4196 return CreateHalftonePalette(hdc
);
4199 /*************************************************************************
4200 * SHGetInverseCMAP (SHLWAPI.@)
4202 * Get an inverse color map table.
4205 * lpCmap [O] Destination for color map
4206 * dwSize [I] Size of memory pointed to by lpCmap
4210 * Failure: E_POINTER, If lpCmap is invalid.
4211 * E_INVALIDARG, If dwFlags is invalid
4212 * E_OUTOFMEMORY, If there is no memory available
4215 * dwSize may only be CMAP_PTR_SIZE (4) or CMAP_SIZE (8192).
4216 * If dwSize = CMAP_PTR_SIZE, *lpCmap is set to the address of this DLL's
4218 * If dwSize = CMAP_SIZE, lpCmap is filled with a copy of the data from
4219 * this DLL's internal CMap.
4221 HRESULT WINAPI
SHGetInverseCMAP(LPDWORD dest
, DWORD dwSize
)
4224 FIXME(" - returning bogus address for SHGetInverseCMAP\n");
4225 *dest
= (DWORD
)0xabba1249;
4228 FIXME("(%p, %#x) stub\n", dest
, dwSize
);
4232 /*************************************************************************
4233 * SHIsLowMemoryMachine [SHLWAPI.@]
4235 * Determine if the current computer has low memory.
4241 * TRUE if the users machine has 16 Megabytes of memory or less,
4244 BOOL WINAPI
SHIsLowMemoryMachine (DWORD x
)
4246 FIXME("(0x%08x) stub\n", x
);
4250 /*************************************************************************
4251 * GetMenuPosFromID [SHLWAPI.@]
4253 * Return the position of a menu item from its Id.
4256 * hMenu [I] Menu containing the item
4257 * wID [I] Id of the menu item
4260 * Success: The index of the menu item in hMenu.
4261 * Failure: -1, If the item is not found.
4263 INT WINAPI
GetMenuPosFromID(HMENU hMenu
, UINT wID
)
4266 INT nCount
= GetMenuItemCount(hMenu
), nIter
= 0;
4268 while (nIter
< nCount
)
4270 mi
.cbSize
= sizeof(mi
);
4272 if (GetMenuItemInfoW(hMenu
, nIter
, TRUE
, &mi
) && mi
.wID
== wID
)
4279 /*************************************************************************
4282 * Same as SHLWAPI.GetMenuPosFromID
4284 DWORD WINAPI
SHMenuIndexFromID(HMENU hMenu
, UINT uID
)
4286 return GetMenuPosFromID(hMenu
, uID
);
4290 /*************************************************************************
4293 VOID WINAPI
FixSlashesAndColonW(LPWSTR lpwstr
)
4304 /*************************************************************************
4307 DWORD WINAPI
SHGetAppCompatFlags(DWORD dwUnknown
)
4309 FIXME("(0x%08x) stub\n", dwUnknown
);
4314 /*************************************************************************
4317 HRESULT WINAPI
SHCoCreateInstanceAC(REFCLSID rclsid
, LPUNKNOWN pUnkOuter
,
4318 DWORD dwClsContext
, REFIID iid
, LPVOID
*ppv
)
4320 return CoCreateInstance(rclsid
, pUnkOuter
, dwClsContext
, iid
, ppv
);
4323 /*************************************************************************
4324 * SHSkipJunction [SHLWAPI.@]
4326 * Determine if a bind context can be bound to an object
4329 * pbc [I] Bind context to check
4330 * pclsid [I] CLSID of object to be bound to
4333 * TRUE: If it is safe to bind
4334 * FALSE: If pbc is invalid or binding would not be safe
4337 BOOL WINAPI
SHSkipJunction(IBindCtx
*pbc
, const CLSID
*pclsid
)
4339 static WCHAR szSkipBinding
[] = { 'S','k','i','p',' ',
4340 'B','i','n','d','i','n','g',' ','C','L','S','I','D','\0' };
4347 if (SUCCEEDED(IBindCtx_GetObjectParam(pbc
, szSkipBinding
, &lpUnk
)))
4351 if (SUCCEEDED(IUnknown_GetClassID(lpUnk
, &clsid
)) &&
4352 IsEqualGUID(pclsid
, &clsid
))
4355 IUnknown_Release(lpUnk
);
4361 /***********************************************************************
4362 * SHGetShellKey (SHLWAPI.@)
4364 HKEY WINAPI
SHGetShellKey(DWORD flags
, LPCWSTR sub_key
, BOOL create
)
4366 FIXME("(0x%08x, %s, %d): stub\n", flags
, debugstr_w(sub_key
), create
);
4370 /***********************************************************************
4371 * SHQueueUserWorkItem (SHLWAPI.@)
4373 BOOL WINAPI
SHQueueUserWorkItem(LPTHREAD_START_ROUTINE pfnCallback
,
4374 LPVOID pContext
, LONG lPriority
, DWORD_PTR dwTag
,
4375 DWORD_PTR
*pdwId
, LPCSTR pszModule
, DWORD dwFlags
)
4377 TRACE("(%p, %p, %d, %lx, %p, %s, %08x)\n", pfnCallback
, pContext
,
4378 lPriority
, dwTag
, pdwId
, debugstr_a(pszModule
), dwFlags
);
4380 if(lPriority
|| dwTag
|| pdwId
|| pszModule
|| dwFlags
)
4381 FIXME("Unsupported arguments\n");
4383 return QueueUserWorkItem(pfnCallback
, pContext
, 0);
4386 /***********************************************************************
4387 * SHSetTimerQueueTimer (SHLWAPI.263)
4389 HANDLE WINAPI
SHSetTimerQueueTimer(HANDLE hQueue
,
4390 WAITORTIMERCALLBACK pfnCallback
, LPVOID pContext
, DWORD dwDueTime
,
4391 DWORD dwPeriod
, LPCSTR lpszLibrary
, DWORD dwFlags
)
4395 /* SHSetTimerQueueTimer flags -> CreateTimerQueueTimer flags */
4396 if (dwFlags
& TPS_LONGEXECTIME
) {
4397 dwFlags
&= ~TPS_LONGEXECTIME
;
4398 dwFlags
|= WT_EXECUTELONGFUNCTION
;
4400 if (dwFlags
& TPS_EXECUTEIO
) {
4401 dwFlags
&= ~TPS_EXECUTEIO
;
4402 dwFlags
|= WT_EXECUTEINIOTHREAD
;
4405 if (!CreateTimerQueueTimer(&hNewTimer
, hQueue
, pfnCallback
, pContext
,
4406 dwDueTime
, dwPeriod
, dwFlags
))
4412 /***********************************************************************
4413 * IUnknown_OnFocusChangeIS (SHLWAPI.@)
4415 HRESULT WINAPI
IUnknown_OnFocusChangeIS(LPUNKNOWN lpUnknown
, LPUNKNOWN pFocusObject
, BOOL bFocus
)
4417 IInputObjectSite
*pIOS
= NULL
;
4418 HRESULT hRet
= E_INVALIDARG
;
4420 TRACE("(%p, %p, %s)\n", lpUnknown
, pFocusObject
, bFocus
? "TRUE" : "FALSE");
4424 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IInputObjectSite
,
4426 if (SUCCEEDED(hRet
) && pIOS
)
4428 hRet
= IInputObjectSite_OnFocusChangeIS(pIOS
, pFocusObject
, bFocus
);
4429 IInputObjectSite_Release(pIOS
);
4435 /***********************************************************************
4436 * SHGetValueW (SHLWAPI.@)
4438 HRESULT WINAPI
SKGetValueW(DWORD a
, LPWSTR b
, LPWSTR c
, DWORD d
, DWORD e
, DWORD f
)
4440 FIXME("(%x, %s, %s, %x, %x, %x): stub\n", a
, debugstr_w(b
), debugstr_w(c
), d
, e
, f
);
4444 typedef HRESULT (WINAPI
*DllGetVersion_func
)(DLLVERSIONINFO
*);
4446 /***********************************************************************
4447 * GetUIVersion (SHLWAPI.452)
4449 DWORD WINAPI
GetUIVersion(void)
4451 static DWORD version
;
4455 DllGetVersion_func pDllGetVersion
;
4456 HMODULE dll
= LoadLibraryA("shell32.dll");
4459 pDllGetVersion
= (DllGetVersion_func
)GetProcAddress(dll
, "DllGetVersion");
4463 dvi
.cbSize
= sizeof(DLLVERSIONINFO
);
4464 if (pDllGetVersion(&dvi
) == S_OK
) version
= dvi
.dwMajorVersion
;
4467 if (!version
) version
= 3; /* old shell dlls don't have DllGetVersion */
4472 /***********************************************************************
4473 * ShellMessageBoxWrapW [SHLWAPI.388]
4475 * See shell32.ShellMessageBoxW
4478 * shlwapi.ShellMessageBoxWrapW is a duplicate of shell32.ShellMessageBoxW
4479 * because we can't forward to it in the .spec file since it's exported by
4480 * ordinal. If you change the implementation here please update the code in
4483 INT WINAPIV
ShellMessageBoxWrapW(HINSTANCE hInstance
, HWND hWnd
, LPCWSTR lpText
,
4484 LPCWSTR lpCaption
, UINT uType
, ...)
4486 WCHAR szText
[100], szTitle
[100];
4487 LPCWSTR pszText
= szText
, pszTitle
= szTitle
;
4492 __ms_va_start(args
, uType
);
4494 TRACE("(%p,%p,%p,%p,%08x)\n", hInstance
, hWnd
, lpText
, lpCaption
, uType
);
4496 if (IS_INTRESOURCE(lpCaption
))
4497 LoadStringW(hInstance
, LOWORD(lpCaption
), szTitle
, sizeof(szTitle
)/sizeof(szTitle
[0]));
4499 pszTitle
= lpCaption
;
4501 if (IS_INTRESOURCE(lpText
))
4502 LoadStringW(hInstance
, LOWORD(lpText
), szText
, sizeof(szText
)/sizeof(szText
[0]));
4506 FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_STRING
,
4507 pszText
, 0, 0, (LPWSTR
)&pszTemp
, 0, &args
);
4511 ret
= MessageBoxW(hWnd
, pszTemp
, pszTitle
, uType
);
4516 /***********************************************************************
4517 * ZoneComputePaneSize [SHLWAPI.382]
4519 UINT WINAPI
ZoneComputePaneSize(HWND hwnd
)
4525 /***********************************************************************
4526 * SHChangeNotifyWrap [SHLWAPI.394]
4528 void WINAPI
SHChangeNotifyWrap(LONG wEventId
, UINT uFlags
, LPCVOID dwItem1
, LPCVOID dwItem2
)
4530 SHChangeNotify(wEventId
, uFlags
, dwItem1
, dwItem2
);
4533 typedef struct SHELL_USER_SID
{ /* according to MSDN this should be in shlobj.h... */
4534 SID_IDENTIFIER_AUTHORITY sidAuthority
;
4535 DWORD dwUserGroupID
;
4537 } SHELL_USER_SID
, *PSHELL_USER_SID
;
4539 typedef struct SHELL_USER_PERMISSION
{ /* ...and this should be in shlwapi.h */
4540 SHELL_USER_SID susID
;
4544 DWORD dwInheritMask
;
4545 DWORD dwInheritAccessMask
;
4546 } SHELL_USER_PERMISSION
, *PSHELL_USER_PERMISSION
;
4548 /***********************************************************************
4549 * GetShellSecurityDescriptor [SHLWAPI.475]
4551 * prepares SECURITY_DESCRIPTOR from a set of ACEs
4554 * apUserPerm [I] array of pointers to SHELL_USER_PERMISSION structures,
4555 * each of which describes permissions to apply
4556 * cUserPerm [I] number of entries in apUserPerm array
4559 * success: pointer to SECURITY_DESCRIPTOR
4563 * Call should free returned descriptor with LocalFree
4565 PSECURITY_DESCRIPTOR WINAPI
GetShellSecurityDescriptor(PSHELL_USER_PERMISSION
*apUserPerm
, int cUserPerm
)
4568 PSID cur_user
= NULL
;
4572 PSECURITY_DESCRIPTOR psd
= NULL
;
4574 TRACE("%p %d\n", apUserPerm
, cUserPerm
);
4576 if (apUserPerm
== NULL
|| cUserPerm
<= 0)
4579 sidlist
= HeapAlloc(GetProcessHeap(), 0, cUserPerm
* sizeof(PSID
));
4583 acl_size
= sizeof(ACL
);
4585 for(sid_count
= 0; sid_count
< cUserPerm
; sid_count
++)
4587 static SHELL_USER_SID null_sid
= {{SECURITY_NULL_SID_AUTHORITY
}, 0, 0};
4588 PSHELL_USER_PERMISSION perm
= apUserPerm
[sid_count
];
4589 PSHELL_USER_SID sid
= &perm
->susID
;
4593 if (!memcmp((void*)sid
, (void*)&null_sid
, sizeof(SHELL_USER_SID
)))
4594 { /* current user's SID */
4598 DWORD bufsize
= sizeof(tuUser
);
4600 ret
= OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY
, &Token
);
4603 ret
= GetTokenInformation(Token
, TokenUser
, (void*)tuUser
, bufsize
, &bufsize
);
4605 cur_user
= ((PTOKEN_USER
)tuUser
)->User
.Sid
;
4610 } else if (sid
->dwUserID
==0) /* one sub-authority */
4611 ret
= AllocateAndInitializeSid(&sid
->sidAuthority
, 1, sid
->dwUserGroupID
, 0,
4612 0, 0, 0, 0, 0, 0, &pSid
);
4614 ret
= AllocateAndInitializeSid(&sid
->sidAuthority
, 2, sid
->dwUserGroupID
, sid
->dwUserID
,
4615 0, 0, 0, 0, 0, 0, &pSid
);
4619 sidlist
[sid_count
] = pSid
;
4620 /* increment acl_size (1 ACE for non-inheritable and 2 ACEs for inheritable records */
4621 acl_size
+= (sizeof(ACCESS_ALLOWED_ACE
)-sizeof(DWORD
) + GetLengthSid(pSid
)) * (perm
->fInherit
? 2 : 1);
4624 psd
= LocalAlloc(0, sizeof(SECURITY_DESCRIPTOR
) + acl_size
);
4628 PACL pAcl
= (PACL
)(((BYTE
*)psd
)+sizeof(SECURITY_DESCRIPTOR
));
4630 if (!InitializeSecurityDescriptor(psd
, SECURITY_DESCRIPTOR_REVISION
))
4633 if (!InitializeAcl(pAcl
, acl_size
, ACL_REVISION
))
4636 for(i
= 0; i
< sid_count
; i
++)
4638 PSHELL_USER_PERMISSION sup
= apUserPerm
[i
];
4639 PSID sid
= sidlist
[i
];
4641 switch(sup
->dwAccessType
)
4643 case ACCESS_ALLOWED_ACE_TYPE
:
4644 if (!AddAccessAllowedAce(pAcl
, ACL_REVISION
, sup
->dwAccessMask
, sid
))
4646 if (sup
->fInherit
&& !AddAccessAllowedAceEx(pAcl
, ACL_REVISION
,
4647 (BYTE
)sup
->dwInheritMask
, sup
->dwInheritAccessMask
, sid
))
4650 case ACCESS_DENIED_ACE_TYPE
:
4651 if (!AddAccessDeniedAce(pAcl
, ACL_REVISION
, sup
->dwAccessMask
, sid
))
4653 if (sup
->fInherit
&& !AddAccessDeniedAceEx(pAcl
, ACL_REVISION
,
4654 (BYTE
)sup
->dwInheritMask
, sup
->dwInheritAccessMask
, sid
))
4662 if (!SetSecurityDescriptorDacl(psd
, TRUE
, pAcl
, FALSE
))
4671 for(i
= 0; i
< sid_count
; i
++)
4673 if (!cur_user
|| sidlist
[i
] != cur_user
)
4674 FreeSid(sidlist
[i
]);
4676 HeapFree(GetProcessHeap(), 0, sidlist
);
4681 /***********************************************************************
4682 * SHCreatePropertyBagOnRegKey [SHLWAPI.471]
4684 * Creates a property bag from a registry key
4687 * hKey [I] Handle to the desired registry key
4688 * subkey [I] Name of desired subkey, or NULL to open hKey directly
4689 * grfMode [I] Optional flags
4690 * riid [I] IID of requested property bag interface
4691 * ppv [O] Address to receive pointer to the new interface
4695 * failure: error code
4698 HRESULT WINAPI
SHCreatePropertyBagOnRegKey (HKEY hKey
, LPCWSTR subkey
,
4699 DWORD grfMode
, REFIID riid
, void **ppv
)
4701 FIXME("%p %s %d %s %p STUB\n", hKey
, debugstr_w(subkey
), grfMode
,
4702 debugstr_guid(riid
), ppv
);
4707 /***********************************************************************
4708 * SHGetViewStatePropertyBag [SHLWAPI.515]
4710 * Retrieves a property bag in which the view state information of a folder
4714 * pidl [I] PIDL of the folder requested
4715 * bag_name [I] Name of the property bag requested
4716 * flags [I] Optional flags
4717 * riid [I] IID of requested property bag interface
4718 * ppv [O] Address to receive pointer to the new interface
4722 * failure: error code
4725 HRESULT WINAPI
SHGetViewStatePropertyBag(LPCITEMIDLIST pidl
, LPWSTR bag_name
,
4726 DWORD flags
, REFIID riid
, void **ppv
)
4728 FIXME("%p %s %d %s %p STUB\n", pidl
, debugstr_w(bag_name
), flags
,
4729 debugstr_guid(riid
), ppv
);
4734 /***********************************************************************
4735 * SHFormatDateTimeW [SHLWAPI.354]
4737 * Produces a string representation of a time.
4740 * fileTime [I] Pointer to FILETIME structure specifying the time
4741 * flags [I] Flags specifying the desired output
4742 * buf [O] Pointer to buffer for output
4743 * size [I] Number of characters that can be contained in buffer
4746 * success: number of characters written to the buffer
4750 INT WINAPI
SHFormatDateTimeW(const FILETIME UNALIGNED
*fileTime
, DWORD
*flags
,
4751 LPWSTR buf
, UINT size
)
4753 #define SHFORMATDT_UNSUPPORTED_FLAGS (FDTF_RELATIVE | FDTF_LTRDATE | FDTF_RTLDATE | FDTF_NOAUTOREADINGORDER)
4754 DWORD fmt_flags
= flags
? *flags
: FDTF_DEFAULT
;
4759 TRACE("%p %p %p %u\n", fileTime
, flags
, buf
, size
);
4764 if (fmt_flags
& SHFORMATDT_UNSUPPORTED_FLAGS
)
4765 FIXME("ignoring some flags - 0x%08x\n", fmt_flags
& SHFORMATDT_UNSUPPORTED_FLAGS
);
4767 FileTimeToLocalFileTime(fileTime
, &ft
);
4768 FileTimeToSystemTime(&ft
, &st
);
4770 /* first of all date */
4771 if (fmt_flags
& (FDTF_LONGDATE
| FDTF_SHORTDATE
))
4773 static const WCHAR sep1
[] = {',',' ',0};
4774 static const WCHAR sep2
[] = {' ',0};
4776 DWORD date
= fmt_flags
& FDTF_LONGDATE
? DATE_LONGDATE
: DATE_SHORTDATE
;
4777 ret
= GetDateFormatW(LOCALE_USER_DEFAULT
, date
, &st
, NULL
, buf
, size
);
4778 if (ret
>= size
) return ret
;
4781 if (ret
< size
&& (fmt_flags
& (FDTF_LONGTIME
| FDTF_SHORTTIME
)))
4783 if ((fmt_flags
& FDTF_LONGDATE
) && (ret
< size
+ 2))
4787 lstrcatW(&buf
[ret
-1], sep1
);
4793 lstrcatW(&buf
[ret
-1], sep2
);
4799 if (fmt_flags
& (FDTF_LONGTIME
| FDTF_SHORTTIME
))
4801 DWORD time
= fmt_flags
& FDTF_LONGTIME
? 0 : TIME_NOSECONDS
;
4804 ret
+= GetTimeFormatW(LOCALE_USER_DEFAULT
, time
, &st
, NULL
, &buf
[ret
], size
- ret
);
4809 #undef SHFORMATDT_UNSUPPORTED_FLAGS
4812 /***********************************************************************
4813 * SHFormatDateTimeA [SHLWAPI.353]
4815 * See SHFormatDateTimeW.
4818 INT WINAPI
SHFormatDateTimeA(const FILETIME UNALIGNED
*fileTime
, DWORD
*flags
,
4819 LPSTR buf
, UINT size
)
4827 bufW
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
) * size
);
4828 retval
= SHFormatDateTimeW(fileTime
, flags
, bufW
, size
);
4831 WideCharToMultiByte(CP_ACP
, 0, bufW
, -1, buf
, size
, NULL
, NULL
);
4833 HeapFree(GetProcessHeap(), 0, bufW
);
4837 /***********************************************************************
4838 * ZoneCheckUrlExW [SHLWAPI.231]
4840 * Checks the details of the security zone for the supplied site. (?)
4844 * szURL [I] Pointer to the URL to check
4846 * Other parameters currently unknown.
4852 INT WINAPI
ZoneCheckUrlExW(LPWSTR szURL
, PVOID pUnknown
, DWORD dwUnknown2
,
4853 DWORD dwUnknown3
, DWORD dwUnknown4
, DWORD dwUnknown5
, DWORD dwUnknown6
,
4856 FIXME("(%s,%p,%x,%x,%x,%x,%x,%x) STUB\n", debugstr_w(szURL
), pUnknown
, dwUnknown2
,
4857 dwUnknown3
, dwUnknown4
, dwUnknown5
, dwUnknown6
, dwUnknown7
);
4862 /***********************************************************************
4863 * SHVerbExistsNA [SHLWAPI.196]
4868 * verb [I] a string, often appears to be an extension.
4870 * Other parameters currently unknown.
4875 INT WINAPI
SHVerbExistsNA(LPSTR verb
, PVOID pUnknown
, PVOID pUnknown2
, DWORD dwUnknown3
)
4877 FIXME("(%s, %p, %p, %i) STUB\n",verb
, pUnknown
, pUnknown2
, dwUnknown3
);
4881 /*************************************************************************
4884 * Undocumented: Implementation guessed at via Name and behavior
4887 * lpUnknown [I] Object to get an IServiceProvider interface from
4888 * riid [I] Function requested for QueryService call
4889 * lppOut [O] Destination for the service interface pointer
4892 * Success: S_OK. lppOut contains an object providing the requested service
4893 * Failure: An HRESULT error code
4896 * lpUnknown is expected to support the IServiceProvider interface.
4898 HRESULT WINAPI
IUnknown_QueryServiceForWebBrowserApp(IUnknown
* lpUnknown
,
4899 REFGUID riid
, LPVOID
*lppOut
)
4901 FIXME("%p %s %p semi-STUB\n", lpUnknown
, debugstr_guid(riid
), lppOut
);
4902 return IUnknown_QueryService(lpUnknown
,&IID_IWebBrowserApp
,riid
,lppOut
);
4905 /**************************************************************************
4906 * SHPropertyBag_ReadLONG (SHLWAPI.496)
4908 * This function asks a property bag to read a named property as a LONG.
4911 * ppb: a IPropertyBag interface
4912 * pszPropName: Unicode string that names the property
4913 * pValue: address to receive the property value as a 32-bit signed integer
4918 BOOL WINAPI
SHPropertyBag_ReadLONG(IPropertyBag
*ppb
, LPCWSTR pszPropName
, LPLONG pValue
)
4922 TRACE("%p %s %p\n", ppb
,debugstr_w(pszPropName
),pValue
);
4923 if (!pszPropName
|| !ppb
|| !pValue
)
4924 return E_INVALIDARG
;
4926 hr
= IPropertyBag_Read(ppb
, pszPropName
, &var
, NULL
);
4929 if (V_VT(&var
) == VT_I4
)
4930 *pValue
= V_I4(&var
);
4932 hr
= DISP_E_BADVARTYPE
;
4937 /* return flags for SHGetObjectCompatFlags, names derived from registry value names */
4938 #define OBJCOMPAT_OTNEEDSSFCACHE 0x00000001
4939 #define OBJCOMPAT_NO_WEBVIEW 0x00000002
4940 #define OBJCOMPAT_UNBINDABLE 0x00000004
4941 #define OBJCOMPAT_PINDLL 0x00000008
4942 #define OBJCOMPAT_NEEDSFILESYSANCESTOR 0x00000010
4943 #define OBJCOMPAT_NOTAFILESYSTEM 0x00000020
4944 #define OBJCOMPAT_CTXMENU_NOVERBS 0x00000040
4945 #define OBJCOMPAT_CTXMENU_LIMITEDQI 0x00000080
4946 #define OBJCOMPAT_COCREATESHELLFOLDERONLY 0x00000100
4947 #define OBJCOMPAT_NEEDSSTORAGEANCESTOR 0x00000200
4948 #define OBJCOMPAT_NOLEGACYWEBVIEW 0x00000400
4949 #define OBJCOMPAT_CTXMENU_XPQCMFLAGS 0x00001000
4950 #define OBJCOMPAT_NOIPROPERTYSTORE 0x00002000
4952 /* a search table for compatibility flags */
4953 struct objcompat_entry
{
4954 const WCHAR name
[30];
4958 /* expected to be sorted by name */
4959 static const struct objcompat_entry objcompat_table
[] = {
4960 { {'C','O','C','R','E','A','T','E','S','H','E','L','L','F','O','L','D','E','R','O','N','L','Y',0},
4961 OBJCOMPAT_COCREATESHELLFOLDERONLY
},
4962 { {'C','T','X','M','E','N','U','_','L','I','M','I','T','E','D','Q','I',0},
4963 OBJCOMPAT_CTXMENU_LIMITEDQI
},
4964 { {'C','T','X','M','E','N','U','_','N','O','V','E','R','B','S',0},
4965 OBJCOMPAT_CTXMENU_LIMITEDQI
},
4966 { {'C','T','X','M','E','N','U','_','X','P','Q','C','M','F','L','A','G','S',0},
4967 OBJCOMPAT_CTXMENU_XPQCMFLAGS
},
4968 { {'N','E','E','D','S','F','I','L','E','S','Y','S','A','N','C','E','S','T','O','R',0},
4969 OBJCOMPAT_NEEDSFILESYSANCESTOR
},
4970 { {'N','E','E','D','S','S','T','O','R','A','G','E','A','N','C','E','S','T','O','R',0},
4971 OBJCOMPAT_NEEDSSTORAGEANCESTOR
},
4972 { {'N','O','I','P','R','O','P','E','R','T','Y','S','T','O','R','E',0},
4973 OBJCOMPAT_NOIPROPERTYSTORE
},
4974 { {'N','O','L','E','G','A','C','Y','W','E','B','V','I','E','W',0},
4975 OBJCOMPAT_NOLEGACYWEBVIEW
},
4976 { {'N','O','T','A','F','I','L','E','S','Y','S','T','E','M',0},
4977 OBJCOMPAT_NOTAFILESYSTEM
},
4978 { {'N','O','_','W','E','B','V','I','E','W',0},
4979 OBJCOMPAT_NO_WEBVIEW
},
4980 { {'O','T','N','E','E','D','S','S','F','C','A','C','H','E',0},
4981 OBJCOMPAT_OTNEEDSSFCACHE
},
4982 { {'P','I','N','D','L','L',0},
4984 { {'U','N','B','I','N','D','A','B','L','E',0},
4985 OBJCOMPAT_UNBINDABLE
}
4988 /**************************************************************************
4989 * SHGetObjectCompatFlags (SHLWAPI.476)
4991 * Function returns an integer representation of compatibility flags stored
4992 * in registry for CLSID under ShellCompatibility subkey.
4995 * pUnk: pointer to object IUnknown interface, idetifies CLSID
4996 * clsid: pointer to CLSID to retrieve data for
4999 * 0 on failure, flags set on success
5001 DWORD WINAPI
SHGetObjectCompatFlags(IUnknown
*pUnk
, const CLSID
*clsid
)
5003 static const WCHAR compatpathW
[] =
5004 {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
5005 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
5006 'S','h','e','l','l','C','o','m','p','a','t','i','b','i','l','i','t','y','\\',
5007 'O','b','j','e','c','t','s','\\','%','s',0};
5008 WCHAR strW
[sizeof(compatpathW
)/sizeof(WCHAR
) + 38 /* { CLSID } */];
5009 DWORD ret
, length
= sizeof(strW
)/sizeof(WCHAR
);
5014 TRACE("%p %s\n", pUnk
, debugstr_guid(clsid
));
5016 if (!pUnk
&& !clsid
) return 0;
5020 FIXME("iface not handled\n");
5024 StringFromCLSID(clsid
, &clsid_str
);
5025 sprintfW(strW
, compatpathW
, clsid_str
);
5026 CoTaskMemFree(clsid_str
);
5028 ret
= RegOpenKeyW(HKEY_LOCAL_MACHINE
, strW
, &key
);
5029 if (ret
!= ERROR_SUCCESS
) return 0;
5031 /* now collect flag values */
5033 for (i
= 0; RegEnumValueW(key
, i
, strW
, &length
, NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
; i
++)
5035 INT left
, right
, res
, x
;
5037 /* search in table */
5039 right
= sizeof(objcompat_table
) / sizeof(struct objcompat_entry
) - 1;
5041 while (right
>= left
) {
5042 x
= (left
+ right
) / 2;
5043 res
= strcmpW(strW
, objcompat_table
[x
].name
);
5046 ret
|= objcompat_table
[x
].value
;
5055 length
= sizeof(strW
)/sizeof(WCHAR
);