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
50 #include "wine/unicode.h"
51 #include "wine/debug.h"
54 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
56 /* DLL handles for late bound calls */
57 extern HINSTANCE shlwapi_hInstance
;
58 extern DWORD SHLWAPI_ThreadRef_index
;
60 HRESULT WINAPI
IUnknown_QueryService(IUnknown
*,REFGUID
,REFIID
,LPVOID
*);
61 HRESULT WINAPI
SHInvokeCommand(HWND
,IShellFolder
*,LPCITEMIDLIST
,BOOL
);
62 BOOL WINAPI
SHAboutInfoW(LPWSTR
,DWORD
);
65 NOTES: Most functions exported by ordinal seem to be superfluous.
66 The reason for these functions to be there is to provide a wrapper
67 for unicode functions to provide these functions on systems without
68 unicode functions eg. win95/win98. Since we have such functions we just
69 call these. If running Wine with native DLLs, some late bound calls may
70 fail. However, it is better to implement the functions in the forward DLL
71 and recommend the builtin rather than reimplementing the calls here!
74 /*************************************************************************
75 * SHLWAPI_DupSharedHandle
77 * Internal implemetation of SHLWAPI_11.
79 static HANDLE
SHLWAPI_DupSharedHandle(HANDLE hShared
, DWORD dwDstProcId
,
80 DWORD dwSrcProcId
, DWORD dwAccess
,
84 DWORD dwMyProcId
= GetCurrentProcessId();
87 TRACE("(%p,%d,%d,%08x,%08x)\n", hShared
, dwDstProcId
, dwSrcProcId
,
90 /* Get dest process handle */
91 if (dwDstProcId
== dwMyProcId
)
92 hDst
= GetCurrentProcess();
94 hDst
= OpenProcess(PROCESS_DUP_HANDLE
, 0, dwDstProcId
);
98 /* Get src process handle */
99 if (dwSrcProcId
== dwMyProcId
)
100 hSrc
= GetCurrentProcess();
102 hSrc
= OpenProcess(PROCESS_DUP_HANDLE
, 0, dwSrcProcId
);
106 /* Make handle available to dest process */
107 if (!DuplicateHandle(hDst
, hShared
, hSrc
, &hRet
,
108 dwAccess
, 0, dwOptions
| DUPLICATE_SAME_ACCESS
))
111 if (dwSrcProcId
!= dwMyProcId
)
115 if (dwDstProcId
!= dwMyProcId
)
119 TRACE("Returning handle %p\n", hRet
);
123 /*************************************************************************
126 * Create a block of sharable memory and initialise it with data.
129 * lpvData [I] Pointer to data to write
130 * dwSize [I] Size of data
131 * dwProcId [I] ID of process owning data
134 * Success: A shared memory handle
138 * Ordinals 7-11 provide a set of calls to create shared memory between a
139 * group of processes. The shared memory is treated opaquely in that its size
140 * is not exposed to clients who map it. This is accomplished by storing
141 * the size of the map as the first DWORD of mapped data, and then offsetting
142 * the view pointer returned by this size.
145 HANDLE WINAPI
SHAllocShared(LPCVOID lpvData
, DWORD dwSize
, DWORD dwProcId
)
151 TRACE("(%p,%d,%d)\n", lpvData
, dwSize
, dwProcId
);
153 /* Create file mapping of the correct length */
154 hMap
= CreateFileMappingA(INVALID_HANDLE_VALUE
, NULL
, FILE_MAP_READ
, 0,
155 dwSize
+ sizeof(dwSize
), NULL
);
159 /* Get a view in our process address space */
160 pMapped
= MapViewOfFile(hMap
, FILE_MAP_READ
| FILE_MAP_WRITE
, 0, 0, 0);
164 /* Write size of data, followed by the data, to the view */
165 *((DWORD
*)pMapped
) = dwSize
;
167 memcpy((char *) pMapped
+ sizeof(dwSize
), lpvData
, dwSize
);
169 /* Release view. All further views mapped will be opaque */
170 UnmapViewOfFile(pMapped
);
171 hRet
= SHLWAPI_DupSharedHandle(hMap
, dwProcId
,
172 GetCurrentProcessId(), FILE_MAP_ALL_ACCESS
,
173 DUPLICATE_SAME_ACCESS
);
180 /*************************************************************************
183 * Get a pointer to a block of shared memory from a shared memory handle.
186 * hShared [I] Shared memory handle
187 * dwProcId [I] ID of process owning hShared
190 * Success: A pointer to the shared memory
194 PVOID WINAPI
SHLockShared(HANDLE hShared
, DWORD dwProcId
)
199 TRACE("(%p %d)\n", hShared
, dwProcId
);
201 /* Get handle to shared memory for current process */
202 hDup
= SHLWAPI_DupSharedHandle(hShared
, dwProcId
, GetCurrentProcessId(),
203 FILE_MAP_ALL_ACCESS
, 0);
205 pMapped
= MapViewOfFile(hDup
, FILE_MAP_READ
| FILE_MAP_WRITE
, 0, 0, 0);
209 return (char *) pMapped
+ sizeof(DWORD
); /* Hide size */
213 /*************************************************************************
216 * Release a pointer to a block of shared memory.
219 * lpView [I] Shared memory pointer
226 BOOL WINAPI
SHUnlockShared(LPVOID lpView
)
228 TRACE("(%p)\n", lpView
);
229 return UnmapViewOfFile((char *) lpView
- sizeof(DWORD
)); /* Include size */
232 /*************************************************************************
235 * Destroy a block of sharable memory.
238 * hShared [I] Shared memory handle
239 * dwProcId [I] ID of process owning hShared
246 BOOL WINAPI
SHFreeShared(HANDLE hShared
, DWORD dwProcId
)
250 TRACE("(%p %d)\n", hShared
, dwProcId
);
252 /* Get a copy of the handle for our process, closing the source handle */
253 hClose
= SHLWAPI_DupSharedHandle(hShared
, dwProcId
, GetCurrentProcessId(),
254 FILE_MAP_ALL_ACCESS
,DUPLICATE_CLOSE_SOURCE
);
255 /* Close local copy */
256 return CloseHandle(hClose
);
259 /*************************************************************************
262 * Copy a sharable memory handle from one process to another.
265 * hShared [I] Shared memory handle to duplicate
266 * dwDstProcId [I] ID of the process wanting the duplicated handle
267 * dwSrcProcId [I] ID of the process owning hShared
268 * dwAccess [I] Desired DuplicateHandle() access
269 * dwOptions [I] Desired DuplicateHandle() options
272 * Success: A handle suitable for use by the dwDstProcId process.
273 * Failure: A NULL handle.
276 HANDLE WINAPI
SHMapHandle(HANDLE hShared
, DWORD dwDstProcId
, DWORD dwSrcProcId
,
277 DWORD dwAccess
, DWORD dwOptions
)
281 hRet
= SHLWAPI_DupSharedHandle(hShared
, dwDstProcId
, dwSrcProcId
,
282 dwAccess
, dwOptions
);
286 /*************************************************************************
289 * Create and register a clipboard enumerator for a web browser.
292 * lpBC [I] Binding context
293 * lpUnknown [I] An object exposing the IWebBrowserApp interface
297 * Failure: An HRESULT error code.
300 * The enumerator is stored as a property of the web browser. If it does not
301 * yet exist, it is created and set before being registered.
303 HRESULT WINAPI
RegisterDefaultAcceptHeaders(LPBC lpBC
, IUnknown
*lpUnknown
)
305 static const WCHAR szProperty
[] = { '{','D','0','F','C','A','4','2','0',
306 '-','D','3','F','5','-','1','1','C','F', '-','B','2','1','1','-','0',
307 '0','A','A','0','0','4','A','E','8','3','7','}','\0' };
309 IEnumFORMATETC
* pIEnumFormatEtc
= NULL
;
312 IWebBrowserApp
* pBrowser
= NULL
;
314 TRACE("(%p, %p)\n", lpBC
, lpUnknown
);
316 /* Get An IWebBrowserApp interface from lpUnknown */
317 hRet
= IUnknown_QueryService(lpUnknown
, &IID_IWebBrowserApp
, &IID_IWebBrowserApp
, (PVOID
)&pBrowser
);
318 if (FAILED(hRet
) || !pBrowser
)
319 return E_NOINTERFACE
;
321 V_VT(&var
) = VT_EMPTY
;
323 /* The property we get is the browsers clipboard enumerator */
324 property
= SysAllocString(szProperty
);
325 hRet
= IWebBrowserApp_GetProperty(pBrowser
, property
, &var
);
326 SysFreeString(property
);
330 if (V_VT(&var
) == VT_EMPTY
)
332 /* Iterate through accepted documents and RegisterClipBoardFormatA() them */
333 char szKeyBuff
[128], szValueBuff
[128];
334 DWORD dwKeySize
, dwValueSize
, dwRet
= 0, dwCount
= 0, dwNumValues
, dwType
;
335 FORMATETC
* formatList
, *format
;
338 TRACE("Registering formats and creating IEnumFORMATETC instance\n");
340 if (!RegOpenKeyA(HKEY_LOCAL_MACHINE
, "Software\\Microsoft\\Windows\\Current"
341 "Version\\Internet Settings\\Accepted Documents", &hDocs
))
344 /* Get count of values in key */
347 dwKeySize
= sizeof(szKeyBuff
);
348 dwRet
= RegEnumValueA(hDocs
,dwCount
,szKeyBuff
,&dwKeySize
,0,&dwType
,0,0);
352 dwNumValues
= dwCount
;
354 /* Note: dwCount = number of items + 1; The extra item is the end node */
355 format
= formatList
= HeapAlloc(GetProcessHeap(), 0, dwCount
* sizeof(FORMATETC
));
357 return E_OUTOFMEMORY
;
366 /* Register clipboard formats for the values and populate format list */
367 while(!dwRet
&& dwCount
< dwNumValues
)
369 dwKeySize
= sizeof(szKeyBuff
);
370 dwValueSize
= sizeof(szValueBuff
);
371 dwRet
= RegEnumValueA(hDocs
, dwCount
, szKeyBuff
, &dwKeySize
, 0, &dwType
,
372 (PBYTE
)szValueBuff
, &dwValueSize
);
376 format
->cfFormat
= RegisterClipboardFormatA(szValueBuff
);
378 format
->dwAspect
= 1;
387 /* Terminate the (maybe empty) list, last entry has a cfFormat of 0 */
388 format
->cfFormat
= 0;
390 format
->dwAspect
= 1;
394 /* Create a clipboard enumerator */
395 hRet
= CreateFormatEnumerator(dwNumValues
, formatList
, &pIEnumFormatEtc
);
397 if (FAILED(hRet
) || !pIEnumFormatEtc
)
400 /* Set our enumerator as the browsers property */
401 V_VT(&var
) = VT_UNKNOWN
;
402 V_UNKNOWN(&var
) = (IUnknown
*)pIEnumFormatEtc
;
404 hRet
= IWebBrowserApp_PutProperty(pBrowser
, (BSTR
)szProperty
, var
);
407 IEnumFORMATETC_Release(pIEnumFormatEtc
);
408 goto RegisterDefaultAcceptHeaders_Exit
;
412 if (V_VT(&var
) == VT_UNKNOWN
)
414 /* Our variant is holding the clipboard enumerator */
415 IUnknown
* pIUnknown
= V_UNKNOWN(&var
);
416 IEnumFORMATETC
* pClone
= NULL
;
418 TRACE("Retrieved IEnumFORMATETC property\n");
420 /* Get an IEnumFormatEtc interface from the variants value */
421 pIEnumFormatEtc
= NULL
;
422 hRet
= IUnknown_QueryInterface(pIUnknown
, &IID_IEnumFORMATETC
,
423 (PVOID
)&pIEnumFormatEtc
);
424 if (hRet
== S_OK
&& pIEnumFormatEtc
)
426 /* Clone and register the enumerator */
427 hRet
= IEnumFORMATETC_Clone(pIEnumFormatEtc
, &pClone
);
428 if (hRet
== S_OK
&& pClone
)
430 RegisterFormatEnumerator(lpBC
, pClone
, 0);
432 IEnumFORMATETC_Release(pClone
);
435 /* Release the IEnumFormatEtc interface */
436 IEnumFORMATETC_Release(pIUnknown
);
438 IUnknown_Release(V_UNKNOWN(&var
));
441 RegisterDefaultAcceptHeaders_Exit
:
442 IWebBrowserApp_Release(pBrowser
);
446 /*************************************************************************
449 * Get Explorers "AcceptLanguage" setting.
452 * langbuf [O] Destination for language string
453 * buflen [I] Length of langbuf
454 * [0] Success: used length of langbuf
457 * Success: S_OK. langbuf is set to the language string found.
458 * Failure: E_FAIL, If any arguments are invalid, error occurred, or Explorer
459 * does not contain the setting.
460 * E_INVALIDARG, If the buffer is not big enough
462 HRESULT WINAPI
GetAcceptLanguagesW( LPWSTR langbuf
, LPDWORD buflen
)
464 static const WCHAR szkeyW
[] = {
465 'S','o','f','t','w','a','r','e','\\',
466 'M','i','c','r','o','s','o','f','t','\\',
467 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
468 'I','n','t','e','r','n','a','t','i','o','n','a','l',0};
469 static const WCHAR valueW
[] = {
470 'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0};
471 static const WCHAR enusW
[] = {'e','n','-','u','s',0};
472 DWORD mystrlen
, mytype
;
478 if(!langbuf
|| !buflen
|| !*buflen
)
481 mystrlen
= (*buflen
> 20) ? *buflen
: 20 ;
482 mystr
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
) * mystrlen
);
483 RegOpenKeyW(HKEY_CURRENT_USER
, szkeyW
, &mykey
);
484 if(RegQueryValueExW(mykey
, valueW
, 0, &mytype
, (PBYTE
)mystr
, &mystrlen
)) {
485 /* Did not find value */
486 mylcid
= GetUserDefaultLCID();
487 /* somehow the mylcid translates into "en-us"
488 * this is similar to "LOCALE_SABBREVLANGNAME"
489 * which could be gotten via GetLocaleInfo.
490 * The only problem is LOCALE_SABBREVLANGUAGE" is
491 * a 3 char string (first 2 are country code and third is
492 * letter for "sublanguage", which does not come close to
495 lstrcpyW(mystr
, enusW
);
496 mystrlen
= lstrlenW(mystr
);
498 /* handle returned string */
499 FIXME("missing code\n");
501 memcpy( langbuf
, mystr
, min(*buflen
,strlenW(mystr
)+1)*sizeof(WCHAR
) );
503 if(*buflen
> strlenW(mystr
)) {
504 *buflen
= strlenW(mystr
);
508 retval
= E_INVALIDARG
;
509 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
512 HeapFree(GetProcessHeap(), 0, mystr
);
516 /*************************************************************************
519 * Ascii version of GetAcceptLanguagesW.
521 HRESULT WINAPI
GetAcceptLanguagesA( LPSTR langbuf
, LPDWORD buflen
)
524 DWORD buflenW
, convlen
;
527 if(!langbuf
|| !buflen
|| !*buflen
) return E_FAIL
;
530 langbufW
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
) * buflenW
);
531 retval
= GetAcceptLanguagesW(langbufW
, &buflenW
);
535 convlen
= WideCharToMultiByte(CP_ACP
, 0, langbufW
, -1, langbuf
, *buflen
, NULL
, NULL
);
537 else /* copy partial string anyway */
539 convlen
= WideCharToMultiByte(CP_ACP
, 0, langbufW
, *buflen
, langbuf
, *buflen
, NULL
, NULL
);
540 if (convlen
< *buflen
) langbuf
[convlen
] = 0;
542 *buflen
= buflenW
? convlen
: 0;
544 HeapFree(GetProcessHeap(), 0, langbufW
);
548 /*************************************************************************
551 * Convert a GUID to a string.
554 * guid [I] GUID to convert
555 * lpszDest [O] Destination for string
556 * cchMax [I] Length of output buffer
559 * The length of the string created.
561 INT WINAPI
SHStringFromGUIDA(REFGUID guid
, LPSTR lpszDest
, INT cchMax
)
566 TRACE("(%s,%p,%d)\n", debugstr_guid(guid
), lpszDest
, cchMax
);
568 sprintf(xguid
, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
569 guid
->Data1
, guid
->Data2
, guid
->Data3
,
570 guid
->Data4
[0], guid
->Data4
[1], guid
->Data4
[2], guid
->Data4
[3],
571 guid
->Data4
[4], guid
->Data4
[5], guid
->Data4
[6], guid
->Data4
[7]);
573 iLen
= strlen(xguid
) + 1;
577 memcpy(lpszDest
, xguid
, iLen
);
581 /*************************************************************************
584 * Convert a GUID to a string.
587 * guid [I] GUID to convert
588 * str [O] Destination for string
589 * cmax [I] Length of output buffer
592 * The length of the string created.
594 INT WINAPI
SHStringFromGUIDW(REFGUID guid
, LPWSTR lpszDest
, INT cchMax
)
598 static const WCHAR wszFormat
[] = {'{','%','0','8','l','X','-','%','0','4','X','-','%','0','4','X','-',
599 '%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','%','0','2','X','%','0','2',
600 'X','%','0','2','X','%','0','2','X','}',0};
602 TRACE("(%s,%p,%d)\n", debugstr_guid(guid
), lpszDest
, cchMax
);
604 sprintfW(xguid
, wszFormat
, guid
->Data1
, guid
->Data2
, guid
->Data3
,
605 guid
->Data4
[0], guid
->Data4
[1], guid
->Data4
[2], guid
->Data4
[3],
606 guid
->Data4
[4], guid
->Data4
[5], guid
->Data4
[6], guid
->Data4
[7]);
608 iLen
= strlenW(xguid
) + 1;
612 memcpy(lpszDest
, xguid
, iLen
*sizeof(WCHAR
));
616 /*************************************************************************
619 * Determine if a Unicode character is a space.
622 * wc [I] Character to check.
625 * TRUE, if wc is a space,
628 BOOL WINAPI
IsCharSpaceW(WCHAR wc
)
632 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_SPACE
);
635 /*************************************************************************
638 * Determine if a Unicode character is a blank.
641 * wc [I] Character to check.
644 * TRUE, if wc is a blank,
648 BOOL WINAPI
IsCharBlankW(WCHAR wc
)
652 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_BLANK
);
655 /*************************************************************************
658 * Determine if a Unicode character is punctuation.
661 * wc [I] Character to check.
664 * TRUE, if wc is punctuation,
667 BOOL WINAPI
IsCharPunctW(WCHAR wc
)
671 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_PUNCT
);
674 /*************************************************************************
677 * Determine if a Unicode character is a control character.
680 * wc [I] Character to check.
683 * TRUE, if wc is a control character,
686 BOOL WINAPI
IsCharCntrlW(WCHAR wc
)
690 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_CNTRL
);
693 /*************************************************************************
696 * Determine if a Unicode character is a digit.
699 * wc [I] Character to check.
702 * TRUE, if wc is a digit,
705 BOOL WINAPI
IsCharDigitW(WCHAR wc
)
709 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_DIGIT
);
712 /*************************************************************************
715 * Determine if a Unicode character is a hex digit.
718 * wc [I] Character to check.
721 * TRUE, if wc is a hex digit,
724 BOOL WINAPI
IsCharXDigitW(WCHAR wc
)
728 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_XDIGIT
);
731 /*************************************************************************
735 BOOL WINAPI
GetStringType3ExW(LPWSTR src
, INT count
, LPWORD type
)
737 return GetStringTypeW(CT_CTYPE3
, src
, count
, type
);
740 /*************************************************************************
743 * Compare two Ascii strings up to a given length.
746 * lpszSrc [I] Source string
747 * lpszCmp [I] String to compare to lpszSrc
748 * len [I] Maximum length
751 * A number greater than, less than or equal to 0 depending on whether
752 * lpszSrc is greater than, less than or equal to lpszCmp.
754 DWORD WINAPI
StrCmpNCA(LPCSTR lpszSrc
, LPCSTR lpszCmp
, INT len
)
756 return StrCmpNA(lpszSrc
, lpszCmp
, len
);
759 /*************************************************************************
762 * Unicode version of StrCmpNCA.
764 DWORD WINAPI
StrCmpNCW(LPCWSTR lpszSrc
, LPCWSTR lpszCmp
, INT len
)
766 return StrCmpNW(lpszSrc
, lpszCmp
, len
);
769 /*************************************************************************
772 * Compare two Ascii strings up to a given length, ignoring case.
775 * lpszSrc [I] Source string
776 * lpszCmp [I] String to compare to lpszSrc
777 * len [I] Maximum length
780 * A number greater than, less than or equal to 0 depending on whether
781 * lpszSrc is greater than, less than or equal to lpszCmp.
783 DWORD WINAPI
StrCmpNICA(LPCSTR lpszSrc
, LPCSTR lpszCmp
, DWORD len
)
785 return StrCmpNIA(lpszSrc
, lpszCmp
, len
);
788 /*************************************************************************
791 * Unicode version of StrCmpNICA.
793 DWORD WINAPI
StrCmpNICW(LPCWSTR lpszSrc
, LPCWSTR lpszCmp
, DWORD len
)
795 return StrCmpNIW(lpszSrc
, lpszCmp
, len
);
798 /*************************************************************************
801 * Compare two Ascii strings.
804 * lpszSrc [I] Source string
805 * lpszCmp [I] String to compare to lpszSrc
808 * A number greater than, less than or equal to 0 depending on whether
809 * lpszSrc is greater than, less than or equal to lpszCmp.
811 DWORD WINAPI
StrCmpCA(LPCSTR lpszSrc
, LPCSTR lpszCmp
)
813 return lstrcmpA(lpszSrc
, lpszCmp
);
816 /*************************************************************************
819 * Unicode version of StrCmpCA.
821 DWORD WINAPI
StrCmpCW(LPCWSTR lpszSrc
, LPCWSTR lpszCmp
)
823 return lstrcmpW(lpszSrc
, lpszCmp
);
826 /*************************************************************************
829 * Compare two Ascii strings, ignoring case.
832 * lpszSrc [I] Source string
833 * lpszCmp [I] String to compare to lpszSrc
836 * A number greater than, less than or equal to 0 depending on whether
837 * lpszSrc is greater than, less than or equal to lpszCmp.
839 DWORD WINAPI
StrCmpICA(LPCSTR lpszSrc
, LPCSTR lpszCmp
)
841 return lstrcmpiA(lpszSrc
, lpszCmp
);
844 /*************************************************************************
847 * Unicode version of StrCmpICA.
849 DWORD WINAPI
StrCmpICW(LPCWSTR lpszSrc
, LPCWSTR lpszCmp
)
851 return lstrcmpiW(lpszSrc
, lpszCmp
);
854 /*************************************************************************
857 * Get an identification string for the OS and explorer.
860 * lpszDest [O] Destination for Id string
861 * dwDestLen [I] Length of lpszDest
864 * TRUE, If the string was created successfully
867 BOOL WINAPI
SHAboutInfoA(LPSTR lpszDest
, DWORD dwDestLen
)
871 TRACE("(%p,%d)\n", lpszDest
, dwDestLen
);
873 if (lpszDest
&& SHAboutInfoW(buff
, dwDestLen
))
875 WideCharToMultiByte(CP_ACP
, 0, buff
, -1, lpszDest
, dwDestLen
, NULL
, NULL
);
881 /*************************************************************************
884 * Unicode version of SHAboutInfoA.
886 BOOL WINAPI
SHAboutInfoW(LPWSTR lpszDest
, DWORD dwDestLen
)
888 static const WCHAR szIEKey
[] = { 'S','O','F','T','W','A','R','E','\\',
889 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
890 ' ','E','x','p','l','o','r','e','r','\0' };
891 static const WCHAR szWinNtKey
[] = { 'S','O','F','T','W','A','R','E','\\',
892 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s',' ',
893 'N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
894 static const WCHAR szWinKey
[] = { 'S','O','F','T','W','A','R','E','\\',
895 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
896 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
897 static const WCHAR szRegKey
[] = { 'S','O','F','T','W','A','R','E','\\',
898 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
899 ' ','E','x','p','l','o','r','e','r','\\',
900 'R','e','g','i','s','t','r','a','t','i','o','n','\0' };
901 static const WCHAR szVersion
[] = { 'V','e','r','s','i','o','n','\0' };
902 static const WCHAR szCustomized
[] = { 'C','u','s','t','o','m','i','z','e','d',
903 'V','e','r','s','i','o','n','\0' };
904 static const WCHAR szOwner
[] = { 'R','e','g','i','s','t','e','r','e','d',
905 'O','w','n','e','r','\0' };
906 static const WCHAR szOrg
[] = { 'R','e','g','i','s','t','e','r','e','d',
907 'O','r','g','a','n','i','z','a','t','i','o','n','\0' };
908 static const WCHAR szProduct
[] = { 'P','r','o','d','u','c','t','I','d','\0' };
909 static const WCHAR szUpdate
[] = { 'I','E','A','K',
910 'U','p','d','a','t','e','U','r','l','\0' };
911 static const WCHAR szHelp
[] = { 'I','E','A','K',
912 'H','e','l','p','S','t','r','i','n','g','\0' };
917 TRACE("(%p,%d)\n", lpszDest
, dwDestLen
);
924 /* Try the NT key first, followed by 95/98 key */
925 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szWinNtKey
, 0, KEY_READ
, &hReg
) &&
926 RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szWinKey
, 0, KEY_READ
, &hReg
))
932 if (!SHGetValueW(HKEY_LOCAL_MACHINE
, szIEKey
, szVersion
, &dwType
, buff
, &dwLen
))
934 DWORD dwStrLen
= strlenW(buff
);
935 dwLen
= 30 - dwStrLen
;
936 SHGetValueW(HKEY_LOCAL_MACHINE
, szIEKey
,
937 szCustomized
, &dwType
, buff
+dwStrLen
, &dwLen
);
939 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
941 /* ~Registered Owner */
944 if (SHGetValueW(hReg
, szOwner
, 0, &dwType
, buff
+1, &dwLen
))
946 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
948 /* ~Registered Organization */
950 if (SHGetValueW(hReg
, szOrg
, 0, &dwType
, buff
+1, &dwLen
))
952 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
954 /* FIXME: Not sure where this number comes from */
958 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
962 if (SHGetValueW(HKEY_LOCAL_MACHINE
, szRegKey
, szProduct
, &dwType
, buff
+1, &dwLen
))
964 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
968 if(SHGetValueW(HKEY_LOCAL_MACHINE
, szWinKey
, szUpdate
, &dwType
, buff
+1, &dwLen
))
970 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
972 /* ~IE Help String */
974 if(SHGetValueW(hReg
, szHelp
, 0, &dwType
, buff
+1, &dwLen
))
976 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
982 /*************************************************************************
985 * Call IOleCommandTarget_QueryStatus() on an object.
988 * lpUnknown [I] Object supporting the IOleCommandTarget interface
989 * pguidCmdGroup [I] GUID for the command group
991 * prgCmds [O] Commands
992 * pCmdText [O] Command text
996 * Failure: E_FAIL, if lpUnknown is NULL.
997 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
998 * Otherwise, an error code from IOleCommandTarget_QueryStatus().
1000 HRESULT WINAPI
IUnknown_QueryStatus(IUnknown
* lpUnknown
, REFGUID pguidCmdGroup
,
1001 ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
* pCmdText
)
1003 HRESULT hRet
= E_FAIL
;
1005 TRACE("(%p,%p,%d,%p,%p)\n",lpUnknown
, pguidCmdGroup
, cCmds
, prgCmds
, pCmdText
);
1009 IOleCommandTarget
* lpOle
;
1011 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleCommandTarget
,
1014 if (SUCCEEDED(hRet
) && lpOle
)
1016 hRet
= IOleCommandTarget_QueryStatus(lpOle
, pguidCmdGroup
, cCmds
,
1018 IOleCommandTarget_Release(lpOle
);
1024 /*************************************************************************
1027 * Call IOleCommandTarget_Exec() on an object.
1030 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1031 * pguidCmdGroup [I] GUID for the command group
1035 * Failure: E_FAIL, if lpUnknown is NULL.
1036 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1037 * Otherwise, an error code from IOleCommandTarget_Exec().
1039 HRESULT WINAPI
IUnknown_Exec(IUnknown
* lpUnknown
, REFGUID pguidCmdGroup
,
1040 DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
* pvaIn
,
1043 HRESULT hRet
= E_FAIL
;
1045 TRACE("(%p,%p,%d,%d,%p,%p)\n",lpUnknown
, pguidCmdGroup
, nCmdID
,
1046 nCmdexecopt
, pvaIn
, pvaOut
);
1050 IOleCommandTarget
* lpOle
;
1052 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleCommandTarget
,
1054 if (SUCCEEDED(hRet
) && lpOle
)
1056 hRet
= IOleCommandTarget_Exec(lpOle
, pguidCmdGroup
, nCmdID
,
1057 nCmdexecopt
, pvaIn
, pvaOut
);
1058 IOleCommandTarget_Release(lpOle
);
1064 /*************************************************************************
1067 * Retrieve, modify, and re-set a value from a window.
1070 * hWnd [I] Window to get value from
1071 * offset [I] Offset of value
1072 * wMask [I] Mask for uiFlags
1073 * wFlags [I] Bits to set in window value
1076 * The new value as it was set, or 0 if any parameter is invalid.
1079 * Any bits set in uiMask are cleared from the value, then any bits set in
1080 * uiFlags are set in the value.
1082 LONG WINAPI
SHSetWindowBits(HWND hwnd
, INT offset
, UINT wMask
, UINT wFlags
)
1084 LONG ret
= GetWindowLongA(hwnd
, offset
);
1085 LONG newFlags
= (wFlags
& wMask
) | (ret
& ~wFlags
);
1087 if (newFlags
!= ret
)
1088 ret
= SetWindowLongA(hwnd
, offset
, newFlags
);
1092 /*************************************************************************
1095 * Change a window's parent.
1098 * hWnd [I] Window to change parent of
1099 * hWndParent [I] New parent window
1102 * The old parent of hWnd.
1105 * If hWndParent is NULL (desktop), the window style is changed to WS_POPUP.
1106 * If hWndParent is NOT NULL then we set the WS_CHILD style.
1108 HWND WINAPI
SHSetParentHwnd(HWND hWnd
, HWND hWndParent
)
1110 TRACE("%p, %p\n", hWnd
, hWndParent
);
1112 if(GetParent(hWnd
) == hWndParent
)
1116 SHSetWindowBits(hWnd
, GWL_STYLE
, WS_CHILD
, WS_CHILD
);
1118 SHSetWindowBits(hWnd
, GWL_STYLE
, WS_POPUP
, WS_POPUP
);
1120 return SetParent(hWnd
, hWndParent
);
1123 /*************************************************************************
1126 * Locate and advise a connection point in an IConnectionPointContainer object.
1129 * lpUnkSink [I] Sink for the connection point advise call
1130 * riid [I] REFIID of connection point to advise
1131 * fConnect [I] TRUE = Connection being establisted, FALSE = broken
1132 * lpUnknown [I] Object supporting the IConnectionPointContainer interface
1133 * lpCookie [O] Pointer to connection point cookie
1134 * lppCP [O] Destination for the IConnectionPoint found
1137 * Success: S_OK. If lppCP is non-NULL, it is filled with the IConnectionPoint
1138 * that was advised. The caller is responsible for releasing it.
1139 * Failure: E_FAIL, if any arguments are invalid.
1140 * E_NOINTERFACE, if lpUnknown isn't an IConnectionPointContainer,
1141 * Or an HRESULT error code if any call fails.
1143 HRESULT WINAPI
ConnectToConnectionPoint(IUnknown
* lpUnkSink
, REFIID riid
, BOOL fConnect
,
1144 IUnknown
* lpUnknown
, LPDWORD lpCookie
,
1145 IConnectionPoint
**lppCP
)
1148 IConnectionPointContainer
* lpContainer
;
1149 IConnectionPoint
*lpCP
;
1151 if(!lpUnknown
|| (fConnect
&& !lpUnkSink
))
1157 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IConnectionPointContainer
,
1158 (void**)&lpContainer
);
1159 if (SUCCEEDED(hRet
))
1161 hRet
= IConnectionPointContainer_FindConnectionPoint(lpContainer
, riid
, &lpCP
);
1163 if (SUCCEEDED(hRet
))
1166 hRet
= IConnectionPoint_Unadvise(lpCP
, *lpCookie
);
1168 hRet
= IConnectionPoint_Advise(lpCP
, lpUnkSink
, lpCookie
);
1173 if (lppCP
&& SUCCEEDED(hRet
))
1174 *lppCP
= lpCP
; /* Caller keeps the interface */
1176 IConnectionPoint_Release(lpCP
); /* Release it */
1179 IUnknown_Release(lpContainer
);
1184 /*************************************************************************
1187 * Release an interface.
1190 * lpUnknown [I] Object to release
1195 DWORD WINAPI
IUnknown_AtomicRelease(IUnknown
** lpUnknown
)
1199 TRACE("(%p)\n",lpUnknown
);
1201 if(!lpUnknown
|| !*((LPDWORD
)lpUnknown
)) return 0;
1205 TRACE("doing Release\n");
1207 return IUnknown_Release(temp
);
1210 /*************************************************************************
1213 * Skip '//' if present in a string.
1216 * lpszSrc [I] String to check for '//'
1219 * Success: The next character after the '//' or the string if not present
1220 * Failure: NULL, if lpszStr is NULL.
1222 LPCSTR WINAPI
PathSkipLeadingSlashesA(LPCSTR lpszSrc
)
1224 if (lpszSrc
&& lpszSrc
[0] == '/' && lpszSrc
[1] == '/')
1229 /*************************************************************************
1232 * Check if two interfaces come from the same object.
1235 * lpInt1 [I] Interface to check against lpInt2.
1236 * lpInt2 [I] Interface to check against lpInt1.
1239 * TRUE, If the interfaces come from the same object.
1242 BOOL WINAPI
SHIsSameObject(IUnknown
* lpInt1
, IUnknown
* lpInt2
)
1244 LPVOID lpUnknown1
, lpUnknown2
;
1246 TRACE("%p %p\n", lpInt1
, lpInt2
);
1248 if (!lpInt1
|| !lpInt2
)
1251 if (lpInt1
== lpInt2
)
1254 if (FAILED(IUnknown_QueryInterface(lpInt1
, &IID_IUnknown
, &lpUnknown1
)))
1257 if (FAILED(IUnknown_QueryInterface(lpInt2
, &IID_IUnknown
, &lpUnknown2
)))
1260 if (lpUnknown1
== lpUnknown2
)
1266 /*************************************************************************
1269 * Get the window handle of an object.
1272 * lpUnknown [I] Object to get the window handle of
1273 * lphWnd [O] Destination for window handle
1276 * Success: S_OK. lphWnd contains the objects window handle.
1277 * Failure: An HRESULT error code.
1280 * lpUnknown is expected to support one of the following interfaces:
1281 * IOleWindow(), IInternetSecurityMgrSite(), or IShellView().
1283 HRESULT WINAPI
IUnknown_GetWindow(IUnknown
*lpUnknown
, HWND
*lphWnd
)
1286 HRESULT hRet
= E_FAIL
;
1288 TRACE("(%p,%p)\n", lpUnknown
, lphWnd
);
1293 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleWindow
, (void**)&lpOle
);
1297 hRet
= IUnknown_QueryInterface(lpUnknown
,&IID_IShellView
, (void**)&lpOle
);
1301 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IInternetSecurityMgrSite
,
1306 if (SUCCEEDED(hRet
))
1308 /* Lazyness here - Since GetWindow() is the first method for the above 3
1309 * interfaces, we use the same call for them all.
1311 hRet
= IOleWindow_GetWindow((IOleWindow
*)lpOle
, lphWnd
);
1312 IUnknown_Release(lpOle
);
1314 TRACE("Returning HWND=%p\n", *lphWnd
);
1320 /*************************************************************************
1323 * Call a method on as as yet unidentified object.
1326 * pUnk [I] Object supporting the unidentified interface,
1327 * arg [I] Argument for the call on the object.
1332 HRESULT WINAPI
IUnknown_SetOwner(IUnknown
*pUnk
, ULONG arg
)
1334 static const GUID guid_173
= {
1335 0x5836fb00, 0x8187, 0x11cf, { 0xa1,0x2b,0x00,0xaa,0x00,0x4a,0xe8,0x37 }
1339 TRACE("(%p,%d)\n", pUnk
, arg
);
1341 /* Note: arg may not be a ULONG and pUnk2 is for sure not an IMalloc -
1342 * We use this interface as its vtable entry is compatible with the
1343 * object in question.
1344 * FIXME: Find out what this object is and where it should be defined.
1347 SUCCEEDED(IUnknown_QueryInterface(pUnk
, &guid_173
, (void**)&pUnk2
)))
1349 IMalloc_Alloc(pUnk2
, arg
); /* Faked call!! */
1350 IMalloc_Release(pUnk2
);
1355 /*************************************************************************
1358 * Call either IObjectWithSite_SetSite() or IInternetSecurityManager_SetSecuritySite() on
1362 HRESULT WINAPI
IUnknown_SetSite(
1363 IUnknown
*obj
, /* [in] OLE object */
1364 IUnknown
*site
) /* [in] Site interface */
1367 IObjectWithSite
*iobjwithsite
;
1368 IInternetSecurityManager
*isecmgr
;
1370 if (!obj
) return E_FAIL
;
1372 hr
= IUnknown_QueryInterface(obj
, &IID_IObjectWithSite
, (LPVOID
*)&iobjwithsite
);
1373 TRACE("IID_IObjectWithSite QI ret=%08x, %p\n", hr
, iobjwithsite
);
1376 hr
= IObjectWithSite_SetSite(iobjwithsite
, site
);
1377 TRACE("done IObjectWithSite_SetSite ret=%08x\n", hr
);
1378 IUnknown_Release(iobjwithsite
);
1382 hr
= IUnknown_QueryInterface(obj
, &IID_IInternetSecurityManager
, (LPVOID
*)&isecmgr
);
1383 TRACE("IID_IInternetSecurityManager QI ret=%08x, %p\n", hr
, isecmgr
);
1384 if (FAILED(hr
)) return hr
;
1386 hr
= IInternetSecurityManager_SetSecuritySite(isecmgr
, (IInternetSecurityMgrSite
*)site
);
1387 TRACE("done IInternetSecurityManager_SetSecuritySite ret=%08x\n", hr
);
1388 IUnknown_Release(isecmgr
);
1393 /*************************************************************************
1396 * Call IPersist_GetClassID() on an object.
1399 * lpUnknown [I] Object supporting the IPersist interface
1400 * lpClassId [O] Destination for Class Id
1403 * Success: S_OK. lpClassId contains the Class Id requested.
1404 * Failure: E_FAIL, If lpUnknown is NULL,
1405 * E_NOINTERFACE If lpUnknown does not support IPersist,
1406 * Or an HRESULT error code.
1408 HRESULT WINAPI
IUnknown_GetClassID(IUnknown
*lpUnknown
, CLSID
* lpClassId
)
1410 IPersist
* lpPersist
;
1411 HRESULT hRet
= E_FAIL
;
1413 TRACE("(%p,%p)\n", lpUnknown
, debugstr_guid(lpClassId
));
1417 hRet
= IUnknown_QueryInterface(lpUnknown
,&IID_IPersist
,(void**)&lpPersist
);
1418 if (SUCCEEDED(hRet
))
1420 IPersist_GetClassID(lpPersist
, lpClassId
);
1421 IPersist_Release(lpPersist
);
1427 /*************************************************************************
1430 * Retrieve a Service Interface from an object.
1433 * lpUnknown [I] Object to get an IServiceProvider interface from
1434 * sid [I] Service ID for IServiceProvider_QueryService() call
1435 * riid [I] Function requested for QueryService call
1436 * lppOut [O] Destination for the service interface pointer
1439 * Success: S_OK. lppOut contains an object providing the requested service
1440 * Failure: An HRESULT error code
1443 * lpUnknown is expected to support the IServiceProvider interface.
1445 HRESULT WINAPI
IUnknown_QueryService(IUnknown
* lpUnknown
, REFGUID sid
, REFIID riid
,
1448 IServiceProvider
* pService
= NULL
;
1459 /* Get an IServiceProvider interface from the object */
1460 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IServiceProvider
,
1461 (LPVOID
*)&pService
);
1463 if (hRet
== S_OK
&& pService
)
1465 TRACE("QueryInterface returned (IServiceProvider*)%p\n", pService
);
1467 /* Get a Service interface from the object */
1468 hRet
= IServiceProvider_QueryService(pService
, sid
, riid
, lppOut
);
1470 TRACE("(IServiceProvider*)%p returned (IUnknown*)%p\n", pService
, *lppOut
);
1472 /* Release the IServiceProvider interface */
1473 IUnknown_Release(pService
);
1478 /*************************************************************************
1481 * Call an object's UIActivateIO method.
1484 * unknown [I] Object to call the UIActivateIO method on
1485 * activate [I] Parameter for UIActivateIO call
1486 * msg [I] Parameter for UIActivateIO call
1489 * Success: Value of UI_ActivateIO call
1490 * Failure: An HRESULT error code
1493 * unknown is expected to support the IInputObject interface.
1495 HRESULT WINAPI
IUnknown_UIActivateIO(IUnknown
*unknown
, BOOL activate
, LPMSG msg
)
1497 IInputObject
* object
= NULL
;
1503 /* Get an IInputObject interface from the object */
1504 ret
= IUnknown_QueryInterface(unknown
, &IID_IInputObject
, (LPVOID
*) &object
);
1508 ret
= IInputObject_UIActivateIO(object
, activate
, msg
);
1509 IUnknown_Release(object
);
1515 /*************************************************************************
1518 * Loads a popup menu.
1521 * hInst [I] Instance handle
1522 * szName [I] Menu name
1528 BOOL WINAPI
SHLoadMenuPopup(HINSTANCE hInst
, LPCWSTR szName
)
1532 if ((hMenu
= LoadMenuW(hInst
, szName
)))
1534 if (GetSubMenu(hMenu
, 0))
1535 RemoveMenu(hMenu
, 0, MF_BYPOSITION
);
1543 typedef struct _enumWndData
1548 LRESULT (WINAPI
*pfnPost
)(HWND
,UINT
,WPARAM
,LPARAM
);
1551 /* Callback for SHLWAPI_178 */
1552 static BOOL CALLBACK
SHLWAPI_EnumChildProc(HWND hWnd
, LPARAM lParam
)
1554 enumWndData
*data
= (enumWndData
*)lParam
;
1556 TRACE("(%p,%p)\n", hWnd
, data
);
1557 data
->pfnPost(hWnd
, data
->uiMsgId
, data
->wParam
, data
->lParam
);
1561 /*************************************************************************
1564 * Send or post a message to every child of a window.
1567 * hWnd [I] Window whose children will get the messages
1568 * uiMsgId [I] Message Id
1569 * wParam [I] WPARAM of message
1570 * lParam [I] LPARAM of message
1571 * bSend [I] TRUE = Use SendMessageA(), FALSE = Use PostMessageA()
1577 * The appropriate ASCII or Unicode function is called for the window.
1579 void WINAPI
SHPropagateMessage(HWND hWnd
, UINT uiMsgId
, WPARAM wParam
, LPARAM lParam
, BOOL bSend
)
1583 TRACE("(%p,%u,%ld,%ld,%d)\n", hWnd
, uiMsgId
, wParam
, lParam
, bSend
);
1587 data
.uiMsgId
= uiMsgId
;
1588 data
.wParam
= wParam
;
1589 data
.lParam
= lParam
;
1592 data
.pfnPost
= IsWindowUnicode(hWnd
) ? (void*)SendMessageW
: (void*)SendMessageA
;
1594 data
.pfnPost
= IsWindowUnicode(hWnd
) ? (void*)PostMessageW
: (void*)PostMessageA
;
1596 EnumChildWindows(hWnd
, SHLWAPI_EnumChildProc
, (LPARAM
)&data
);
1600 /*************************************************************************
1603 * Remove all sub-menus from a menu.
1606 * hMenu [I] Menu to remove sub-menus from
1609 * Success: 0. All sub-menus under hMenu are removed
1610 * Failure: -1, if any parameter is invalid
1612 DWORD WINAPI
SHRemoveAllSubMenus(HMENU hMenu
)
1614 int iItemCount
= GetMenuItemCount(hMenu
) - 1;
1615 while (iItemCount
>= 0)
1617 HMENU hSubMenu
= GetSubMenu(hMenu
, iItemCount
);
1619 RemoveMenu(hMenu
, iItemCount
, MF_BYPOSITION
);
1625 /*************************************************************************
1628 * Enable or disable a menu item.
1631 * hMenu [I] Menu holding menu item
1632 * uID [I] ID of menu item to enable/disable
1633 * bEnable [I] Whether to enable (TRUE) or disable (FALSE) the item.
1636 * The return code from EnableMenuItem.
1638 UINT WINAPI
SHEnableMenuItem(HMENU hMenu
, UINT wItemID
, BOOL bEnable
)
1640 return EnableMenuItem(hMenu
, wItemID
, bEnable
? MF_ENABLED
: MF_GRAYED
);
1643 /*************************************************************************
1646 * Check or uncheck a menu item.
1649 * hMenu [I] Menu holding menu item
1650 * uID [I] ID of menu item to check/uncheck
1651 * bCheck [I] Whether to check (TRUE) or uncheck (FALSE) the item.
1654 * The return code from CheckMenuItem.
1656 DWORD WINAPI
SHCheckMenuItem(HMENU hMenu
, UINT uID
, BOOL bCheck
)
1658 return CheckMenuItem(hMenu
, uID
, bCheck
? MF_CHECKED
: MF_UNCHECKED
);
1661 /*************************************************************************
1664 * Register a window class if it isn't already.
1667 * lpWndClass [I] Window class to register
1670 * The result of the RegisterClassA call.
1672 DWORD WINAPI
SHRegisterClassA(WNDCLASSA
*wndclass
)
1675 if (GetClassInfoA(wndclass
->hInstance
, wndclass
->lpszClassName
, &wca
))
1677 return (DWORD
)RegisterClassA(wndclass
);
1680 /*************************************************************************
1683 BOOL WINAPI
SHSimulateDrop(IDropTarget
*pDrop
, IDataObject
*pDataObj
,
1684 DWORD grfKeyState
, PPOINTL lpPt
, DWORD
* pdwEffect
)
1686 DWORD dwEffect
= DROPEFFECT_LINK
| DROPEFFECT_MOVE
| DROPEFFECT_COPY
;
1687 POINTL pt
= { 0, 0 };
1693 pdwEffect
= &dwEffect
;
1695 IDropTarget_DragEnter(pDrop
, pDataObj
, grfKeyState
, *lpPt
, pdwEffect
);
1698 return IDropTarget_Drop(pDrop
, pDataObj
, grfKeyState
, *lpPt
, pdwEffect
);
1700 IDropTarget_DragLeave(pDrop
);
1704 /*************************************************************************
1707 * Call IPersistPropertyBag_Load() on an object.
1710 * lpUnknown [I] Object supporting the IPersistPropertyBag interface
1711 * lpPropBag [O] Destination for loaded IPropertyBag
1715 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1717 DWORD WINAPI
SHLoadFromPropertyBag(IUnknown
*lpUnknown
, IPropertyBag
* lpPropBag
)
1719 IPersistPropertyBag
* lpPPBag
;
1720 HRESULT hRet
= E_FAIL
;
1722 TRACE("(%p,%p)\n", lpUnknown
, lpPropBag
);
1726 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IPersistPropertyBag
,
1728 if (SUCCEEDED(hRet
) && lpPPBag
)
1730 hRet
= IPersistPropertyBag_Load(lpPPBag
, lpPropBag
, NULL
);
1731 IPersistPropertyBag_Release(lpPPBag
);
1737 /*************************************************************************
1740 * Call IOleControlSite_TranslateAccelerator() on an object.
1743 * lpUnknown [I] Object supporting the IOleControlSite interface.
1744 * lpMsg [I] Key message to be processed.
1745 * dwModifiers [I] Flags containing the state of the modifier keys.
1749 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
1751 HRESULT WINAPI
IUnknown_TranslateAcceleratorOCS(IUnknown
*lpUnknown
, LPMSG lpMsg
, DWORD dwModifiers
)
1753 IOleControlSite
* lpCSite
= NULL
;
1754 HRESULT hRet
= E_INVALIDARG
;
1756 TRACE("(%p,%p,0x%08x)\n", lpUnknown
, lpMsg
, dwModifiers
);
1759 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleControlSite
,
1761 if (SUCCEEDED(hRet
) && lpCSite
)
1763 hRet
= IOleControlSite_TranslateAccelerator(lpCSite
, lpMsg
, dwModifiers
);
1764 IOleControlSite_Release(lpCSite
);
1771 /*************************************************************************
1774 * Call IOleControlSite_OnFocus() on an object.
1777 * lpUnknown [I] Object supporting the IOleControlSite interface.
1778 * fGotFocus [I] Whether focus was gained (TRUE) or lost (FALSE).
1782 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1784 HRESULT WINAPI
IUnknown_OnFocusOCS(IUnknown
*lpUnknown
, BOOL fGotFocus
)
1786 IOleControlSite
* lpCSite
= NULL
;
1787 HRESULT hRet
= E_FAIL
;
1789 TRACE("(%p,%s)\n", lpUnknown
, fGotFocus
? "TRUE" : "FALSE");
1792 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleControlSite
,
1794 if (SUCCEEDED(hRet
) && lpCSite
)
1796 hRet
= IOleControlSite_OnFocus(lpCSite
, fGotFocus
);
1797 IOleControlSite_Release(lpCSite
);
1803 /*************************************************************************
1806 HRESULT WINAPI
IUnknown_HandleIRestrict(LPUNKNOWN lpUnknown
, PVOID lpArg1
,
1807 PVOID lpArg2
, PVOID lpArg3
, PVOID lpArg4
)
1809 /* FIXME: {D12F26B2-D90A-11D0-830D-00AA005B4383} - What object does this represent? */
1810 static const DWORD service_id
[] = { 0xd12f26b2, 0x11d0d90a, 0xaa000d83, 0x83435b00 };
1811 /* FIXME: {D12F26B1-D90A-11D0-830D-00AA005B4383} - Also Unknown/undocumented */
1812 static const DWORD function_id
[] = { 0xd12f26b1, 0x11d0d90a, 0xaa000d83, 0x83435b00 };
1813 HRESULT hRet
= E_INVALIDARG
;
1814 LPUNKNOWN lpUnkInner
= NULL
; /* FIXME: Real type is unknown */
1816 TRACE("(%p,%p,%p,%p,%p)\n", lpUnknown
, lpArg1
, lpArg2
, lpArg3
, lpArg4
);
1818 if (lpUnknown
&& lpArg4
)
1820 hRet
= IUnknown_QueryService(lpUnknown
, (REFGUID
)service_id
,
1821 (REFGUID
)function_id
, (void**)&lpUnkInner
);
1823 if (SUCCEEDED(hRet
) && lpUnkInner
)
1825 /* FIXME: The type of service object requested is unknown, however
1826 * testing shows that its first method is called with 4 parameters.
1827 * Fake this by using IParseDisplayName_ParseDisplayName since the
1828 * signature and position in the vtable matches our unknown object type.
1830 hRet
= IParseDisplayName_ParseDisplayName((LPPARSEDISPLAYNAME
)lpUnkInner
,
1831 lpArg1
, lpArg2
, lpArg3
, lpArg4
);
1832 IUnknown_Release(lpUnkInner
);
1838 /*************************************************************************
1841 * Get a sub-menu from a menu item.
1844 * hMenu [I] Menu to get sub-menu from
1845 * uID [I] ID of menu item containing sub-menu
1848 * The sub-menu of the item, or a NULL handle if any parameters are invalid.
1850 HMENU WINAPI
SHGetMenuFromID(HMENU hMenu
, UINT uID
)
1854 TRACE("(%p,%u)\n", hMenu
, uID
);
1856 mi
.cbSize
= sizeof(mi
);
1857 mi
.fMask
= MIIM_SUBMENU
;
1859 if (!GetMenuItemInfoW(hMenu
, uID
, FALSE
, &mi
))
1865 /*************************************************************************
1868 * Get the color depth of the primary display.
1874 * The color depth of the primary display.
1876 DWORD WINAPI
SHGetCurColorRes(void)
1884 ret
= GetDeviceCaps(hdc
, BITSPIXEL
) * GetDeviceCaps(hdc
, PLANES
);
1889 /*************************************************************************
1892 * Wait for a message to arrive, with a timeout.
1895 * hand [I] Handle to query
1896 * dwTimeout [I] Timeout in ticks or INFINITE to never timeout
1899 * STATUS_TIMEOUT if no message is received before dwTimeout ticks passes.
1900 * Otherwise returns the value from MsgWaitForMultipleObjectsEx when a
1901 * message is available.
1903 DWORD WINAPI
SHWaitForSendMessageThread(HANDLE hand
, DWORD dwTimeout
)
1905 DWORD dwEndTicks
= GetTickCount() + dwTimeout
;
1908 while ((dwRet
= MsgWaitForMultipleObjectsEx(1, &hand
, dwTimeout
, QS_SENDMESSAGE
, 0)) == 1)
1912 PeekMessageW(&msg
, NULL
, 0, 0, PM_NOREMOVE
);
1914 if (dwTimeout
!= INFINITE
)
1916 if ((int)(dwTimeout
= dwEndTicks
- GetTickCount()) <= 0)
1917 return WAIT_TIMEOUT
;
1924 /*************************************************************************
1927 * Determine if a shell folder can be expanded.
1930 * lpFolder [I] Parent folder containing the object to test.
1931 * pidl [I] Id of the object to test.
1934 * Success: S_OK, if the object is expandable, S_FALSE otherwise.
1935 * Failure: E_INVALIDARG, if any argument is invalid.
1938 * If the object to be tested does not expose the IQueryInfo() interface it
1939 * will not be identified as an expandable folder.
1941 HRESULT WINAPI
SHIsExpandableFolder(LPSHELLFOLDER lpFolder
, LPCITEMIDLIST pidl
)
1943 HRESULT hRet
= E_INVALIDARG
;
1946 if (lpFolder
&& pidl
)
1948 hRet
= IShellFolder_GetUIObjectOf(lpFolder
, NULL
, 1, &pidl
, &IID_IQueryInfo
,
1949 NULL
, (void**)&lpInfo
);
1951 hRet
= S_FALSE
; /* Doesn't expose IQueryInfo */
1956 /* MSDN states of IQueryInfo_GetInfoFlags() that "This method is not
1957 * currently used". Really? You wouldn't be holding out on me would you?
1959 hRet
= IQueryInfo_GetInfoFlags(lpInfo
, &dwFlags
);
1961 if (SUCCEEDED(hRet
))
1963 /* 0x2 is an undocumented flag apparently indicating expandability */
1964 hRet
= dwFlags
& 0x2 ? S_OK
: S_FALSE
;
1967 IQueryInfo_Release(lpInfo
);
1973 /*************************************************************************
1976 * Blank out a region of text by drawing the background only.
1979 * hDC [I] Device context to draw in
1980 * pRect [I] Area to draw in
1981 * cRef [I] Color to draw in
1986 DWORD WINAPI
SHFillRectClr(HDC hDC
, LPCRECT pRect
, COLORREF cRef
)
1988 COLORREF cOldColor
= SetBkColor(hDC
, cRef
);
1989 ExtTextOutA(hDC
, 0, 0, ETO_OPAQUE
, pRect
, 0, 0, 0);
1990 SetBkColor(hDC
, cOldColor
);
1994 /*************************************************************************
1997 * Return the value associated with a key in a map.
2000 * lpKeys [I] A list of keys of length iLen
2001 * lpValues [I] A list of values associated with lpKeys, of length iLen
2002 * iLen [I] Length of both lpKeys and lpValues
2003 * iKey [I] The key value to look up in lpKeys
2006 * The value in lpValues associated with iKey, or -1 if iKey is not
2010 * - If two elements in the map share the same key, this function returns
2011 * the value closest to the start of the map
2012 * - The native version of this function crashes if lpKeys or lpValues is NULL.
2014 int WINAPI
SHSearchMapInt(const int *lpKeys
, const int *lpValues
, int iLen
, int iKey
)
2016 if (lpKeys
&& lpValues
)
2022 if (lpKeys
[i
] == iKey
)
2023 return lpValues
[i
]; /* Found */
2027 return -1; /* Not found */
2031 /*************************************************************************
2034 * Copy an interface pointer
2037 * lppDest [O] Destination for copy
2038 * lpUnknown [I] Source for copy
2043 VOID WINAPI
IUnknown_Set(IUnknown
**lppDest
, IUnknown
*lpUnknown
)
2045 TRACE("(%p,%p)\n", lppDest
, lpUnknown
);
2048 IUnknown_AtomicRelease(lppDest
); /* Release existing interface */
2053 IUnknown_AddRef(lpUnknown
);
2054 *lppDest
= lpUnknown
;
2058 /*************************************************************************
2062 HRESULT WINAPI
MayQSForward(IUnknown
* lpUnknown
, PVOID lpReserved
,
2063 REFGUID riidCmdGrp
, ULONG cCmds
,
2064 OLECMD
*prgCmds
, OLECMDTEXT
* pCmdText
)
2066 FIXME("(%p,%p,%p,%d,%p,%p) - stub\n",
2067 lpUnknown
, lpReserved
, riidCmdGrp
, cCmds
, prgCmds
, pCmdText
);
2069 /* FIXME: Calls IsQSForward & IUnknown_QueryStatus */
2070 return DRAGDROP_E_NOTREGISTERED
;
2073 /*************************************************************************
2077 HRESULT WINAPI
MayExecForward(IUnknown
* lpUnknown
, INT iUnk
, REFGUID pguidCmdGroup
,
2078 DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
* pvaIn
,
2081 FIXME("(%p,%d,%p,%d,%d,%p,%p) - stub!\n", lpUnknown
, iUnk
, pguidCmdGroup
,
2082 nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2083 return DRAGDROP_E_NOTREGISTERED
;
2086 /*************************************************************************
2090 HRESULT WINAPI
IsQSForward(REFGUID pguidCmdGroup
,ULONG cCmds
, OLECMD
*prgCmds
)
2092 FIXME("(%p,%d,%p) - stub!\n", pguidCmdGroup
, cCmds
, prgCmds
);
2093 return DRAGDROP_E_NOTREGISTERED
;
2096 /*************************************************************************
2099 * Determine if a window is not a child of another window.
2102 * hParent [I] Suspected parent window
2103 * hChild [I] Suspected child window
2106 * TRUE: If hChild is a child window of hParent
2107 * FALSE: If hChild is not a child window of hParent, or they are equal
2109 BOOL WINAPI
SHIsChildOrSelf(HWND hParent
, HWND hChild
)
2111 TRACE("(%p,%p)\n", hParent
, hChild
);
2113 if (!hParent
|| !hChild
)
2115 else if(hParent
== hChild
)
2117 return !IsChild(hParent
, hChild
);
2120 /*************************************************************************
2121 * FDSA functions. Manage a dynamic array of fixed size memory blocks.
2126 DWORD num_items
; /* Number of elements inserted */
2127 void *mem
; /* Ptr to array */
2128 DWORD blocks_alloced
; /* Number of elements allocated */
2129 BYTE inc
; /* Number of elements to grow by when we need to expand */
2130 BYTE block_size
; /* Size in bytes of an element */
2131 BYTE flags
; /* Flags */
2134 #define FDSA_FLAG_INTERNAL_ALLOC 0x01 /* When set we have allocated mem internally */
2136 /*************************************************************************
2139 * Initialize an FDSA array.
2141 BOOL WINAPI
FDSA_Initialize(DWORD block_size
, DWORD inc
, FDSA_info
*info
, void *mem
,
2144 TRACE("(0x%08x 0x%08x %p %p 0x%08x)\n", block_size
, inc
, info
, mem
, init_blocks
);
2150 memset(mem
, 0, block_size
* init_blocks
);
2152 info
->num_items
= 0;
2155 info
->blocks_alloced
= init_blocks
;
2156 info
->block_size
= block_size
;
2162 /*************************************************************************
2165 * Destroy an FDSA array
2167 BOOL WINAPI
FDSA_Destroy(FDSA_info
*info
)
2169 TRACE("(%p)\n", info
);
2171 if(info
->flags
& FDSA_FLAG_INTERNAL_ALLOC
)
2173 HeapFree(GetProcessHeap(), 0, info
->mem
);
2180 /*************************************************************************
2183 * Insert element into an FDSA array
2185 DWORD WINAPI
FDSA_InsertItem(FDSA_info
*info
, DWORD where
, const void *block
)
2187 TRACE("(%p 0x%08x %p)\n", info
, where
, block
);
2188 if(where
> info
->num_items
)
2189 where
= info
->num_items
;
2191 if(info
->num_items
>= info
->blocks_alloced
)
2193 DWORD size
= (info
->blocks_alloced
+ info
->inc
) * info
->block_size
;
2194 if(info
->flags
& 0x1)
2195 info
->mem
= HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, info
->mem
, size
);
2198 void *old_mem
= info
->mem
;
2199 info
->mem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
2200 memcpy(info
->mem
, old_mem
, info
->blocks_alloced
* info
->block_size
);
2202 info
->blocks_alloced
+= info
->inc
;
2206 if(where
< info
->num_items
)
2208 memmove((char*)info
->mem
+ (where
+ 1) * info
->block_size
,
2209 (char*)info
->mem
+ where
* info
->block_size
,
2210 (info
->num_items
- where
) * info
->block_size
);
2212 memcpy((char*)info
->mem
+ where
* info
->block_size
, block
, info
->block_size
);
2218 /*************************************************************************
2221 * Delete an element from an FDSA array.
2223 BOOL WINAPI
FDSA_DeleteItem(FDSA_info
*info
, DWORD where
)
2225 TRACE("(%p 0x%08x)\n", info
, where
);
2227 if(where
>= info
->num_items
)
2230 if(where
< info
->num_items
- 1)
2232 memmove((char*)info
->mem
+ where
* info
->block_size
,
2233 (char*)info
->mem
+ (where
+ 1) * info
->block_size
,
2234 (info
->num_items
- where
- 1) * info
->block_size
);
2236 memset((char*)info
->mem
+ (info
->num_items
- 1) * info
->block_size
,
2237 0, info
->block_size
);
2248 /*************************************************************************
2251 * Call IUnknown_QueryInterface() on a table of objects.
2255 * Failure: E_POINTER or E_NOINTERFACE.
2257 HRESULT WINAPI
QISearch(
2258 LPVOID w
, /* [in] Table of interfaces */
2259 IFACE_INDEX_TBL
*x
, /* [in] Array of REFIIDs and indexes into the table */
2260 REFIID riid
, /* [in] REFIID to get interface for */
2261 LPVOID
*ppv
) /* [out] Destination for interface pointer */
2265 IFACE_INDEX_TBL
*xmove
;
2267 TRACE("(%p %p %s %p)\n", w
,x
,debugstr_guid(riid
),ppv
);
2270 while (xmove
->refid
) {
2271 TRACE("trying (indx %d) %s\n", xmove
->indx
, debugstr_guid(xmove
->refid
));
2272 if (IsEqualIID(riid
, xmove
->refid
)) {
2273 a_vtbl
= (IUnknown
*)(xmove
->indx
+ (LPBYTE
)w
);
2274 TRACE("matched, returning (%p)\n", a_vtbl
);
2276 IUnknown_AddRef(a_vtbl
);
2282 if (IsEqualIID(riid
, &IID_IUnknown
)) {
2283 a_vtbl
= (IUnknown
*)(x
->indx
+ (LPBYTE
)w
);
2284 TRACE("returning first for IUnknown (%p)\n", a_vtbl
);
2286 IUnknown_AddRef(a_vtbl
);
2290 ret
= E_NOINTERFACE
;
2294 TRACE("-- 0x%08x\n", ret
);
2298 /*************************************************************************
2301 * Set the Font for a window and the "PropDlgFont" property of the parent window.
2304 * hWnd [I] Parent Window to set the property
2305 * id [I] Index of child Window to set the Font
2311 HRESULT WINAPI
SHSetDefaultDialogFont(HWND hWnd
, INT id
)
2313 FIXME("(%p, %d) stub\n", hWnd
, id
);
2317 /*************************************************************************
2320 * Remove the "PropDlgFont" property from a window.
2323 * hWnd [I] Window to remove the property from
2326 * A handle to the removed property, or NULL if it did not exist.
2328 HANDLE WINAPI
SHRemoveDefaultDialogFont(HWND hWnd
)
2332 TRACE("(%p)\n", hWnd
);
2334 hProp
= GetPropA(hWnd
, "PropDlgFont");
2338 DeleteObject(hProp
);
2339 hProp
= RemovePropA(hWnd
, "PropDlgFont");
2344 /*************************************************************************
2347 * Load the in-process server of a given GUID.
2350 * refiid [I] GUID of the server to load.
2353 * Success: A handle to the loaded server dll.
2354 * Failure: A NULL handle.
2356 HMODULE WINAPI
SHPinDllOfCLSID(REFIID refiid
)
2360 CHAR value
[MAX_PATH
], string
[MAX_PATH
];
2362 strcpy(string
, "CLSID\\");
2363 SHStringFromGUIDA(refiid
, string
+ 6, sizeof(string
)/sizeof(char) - 6);
2364 strcat(string
, "\\InProcServer32");
2367 RegOpenKeyExA(HKEY_CLASSES_ROOT
, string
, 0, 1, &newkey
);
2368 RegQueryValueExA(newkey
, 0, 0, &type
, (PBYTE
)value
, &count
);
2369 RegCloseKey(newkey
);
2370 return LoadLibraryExA(value
, 0, 0);
2373 /*************************************************************************
2376 * Unicode version of SHLWAPI_183.
2378 DWORD WINAPI
SHRegisterClassW(WNDCLASSW
* lpWndClass
)
2382 TRACE("(%p %s)\n",lpWndClass
->hInstance
, debugstr_w(lpWndClass
->lpszClassName
));
2384 if (GetClassInfoW(lpWndClass
->hInstance
, lpWndClass
->lpszClassName
, &WndClass
))
2386 return RegisterClassW(lpWndClass
);
2389 /*************************************************************************
2392 * Unregister a list of classes.
2395 * hInst [I] Application instance that registered the classes
2396 * lppClasses [I] List of class names
2397 * iCount [I] Number of names in lppClasses
2402 void WINAPI
SHUnregisterClassesA(HINSTANCE hInst
, LPCSTR
*lppClasses
, INT iCount
)
2406 TRACE("(%p,%p,%d)\n", hInst
, lppClasses
, iCount
);
2410 if (GetClassInfoA(hInst
, *lppClasses
, &WndClass
))
2411 UnregisterClassA(*lppClasses
, hInst
);
2417 /*************************************************************************
2420 * Unicode version of SHUnregisterClassesA.
2422 void WINAPI
SHUnregisterClassesW(HINSTANCE hInst
, LPCWSTR
*lppClasses
, INT iCount
)
2426 TRACE("(%p,%p,%d)\n", hInst
, lppClasses
, iCount
);
2430 if (GetClassInfoW(hInst
, *lppClasses
, &WndClass
))
2431 UnregisterClassW(*lppClasses
, hInst
);
2437 /*************************************************************************
2440 * Call The correct (Ascii/Unicode) default window procedure for a window.
2443 * hWnd [I] Window to call the default procedure for
2444 * uMessage [I] Message ID
2445 * wParam [I] WPARAM of message
2446 * lParam [I] LPARAM of message
2449 * The result of calling DefWindowProcA() or DefWindowProcW().
2451 LRESULT CALLBACK
SHDefWindowProc(HWND hWnd
, UINT uMessage
, WPARAM wParam
, LPARAM lParam
)
2453 if (IsWindowUnicode(hWnd
))
2454 return DefWindowProcW(hWnd
, uMessage
, wParam
, lParam
);
2455 return DefWindowProcA(hWnd
, uMessage
, wParam
, lParam
);
2458 /*************************************************************************
2461 HRESULT WINAPI
IUnknown_GetSite(LPUNKNOWN lpUnknown
, REFIID iid
, PVOID
*lppSite
)
2463 HRESULT hRet
= E_INVALIDARG
;
2464 LPOBJECTWITHSITE lpSite
= NULL
;
2466 TRACE("(%p,%s,%p)\n", lpUnknown
, debugstr_guid(iid
), lppSite
);
2468 if (lpUnknown
&& iid
&& lppSite
)
2470 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IObjectWithSite
,
2472 if (SUCCEEDED(hRet
) && lpSite
)
2474 hRet
= IObjectWithSite_GetSite(lpSite
, iid
, lppSite
);
2475 IObjectWithSite_Release(lpSite
);
2481 /*************************************************************************
2484 * Create a worker window using CreateWindowExA().
2487 * wndProc [I] Window procedure
2488 * hWndParent [I] Parent window
2489 * dwExStyle [I] Extra style flags
2490 * dwStyle [I] Style flags
2491 * hMenu [I] Window menu
2495 * Success: The window handle of the newly created window.
2498 HWND WINAPI
SHCreateWorkerWindowA(LONG wndProc
, HWND hWndParent
, DWORD dwExStyle
,
2499 DWORD dwStyle
, HMENU hMenu
, LONG z
)
2501 static const char szClass
[] = "WorkerA";
2505 TRACE("(0x%08x,%p,0x%08x,0x%08x,%p,0x%08x)\n",
2506 wndProc
, hWndParent
, dwExStyle
, dwStyle
, hMenu
, z
);
2508 /* Create Window class */
2510 wc
.lpfnWndProc
= DefWindowProcA
;
2513 wc
.hInstance
= shlwapi_hInstance
;
2515 wc
.hCursor
= LoadCursorA(NULL
, (LPSTR
)IDC_ARROW
);
2516 wc
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
2517 wc
.lpszMenuName
= NULL
;
2518 wc
.lpszClassName
= szClass
;
2520 SHRegisterClassA(&wc
); /* Register class */
2522 /* FIXME: Set extra bits in dwExStyle */
2524 hWnd
= CreateWindowExA(dwExStyle
, szClass
, 0, dwStyle
, 0, 0, 0, 0,
2525 hWndParent
, hMenu
, shlwapi_hInstance
, 0);
2528 SetWindowLongPtrW(hWnd
, DWLP_MSGRESULT
, z
);
2531 SetWindowLongPtrA(hWnd
, GWLP_WNDPROC
, wndProc
);
2536 typedef struct tagPOLICYDATA
2538 DWORD policy
; /* flags value passed to SHRestricted */
2539 LPCWSTR appstr
; /* application str such as "Explorer" */
2540 LPCWSTR keystr
; /* name of the actual registry key / policy */
2541 } POLICYDATA
, *LPPOLICYDATA
;
2543 #define SHELL_NO_POLICY 0xffffffff
2545 /* default shell policy registry key */
2546 static const WCHAR strRegistryPolicyW
[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o',
2547 's','o','f','t','\\','W','i','n','d','o','w','s','\\',
2548 'C','u','r','r','e','n','t','V','e','r','s','i','o','n',
2549 '\\','P','o','l','i','c','i','e','s',0};
2551 /*************************************************************************
2554 * Retrieve a policy value from the registry.
2557 * lpSubKey [I] registry key name
2558 * lpSubName [I] subname of registry key
2559 * lpValue [I] value name of registry value
2562 * the value associated with the registry key or 0 if not found
2564 DWORD WINAPI
SHGetRestriction(LPCWSTR lpSubKey
, LPCWSTR lpSubName
, LPCWSTR lpValue
)
2566 DWORD retval
, datsize
= sizeof(retval
);
2570 lpSubKey
= strRegistryPolicyW
;
2572 retval
= RegOpenKeyW(HKEY_LOCAL_MACHINE
, lpSubKey
, &hKey
);
2573 if (retval
!= ERROR_SUCCESS
)
2574 retval
= RegOpenKeyW(HKEY_CURRENT_USER
, lpSubKey
, &hKey
);
2575 if (retval
!= ERROR_SUCCESS
)
2578 SHGetValueW(hKey
, lpSubName
, lpValue
, NULL
, &retval
, &datsize
);
2583 /*************************************************************************
2586 * Helper function to retrieve the possibly cached value for a specific policy
2589 * policy [I] The policy to look for
2590 * initial [I] Main registry key to open, if NULL use default
2591 * polTable [I] Table of known policies, 0 terminated
2592 * polArr [I] Cache array of policy values
2595 * The retrieved policy value or 0 if not successful
2598 * This function is used by the native SHRestricted function to search for the
2599 * policy and cache it once retrieved. The current Wine implementation uses a
2600 * different POLICYDATA structure and implements a similar algorithm adapted to
2603 DWORD WINAPI
SHRestrictionLookup(
2606 LPPOLICYDATA polTable
,
2609 TRACE("(0x%08x %s %p %p)\n", policy
, debugstr_w(initial
), polTable
, polArr
);
2611 if (!polTable
|| !polArr
)
2614 for (;polTable
->policy
; polTable
++, polArr
++)
2616 if (policy
== polTable
->policy
)
2618 /* we have a known policy */
2620 /* check if this policy has been cached */
2621 if (*polArr
== SHELL_NO_POLICY
)
2622 *polArr
= SHGetRestriction(initial
, polTable
->appstr
, polTable
->keystr
);
2626 /* we don't know this policy, return 0 */
2627 TRACE("unknown policy: (%08x)\n", policy
);
2631 /*************************************************************************
2634 * Get an interface from an object.
2637 * Success: S_OK. ppv contains the requested interface.
2638 * Failure: An HRESULT error code.
2641 * This QueryInterface asks the inner object for an interface. In case
2642 * of aggregation this request would be forwarded by the inner to the
2643 * outer object. This function asks the inner object directly for the
2644 * interface circumventing the forwarding to the outer object.
2646 HRESULT WINAPI
SHWeakQueryInterface(
2647 IUnknown
* pUnk
, /* [in] Outer object */
2648 IUnknown
* pInner
, /* [in] Inner object */
2649 IID
* riid
, /* [in] Interface GUID to query for */
2650 LPVOID
* ppv
) /* [out] Destination for queried interface */
2652 HRESULT hret
= E_NOINTERFACE
;
2653 TRACE("(pUnk=%p pInner=%p\n\tIID: %s %p)\n",pUnk
,pInner
,debugstr_guid(riid
), ppv
);
2656 if(pUnk
&& pInner
) {
2657 hret
= IUnknown_QueryInterface(pInner
, riid
, ppv
);
2658 if (SUCCEEDED(hret
)) IUnknown_Release(pUnk
);
2660 TRACE("-- 0x%08x\n", hret
);
2664 /*************************************************************************
2667 * Move a reference from one interface to another.
2670 * lpDest [O] Destination to receive the reference
2671 * lppUnknown [O] Source to give up the reference to lpDest
2676 VOID WINAPI
SHWeakReleaseInterface(IUnknown
*lpDest
, IUnknown
**lppUnknown
)
2678 TRACE("(%p,%p)\n", lpDest
, lppUnknown
);
2683 IUnknown_AddRef(lpDest
);
2684 IUnknown_AtomicRelease(lppUnknown
); /* Release existing interface */
2688 /*************************************************************************
2691 * Convert an ASCII string of a CLSID into a CLSID.
2694 * idstr [I] String representing a CLSID in registry format
2695 * id [O] Destination for the converted CLSID
2698 * Success: TRUE. id contains the converted CLSID.
2701 BOOL WINAPI
GUIDFromStringA(LPCSTR idstr
, CLSID
*id
)
2704 MultiByteToWideChar(CP_ACP
, 0, idstr
, -1, wClsid
, sizeof(wClsid
)/sizeof(WCHAR
));
2705 return SUCCEEDED(CLSIDFromString(wClsid
, id
));
2708 /*************************************************************************
2711 * Unicode version of GUIDFromStringA.
2713 BOOL WINAPI
GUIDFromStringW(LPCWSTR idstr
, CLSID
*id
)
2715 return SUCCEEDED(CLSIDFromString((LPOLESTR
)idstr
, id
));
2718 /*************************************************************************
2721 * Determine if the browser is integrated into the shell, and set a registry
2728 * 1, If the browser is not integrated.
2729 * 2, If the browser is integrated.
2732 * The key "HKLM\Software\Microsoft\Internet Explorer\IntegratedBrowser" is
2733 * either set to TRUE, or removed depending on whether the browser is deemed
2736 DWORD WINAPI
WhichPlatform(void)
2738 static const char szIntegratedBrowser
[] = "IntegratedBrowser";
2739 static DWORD dwState
= 0;
2741 DWORD dwRet
, dwData
, dwSize
;
2747 /* If shell32 exports DllGetVersion(), the browser is integrated */
2749 hshell32
= LoadLibraryA("shell32.dll");
2752 FARPROC pDllGetVersion
;
2753 pDllGetVersion
= GetProcAddress(hshell32
, "DllGetVersion");
2754 dwState
= pDllGetVersion
? 2 : 1;
2755 FreeLibrary(hshell32
);
2758 /* Set or delete the key accordingly */
2759 dwRet
= RegOpenKeyExA(HKEY_LOCAL_MACHINE
,
2760 "Software\\Microsoft\\Internet Explorer", 0,
2761 KEY_ALL_ACCESS
, &hKey
);
2764 dwRet
= RegQueryValueExA(hKey
, szIntegratedBrowser
, 0, 0,
2765 (LPBYTE
)&dwData
, &dwSize
);
2767 if (!dwRet
&& dwState
== 1)
2769 /* Value exists but browser is not integrated */
2770 RegDeleteValueA(hKey
, szIntegratedBrowser
);
2772 else if (dwRet
&& dwState
== 2)
2774 /* Browser is integrated but value does not exist */
2776 RegSetValueExA(hKey
, szIntegratedBrowser
, 0, REG_DWORD
,
2777 (LPBYTE
)&dwData
, sizeof(dwData
));
2784 /*************************************************************************
2787 * Unicode version of SHCreateWorkerWindowA.
2789 HWND WINAPI
SHCreateWorkerWindowW(LONG wndProc
, HWND hWndParent
, DWORD dwExStyle
,
2790 DWORD dwStyle
, HMENU hMenu
, LONG z
)
2792 static const WCHAR szClass
[] = { 'W', 'o', 'r', 'k', 'e', 'r', 'W', '\0' };
2796 TRACE("(0x%08x,%p,0x%08x,0x%08x,%p,0x%08x)\n",
2797 wndProc
, hWndParent
, dwExStyle
, dwStyle
, hMenu
, z
);
2799 /* If our OS is natively ASCII, use the ASCII version */
2800 if (!(GetVersion() & 0x80000000)) /* NT */
2801 return SHCreateWorkerWindowA(wndProc
, hWndParent
, dwExStyle
, dwStyle
, hMenu
, z
);
2803 /* Create Window class */
2805 wc
.lpfnWndProc
= DefWindowProcW
;
2808 wc
.hInstance
= shlwapi_hInstance
;
2810 wc
.hCursor
= LoadCursorW(NULL
, (LPWSTR
)IDC_ARROW
);
2811 wc
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
2812 wc
.lpszMenuName
= NULL
;
2813 wc
.lpszClassName
= szClass
;
2815 SHRegisterClassW(&wc
); /* Register class */
2817 /* FIXME: Set extra bits in dwExStyle */
2819 hWnd
= CreateWindowExW(dwExStyle
, szClass
, 0, dwStyle
, 0, 0, 0, 0,
2820 hWndParent
, hMenu
, shlwapi_hInstance
, 0);
2823 SetWindowLongPtrW(hWnd
, DWLP_MSGRESULT
, z
);
2826 SetWindowLongPtrW(hWnd
, GWLP_WNDPROC
, wndProc
);
2831 /*************************************************************************
2834 * Get and show a context menu from a shell folder.
2837 * hWnd [I] Window displaying the shell folder
2838 * lpFolder [I] IShellFolder interface
2839 * lpApidl [I] Id for the particular folder desired
2843 * Failure: An HRESULT error code indicating the error.
2845 HRESULT WINAPI
SHInvokeDefaultCommand(HWND hWnd
, IShellFolder
* lpFolder
, LPCITEMIDLIST lpApidl
)
2847 return SHInvokeCommand(hWnd
, lpFolder
, lpApidl
, FALSE
);
2850 /*************************************************************************
2853 * _SHPackDispParamsV
2855 HRESULT WINAPI
SHPackDispParamsV(DISPPARAMS
*params
, VARIANTARG
*args
, UINT cnt
, __ms_va_list valist
)
2859 TRACE("(%p %p %u ...)\n", params
, args
, cnt
);
2861 params
->rgvarg
= args
;
2862 params
->rgdispidNamedArgs
= NULL
;
2863 params
->cArgs
= cnt
;
2864 params
->cNamedArgs
= 0;
2868 while(iter
-- > args
) {
2869 V_VT(iter
) = va_arg(valist
, enum VARENUM
);
2871 TRACE("vt=%d\n", V_VT(iter
));
2873 if(V_VT(iter
) & VT_BYREF
) {
2874 V_BYREF(iter
) = va_arg(valist
, LPVOID
);
2876 switch(V_VT(iter
)) {
2878 V_I4(iter
) = va_arg(valist
, LONG
);
2881 V_BSTR(iter
) = va_arg(valist
, BSTR
);
2884 V_DISPATCH(iter
) = va_arg(valist
, IDispatch
*);
2887 V_BOOL(iter
) = va_arg(valist
, int);
2890 V_UNKNOWN(iter
) = va_arg(valist
, IUnknown
*);
2894 V_I4(iter
) = va_arg(valist
, LONG
);
2902 /*************************************************************************
2907 HRESULT WINAPIV
SHPackDispParams(DISPPARAMS
*params
, VARIANTARG
*args
, UINT cnt
, ...)
2909 __ms_va_list valist
;
2912 __ms_va_start(valist
, cnt
);
2913 hres
= SHPackDispParamsV(params
, args
, cnt
, valist
);
2914 __ms_va_end(valist
);
2918 /*************************************************************************
2919 * SHLWAPI_InvokeByIID
2921 * This helper function calls IDispatch::Invoke for each sink
2922 * which implements given iid or IDispatch.
2925 static HRESULT
SHLWAPI_InvokeByIID(
2926 IConnectionPoint
* iCP
,
2929 DISPPARAMS
* dispParams
)
2931 IEnumConnections
*enumerator
;
2933 static DISPPARAMS empty
= {NULL
, NULL
, 0, 0};
2934 DISPPARAMS
* params
= dispParams
;
2936 HRESULT result
= IConnectionPoint_EnumConnections(iCP
, &enumerator
);
2940 /* Invoke is never happening with an NULL dispParams */
2944 while(IEnumConnections_Next(enumerator
, 1, &rgcd
, NULL
)==S_OK
)
2946 IDispatch
*dispIface
;
2947 if ((iid
&& SUCCEEDED(IUnknown_QueryInterface(rgcd
.pUnk
, iid
, (LPVOID
*)&dispIface
))) ||
2948 SUCCEEDED(IUnknown_QueryInterface(rgcd
.pUnk
, &IID_IDispatch
, (LPVOID
*)&dispIface
)))
2950 IDispatch_Invoke(dispIface
, dispId
, &IID_NULL
, 0, DISPATCH_METHOD
, params
, NULL
, NULL
, NULL
);
2951 IDispatch_Release(dispIface
);
2953 IUnknown_Release(rgcd
.pUnk
);
2956 IEnumConnections_Release(enumerator
);
2961 /*************************************************************************
2962 * IConnectionPoint_InvokeWithCancel [SHLWAPI.283]
2964 HRESULT WINAPI
IConnectionPoint_InvokeWithCancel( IConnectionPoint
* iCP
,
2965 DISPID dispId
, DISPPARAMS
* dispParams
,
2966 DWORD unknown1
, DWORD unknown2
)
2971 FIXME("(%p)->(0x%x %p %x %x) partial stub\n", iCP
, dispId
, dispParams
, unknown1
, unknown2
);
2973 result
= IConnectionPoint_GetConnectionInterface(iCP
, &iid
);
2974 if (SUCCEEDED(result
))
2975 result
= SHLWAPI_InvokeByIID(iCP
, &iid
, dispId
, dispParams
);
2977 result
= SHLWAPI_InvokeByIID(iCP
, NULL
, dispId
, dispParams
);
2983 /*************************************************************************
2986 * IConnectionPoint_SimpleInvoke
2988 HRESULT WINAPI
IConnectionPoint_SimpleInvoke(
2989 IConnectionPoint
* iCP
,
2991 DISPPARAMS
* dispParams
)
2996 TRACE("(%p)->(0x%x %p)\n",iCP
,dispId
,dispParams
);
2998 result
= IConnectionPoint_GetConnectionInterface(iCP
, &iid
);
2999 if (SUCCEEDED(result
))
3000 result
= SHLWAPI_InvokeByIID(iCP
, &iid
, dispId
, dispParams
);
3002 result
= SHLWAPI_InvokeByIID(iCP
, NULL
, dispId
, dispParams
);
3007 /*************************************************************************
3010 * Notify an IConnectionPoint object of changes.
3013 * lpCP [I] Object to notify
3018 * Failure: E_NOINTERFACE, if lpCP is NULL or does not support the
3019 * IConnectionPoint interface.
3021 HRESULT WINAPI
IConnectionPoint_OnChanged(IConnectionPoint
* lpCP
, DISPID dispID
)
3023 IEnumConnections
*lpEnum
;
3024 HRESULT hRet
= E_NOINTERFACE
;
3026 TRACE("(%p,0x%8X)\n", lpCP
, dispID
);
3028 /* Get an enumerator for the connections */
3030 hRet
= IConnectionPoint_EnumConnections(lpCP
, &lpEnum
);
3032 if (SUCCEEDED(hRet
))
3034 IPropertyNotifySink
*lpSink
;
3035 CONNECTDATA connData
;
3038 /* Call OnChanged() for every notify sink in the connection point */
3039 while (IEnumConnections_Next(lpEnum
, 1, &connData
, &ulFetched
) == S_OK
)
3041 if (SUCCEEDED(IUnknown_QueryInterface(connData
.pUnk
, &IID_IPropertyNotifySink
, (void**)&lpSink
)) &&
3044 IPropertyNotifySink_OnChanged(lpSink
, dispID
);
3045 IPropertyNotifySink_Release(lpSink
);
3047 IUnknown_Release(connData
.pUnk
);
3050 IEnumConnections_Release(lpEnum
);
3055 /*************************************************************************
3058 * IUnknown_CPContainerInvokeParam
3060 HRESULT WINAPIV
IUnknown_CPContainerInvokeParam(
3061 IUnknown
*container
,
3068 IConnectionPoint
*iCP
;
3069 IConnectionPointContainer
*iCPC
;
3070 DISPPARAMS dispParams
= {buffer
, NULL
, cParams
, 0};
3071 __ms_va_list valist
;
3074 return E_NOINTERFACE
;
3076 result
= IUnknown_QueryInterface(container
, &IID_IConnectionPointContainer
,(LPVOID
*) &iCPC
);
3080 result
= IConnectionPointContainer_FindConnectionPoint(iCPC
, riid
, &iCP
);
3081 IConnectionPointContainer_Release(iCPC
);
3085 __ms_va_start(valist
, cParams
);
3086 SHPackDispParamsV(&dispParams
, buffer
, cParams
, valist
);
3087 __ms_va_end(valist
);
3089 result
= SHLWAPI_InvokeByIID(iCP
, riid
, dispId
, &dispParams
);
3090 IConnectionPoint_Release(iCP
);
3095 /*************************************************************************
3098 * Notify an IConnectionPointContainer object of changes.
3101 * lpUnknown [I] Object to notify
3106 * Failure: E_NOINTERFACE, if lpUnknown is NULL or does not support the
3107 * IConnectionPointContainer interface.
3109 HRESULT WINAPI
IUnknown_CPContainerOnChanged(IUnknown
*lpUnknown
, DISPID dispID
)
3111 IConnectionPointContainer
* lpCPC
= NULL
;
3112 HRESULT hRet
= E_NOINTERFACE
;
3114 TRACE("(%p,0x%8X)\n", lpUnknown
, dispID
);
3117 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IConnectionPointContainer
, (void**)&lpCPC
);
3119 if (SUCCEEDED(hRet
))
3121 IConnectionPoint
* lpCP
;
3123 hRet
= IConnectionPointContainer_FindConnectionPoint(lpCPC
, &IID_IPropertyNotifySink
, &lpCP
);
3124 IConnectionPointContainer_Release(lpCPC
);
3126 hRet
= IConnectionPoint_OnChanged(lpCP
, dispID
);
3127 IConnectionPoint_Release(lpCP
);
3132 /*************************************************************************
3137 BOOL WINAPI
PlaySoundWrapW(LPCWSTR pszSound
, HMODULE hmod
, DWORD fdwSound
)
3139 return PlaySoundW(pszSound
, hmod
, fdwSound
);
3142 /*************************************************************************
3145 BOOL WINAPI
SHGetIniStringW(LPCWSTR str1
, LPCWSTR str2
, LPWSTR pStr
, DWORD some_len
, LPCWSTR lpStr2
)
3147 FIXME("(%s,%s,%p,%08x,%s): stub!\n", debugstr_w(str1
), debugstr_w(str2
),
3148 pStr
, some_len
, debugstr_w(lpStr2
));
3152 /*************************************************************************
3155 * Called by ICQ2000b install via SHDOCVW:
3156 * str1: "InternetShortcut"
3157 * x: some unknown pointer
3158 * str2: "http://free.aol.com/tryaolfree/index.adp?139269"
3159 * str3: "C:\\WINDOWS\\Desktop.new2\\Free AOL & Unlimited Internet.url"
3161 * In short: this one maybe creates a desktop link :-)
3163 BOOL WINAPI
SHSetIniStringW(LPWSTR str1
, LPVOID x
, LPWSTR str2
, LPWSTR str3
)
3165 FIXME("(%s, %p, %s, %s), stub.\n", debugstr_w(str1
), x
, debugstr_w(str2
), debugstr_w(str3
));
3169 /*************************************************************************
3172 * See SHGetFileInfoW.
3174 DWORD WINAPI
SHGetFileInfoWrapW(LPCWSTR path
, DWORD dwFileAttributes
,
3175 SHFILEINFOW
*psfi
, UINT sizeofpsfi
, UINT flags
)
3177 return SHGetFileInfoW(path
, dwFileAttributes
, psfi
, sizeofpsfi
, flags
);
3180 /*************************************************************************
3183 * See DragQueryFileW.
3185 UINT WINAPI
DragQueryFileWrapW(HDROP hDrop
, UINT lFile
, LPWSTR lpszFile
, UINT lLength
)
3187 return DragQueryFileW(hDrop
, lFile
, lpszFile
, lLength
);
3190 /*************************************************************************
3193 * See SHBrowseForFolderW.
3195 LPITEMIDLIST WINAPI
SHBrowseForFolderWrapW(LPBROWSEINFOW lpBi
)
3197 return SHBrowseForFolderW(lpBi
);
3200 /*************************************************************************
3203 * See SHGetPathFromIDListW.
3205 BOOL WINAPI
SHGetPathFromIDListWrapW(LPCITEMIDLIST pidl
,LPWSTR pszPath
)
3207 return SHGetPathFromIDListW(pidl
, pszPath
);
3210 /*************************************************************************
3213 * See ShellExecuteExW.
3215 BOOL WINAPI
ShellExecuteExWrapW(LPSHELLEXECUTEINFOW lpExecInfo
)
3217 return ShellExecuteExW(lpExecInfo
);
3220 /*************************************************************************
3223 * See SHFileOperationW.
3225 INT WINAPI
SHFileOperationWrapW(LPSHFILEOPSTRUCTW lpFileOp
)
3227 return SHFileOperationW(lpFileOp
);
3230 /*************************************************************************
3234 PVOID WINAPI
SHInterlockedCompareExchange( PVOID
*dest
, PVOID xchg
, PVOID compare
)
3236 return InterlockedCompareExchangePointer( dest
, xchg
, compare
);
3239 /*************************************************************************
3242 * See GetFileVersionInfoSizeW.
3244 DWORD WINAPI
GetFileVersionInfoSizeWrapW( LPCWSTR filename
, LPDWORD handle
)
3246 return GetFileVersionInfoSizeW( filename
, handle
);
3249 /*************************************************************************
3252 * See GetFileVersionInfoW.
3254 BOOL WINAPI
GetFileVersionInfoWrapW( LPCWSTR filename
, DWORD handle
,
3255 DWORD datasize
, LPVOID data
)
3257 return GetFileVersionInfoW( filename
, handle
, datasize
, data
);
3260 /*************************************************************************
3263 * See VerQueryValueW.
3265 WORD WINAPI
VerQueryValueWrapW( LPVOID pBlock
, LPCWSTR lpSubBlock
,
3266 LPVOID
*lplpBuffer
, UINT
*puLen
)
3268 return VerQueryValueW( pBlock
, lpSubBlock
, lplpBuffer
, puLen
);
3271 #define IsIface(type) SUCCEEDED((hRet = IUnknown_QueryInterface(lpUnknown, &IID_##type, (void**)&lpObj)))
3272 #define IShellBrowser_EnableModeless IShellBrowser_EnableModelessSB
3273 #define EnableModeless(type) type##_EnableModeless((type*)lpObj, bModeless)
3275 /*************************************************************************
3278 * Change the modality of a shell object.
3281 * lpUnknown [I] Object to make modeless
3282 * bModeless [I] TRUE=Make modeless, FALSE=Make modal
3285 * Success: S_OK. The modality lpUnknown is changed.
3286 * Failure: An HRESULT error code indicating the error.
3289 * lpUnknown must support the IOleInPlaceFrame interface, the
3290 * IInternetSecurityMgrSite interface, the IShellBrowser interface
3291 * the IDocHostUIHandler interface, or the IOleInPlaceActiveObject interface,
3292 * or this call will fail.
3294 HRESULT WINAPI
IUnknown_EnableModeless(IUnknown
*lpUnknown
, BOOL bModeless
)
3299 TRACE("(%p,%d)\n", lpUnknown
, bModeless
);
3304 if (IsIface(IOleInPlaceActiveObject
))
3305 EnableModeless(IOleInPlaceActiveObject
);
3306 else if (IsIface(IOleInPlaceFrame
))
3307 EnableModeless(IOleInPlaceFrame
);
3308 else if (IsIface(IShellBrowser
))
3309 EnableModeless(IShellBrowser
);
3310 else if (IsIface(IInternetSecurityMgrSite
))
3311 EnableModeless(IInternetSecurityMgrSite
);
3312 else if (IsIface(IDocHostUIHandler
))
3313 EnableModeless(IDocHostUIHandler
);
3317 IUnknown_Release(lpObj
);
3321 /*************************************************************************
3324 * See SHGetNewLinkInfoW.
3326 BOOL WINAPI
SHGetNewLinkInfoWrapW(LPCWSTR pszLinkTo
, LPCWSTR pszDir
, LPWSTR pszName
,
3327 BOOL
*pfMustCopy
, UINT uFlags
)
3329 return SHGetNewLinkInfoW(pszLinkTo
, pszDir
, pszName
, pfMustCopy
, uFlags
);
3332 /*************************************************************************
3335 * See SHDefExtractIconW.
3337 UINT WINAPI
SHDefExtractIconWrapW(LPCWSTR pszIconFile
, int iIndex
, UINT uFlags
, HICON
* phiconLarge
,
3338 HICON
* phiconSmall
, UINT nIconSize
)
3340 return SHDefExtractIconW(pszIconFile
, iIndex
, uFlags
, phiconLarge
, phiconSmall
, nIconSize
);
3343 /*************************************************************************
3346 * Get and show a context menu from a shell folder.
3349 * hWnd [I] Window displaying the shell folder
3350 * lpFolder [I] IShellFolder interface
3351 * lpApidl [I] Id for the particular folder desired
3352 * bInvokeDefault [I] Whether to invoke the default menu item
3355 * Success: S_OK. If bInvokeDefault is TRUE, the default menu action was
3357 * Failure: An HRESULT error code indicating the error.
3359 HRESULT WINAPI
SHInvokeCommand(HWND hWnd
, IShellFolder
* lpFolder
, LPCITEMIDLIST lpApidl
, BOOL bInvokeDefault
)
3361 IContextMenu
*iContext
;
3362 HRESULT hRet
= E_FAIL
;
3364 TRACE("(%p,%p,%p,%d)\n", hWnd
, lpFolder
, lpApidl
, bInvokeDefault
);
3369 /* Get the context menu from the shell folder */
3370 hRet
= IShellFolder_GetUIObjectOf(lpFolder
, hWnd
, 1, &lpApidl
,
3371 &IID_IContextMenu
, 0, (void**)&iContext
);
3372 if (SUCCEEDED(hRet
))
3375 if ((hMenu
= CreatePopupMenu()))
3378 DWORD dwDefaultId
= 0;
3380 /* Add the context menu entries to the popup */
3381 hQuery
= IContextMenu_QueryContextMenu(iContext
, hMenu
, 0, 1, 0x7FFF,
3382 bInvokeDefault
? CMF_NORMAL
: CMF_DEFAULTONLY
);
3384 if (SUCCEEDED(hQuery
))
3386 if (bInvokeDefault
&&
3387 (dwDefaultId
= GetMenuDefaultItem(hMenu
, 0, 0)) != 0xFFFFFFFF)
3389 CMINVOKECOMMANDINFO cmIci
;
3390 /* Invoke the default item */
3391 memset(&cmIci
,0,sizeof(cmIci
));
3392 cmIci
.cbSize
= sizeof(cmIci
);
3393 cmIci
.fMask
= CMIC_MASK_ASYNCOK
;
3395 cmIci
.lpVerb
= MAKEINTRESOURCEA(dwDefaultId
);
3396 cmIci
.nShow
= SW_SCROLLCHILDREN
;
3398 hRet
= IContextMenu_InvokeCommand(iContext
, &cmIci
);
3403 IContextMenu_Release(iContext
);
3408 /*************************************************************************
3413 HICON WINAPI
ExtractIconWrapW(HINSTANCE hInstance
, LPCWSTR lpszExeFileName
,
3416 return ExtractIconW(hInstance
, lpszExeFileName
, nIconIndex
);
3419 /*************************************************************************
3422 * Load a library from the directory of a particular process.
3425 * new_mod [I] Library name
3426 * inst_hwnd [I] Module whose directory is to be used
3427 * dwCrossCodePage [I] Should be FALSE (currently ignored)
3430 * Success: A handle to the loaded module
3431 * Failure: A NULL handle.
3433 HMODULE WINAPI
MLLoadLibraryA(LPCSTR new_mod
, HMODULE inst_hwnd
, DWORD dwCrossCodePage
)
3435 /* FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for
3437 * FIXME: Native shows calls to:
3438 * SHRegGetUSValue for "Software\Microsoft\Internet Explorer\International"
3440 * RegOpenKeyExA for "HKLM\Software\Microsoft\Internet Explorer"
3441 * RegQueryValueExA for "LPKInstalled"
3443 * RegOpenKeyExA for "HKCU\Software\Microsoft\Internet Explorer\International"
3444 * RegQueryValueExA for "ResourceLocale"
3446 * RegOpenKeyExA for "HKLM\Software\Microsoft\Active Setup\Installed Components\{guid}"
3447 * RegQueryValueExA for "Locale"
3449 * and then tests the Locale ("en" for me).
3451 * after the code then a DPA_Create (first time) and DPA_InsertPtr are done.
3453 CHAR mod_path
[2*MAX_PATH
];
3457 FIXME("(%s,%p,%d) semi-stub!\n", debugstr_a(new_mod
), inst_hwnd
, dwCrossCodePage
);
3458 len
= GetModuleFileNameA(inst_hwnd
, mod_path
, sizeof(mod_path
));
3459 if (!len
|| len
>= sizeof(mod_path
)) return NULL
;
3461 ptr
= strrchr(mod_path
, '\\');
3463 strcpy(ptr
+1, new_mod
);
3464 TRACE("loading %s\n", debugstr_a(mod_path
));
3465 return LoadLibraryA(mod_path
);
3470 /*************************************************************************
3473 * Unicode version of MLLoadLibraryA.
3475 HMODULE WINAPI
MLLoadLibraryW(LPCWSTR new_mod
, HMODULE inst_hwnd
, DWORD dwCrossCodePage
)
3477 WCHAR mod_path
[2*MAX_PATH
];
3481 FIXME("(%s,%p,%d) semi-stub!\n", debugstr_w(new_mod
), inst_hwnd
, dwCrossCodePage
);
3482 len
= GetModuleFileNameW(inst_hwnd
, mod_path
, sizeof(mod_path
) / sizeof(WCHAR
));
3483 if (!len
|| len
>= sizeof(mod_path
) / sizeof(WCHAR
)) return NULL
;
3485 ptr
= strrchrW(mod_path
, '\\');
3487 strcpyW(ptr
+1, new_mod
);
3488 TRACE("loading %s\n", debugstr_w(mod_path
));
3489 return LoadLibraryW(mod_path
);
3494 /*************************************************************************
3495 * ColorAdjustLuma [SHLWAPI.@]
3497 * Adjust the luminosity of a color
3500 * cRGB [I] RGB value to convert
3501 * dwLuma [I] Luma adjustment
3502 * bUnknown [I] Unknown
3505 * The adjusted RGB color.
3507 COLORREF WINAPI
ColorAdjustLuma(COLORREF cRGB
, int dwLuma
, BOOL bUnknown
)
3509 TRACE("(0x%8x,%d,%d)\n", cRGB
, dwLuma
, bUnknown
);
3515 ColorRGBToHLS(cRGB
, &wH
, &wL
, &wS
);
3517 FIXME("Ignoring luma adjustment\n");
3519 /* FIXME: The adjustment is not linear */
3521 cRGB
= ColorHLSToRGB(wH
, wL
, wS
);
3526 /*************************************************************************
3529 * See GetSaveFileNameW.
3531 BOOL WINAPI
GetSaveFileNameWrapW(LPOPENFILENAMEW ofn
)
3533 return GetSaveFileNameW(ofn
);
3536 /*************************************************************************
3539 * See WNetRestoreConnectionW.
3541 DWORD WINAPI
WNetRestoreConnectionWrapW(HWND hwndOwner
, LPWSTR lpszDevice
)
3543 return WNetRestoreConnectionW(hwndOwner
, lpszDevice
);
3546 /*************************************************************************
3549 * See WNetGetLastErrorW.
3551 DWORD WINAPI
WNetGetLastErrorWrapW(LPDWORD lpError
, LPWSTR lpErrorBuf
, DWORD nErrorBufSize
,
3552 LPWSTR lpNameBuf
, DWORD nNameBufSize
)
3554 return WNetGetLastErrorW(lpError
, lpErrorBuf
, nErrorBufSize
, lpNameBuf
, nNameBufSize
);
3557 /*************************************************************************
3560 * See PageSetupDlgW.
3562 BOOL WINAPI
PageSetupDlgWrapW(LPPAGESETUPDLGW pagedlg
)
3564 return PageSetupDlgW(pagedlg
);
3567 /*************************************************************************
3572 BOOL WINAPI
PrintDlgWrapW(LPPRINTDLGW printdlg
)
3574 return PrintDlgW(printdlg
);
3577 /*************************************************************************
3580 * See GetOpenFileNameW.
3582 BOOL WINAPI
GetOpenFileNameWrapW(LPOPENFILENAMEW ofn
)
3584 return GetOpenFileNameW(ofn
);
3587 /*************************************************************************
3590 HRESULT WINAPI
SHIShellFolder_EnumObjects(LPSHELLFOLDER lpFolder
, HWND hwnd
, SHCONTF flags
, IEnumIDList
**ppenum
)
3595 hr
= IShellFolder_QueryInterface(lpFolder
, &IID_IPersist
, (LPVOID
)&persist
);
3599 hr
= IPersist_GetClassID(persist
, &clsid
);
3602 if(IsEqualCLSID(&clsid
, &CLSID_ShellFSFolder
))
3603 hr
= IShellFolder_EnumObjects(lpFolder
, hwnd
, flags
, ppenum
);
3607 IPersist_Release(persist
);
3612 /* INTERNAL: Map from HLS color space to RGB */
3613 static WORD
ConvertHue(int wHue
, WORD wMid1
, WORD wMid2
)
3615 wHue
= wHue
> 240 ? wHue
- 240 : wHue
< 0 ? wHue
+ 240 : wHue
;
3619 else if (wHue
> 120)
3624 return ((wHue
* (wMid2
- wMid1
) + 20) / 40) + wMid1
;
3627 /* Convert to RGB and scale into RGB range (0..255) */
3628 #define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240
3630 /*************************************************************************
3631 * ColorHLSToRGB [SHLWAPI.@]
3633 * Convert from hls color space into an rgb COLORREF.
3636 * wHue [I] Hue amount
3637 * wLuminosity [I] Luminosity amount
3638 * wSaturation [I] Saturation amount
3641 * A COLORREF representing the converted color.
3644 * Input hls values are constrained to the range (0..240).
3646 COLORREF WINAPI
ColorHLSToRGB(WORD wHue
, WORD wLuminosity
, WORD wSaturation
)
3652 WORD wGreen
, wBlue
, wMid1
, wMid2
;
3654 if (wLuminosity
> 120)
3655 wMid2
= wSaturation
+ wLuminosity
- (wSaturation
* wLuminosity
+ 120) / 240;
3657 wMid2
= ((wSaturation
+ 240) * wLuminosity
+ 120) / 240;
3659 wMid1
= wLuminosity
* 2 - wMid2
;
3661 wRed
= GET_RGB(wHue
+ 80);
3662 wGreen
= GET_RGB(wHue
);
3663 wBlue
= GET_RGB(wHue
- 80);
3665 return RGB(wRed
, wGreen
, wBlue
);
3668 wRed
= wLuminosity
* 255 / 240;
3669 return RGB(wRed
, wRed
, wRed
);
3672 /*************************************************************************
3675 * Get the current docking status of the system.
3678 * dwFlags [I] DOCKINFO_ flags from "winbase.h", unused
3681 * One of DOCKINFO_UNDOCKED, DOCKINFO_UNDOCKED, or 0 if the system is not
3684 DWORD WINAPI
SHGetMachineInfo(DWORD dwFlags
)
3686 HW_PROFILE_INFOA hwInfo
;
3688 TRACE("(0x%08x)\n", dwFlags
);
3690 GetCurrentHwProfileA(&hwInfo
);
3691 switch (hwInfo
.dwDockInfo
& (DOCKINFO_DOCKED
|DOCKINFO_UNDOCKED
))
3693 case DOCKINFO_DOCKED
:
3694 case DOCKINFO_UNDOCKED
:
3695 return hwInfo
.dwDockInfo
& (DOCKINFO_DOCKED
|DOCKINFO_UNDOCKED
);
3701 /*************************************************************************
3704 * Function seems to do FreeLibrary plus other things.
3706 * FIXME native shows the following calls:
3707 * RtlEnterCriticalSection
3709 * GetProcAddress(Comctl32??, 150L)
3711 * RtlLeaveCriticalSection
3712 * followed by the FreeLibrary.
3713 * The above code may be related to .377 above.
3715 BOOL WINAPI
MLFreeLibrary(HMODULE hModule
)
3717 FIXME("(%p) semi-stub\n", hModule
);
3718 return FreeLibrary(hModule
);
3721 /*************************************************************************
3724 BOOL WINAPI
SHFlushSFCacheWrap(void) {
3729 /*************************************************************************
3731 * FIXME I have no idea what this function does or what its arguments are.
3733 BOOL WINAPI
MLIsMLHInstance(HINSTANCE hInst
)
3735 FIXME("(%p) stub\n", hInst
);
3740 /*************************************************************************
3743 DWORD WINAPI
MLSetMLHInstance(HINSTANCE hInst
, HANDLE hHeap
)
3745 FIXME("(%p,%p) stub\n", hInst
, hHeap
);
3746 return E_FAIL
; /* This is what is used if shlwapi not loaded */
3749 /*************************************************************************
3752 DWORD WINAPI
MLClearMLHInstance(DWORD x
)
3754 FIXME("(0x%08x)stub\n", x
);
3758 /*************************************************************************
3761 * See SHSendMessageBroadcastW
3764 DWORD WINAPI
SHSendMessageBroadcastA(UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3766 return SendMessageTimeoutA(HWND_BROADCAST
, uMsg
, wParam
, lParam
,
3767 SMTO_ABORTIFHUNG
, 2000, NULL
);
3770 /*************************************************************************
3773 * A wrapper for sending Broadcast Messages to all top level Windows
3776 DWORD WINAPI
SHSendMessageBroadcastW(UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3778 return SendMessageTimeoutW(HWND_BROADCAST
, uMsg
, wParam
, lParam
,
3779 SMTO_ABORTIFHUNG
, 2000, NULL
);
3782 /*************************************************************************
3785 * Convert a Unicode string CLSID into a CLSID.
3788 * idstr [I] string containing a CLSID in text form
3789 * id [O] CLSID extracted from the string
3792 * S_OK on success or E_INVALIDARG on failure
3794 HRESULT WINAPI
CLSIDFromStringWrap(LPCWSTR idstr
, CLSID
*id
)
3796 return CLSIDFromString((LPOLESTR
)idstr
, id
);
3799 /*************************************************************************
3802 * Determine if the OS supports a given feature.
3805 * dwFeature [I] Feature requested (undocumented)
3808 * TRUE If the feature is available.
3809 * FALSE If the feature is not available.
3811 BOOL WINAPI
IsOS(DWORD feature
)
3813 OSVERSIONINFOA osvi
;
3814 DWORD platform
, majorv
, minorv
;
3816 osvi
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFOA
);
3817 if(!GetVersionExA(&osvi
)) {
3818 ERR("GetVersionEx failed\n");
3822 majorv
= osvi
.dwMajorVersion
;
3823 minorv
= osvi
.dwMinorVersion
;
3824 platform
= osvi
.dwPlatformId
;
3826 #define ISOS_RETURN(x) \
3827 TRACE("(0x%x) ret=%d\n",feature,(x)); \
3831 case OS_WIN32SORGREATER
:
3832 ISOS_RETURN(platform
== VER_PLATFORM_WIN32s
3833 || platform
== VER_PLATFORM_WIN32_WINDOWS
)
3835 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3836 case OS_WIN95ORGREATER
:
3837 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
)
3838 case OS_NT4ORGREATER
:
3839 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 4)
3840 case OS_WIN2000ORGREATER_ALT
:
3841 case OS_WIN2000ORGREATER
:
3842 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5)
3843 case OS_WIN98ORGREATER
:
3844 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
&& minorv
>= 10)
3846 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
&& minorv
== 10)
3848 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5)
3849 case OS_WIN2000SERVER
:
3850 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& (minorv
== 0 || minorv
== 1))
3851 case OS_WIN2000ADVSERVER
:
3852 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& (minorv
== 0 || minorv
== 1))
3853 case OS_WIN2000DATACENTER
:
3854 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& (minorv
== 0 || minorv
== 1))
3855 case OS_WIN2000TERMINAL
:
3856 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& (minorv
== 0 || minorv
== 1))
3858 FIXME("(OS_EMBEDDED) What should we return here?\n");
3860 case OS_TERMINALCLIENT
:
3861 FIXME("(OS_TERMINALCLIENT) What should we return here?\n");
3863 case OS_TERMINALREMOTEADMIN
:
3864 FIXME("(OS_TERMINALREMOTEADMIN) What should we return here?\n");
3867 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
&& minorv
== 0)
3868 case OS_MEORGREATER
:
3869 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
&& minorv
>= 90)
3870 case OS_XPORGREATER
:
3871 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5 && minorv
>= 1)
3873 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5 && minorv
>= 1)
3874 case OS_PROFESSIONAL
:
3875 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3877 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3879 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5)
3881 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3882 case OS_TERMINALSERVER
:
3883 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3884 case OS_PERSONALTERMINALSERVER
:
3885 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& minorv
>= 1 && majorv
>= 5)
3886 case OS_FASTUSERSWITCHING
:
3887 FIXME("(OS_FASTUSERSWITCHING) What should we return here?\n");
3889 case OS_WELCOMELOGONUI
:
3890 FIXME("(OS_WELCOMELOGONUI) What should we return here?\n");
3892 case OS_DOMAINMEMBER
:
3893 FIXME("(OS_DOMAINMEMBER) What should we return here?\n");
3896 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3898 FIXME("(OS_WOW6432) Should we check this?\n");
3901 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3902 case OS_SMALLBUSINESSSERVER
:
3903 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3905 FIXME("(OS_TABLEPC) What should we return here?\n");
3907 case OS_SERVERADMINUI
:
3908 FIXME("(OS_SERVERADMINUI) What should we return here?\n");
3910 case OS_MEDIACENTER
:
3911 FIXME("(OS_MEDIACENTER) What should we return here?\n");
3914 FIXME("(OS_APPLIANCE) What should we return here?\n");
3920 WARN("(0x%x) unknown parameter\n",feature
);
3925 /*************************************************************************
3928 HRESULT WINAPI
SHLoadRegUIStringW(HKEY hkey
, LPCWSTR value
, LPWSTR buf
, DWORD size
)
3930 DWORD type
, sz
= size
;
3932 if(RegQueryValueExW(hkey
, value
, NULL
, &type
, (LPBYTE
)buf
, &sz
) != ERROR_SUCCESS
)
3935 return SHLoadIndirectString(buf
, buf
, size
, NULL
);
3938 /*************************************************************************
3941 * Call IInputObject_TranslateAcceleratorIO() on an object.
3944 * lpUnknown [I] Object supporting the IInputObject interface.
3945 * lpMsg [I] Key message to be processed.
3949 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
3951 HRESULT WINAPI
IUnknown_TranslateAcceleratorIO(IUnknown
*lpUnknown
, LPMSG lpMsg
)
3953 IInputObject
* lpInput
= NULL
;
3954 HRESULT hRet
= E_INVALIDARG
;
3956 TRACE("(%p,%p)\n", lpUnknown
, lpMsg
);
3959 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IInputObject
,
3961 if (SUCCEEDED(hRet
) && lpInput
)
3963 hRet
= IInputObject_TranslateAcceleratorIO(lpInput
, lpMsg
);
3964 IInputObject_Release(lpInput
);
3970 /*************************************************************************
3973 * Call IInputObject_HasFocusIO() on an object.
3976 * lpUnknown [I] Object supporting the IInputObject interface.
3979 * Success: S_OK, if lpUnknown is an IInputObject object and has the focus,
3980 * or S_FALSE otherwise.
3981 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
3983 HRESULT WINAPI
IUnknown_HasFocusIO(IUnknown
*lpUnknown
)
3985 IInputObject
* lpInput
= NULL
;
3986 HRESULT hRet
= E_INVALIDARG
;
3988 TRACE("(%p)\n", lpUnknown
);
3991 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IInputObject
,
3993 if (SUCCEEDED(hRet
) && lpInput
)
3995 hRet
= IInputObject_HasFocusIO(lpInput
);
3996 IInputObject_Release(lpInput
);
4002 /*************************************************************************
4003 * ColorRGBToHLS [SHLWAPI.@]
4005 * Convert an rgb COLORREF into the hls color space.
4008 * cRGB [I] Source rgb value
4009 * pwHue [O] Destination for converted hue
4010 * pwLuminance [O] Destination for converted luminance
4011 * pwSaturation [O] Destination for converted saturation
4014 * Nothing. pwHue, pwLuminance and pwSaturation are set to the converted
4018 * Output HLS values are constrained to the range (0..240).
4019 * For Achromatic conversions, Hue is set to 160.
4021 VOID WINAPI
ColorRGBToHLS(COLORREF cRGB
, LPWORD pwHue
,
4022 LPWORD pwLuminance
, LPWORD pwSaturation
)
4024 int wR
, wG
, wB
, wMax
, wMin
, wHue
, wLuminosity
, wSaturation
;
4026 TRACE("(%08x,%p,%p,%p)\n", cRGB
, pwHue
, pwLuminance
, pwSaturation
);
4028 wR
= GetRValue(cRGB
);
4029 wG
= GetGValue(cRGB
);
4030 wB
= GetBValue(cRGB
);
4032 wMax
= max(wR
, max(wG
, wB
));
4033 wMin
= min(wR
, min(wG
, wB
));
4036 wLuminosity
= ((wMax
+ wMin
) * 240 + 255) / 510;
4040 /* Achromatic case */
4042 /* Hue is now unrepresentable, but this is what native returns... */
4047 /* Chromatic case */
4048 int wDelta
= wMax
- wMin
, wRNorm
, wGNorm
, wBNorm
;
4051 if (wLuminosity
<= 120)
4052 wSaturation
= ((wMax
+ wMin
)/2 + wDelta
* 240) / (wMax
+ wMin
);
4054 wSaturation
= ((510 - wMax
- wMin
)/2 + wDelta
* 240) / (510 - wMax
- wMin
);
4057 wRNorm
= (wDelta
/2 + wMax
* 40 - wR
* 40) / wDelta
;
4058 wGNorm
= (wDelta
/2 + wMax
* 40 - wG
* 40) / wDelta
;
4059 wBNorm
= (wDelta
/2 + wMax
* 40 - wB
* 40) / wDelta
;
4062 wHue
= wBNorm
- wGNorm
;
4063 else if (wG
== wMax
)
4064 wHue
= 80 + wRNorm
- wBNorm
;
4066 wHue
= 160 + wGNorm
- wRNorm
;
4069 else if (wHue
> 240)
4075 *pwLuminance
= wLuminosity
;
4077 *pwSaturation
= wSaturation
;
4080 /*************************************************************************
4081 * SHCreateShellPalette [SHLWAPI.@]
4083 HPALETTE WINAPI
SHCreateShellPalette(HDC hdc
)
4086 return CreateHalftonePalette(hdc
);
4089 /*************************************************************************
4090 * SHGetInverseCMAP (SHLWAPI.@)
4092 * Get an inverse color map table.
4095 * lpCmap [O] Destination for color map
4096 * dwSize [I] Size of memory pointed to by lpCmap
4100 * Failure: E_POINTER, If lpCmap is invalid.
4101 * E_INVALIDARG, If dwFlags is invalid
4102 * E_OUTOFMEMORY, If there is no memory available
4105 * dwSize may only be CMAP_PTR_SIZE (4) or CMAP_SIZE (8192).
4106 * If dwSize = CMAP_PTR_SIZE, *lpCmap is set to the address of this DLL's
4108 * If dwSize = CMAP_SIZE, lpCmap is filled with a copy of the data from
4109 * this DLL's internal CMap.
4111 HRESULT WINAPI
SHGetInverseCMAP(LPDWORD dest
, DWORD dwSize
)
4114 FIXME(" - returning bogus address for SHGetInverseCMAP\n");
4115 *dest
= (DWORD
)0xabba1249;
4118 FIXME("(%p, %#x) stub\n", dest
, dwSize
);
4122 /*************************************************************************
4123 * SHIsLowMemoryMachine [SHLWAPI.@]
4125 * Determine if the current computer has low memory.
4131 * TRUE if the users machine has 16 Megabytes of memory or less,
4134 BOOL WINAPI
SHIsLowMemoryMachine (DWORD x
)
4136 FIXME("(0x%08x) stub\n", x
);
4140 /*************************************************************************
4141 * GetMenuPosFromID [SHLWAPI.@]
4143 * Return the position of a menu item from its Id.
4146 * hMenu [I] Menu containing the item
4147 * wID [I] Id of the menu item
4150 * Success: The index of the menu item in hMenu.
4151 * Failure: -1, If the item is not found.
4153 INT WINAPI
GetMenuPosFromID(HMENU hMenu
, UINT wID
)
4156 INT nCount
= GetMenuItemCount(hMenu
), nIter
= 0;
4158 while (nIter
< nCount
)
4160 mi
.cbSize
= sizeof(mi
);
4162 if (GetMenuItemInfoW(hMenu
, nIter
, TRUE
, &mi
) && mi
.wID
== wID
)
4169 /*************************************************************************
4172 * Same as SHLWAPI.GetMenuPosFromID
4174 DWORD WINAPI
SHMenuIndexFromID(HMENU hMenu
, UINT uID
)
4176 return GetMenuPosFromID(hMenu
, uID
);
4180 /*************************************************************************
4183 VOID WINAPI
FixSlashesAndColonW(LPWSTR lpwstr
)
4194 /*************************************************************************
4197 DWORD WINAPI
SHGetAppCompatFlags(DWORD dwUnknown
)
4199 FIXME("(0x%08x) stub\n", dwUnknown
);
4204 /*************************************************************************
4207 HRESULT WINAPI
SHCoCreateInstanceAC(REFCLSID rclsid
, LPUNKNOWN pUnkOuter
,
4208 DWORD dwClsContext
, REFIID iid
, LPVOID
*ppv
)
4210 return CoCreateInstance(rclsid
, pUnkOuter
, dwClsContext
, iid
, ppv
);
4213 /*************************************************************************
4214 * SHSkipJunction [SHLWAPI.@]
4216 * Determine if a bind context can be bound to an object
4219 * pbc [I] Bind context to check
4220 * pclsid [I] CLSID of object to be bound to
4223 * TRUE: If it is safe to bind
4224 * FALSE: If pbc is invalid or binding would not be safe
4227 BOOL WINAPI
SHSkipJunction(IBindCtx
*pbc
, const CLSID
*pclsid
)
4229 static WCHAR szSkipBinding
[] = { 'S','k','i','p',' ',
4230 'B','i','n','d','i','n','g',' ','C','L','S','I','D','\0' };
4237 if (SUCCEEDED(IBindCtx_GetObjectParam(pbc
, szSkipBinding
, &lpUnk
)))
4241 if (SUCCEEDED(IUnknown_GetClassID(lpUnk
, &clsid
)) &&
4242 IsEqualGUID(pclsid
, &clsid
))
4245 IUnknown_Release(lpUnk
);
4251 /***********************************************************************
4252 * SHGetShellKey (SHLWAPI.@)
4254 DWORD WINAPI
SHGetShellKey(DWORD a
, DWORD b
, DWORD c
)
4256 FIXME("(%x, %x, %x): stub\n", a
, b
, c
);
4260 /***********************************************************************
4261 * SHQueueUserWorkItem (SHLWAPI.@)
4263 BOOL WINAPI
SHQueueUserWorkItem(LPTHREAD_START_ROUTINE pfnCallback
,
4264 LPVOID pContext
, LONG lPriority
, DWORD_PTR dwTag
,
4265 DWORD_PTR
*pdwId
, LPCSTR pszModule
, DWORD dwFlags
)
4267 TRACE("(%p, %p, %d, %lx, %p, %s, %08x)\n", pfnCallback
, pContext
,
4268 lPriority
, dwTag
, pdwId
, debugstr_a(pszModule
), dwFlags
);
4270 if(lPriority
|| dwTag
|| pdwId
|| pszModule
|| dwFlags
)
4271 FIXME("Unsupported arguments\n");
4273 return QueueUserWorkItem(pfnCallback
, pContext
, 0);
4276 /***********************************************************************
4277 * SHSetTimerQueueTimer (SHLWAPI.263)
4279 HANDLE WINAPI
SHSetTimerQueueTimer(HANDLE hQueue
,
4280 WAITORTIMERCALLBACK pfnCallback
, LPVOID pContext
, DWORD dwDueTime
,
4281 DWORD dwPeriod
, LPCSTR lpszLibrary
, DWORD dwFlags
)
4285 /* SHSetTimerQueueTimer flags -> CreateTimerQueueTimer flags */
4286 if (dwFlags
& TPS_LONGEXECTIME
) {
4287 dwFlags
&= ~TPS_LONGEXECTIME
;
4288 dwFlags
|= WT_EXECUTELONGFUNCTION
;
4290 if (dwFlags
& TPS_EXECUTEIO
) {
4291 dwFlags
&= ~TPS_EXECUTEIO
;
4292 dwFlags
|= WT_EXECUTEINIOTHREAD
;
4295 if (!CreateTimerQueueTimer(&hNewTimer
, hQueue
, pfnCallback
, pContext
,
4296 dwDueTime
, dwPeriod
, dwFlags
))
4302 /***********************************************************************
4303 * IUnknown_OnFocusChangeIS (SHLWAPI.@)
4305 HRESULT WINAPI
IUnknown_OnFocusChangeIS(LPUNKNOWN lpUnknown
, LPUNKNOWN pFocusObject
, BOOL bFocus
)
4307 IInputObjectSite
*pIOS
= NULL
;
4308 HRESULT hRet
= E_INVALIDARG
;
4310 TRACE("(%p, %p, %s)\n", lpUnknown
, pFocusObject
, bFocus
? "TRUE" : "FALSE");
4314 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IInputObjectSite
,
4316 if (SUCCEEDED(hRet
) && pIOS
)
4318 hRet
= IInputObjectSite_OnFocusChangeIS(pIOS
, pFocusObject
, bFocus
);
4319 IInputObjectSite_Release(pIOS
);
4325 /***********************************************************************
4326 * SHGetValueW (SHLWAPI.@)
4328 HRESULT WINAPI
SKGetValueW(DWORD a
, LPWSTR b
, LPWSTR c
, DWORD d
, DWORD e
, DWORD f
)
4330 FIXME("(%x, %s, %s, %x, %x, %x): stub\n", a
, debugstr_w(b
), debugstr_w(c
), d
, e
, f
);
4334 typedef HRESULT (WINAPI
*DllGetVersion_func
)(DLLVERSIONINFO
*);
4336 /***********************************************************************
4337 * GetUIVersion (SHLWAPI.452)
4339 DWORD WINAPI
GetUIVersion(void)
4341 static DWORD version
;
4345 DllGetVersion_func pDllGetVersion
;
4346 HMODULE dll
= LoadLibraryA("shell32.dll");
4349 pDllGetVersion
= (DllGetVersion_func
)GetProcAddress(dll
, "DllGetVersion");
4353 dvi
.cbSize
= sizeof(DLLVERSIONINFO
);
4354 if (pDllGetVersion(&dvi
) == S_OK
) version
= dvi
.dwMajorVersion
;
4357 if (!version
) version
= 3; /* old shell dlls don't have DllGetVersion */
4362 /***********************************************************************
4363 * ShellMessageBoxWrapW [SHLWAPI.388]
4365 * See shell32.ShellMessageBoxW
4368 * shlwapi.ShellMessageBoxWrapW is a duplicate of shell32.ShellMessageBoxW
4369 * because we can't forward to it in the .spec file since it's exported by
4370 * ordinal. If you change the implementation here please update the code in
4373 INT WINAPIV
ShellMessageBoxWrapW(HINSTANCE hInstance
, HWND hWnd
, LPCWSTR lpText
,
4374 LPCWSTR lpCaption
, UINT uType
, ...)
4376 WCHAR szText
[100], szTitle
[100];
4377 LPCWSTR pszText
= szText
, pszTitle
= szTitle
;
4382 __ms_va_start(args
, uType
);
4384 TRACE("(%p,%p,%p,%p,%08x)\n", hInstance
, hWnd
, lpText
, lpCaption
, uType
);
4386 if (IS_INTRESOURCE(lpCaption
))
4387 LoadStringW(hInstance
, LOWORD(lpCaption
), szTitle
, sizeof(szTitle
)/sizeof(szTitle
[0]));
4389 pszTitle
= lpCaption
;
4391 if (IS_INTRESOURCE(lpText
))
4392 LoadStringW(hInstance
, LOWORD(lpText
), szText
, sizeof(szText
)/sizeof(szText
[0]));
4396 FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_STRING
,
4397 pszText
, 0, 0, (LPWSTR
)&pszTemp
, 0, &args
);
4401 ret
= MessageBoxW(hWnd
, pszTemp
, pszTitle
, uType
);
4406 HRESULT WINAPI
IUnknown_QueryServiceExec(IUnknown
*unk
, REFIID service
, REFIID clsid
,
4407 DWORD x1
, DWORD x2
, DWORD x3
, void **ppvOut
)
4409 FIXME("%p %s %s %08x %08x %08x %p\n", unk
,
4410 debugstr_guid(service
), debugstr_guid(clsid
), x1
, x2
, x3
, ppvOut
);
4414 HRESULT WINAPI
IUnknown_ProfferService(IUnknown
*unk
, void *x0
, void *x1
, void *x2
)
4416 FIXME("%p %p %p %p\n", unk
, x0
, x1
, x2
);
4420 /***********************************************************************
4421 * ZoneComputePaneSize [SHLWAPI.382]
4423 UINT WINAPI
ZoneComputePaneSize(HWND hwnd
)
4429 /***********************************************************************
4430 * SHChangeNotifyWrap [SHLWAPI.394]
4432 void WINAPI
SHChangeNotifyWrap(LONG wEventId
, UINT uFlags
, LPCVOID dwItem1
, LPCVOID dwItem2
)
4434 SHChangeNotify(wEventId
, uFlags
, dwItem1
, dwItem2
);
4437 typedef struct SHELL_USER_SID
{ /* according to MSDN this should be in shlobj.h... */
4438 SID_IDENTIFIER_AUTHORITY sidAuthority
;
4439 DWORD dwUserGroupID
;
4441 } SHELL_USER_SID
, *PSHELL_USER_SID
;
4443 typedef struct SHELL_USER_PERMISSION
{ /* ...and this should be in shlwapi.h */
4444 SHELL_USER_SID susID
;
4448 DWORD dwInheritMask
;
4449 DWORD dwInheritAccessMask
;
4450 } SHELL_USER_PERMISSION
, *PSHELL_USER_PERMISSION
;
4452 /***********************************************************************
4453 * GetShellSecurityDescriptor [SHLWAPI.475]
4455 * prepares SECURITY_DESCRIPTOR from a set of ACEs
4458 * apUserPerm [I] array of pointers to SHELL_USER_PERMISSION structures,
4459 * each of which describes permissions to apply
4460 * cUserPerm [I] number of entries in apUserPerm array
4463 * success: pointer to SECURITY_DESCRIPTOR
4467 * Call should free returned descriptor with LocalFree
4469 PSECURITY_DESCRIPTOR WINAPI
GetShellSecurityDescriptor(PSHELL_USER_PERMISSION
*apUserPerm
, int cUserPerm
)
4472 PSID cur_user
= NULL
;
4476 PSECURITY_DESCRIPTOR psd
= NULL
;
4478 TRACE("%p %d\n", apUserPerm
, cUserPerm
);
4480 if (apUserPerm
== NULL
|| cUserPerm
<= 0)
4483 sidlist
= HeapAlloc(GetProcessHeap(), 0, cUserPerm
* sizeof(PSID
));
4487 acl_size
= sizeof(ACL
);
4489 for(sid_count
= 0; sid_count
< cUserPerm
; sid_count
++)
4491 static SHELL_USER_SID null_sid
= {{SECURITY_NULL_SID_AUTHORITY
}, 0, 0};
4492 PSHELL_USER_PERMISSION perm
= apUserPerm
[sid_count
];
4493 PSHELL_USER_SID sid
= &perm
->susID
;
4497 if (!memcmp((void*)sid
, (void*)&null_sid
, sizeof(SHELL_USER_SID
)))
4498 { /* current user's SID */
4502 DWORD bufsize
= sizeof(tuUser
);
4504 ret
= OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY
, &Token
);
4507 ret
= GetTokenInformation(Token
, TokenUser
, (void*)tuUser
, bufsize
, &bufsize
);
4509 cur_user
= ((PTOKEN_USER
)tuUser
)->User
.Sid
;
4514 } else if (sid
->dwUserID
==0) /* one sub-authority */
4515 ret
= AllocateAndInitializeSid(&sid
->sidAuthority
, 1, sid
->dwUserGroupID
, 0,
4516 0, 0, 0, 0, 0, 0, &pSid
);
4518 ret
= AllocateAndInitializeSid(&sid
->sidAuthority
, 2, sid
->dwUserGroupID
, sid
->dwUserID
,
4519 0, 0, 0, 0, 0, 0, &pSid
);
4523 sidlist
[sid_count
] = pSid
;
4524 /* increment acl_size (1 ACE for non-inheritable and 2 ACEs for inheritable records */
4525 acl_size
+= (sizeof(ACCESS_ALLOWED_ACE
)-sizeof(DWORD
) + GetLengthSid(pSid
)) * (perm
->fInherit
? 2 : 1);
4528 psd
= LocalAlloc(0, sizeof(SECURITY_DESCRIPTOR
) + acl_size
);
4532 PACL pAcl
= (PACL
)(((BYTE
*)psd
)+sizeof(SECURITY_DESCRIPTOR
));
4534 if (!InitializeSecurityDescriptor(psd
, SECURITY_DESCRIPTOR_REVISION
))
4537 if (!InitializeAcl(pAcl
, acl_size
, ACL_REVISION
))
4540 for(i
= 0; i
< sid_count
; i
++)
4542 PSHELL_USER_PERMISSION sup
= apUserPerm
[i
];
4543 PSID sid
= sidlist
[i
];
4545 switch(sup
->dwAccessType
)
4547 case ACCESS_ALLOWED_ACE_TYPE
:
4548 if (!AddAccessAllowedAce(pAcl
, ACL_REVISION
, sup
->dwAccessMask
, sid
))
4550 if (sup
->fInherit
&& !AddAccessAllowedAceEx(pAcl
, ACL_REVISION
,
4551 (BYTE
)sup
->dwInheritMask
, sup
->dwInheritAccessMask
, sid
))
4554 case ACCESS_DENIED_ACE_TYPE
:
4555 if (!AddAccessDeniedAce(pAcl
, ACL_REVISION
, sup
->dwAccessMask
, sid
))
4557 if (sup
->fInherit
&& !AddAccessDeniedAceEx(pAcl
, ACL_REVISION
,
4558 (BYTE
)sup
->dwInheritMask
, sup
->dwInheritAccessMask
, sid
))
4566 if (!SetSecurityDescriptorDacl(psd
, TRUE
, pAcl
, FALSE
))
4575 for(i
= 0; i
< sid_count
; i
++)
4577 if (!cur_user
|| sidlist
[i
] != cur_user
)
4578 FreeSid(sidlist
[i
]);
4580 HeapFree(GetProcessHeap(), 0, sidlist
);
4585 /***********************************************************************
4586 * SHCreatePropertyBagOnRegKey [SHLWAPI.471]
4588 * Creates a property bag from a registry key
4591 * hKey [I] Handle to the desired registry key
4592 * subkey [I] Name of desired subkey, or NULL to open hKey directly
4593 * grfMode [I] Optional flags
4594 * riid [I] IID of requested property bag interface
4595 * ppv [O] Address to receive pointer to the new interface
4599 * failure: error code
4602 HRESULT WINAPI
SHCreatePropertyBagOnRegKey (HKEY hKey
, LPCWSTR subkey
,
4603 DWORD grfMode
, REFIID riid
, void **ppv
)
4605 FIXME("%p %s %d %s %p STUB\n", hKey
, debugstr_w(subkey
), grfMode
,
4606 debugstr_guid(riid
), ppv
);
4611 /***********************************************************************
4612 * SHGetViewStatePropertyBag [SHLWAPI.515]
4614 * Retrieves a property bag in which the view state information of a folder
4618 * pidl [I] PIDL of the folder requested
4619 * bag_name [I] Name of the property bag requested
4620 * flags [I] Optional flags
4621 * riid [I] IID of requested property bag interface
4622 * ppv [O] Address to receive pointer to the new interface
4626 * failure: error code
4629 HRESULT WINAPI
SHGetViewStatePropertyBag(LPCITEMIDLIST pidl
, LPWSTR bag_name
,
4630 DWORD flags
, REFIID riid
, void **ppv
)
4632 FIXME("%p %s %d %s %p STUB\n", pidl
, debugstr_w(bag_name
), flags
,
4633 debugstr_guid(riid
), ppv
);
4638 /***********************************************************************
4639 * SHFormatDateTimeW [SHLWAPI.354]
4641 * Produces a string representation of a time.
4644 * fileTime [I] Pointer to FILETIME structure specifying the time
4645 * flags [I] Flags specifying the desired output
4646 * buf [O] Pointer to buffer for output
4647 * bufSize [I] Number of characters that can be contained in buffer
4650 * success: number of characters written to the buffer
4654 INT WINAPI
SHFormatDateTimeW(const FILETIME UNALIGNED
*fileTime
, DWORD
*flags
,
4655 LPWSTR buf
, UINT bufSize
)
4657 FIXME("%p %p %s %d STUB\n", fileTime
, flags
, debugstr_w(buf
), bufSize
);
4661 /***********************************************************************
4662 * SHFormatDateTimeA [SHLWAPI.353]
4664 * See SHFormatDateTimeW.
4667 INT WINAPI
SHFormatDateTimeA(const FILETIME UNALIGNED
*fileTime
, DWORD
*flags
,
4668 LPCSTR buf
, UINT bufSize
)
4671 DWORD buflenW
, convlen
;
4674 if (!buf
|| !bufSize
)
4678 bufW
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
) * buflenW
);
4679 retval
= SHFormatDateTimeW(fileTime
, flags
, bufW
, buflenW
);
4682 convlen
= WideCharToMultiByte(CP_ACP
, 0, bufW
, -1, (LPSTR
) buf
, bufSize
, NULL
, NULL
);
4684 HeapFree(GetProcessHeap(), 0, bufW
);
4688 /***********************************************************************
4689 * ZoneCheckUrlExW [SHLWAPI.231]
4691 * Checks the details of the security zone for the supplied site. (?)
4695 * szURL [I] Pointer to the URL to check
4697 * Other parameters currently unknown.
4703 INT WINAPI
ZoneCheckUrlExW(LPWSTR szURL
, PVOID pUnknown
, DWORD dwUnknown2
,
4704 DWORD dwUnknown3
, DWORD dwUnknown4
, DWORD dwUnknown5
, DWORD dwUnknown6
,
4707 FIXME("(%s,%p,%x,%x,%x,%x,%x,%x) STUB\n", debugstr_w(szURL
), pUnknown
, dwUnknown2
,
4708 dwUnknown3
, dwUnknown4
, dwUnknown5
, dwUnknown6
, dwUnknown7
);
4713 /***********************************************************************
4714 * SHVerbExistsNA [SHLWAPI.196]
4719 * verb [I] a string, often appears to be an extension.
4721 * Other parameters currently unknown.
4726 INT WINAPI
SHVerbExistsNA(LPSTR verb
, PVOID pUnknown
, PVOID pUnknown2
, DWORD dwUnknown3
)
4728 FIXME("(%s, %p, %p, %i) STUB\n",verb
, pUnknown
, pUnknown2
, dwUnknown3
);
4732 /*************************************************************************
4735 * Undocumented: Implementation guessed at via Name and behavior
4738 * lpUnknown [I] Object to get an IServiceProvider interface from
4739 * riid [I] Function requested for QueryService call
4740 * lppOut [O] Destination for the service interface pointer
4743 * Success: S_OK. lppOut contains an object providing the requested service
4744 * Failure: An HRESULT error code
4747 * lpUnknown is expected to support the IServiceProvider interface.
4749 HRESULT WINAPI
IUnknown_QueryServiceForWebBrowserApp(IUnknown
* lpUnknown
,
4750 REFGUID riid
, LPVOID
*lppOut
)
4752 FIXME("%p %s %p semi-STUB\n", lpUnknown
, debugstr_guid(riid
), lppOut
);
4753 return IUnknown_QueryService(lpUnknown
,&IID_IWebBrowserApp
,riid
,lppOut
);
4756 /**************************************************************************
4757 * SHPropertyBag_ReadLONG (SHLWAPI.496)
4759 * This function asks a property bag to read a named property as a LONG.
4762 * ppb: a IPropertyBag interface
4763 * pszPropName: Unicode string that names the property
4764 * pValue: address to receive the property value as a 32-bit signed integer
4769 BOOL WINAPI
SHPropertyBag_ReadLONG(IPropertyBag
*ppb
, LPCWSTR pszPropName
, LPLONG pValue
)
4773 TRACE("%p %s %p\n", ppb
,debugstr_w(pszPropName
),pValue
);
4774 if (!pszPropName
|| !ppb
|| !pValue
)
4775 return E_INVALIDARG
;
4777 hr
= IPropertyBag_Read(ppb
, pszPropName
, &var
, NULL
);
4780 if (V_VT(&var
) == VT_I4
)
4781 *pValue
= V_I4(&var
);
4783 hr
= DISP_E_BADVARTYPE
;