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
48 #include "wine/unicode.h"
49 #include "wine/debug.h"
52 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
54 /* DLL handles for late bound calls */
55 extern HINSTANCE shlwapi_hInstance
;
56 extern DWORD SHLWAPI_ThreadRef_index
;
58 HRESULT WINAPI
IUnknown_QueryService(IUnknown
*,REFGUID
,REFIID
,LPVOID
*);
59 HRESULT WINAPI
SHInvokeCommand(HWND
,IShellFolder
*,LPCITEMIDLIST
,BOOL
);
60 BOOL WINAPI
SHAboutInfoW(LPWSTR
,DWORD
);
63 NOTES: Most functions exported by ordinal seem to be superflous.
64 The reason for these functions to be there is to provide a wrapper
65 for unicode functions to provide these functions on systems without
66 unicode functions eg. win95/win98. Since we have such functions we just
67 call these. If running Wine with native DLLs, some late bound calls may
68 fail. However, it is better to implement the functions in the forward DLL
69 and recommend the builtin rather than reimplementing the calls here!
72 /*************************************************************************
73 * SHLWAPI_DupSharedHandle
75 * Internal implemetation of SHLWAPI_11.
78 HANDLE WINAPI
SHLWAPI_DupSharedHandle(HANDLE hShared
, DWORD dwDstProcId
,
79 DWORD dwSrcProcId
, DWORD dwAccess
,
83 DWORD dwMyProcId
= GetCurrentProcessId();
86 TRACE("(%p,%d,%d,%08x,%08x)\n", hShared
, dwDstProcId
, dwSrcProcId
,
89 /* Get dest process handle */
90 if (dwDstProcId
== dwMyProcId
)
91 hDst
= GetCurrentProcess();
93 hDst
= OpenProcess(PROCESS_DUP_HANDLE
, 0, dwDstProcId
);
97 /* Get src process handle */
98 if (dwSrcProcId
== dwMyProcId
)
99 hSrc
= GetCurrentProcess();
101 hSrc
= OpenProcess(PROCESS_DUP_HANDLE
, 0, dwSrcProcId
);
105 /* Make handle available to dest process */
106 if (!DuplicateHandle(hDst
, hShared
, hSrc
, &hRet
,
107 dwAccess
, 0, dwOptions
| DUPLICATE_SAME_ACCESS
))
110 if (dwSrcProcId
!= dwMyProcId
)
114 if (dwDstProcId
!= dwMyProcId
)
118 TRACE("Returning handle %p\n", hRet
);
122 /*************************************************************************
125 * Create a block of sharable memory and initialise it with data.
128 * lpvData [I] Pointer to data to write
129 * dwSize [I] Size of data
130 * dwProcId [I] ID of process owning data
133 * Success: A shared memory handle
137 * Ordinals 7-11 provide a set of calls to create shared memory between a
138 * group of processes. The shared memory is treated opaquely in that its size
139 * is not exposed to clients who map it. This is accomplished by storing
140 * the size of the map as the first DWORD of mapped data, and then offsetting
141 * the view pointer returned by this size.
144 HANDLE WINAPI
SHAllocShared(LPCVOID lpvData
, DWORD dwSize
, DWORD dwProcId
)
150 TRACE("(%p,%d,%d)\n", lpvData
, dwSize
, dwProcId
);
152 /* Create file mapping of the correct length */
153 hMap
= CreateFileMappingA(INVALID_HANDLE_VALUE
, NULL
, FILE_MAP_READ
, 0,
154 dwSize
+ sizeof(dwSize
), NULL
);
158 /* Get a view in our process address space */
159 pMapped
= MapViewOfFile(hMap
, FILE_MAP_READ
| FILE_MAP_WRITE
, 0, 0, 0);
163 /* Write size of data, followed by the data, to the view */
164 *((DWORD
*)pMapped
) = dwSize
;
166 memcpy((char *) pMapped
+ sizeof(dwSize
), lpvData
, dwSize
);
168 /* Release view. All further views mapped will be opaque */
169 UnmapViewOfFile(pMapped
);
170 hRet
= SHLWAPI_DupSharedHandle(hMap
, dwProcId
,
171 GetCurrentProcessId(), FILE_MAP_ALL_ACCESS
,
172 DUPLICATE_SAME_ACCESS
);
179 /*************************************************************************
182 * Get a pointer to a block of shared memory from a shared memory handle.
185 * hShared [I] Shared memory handle
186 * dwProcId [I] ID of process owning hShared
189 * Success: A pointer to the shared memory
193 PVOID WINAPI
SHLockShared(HANDLE hShared
, DWORD dwProcId
)
198 TRACE("(%p %d)\n", hShared
, dwProcId
);
200 /* Get handle to shared memory for current process */
201 hDup
= SHLWAPI_DupSharedHandle(hShared
, dwProcId
, GetCurrentProcessId(),
202 FILE_MAP_ALL_ACCESS
, 0);
204 pMapped
= MapViewOfFile(hDup
, FILE_MAP_READ
| FILE_MAP_WRITE
, 0, 0, 0);
208 return (char *) pMapped
+ sizeof(DWORD
); /* Hide size */
212 /*************************************************************************
215 * Release a pointer to a block of shared memory.
218 * lpView [I] Shared memory pointer
225 BOOL WINAPI
SHUnlockShared(LPVOID lpView
)
227 TRACE("(%p)\n", lpView
);
228 return UnmapViewOfFile((char *) lpView
- sizeof(DWORD
)); /* Include size */
231 /*************************************************************************
234 * Destroy a block of sharable memory.
237 * hShared [I] Shared memory handle
238 * dwProcId [I] ID of process owning hShared
245 BOOL WINAPI
SHFreeShared(HANDLE hShared
, DWORD dwProcId
)
249 TRACE("(%p %d)\n", hShared
, dwProcId
);
251 /* Get a copy of the handle for our process, closing the source handle */
252 hClose
= SHLWAPI_DupSharedHandle(hShared
, dwProcId
, GetCurrentProcessId(),
253 FILE_MAP_ALL_ACCESS
,DUPLICATE_CLOSE_SOURCE
);
254 /* Close local copy */
255 return CloseHandle(hClose
);
258 /*************************************************************************
261 * Copy a sharable memory handle from one process to another.
264 * hShared [I] Shared memory handle to duplicate
265 * dwDstProcId [I] ID of the process wanting the duplicated handle
266 * dwSrcProcId [I] ID of the process owning hShared
267 * dwAccess [I] Desired DuplicateHandle() access
268 * dwOptions [I] Desired DuplicateHandle() options
271 * Success: A handle suitable for use by the dwDstProcId process.
272 * Failure: A NULL handle.
275 HANDLE WINAPI
SHMapHandle(HANDLE hShared
, DWORD dwDstProcId
, DWORD dwSrcProcId
,
276 DWORD dwAccess
, DWORD dwOptions
)
280 hRet
= SHLWAPI_DupSharedHandle(hShared
, dwDstProcId
, dwSrcProcId
,
281 dwAccess
, dwOptions
);
285 /*************************************************************************
288 * Create and register a clipboard enumerator for a web browser.
291 * lpBC [I] Binding context
292 * lpUnknown [I] An object exposing the IWebBrowserApp interface
296 * Failure: An HRESULT error code.
299 * The enumerator is stored as a property of the web browser. If it does not
300 * yet exist, it is created and set before being registered.
302 HRESULT WINAPI
RegisterDefaultAcceptHeaders(LPBC lpBC
, IUnknown
*lpUnknown
)
304 static const WCHAR szProperty
[] = { '{','D','0','F','C','A','4','2','0',
305 '-','D','3','F','5','-','1','1','C','F', '-','B','2','1','1','-','0',
306 '0','A','A','0','0','4','A','E','8','3','7','}','\0' };
308 IEnumFORMATETC
* pIEnumFormatEtc
= NULL
;
311 IWebBrowserApp
* pBrowser
= NULL
;
313 TRACE("(%p, %p)\n", lpBC
, lpUnknown
);
315 /* Get An IWebBrowserApp interface from lpUnknown */
316 hRet
= IUnknown_QueryService(lpUnknown
, &IID_IWebBrowserApp
, &IID_IWebBrowserApp
, (PVOID
)&pBrowser
);
317 if (FAILED(hRet
) || !pBrowser
)
318 return E_NOINTERFACE
;
320 V_VT(&var
) = VT_EMPTY
;
322 /* The property we get is the browsers clipboard enumerator */
323 property
= SysAllocString(szProperty
);
324 hRet
= IWebBrowserApp_GetProperty(pBrowser
, property
, &var
);
325 SysFreeString(property
);
329 if (V_VT(&var
) == VT_EMPTY
)
331 /* Iterate through accepted documents and RegisterClipBoardFormatA() them */
332 char szKeyBuff
[128], szValueBuff
[128];
333 DWORD dwKeySize
, dwValueSize
, dwRet
= 0, dwCount
= 0, dwNumValues
, dwType
;
334 FORMATETC
* formatList
, *format
;
337 TRACE("Registering formats and creating IEnumFORMATETC instance\n");
339 if (!RegOpenKeyA(HKEY_LOCAL_MACHINE
, "Software\\Microsoft\\Windows\\Current"
340 "Version\\Internet Settings\\Accepted Documents", &hDocs
))
343 /* Get count of values in key */
346 dwKeySize
= sizeof(szKeyBuff
);
347 dwRet
= RegEnumValueA(hDocs
,dwCount
,szKeyBuff
,&dwKeySize
,0,&dwType
,0,0);
351 dwNumValues
= dwCount
;
353 /* Note: dwCount = number of items + 1; The extra item is the end node */
354 format
= formatList
= HeapAlloc(GetProcessHeap(), 0, dwCount
* sizeof(FORMATETC
));
356 return E_OUTOFMEMORY
;
365 /* Register clipboard formats for the values and populate format list */
366 while(!dwRet
&& dwCount
< dwNumValues
)
368 dwKeySize
= sizeof(szKeyBuff
);
369 dwValueSize
= sizeof(szValueBuff
);
370 dwRet
= RegEnumValueA(hDocs
, dwCount
, szKeyBuff
, &dwKeySize
, 0, &dwType
,
371 (PBYTE
)szValueBuff
, &dwValueSize
);
375 format
->cfFormat
= RegisterClipboardFormatA(szValueBuff
);
377 format
->dwAspect
= 1;
386 /* Terminate the (maybe empty) list, last entry has a cfFormat of 0 */
387 format
->cfFormat
= 0;
389 format
->dwAspect
= 1;
393 /* Create a clipboard enumerator */
394 hRet
= CreateFormatEnumerator(dwNumValues
, formatList
, &pIEnumFormatEtc
);
396 if (FAILED(hRet
) || !pIEnumFormatEtc
)
399 /* Set our enumerator as the browsers property */
400 V_VT(&var
) = VT_UNKNOWN
;
401 V_UNKNOWN(&var
) = (IUnknown
*)pIEnumFormatEtc
;
403 hRet
= IWebBrowserApp_PutProperty(pBrowser
, (BSTR
)szProperty
, var
);
406 IEnumFORMATETC_Release(pIEnumFormatEtc
);
407 goto RegisterDefaultAcceptHeaders_Exit
;
411 if (V_VT(&var
) == VT_UNKNOWN
)
413 /* Our variant is holding the clipboard enumerator */
414 IUnknown
* pIUnknown
= V_UNKNOWN(&var
);
415 IEnumFORMATETC
* pClone
= NULL
;
417 TRACE("Retrieved IEnumFORMATETC property\n");
419 /* Get an IEnumFormatEtc interface from the variants value */
420 pIEnumFormatEtc
= NULL
;
421 hRet
= IUnknown_QueryInterface(pIUnknown
, &IID_IEnumFORMATETC
,
422 (PVOID
)&pIEnumFormatEtc
);
423 if (!hRet
&& pIEnumFormatEtc
)
425 /* Clone and register the enumerator */
426 hRet
= IEnumFORMATETC_Clone(pIEnumFormatEtc
, &pClone
);
429 RegisterFormatEnumerator(lpBC
, pClone
, 0);
431 IEnumFORMATETC_Release(pClone
);
434 /* Release the IEnumFormatEtc interface */
435 IEnumFORMATETC_Release(pIUnknown
);
437 IUnknown_Release(V_UNKNOWN(&var
));
440 RegisterDefaultAcceptHeaders_Exit
:
441 IWebBrowserApp_Release(pBrowser
);
445 /*************************************************************************
448 * Get Explorers "AcceptLanguage" setting.
451 * langbuf [O] Destination for language string
452 * buflen [I] Length of langbuf
453 * [0] Success: used length of langbuf
456 * Success: S_OK. langbuf is set to the language string found.
457 * Failure: E_FAIL, If any arguments are invalid, error occurred, or Explorer
458 * does not contain the setting.
459 * E_INVALIDARG, If the buffer is not big enough
461 HRESULT WINAPI
GetAcceptLanguagesW( LPWSTR langbuf
, LPDWORD buflen
)
463 static const WCHAR szkeyW
[] = {
464 'S','o','f','t','w','a','r','e','\\',
465 'M','i','c','r','o','s','o','f','t','\\',
466 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
467 'I','n','t','e','r','n','a','t','i','o','n','a','l',0};
468 static const WCHAR valueW
[] = {
469 'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0};
470 static const WCHAR enusW
[] = {'e','n','-','u','s',0};
471 DWORD mystrlen
, mytype
;
477 if(!langbuf
|| !buflen
|| !*buflen
)
480 mystrlen
= (*buflen
> 20) ? *buflen
: 20 ;
481 mystr
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
) * mystrlen
);
482 RegOpenKeyW(HKEY_CURRENT_USER
, szkeyW
, &mykey
);
483 if(RegQueryValueExW(mykey
, valueW
, 0, &mytype
, (PBYTE
)mystr
, &mystrlen
)) {
484 /* Did not find value */
485 mylcid
= GetUserDefaultLCID();
486 /* somehow the mylcid translates into "en-us"
487 * this is similar to "LOCALE_SABBREVLANGNAME"
488 * which could be gotten via GetLocaleInfo.
489 * The only problem is LOCALE_SABBREVLANGUAGE" is
490 * a 3 char string (first 2 are country code and third is
491 * letter for "sublanguage", which does not come close to
494 lstrcpyW(mystr
, enusW
);
495 mystrlen
= lstrlenW(mystr
);
497 /* handle returned string */
498 FIXME("missing code\n");
500 memcpy( langbuf
, mystr
, min(*buflen
,strlenW(mystr
)+1)*sizeof(WCHAR
) );
502 if(*buflen
> strlenW(mystr
)) {
503 *buflen
= strlenW(mystr
);
507 retval
= E_INVALIDARG
;
508 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
511 HeapFree(GetProcessHeap(), 0, mystr
);
515 /*************************************************************************
518 * Ascii version of GetAcceptLanguagesW.
520 HRESULT WINAPI
GetAcceptLanguagesA( LPSTR langbuf
, LPDWORD buflen
)
523 DWORD buflenW
, convlen
;
526 if(!langbuf
|| !buflen
|| !*buflen
) return E_FAIL
;
529 langbufW
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
) * buflenW
);
530 retval
= GetAcceptLanguagesW(langbufW
, &buflenW
);
532 /* FIXME: this is wrong, the string may not be null-terminated */
533 convlen
= WideCharToMultiByte(CP_ACP
, 0, langbufW
, -1, langbuf
,
534 *buflen
, NULL
, NULL
);
535 *buflen
= buflenW
? convlen
: 0;
537 HeapFree(GetProcessHeap(), 0, langbufW
);
541 /*************************************************************************
544 * Convert a GUID to a string.
547 * guid [I] GUID to convert
548 * lpszDest [O] Destination for string
549 * cchMax [I] Length of output buffer
552 * The length of the string created.
554 INT WINAPI
SHStringFromGUIDA(REFGUID guid
, LPSTR lpszDest
, INT cchMax
)
559 TRACE("(%s,%p,%d)\n", debugstr_guid(guid
), lpszDest
, cchMax
);
561 sprintf(xguid
, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
562 guid
->Data1
, guid
->Data2
, guid
->Data3
,
563 guid
->Data4
[0], guid
->Data4
[1], guid
->Data4
[2], guid
->Data4
[3],
564 guid
->Data4
[4], guid
->Data4
[5], guid
->Data4
[6], guid
->Data4
[7]);
566 iLen
= strlen(xguid
) + 1;
570 memcpy(lpszDest
, xguid
, iLen
);
574 /*************************************************************************
577 * Convert a GUID to a string.
580 * guid [I] GUID to convert
581 * str [O] Destination for string
582 * cmax [I] Length of output buffer
585 * The length of the string created.
587 INT WINAPI
SHStringFromGUIDW(REFGUID guid
, LPWSTR lpszDest
, INT cchMax
)
591 static const WCHAR wszFormat
[] = {'{','%','0','8','l','X','-','%','0','4','X','-','%','0','4','X','-',
592 '%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','%','0','2','X','%','0','2',
593 'X','%','0','2','X','%','0','2','X','}',0};
595 TRACE("(%s,%p,%d)\n", debugstr_guid(guid
), lpszDest
, cchMax
);
597 sprintfW(xguid
, wszFormat
, guid
->Data1
, guid
->Data2
, guid
->Data3
,
598 guid
->Data4
[0], guid
->Data4
[1], guid
->Data4
[2], guid
->Data4
[3],
599 guid
->Data4
[4], guid
->Data4
[5], guid
->Data4
[6], guid
->Data4
[7]);
601 iLen
= strlenW(xguid
) + 1;
605 memcpy(lpszDest
, xguid
, iLen
*sizeof(WCHAR
));
609 /*************************************************************************
612 * Determine if a Unicode character is a space.
615 * wc [I] Character to check.
618 * TRUE, if wc is a space,
621 BOOL WINAPI
IsCharSpaceW(WCHAR wc
)
625 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_SPACE
);
628 /*************************************************************************
631 * Determine if a Unicode character is a blank.
634 * wc [I] Character to check.
637 * TRUE, if wc is a blank,
641 BOOL WINAPI
IsCharBlankW(WCHAR wc
)
645 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_BLANK
);
648 /*************************************************************************
651 * Determine if a Unicode character is punctuation.
654 * wc [I] Character to check.
657 * TRUE, if wc is punctuation,
660 BOOL WINAPI
IsCharPunctW(WCHAR wc
)
664 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_PUNCT
);
667 /*************************************************************************
670 * Determine if a Unicode character is a control character.
673 * wc [I] Character to check.
676 * TRUE, if wc is a control character,
679 BOOL WINAPI
IsCharCntrlW(WCHAR wc
)
683 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_CNTRL
);
686 /*************************************************************************
689 * Determine if a Unicode character is a digit.
692 * wc [I] Character to check.
695 * TRUE, if wc is a digit,
698 BOOL WINAPI
IsCharDigitW(WCHAR wc
)
702 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_DIGIT
);
705 /*************************************************************************
708 * Determine if a Unicode character is a hex digit.
711 * wc [I] Character to check.
714 * TRUE, if wc is a hex digit,
717 BOOL WINAPI
IsCharXDigitW(WCHAR wc
)
721 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_XDIGIT
);
724 /*************************************************************************
728 BOOL WINAPI
GetStringType3ExW(LPWSTR lpszStr
, DWORD dwLen
, LPVOID p3
)
730 FIXME("(%s,0x%08x,%p): stub\n", debugstr_w(lpszStr
), dwLen
, p3
);
734 /*************************************************************************
737 * Insert a bitmap menu item at the bottom of a menu.
740 * hMenu [I] Menu to insert into
741 * flags [I] Flags for insertion
742 * id [I] Menu ID of the item
743 * str [I] Menu text for the item
746 * Success: TRUE, the item is inserted into the menu
747 * Failure: FALSE, if any parameter is invalid
749 BOOL WINAPI
AppendMenuWrapW(HMENU hMenu
, UINT flags
, UINT id
, LPCWSTR str
)
751 TRACE("(%p,0x%08x,0x%08x,%s)\n",hMenu
, flags
, id
, debugstr_w(str
));
752 return InsertMenuW(hMenu
, -1, flags
| MF_BITMAP
, id
, str
);
755 /*************************************************************************
758 * Set the text of a given dialog item.
761 * hWnd [I] Handle of dialog
762 * iItem [I] Index of item
763 * lpszText [O] Text to set
766 * Success: TRUE. The text of the dialog is set to lpszText.
767 * Failure: FALSE, Otherwise.
769 BOOL WINAPI
SetDlgItemTextWrapW(HWND hWnd
, INT iItem
, LPCWSTR lpszText
)
771 HWND hWndItem
= GetDlgItem(hWnd
, iItem
);
773 return SetWindowTextW(hWndItem
, lpszText
);
777 /*************************************************************************
780 * Compare two Ascii strings up to a given length.
783 * lpszSrc [I] Source string
784 * lpszCmp [I] String to compare to lpszSrc
785 * len [I] Maximum length
788 * A number greater than, less than or equal to 0 depending on whether
789 * lpszSrc is greater than, less than or equal to lpszCmp.
791 DWORD WINAPI
StrCmpNCA(LPCSTR lpszSrc
, LPCSTR lpszCmp
, INT len
)
793 return strncmp(lpszSrc
, lpszCmp
, len
);
796 /*************************************************************************
799 * Unicode version of StrCmpNCA.
801 DWORD WINAPI
StrCmpNCW(LPCWSTR lpszSrc
, LPCWSTR lpszCmp
, INT len
)
803 return strncmpW(lpszSrc
, lpszCmp
, len
);
806 /*************************************************************************
809 * Compare two Ascii strings up to a given length, ignoring case.
812 * lpszSrc [I] Source string
813 * lpszCmp [I] String to compare to lpszSrc
814 * len [I] Maximum length
817 * A number greater than, less than or equal to 0 depending on whether
818 * lpszSrc is greater than, less than or equal to lpszCmp.
820 DWORD WINAPI
StrCmpNICA(LPCSTR lpszSrc
, LPCSTR lpszCmp
, DWORD len
)
822 return strncasecmp(lpszSrc
, lpszCmp
, len
);
825 /*************************************************************************
828 * Unicode version of StrCmpNICA.
830 DWORD WINAPI
StrCmpNICW(LPCWSTR lpszSrc
, LPCWSTR lpszCmp
, DWORD len
)
832 return strncmpiW(lpszSrc
, lpszCmp
, len
);
835 /*************************************************************************
838 * Compare two Ascii strings.
841 * lpszSrc [I] Source string
842 * lpszCmp [I] String to compare to lpszSrc
845 * A number greater than, less than or equal to 0 depending on whether
846 * lpszSrc is greater than, less than or equal to lpszCmp.
848 DWORD WINAPI
StrCmpCA(LPCSTR lpszSrc
, LPCSTR lpszCmp
)
850 return strcmp(lpszSrc
, lpszCmp
);
853 /*************************************************************************
856 * Unicode version of StrCmpCA.
858 DWORD WINAPI
StrCmpCW(LPCWSTR lpszSrc
, LPCWSTR lpszCmp
)
860 return strcmpW(lpszSrc
, lpszCmp
);
863 /*************************************************************************
866 * Compare two Ascii strings, ignoring case.
869 * lpszSrc [I] Source string
870 * lpszCmp [I] String to compare to lpszSrc
873 * A number greater than, less than or equal to 0 depending on whether
874 * lpszSrc is greater than, less than or equal to lpszCmp.
876 DWORD WINAPI
StrCmpICA(LPCSTR lpszSrc
, LPCSTR lpszCmp
)
878 return strcasecmp(lpszSrc
, lpszCmp
);
881 /*************************************************************************
884 * Unicode version of StrCmpICA.
886 DWORD WINAPI
StrCmpICW(LPCWSTR lpszSrc
, LPCWSTR lpszCmp
)
888 return strcmpiW(lpszSrc
, lpszCmp
);
891 /*************************************************************************
894 * Get an identification string for the OS and explorer.
897 * lpszDest [O] Destination for Id string
898 * dwDestLen [I] Length of lpszDest
901 * TRUE, If the string was created successfully
904 BOOL WINAPI
SHAboutInfoA(LPSTR lpszDest
, DWORD dwDestLen
)
908 TRACE("(%p,%d)\n", lpszDest
, dwDestLen
);
910 if (lpszDest
&& SHAboutInfoW(buff
, dwDestLen
))
912 WideCharToMultiByte(CP_ACP
, 0, buff
, -1, lpszDest
, dwDestLen
, NULL
, NULL
);
918 /*************************************************************************
921 * Unicode version of SHAboutInfoA.
923 BOOL WINAPI
SHAboutInfoW(LPWSTR lpszDest
, DWORD dwDestLen
)
925 static const WCHAR szIEKey
[] = { 'S','O','F','T','W','A','R','E','\\',
926 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
927 ' ','E','x','p','l','o','r','e','r','\0' };
928 static const WCHAR szWinNtKey
[] = { 'S','O','F','T','W','A','R','E','\\',
929 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s',' ',
930 'N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
931 static const WCHAR szWinKey
[] = { 'S','O','F','T','W','A','R','E','\\',
932 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
933 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
934 static const WCHAR szRegKey
[] = { 'S','O','F','T','W','A','R','E','\\',
935 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
936 ' ','E','x','p','l','o','r','e','r','\\',
937 'R','e','g','i','s','t','r','a','t','i','o','n','\0' };
938 static const WCHAR szVersion
[] = { 'V','e','r','s','i','o','n','\0' };
939 static const WCHAR szCustomized
[] = { 'C','u','s','t','o','m','i','z','e','d',
940 'V','e','r','s','i','o','n','\0' };
941 static const WCHAR szOwner
[] = { 'R','e','g','i','s','t','e','r','e','d',
942 'O','w','n','e','r','\0' };
943 static const WCHAR szOrg
[] = { 'R','e','g','i','s','t','e','r','e','d',
944 'O','r','g','a','n','i','z','a','t','i','o','n','\0' };
945 static const WCHAR szProduct
[] = { 'P','r','o','d','u','c','t','I','d','\0' };
946 static const WCHAR szUpdate
[] = { 'I','E','A','K',
947 'U','p','d','a','t','e','U','r','l','\0' };
948 static const WCHAR szHelp
[] = { 'I','E','A','K',
949 'H','e','l','p','S','t','r','i','n','g','\0' };
954 TRACE("(%p,%d)\n", lpszDest
, dwDestLen
);
961 /* Try the NT key first, followed by 95/98 key */
962 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szWinNtKey
, 0, KEY_READ
, &hReg
) &&
963 RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szWinKey
, 0, KEY_READ
, &hReg
))
969 if (!SHGetValueW(HKEY_LOCAL_MACHINE
, szIEKey
, szVersion
, &dwType
, buff
, &dwLen
))
971 DWORD dwStrLen
= strlenW(buff
);
972 dwLen
= 30 - dwStrLen
;
973 SHGetValueW(HKEY_LOCAL_MACHINE
, szIEKey
,
974 szCustomized
, &dwType
, buff
+dwStrLen
, &dwLen
);
976 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
978 /* ~Registered Owner */
981 if (SHGetValueW(hReg
, szOwner
, 0, &dwType
, buff
+1, &dwLen
))
983 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
985 /* ~Registered Organization */
987 if (SHGetValueW(hReg
, szOrg
, 0, &dwType
, buff
+1, &dwLen
))
989 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
991 /* FIXME: Not sure where this number comes from */
995 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
999 if (SHGetValueW(HKEY_LOCAL_MACHINE
, szRegKey
, szProduct
, &dwType
, buff
+1, &dwLen
))
1001 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
1003 /* ~IE Update Url */
1005 if(SHGetValueW(HKEY_LOCAL_MACHINE
, szWinKey
, szUpdate
, &dwType
, buff
+1, &dwLen
))
1007 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
1009 /* ~IE Help String */
1011 if(SHGetValueW(hReg
, szHelp
, 0, &dwType
, buff
+1, &dwLen
))
1013 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
1019 /*************************************************************************
1022 * Call IOleCommandTarget_QueryStatus() on an object.
1025 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1026 * pguidCmdGroup [I] GUID for the command group
1028 * prgCmds [O] Commands
1029 * pCmdText [O] Command text
1033 * Failure: E_FAIL, if lpUnknown is NULL.
1034 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1035 * Otherwise, an error code from IOleCommandTarget_QueryStatus().
1037 HRESULT WINAPI
IUnknown_QueryStatus(IUnknown
* lpUnknown
, REFGUID pguidCmdGroup
,
1038 ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
* pCmdText
)
1040 HRESULT hRet
= E_FAIL
;
1042 TRACE("(%p,%p,%d,%p,%p)\n",lpUnknown
, pguidCmdGroup
, cCmds
, prgCmds
, pCmdText
);
1046 IOleCommandTarget
* lpOle
;
1048 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleCommandTarget
,
1051 if (SUCCEEDED(hRet
) && lpOle
)
1053 hRet
= IOleCommandTarget_QueryStatus(lpOle
, pguidCmdGroup
, cCmds
,
1055 IOleCommandTarget_Release(lpOle
);
1061 /*************************************************************************
1064 * Call IOleCommandTarget_Exec() on an object.
1067 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1068 * pguidCmdGroup [I] GUID for the command group
1072 * Failure: E_FAIL, if lpUnknown is NULL.
1073 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1074 * Otherwise, an error code from IOleCommandTarget_Exec().
1076 HRESULT WINAPI
IUnknown_Exec(IUnknown
* lpUnknown
, REFGUID pguidCmdGroup
,
1077 DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
* pvaIn
,
1080 HRESULT hRet
= E_FAIL
;
1082 TRACE("(%p,%p,%d,%d,%p,%p)\n",lpUnknown
, pguidCmdGroup
, nCmdID
,
1083 nCmdexecopt
, pvaIn
, pvaOut
);
1087 IOleCommandTarget
* lpOle
;
1089 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleCommandTarget
,
1091 if (SUCCEEDED(hRet
) && lpOle
)
1093 hRet
= IOleCommandTarget_Exec(lpOle
, pguidCmdGroup
, nCmdID
,
1094 nCmdexecopt
, pvaIn
, pvaOut
);
1095 IOleCommandTarget_Release(lpOle
);
1101 /*************************************************************************
1104 * Retrieve, modify, and re-set a value from a window.
1107 * hWnd [I] Window to get value from
1108 * offset [I] Offset of value
1109 * wMask [I] Mask for uiFlags
1110 * wFlags [I] Bits to set in window value
1113 * The new value as it was set, or 0 if any parameter is invalid.
1116 * Any bits set in uiMask are cleared from the value, then any bits set in
1117 * uiFlags are set in the value.
1119 LONG WINAPI
SHSetWindowBits(HWND hwnd
, INT offset
, UINT wMask
, UINT wFlags
)
1121 LONG ret
= GetWindowLongA(hwnd
, offset
);
1122 LONG newFlags
= (wFlags
& wMask
) | (ret
& ~wFlags
);
1124 if (newFlags
!= ret
)
1125 ret
= SetWindowLongA(hwnd
, offset
, newFlags
);
1129 /*************************************************************************
1132 * Change a window's parent.
1135 * hWnd [I] Window to change parent of
1136 * hWndParent [I] New parent window
1139 * The old parent of hWnd.
1142 * If hWndParent is NULL (desktop), the window style is changed to WS_POPUP.
1143 * If hWndParent is NOT NULL then we set the WS_CHILD style.
1145 HWND WINAPI
SHSetParentHwnd(HWND hWnd
, HWND hWndParent
)
1147 TRACE("%p, %p\n", hWnd
, hWndParent
);
1149 if(GetParent(hWnd
) == hWndParent
)
1153 SHSetWindowBits(hWnd
, GWL_STYLE
, WS_CHILD
, WS_CHILD
);
1155 SHSetWindowBits(hWnd
, GWL_STYLE
, WS_POPUP
, WS_POPUP
);
1157 return SetParent(hWnd
, hWndParent
);
1160 /*************************************************************************
1163 * Locate and advise a connection point in an IConnectionPointContainer object.
1166 * lpUnkSink [I] Sink for the connection point advise call
1167 * riid [I] REFIID of connection point to advise
1168 * bAdviseOnly [I] TRUE = Advise only, FALSE = Unadvise first
1169 * lpUnknown [I] Object supporting the IConnectionPointContainer interface
1170 * lpCookie [O] Pointer to connection point cookie
1171 * lppCP [O] Destination for the IConnectionPoint found
1174 * Success: S_OK. If lppCP is non-NULL, it is filled with the IConnectionPoint
1175 * that was advised. The caller is responsible for releasing it.
1176 * Failure: E_FAIL, if any arguments are invalid.
1177 * E_NOINTERFACE, if lpUnknown isn't an IConnectionPointContainer,
1178 * Or an HRESULT error code if any call fails.
1180 HRESULT WINAPI
ConnectToConnectionPoint(IUnknown
* lpUnkSink
, REFIID riid
, BOOL bAdviseOnly
,
1181 IUnknown
* lpUnknown
, LPDWORD lpCookie
,
1182 IConnectionPoint
**lppCP
)
1185 IConnectionPointContainer
* lpContainer
;
1186 IConnectionPoint
*lpCP
;
1188 if(!lpUnknown
|| (bAdviseOnly
&& !lpUnkSink
))
1194 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IConnectionPointContainer
,
1195 (void**)&lpContainer
);
1196 if (SUCCEEDED(hRet
))
1198 hRet
= IConnectionPointContainer_FindConnectionPoint(lpContainer
, riid
, &lpCP
);
1200 if (SUCCEEDED(hRet
))
1203 hRet
= IConnectionPoint_Unadvise(lpCP
, *lpCookie
);
1204 hRet
= IConnectionPoint_Advise(lpCP
, lpUnkSink
, lpCookie
);
1209 if (lppCP
&& SUCCEEDED(hRet
))
1210 *lppCP
= lpCP
; /* Caller keeps the interface */
1212 IConnectionPoint_Release(lpCP
); /* Release it */
1215 IUnknown_Release(lpContainer
);
1220 /*************************************************************************
1223 * Release an interface.
1226 * lpUnknown [I] Object to release
1231 DWORD WINAPI
IUnknown_AtomicRelease(IUnknown
** lpUnknown
)
1235 TRACE("(%p)\n",lpUnknown
);
1237 if(!lpUnknown
|| !*((LPDWORD
)lpUnknown
)) return 0;
1241 TRACE("doing Release\n");
1243 return IUnknown_Release(temp
);
1246 /*************************************************************************
1249 * Skip '//' if present in a string.
1252 * lpszSrc [I] String to check for '//'
1255 * Success: The next character after the '//' or the string if not present
1256 * Failure: NULL, if lpszStr is NULL.
1258 LPCSTR WINAPI
PathSkipLeadingSlashesA(LPCSTR lpszSrc
)
1260 if (lpszSrc
&& lpszSrc
[0] == '/' && lpszSrc
[1] == '/')
1265 /*************************************************************************
1268 * Check if two interfaces come from the same object.
1271 * lpInt1 [I] Interface to check against lpInt2.
1272 * lpInt2 [I] Interface to check against lpInt1.
1275 * TRUE, If the interfaces come from the same object.
1278 BOOL WINAPI
SHIsSameObject(IUnknown
* lpInt1
, IUnknown
* lpInt2
)
1280 LPVOID lpUnknown1
, lpUnknown2
;
1282 TRACE("%p %p\n", lpInt1
, lpInt2
);
1284 if (!lpInt1
|| !lpInt2
)
1287 if (lpInt1
== lpInt2
)
1290 if (!SUCCEEDED(IUnknown_QueryInterface(lpInt1
, &IID_IUnknown
,
1291 (LPVOID
*)&lpUnknown1
)))
1294 if (!SUCCEEDED(IUnknown_QueryInterface(lpInt2
, &IID_IUnknown
,
1295 (LPVOID
*)&lpUnknown2
)))
1298 if (lpUnknown1
== lpUnknown2
)
1304 /*************************************************************************
1307 * Get the window handle of an object.
1310 * lpUnknown [I] Object to get the window handle of
1311 * lphWnd [O] Destination for window handle
1314 * Success: S_OK. lphWnd contains the objects window handle.
1315 * Failure: An HRESULT error code.
1318 * lpUnknown is expected to support one of the following interfaces:
1319 * IOleWindow(), IInternetSecurityMgrSite(), or IShellView().
1321 HRESULT WINAPI
IUnknown_GetWindow(IUnknown
*lpUnknown
, HWND
*lphWnd
)
1323 /* FIXME: Wine has no header for this object */
1324 static const GUID IID_IInternetSecurityMgrSite
= { 0x79eac9ed,
1325 0xbaf9, 0x11ce, { 0x8c, 0x82, 0x00, 0xaa, 0x00, 0x4b, 0xa9, 0x0b }};
1327 HRESULT hRet
= E_FAIL
;
1329 TRACE("(%p,%p)\n", lpUnknown
, lphWnd
);
1334 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleWindow
, (void**)&lpOle
);
1338 hRet
= IUnknown_QueryInterface(lpUnknown
,&IID_IShellView
, (void**)&lpOle
);
1342 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IInternetSecurityMgrSite
,
1347 if (SUCCEEDED(hRet
))
1349 /* Lazyness here - Since GetWindow() is the first method for the above 3
1350 * interfaces, we use the same call for them all.
1352 hRet
= IOleWindow_GetWindow((IOleWindow
*)lpOle
, lphWnd
);
1353 IUnknown_Release(lpOle
);
1355 TRACE("Returning HWND=%p\n", *lphWnd
);
1361 /*************************************************************************
1364 * Call a method on as as yet unidentified object.
1367 * pUnk [I] Object supporting the unidentified interface,
1368 * arg [I] Argument for the call on the object.
1373 HRESULT WINAPI
IUnknown_SetOwner(IUnknown
*pUnk
, ULONG arg
)
1375 static const GUID guid_173
= {
1376 0x5836fb00, 0x8187, 0x11cf, { 0xa1,0x2b,0x00,0xaa,0x00,0x4a,0xe8,0x37 }
1380 TRACE("(%p,%d)\n", pUnk
, arg
);
1382 /* Note: arg may not be a ULONG and pUnk2 is for sure not an IMalloc -
1383 * We use this interface as its vtable entry is compatible with the
1384 * object in question.
1385 * FIXME: Find out what this object is and where it should be defined.
1388 SUCCEEDED(IUnknown_QueryInterface(pUnk
, &guid_173
, (void**)&pUnk2
)))
1390 IMalloc_Alloc(pUnk2
, arg
); /* Faked call!! */
1391 IMalloc_Release(pUnk2
);
1396 /*************************************************************************
1399 * Call either IObjectWithSite_SetSite() or IInternetSecurityManager_SetSecuritySite() on
1403 HRESULT WINAPI
IUnknown_SetSite(
1404 IUnknown
*obj
, /* [in] OLE object */
1405 IUnknown
*site
) /* [in] Site interface */
1408 IObjectWithSite
*iobjwithsite
;
1409 IInternetSecurityManager
*isecmgr
;
1411 if (!obj
) return E_FAIL
;
1413 hr
= IUnknown_QueryInterface(obj
, &IID_IObjectWithSite
, (LPVOID
*)&iobjwithsite
);
1414 TRACE("IID_IObjectWithSite QI ret=%08x, %p\n", hr
, iobjwithsite
);
1417 hr
= IObjectWithSite_SetSite(iobjwithsite
, site
);
1418 TRACE("done IObjectWithSite_SetSite ret=%08x\n", hr
);
1419 IUnknown_Release(iobjwithsite
);
1423 hr
= IUnknown_QueryInterface(obj
, &IID_IInternetSecurityManager
, (LPVOID
*)&isecmgr
);
1424 TRACE("IID_IInternetSecurityManager QI ret=%08x, %p\n", hr
, isecmgr
);
1425 if (FAILED(hr
)) return hr
;
1427 hr
= IInternetSecurityManager_SetSecuritySite(isecmgr
, (IInternetSecurityMgrSite
*)site
);
1428 TRACE("done IInternetSecurityManager_SetSecuritySite ret=%08x\n", hr
);
1429 IUnknown_Release(isecmgr
);
1434 /*************************************************************************
1437 * Call IPersist_GetClassID() on an object.
1440 * lpUnknown [I] Object supporting the IPersist interface
1441 * lpClassId [O] Destination for Class Id
1444 * Success: S_OK. lpClassId contains the Class Id requested.
1445 * Failure: E_FAIL, If lpUnknown is NULL,
1446 * E_NOINTERFACE If lpUnknown does not support IPersist,
1447 * Or an HRESULT error code.
1449 HRESULT WINAPI
IUnknown_GetClassID(IUnknown
*lpUnknown
, CLSID
* lpClassId
)
1451 IPersist
* lpPersist
;
1452 HRESULT hRet
= E_FAIL
;
1454 TRACE("(%p,%p)\n", lpUnknown
, debugstr_guid(lpClassId
));
1458 hRet
= IUnknown_QueryInterface(lpUnknown
,&IID_IPersist
,(void**)&lpPersist
);
1459 if (SUCCEEDED(hRet
))
1461 IPersist_GetClassID(lpPersist
, lpClassId
);
1462 IPersist_Release(lpPersist
);
1468 /*************************************************************************
1471 * Retrieve a Service Interface from an object.
1474 * lpUnknown [I] Object to get an IServiceProvider interface from
1475 * sid [I] Service ID for IServiceProvider_QueryService() call
1476 * riid [I] Function requested for QueryService call
1477 * lppOut [O] Destination for the service interface pointer
1480 * Success: S_OK. lppOut contains an object providing the requested service
1481 * Failure: An HRESULT error code
1484 * lpUnknown is expected to support the IServiceProvider interface.
1486 HRESULT WINAPI
IUnknown_QueryService(IUnknown
* lpUnknown
, REFGUID sid
, REFIID riid
,
1489 IServiceProvider
* pService
= NULL
;
1500 /* Get an IServiceProvider interface from the object */
1501 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IServiceProvider
,
1502 (LPVOID
*)&pService
);
1504 if (!hRet
&& pService
)
1506 TRACE("QueryInterface returned (IServiceProvider*)%p\n", pService
);
1508 /* Get a Service interface from the object */
1509 hRet
= IServiceProvider_QueryService(pService
, sid
, riid
, lppOut
);
1511 TRACE("(IServiceProvider*)%p returned (IUnknown*)%p\n", pService
, *lppOut
);
1513 /* Release the IServiceProvider interface */
1514 IUnknown_Release(pService
);
1519 /*************************************************************************
1522 * Loads a popup menu.
1525 * hInst [I] Instance handle
1526 * szName [I] Menu name
1532 BOOL WINAPI
SHLoadMenuPopup(HINSTANCE hInst
, LPCWSTR szName
)
1534 HMENU hMenu
, hSubMenu
;
1536 if ((hMenu
= LoadMenuW(hInst
, szName
)))
1538 if ((hSubMenu
= GetSubMenu(hMenu
, 0)))
1539 RemoveMenu(hMenu
, 0, MF_BYPOSITION
);
1547 typedef struct _enumWndData
1552 LRESULT (WINAPI
*pfnPost
)(HWND
,UINT
,WPARAM
,LPARAM
);
1555 /* Callback for SHLWAPI_178 */
1556 static BOOL CALLBACK
SHLWAPI_EnumChildProc(HWND hWnd
, LPARAM lParam
)
1558 enumWndData
*data
= (enumWndData
*)lParam
;
1560 TRACE("(%p,%p)\n", hWnd
, data
);
1561 data
->pfnPost(hWnd
, data
->uiMsgId
, data
->wParam
, data
->lParam
);
1565 /*************************************************************************
1568 * Send or post a message to every child of a window.
1571 * hWnd [I] Window whose children will get the messages
1572 * uiMsgId [I] Message Id
1573 * wParam [I] WPARAM of message
1574 * lParam [I] LPARAM of message
1575 * bSend [I] TRUE = Use SendMessageA(), FALSE = Use PostMessageA()
1581 * The appropriate ASCII or Unicode function is called for the window.
1583 void WINAPI
SHPropagateMessage(HWND hWnd
, UINT uiMsgId
, WPARAM wParam
, LPARAM lParam
, BOOL bSend
)
1587 TRACE("(%p,%u,%ld,%ld,%d)\n", hWnd
, uiMsgId
, wParam
, lParam
, bSend
);
1591 data
.uiMsgId
= uiMsgId
;
1592 data
.wParam
= wParam
;
1593 data
.lParam
= lParam
;
1596 data
.pfnPost
= IsWindowUnicode(hWnd
) ? (void*)SendMessageW
: (void*)SendMessageA
;
1598 data
.pfnPost
= IsWindowUnicode(hWnd
) ? (void*)PostMessageW
: (void*)PostMessageA
;
1600 EnumChildWindows(hWnd
, SHLWAPI_EnumChildProc
, (LPARAM
)&data
);
1604 /*************************************************************************
1607 * Remove all sub-menus from a menu.
1610 * hMenu [I] Menu to remove sub-menus from
1613 * Success: 0. All sub-menus under hMenu are removed
1614 * Failure: -1, if any parameter is invalid
1616 DWORD WINAPI
SHRemoveAllSubMenus(HMENU hMenu
)
1618 int iItemCount
= GetMenuItemCount(hMenu
) - 1;
1619 while (iItemCount
>= 0)
1621 HMENU hSubMenu
= GetSubMenu(hMenu
, iItemCount
);
1623 RemoveMenu(hMenu
, iItemCount
, MF_BYPOSITION
);
1629 /*************************************************************************
1632 * Enable or disable a menu item.
1635 * hMenu [I] Menu holding menu item
1636 * uID [I] ID of menu item to enable/disable
1637 * bEnable [I] Whether to enable (TRUE) or disable (FALSE) the item.
1640 * The return code from EnableMenuItem.
1642 UINT WINAPI
SHEnableMenuItem(HMENU hMenu
, UINT wItemID
, BOOL bEnable
)
1644 return EnableMenuItem(hMenu
, wItemID
, bEnable
? MF_ENABLED
: MF_GRAYED
);
1647 /*************************************************************************
1650 * Check or uncheck a menu item.
1653 * hMenu [I] Menu holding menu item
1654 * uID [I] ID of menu item to check/uncheck
1655 * bCheck [I] Whether to check (TRUE) or uncheck (FALSE) the item.
1658 * The return code from CheckMenuItem.
1660 DWORD WINAPI
SHCheckMenuItem(HMENU hMenu
, UINT uID
, BOOL bCheck
)
1662 return CheckMenuItem(hMenu
, uID
, bCheck
? MF_CHECKED
: MF_UNCHECKED
);
1665 /*************************************************************************
1668 * Register a window class if it isn't already.
1671 * lpWndClass [I] Window class to register
1674 * The result of the RegisterClassA call.
1676 DWORD WINAPI
SHRegisterClassA(WNDCLASSA
*wndclass
)
1679 if (GetClassInfoA(wndclass
->hInstance
, wndclass
->lpszClassName
, &wca
))
1681 return (DWORD
)RegisterClassA(wndclass
);
1684 /*************************************************************************
1687 BOOL WINAPI
SHSimulateDrop(IDropTarget
*pDrop
, IDataObject
*pDataObj
,
1688 DWORD grfKeyState
, PPOINTL lpPt
, DWORD
* pdwEffect
)
1690 DWORD dwEffect
= DROPEFFECT_LINK
| DROPEFFECT_MOVE
| DROPEFFECT_COPY
;
1691 POINTL pt
= { 0, 0 };
1697 pdwEffect
= &dwEffect
;
1699 IDropTarget_DragEnter(pDrop
, pDataObj
, grfKeyState
, *lpPt
, pdwEffect
);
1702 return IDropTarget_Drop(pDrop
, pDataObj
, grfKeyState
, *lpPt
, pdwEffect
);
1704 IDropTarget_DragLeave(pDrop
);
1708 /*************************************************************************
1711 * Call IPersistPropertyBag_Load() on an object.
1714 * lpUnknown [I] Object supporting the IPersistPropertyBag interface
1715 * lpPropBag [O] Destination for loaded IPropertyBag
1719 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1721 DWORD WINAPI
SHLoadFromPropertyBag(IUnknown
*lpUnknown
, IPropertyBag
* lpPropBag
)
1723 IPersistPropertyBag
* lpPPBag
;
1724 HRESULT hRet
= E_FAIL
;
1726 TRACE("(%p,%p)\n", lpUnknown
, lpPropBag
);
1730 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IPersistPropertyBag
,
1732 if (SUCCEEDED(hRet
) && lpPPBag
)
1734 hRet
= IPersistPropertyBag_Load(lpPPBag
, lpPropBag
, NULL
);
1735 IPersistPropertyBag_Release(lpPPBag
);
1741 /*************************************************************************
1744 * Call IOleControlSite_TranslateAccelerator() on an object.
1747 * lpUnknown [I] Object supporting the IOleControlSite interface.
1748 * lpMsg [I] Key message to be processed.
1749 * dwModifiers [I] Flags containing the state of the modifier keys.
1753 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
1755 HRESULT WINAPI
IUnknown_TranslateAcceleratorOCS(IUnknown
*lpUnknown
, LPMSG lpMsg
, DWORD dwModifiers
)
1757 IOleControlSite
* lpCSite
= NULL
;
1758 HRESULT hRet
= E_INVALIDARG
;
1760 TRACE("(%p,%p,0x%08x)\n", lpUnknown
, lpMsg
, dwModifiers
);
1763 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleControlSite
,
1765 if (SUCCEEDED(hRet
) && lpCSite
)
1767 hRet
= IOleControlSite_TranslateAccelerator(lpCSite
, lpMsg
, dwModifiers
);
1768 IOleControlSite_Release(lpCSite
);
1775 /*************************************************************************
1778 * Call IOleControlSite_GetExtendedControl() on an object.
1781 * lpUnknown [I] Object supporting the IOleControlSite interface.
1782 * lppDisp [O] Destination for resulting IDispatch.
1786 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1788 DWORD WINAPI
IUnknown_OnFocusOCS(IUnknown
*lpUnknown
, IDispatch
** lppDisp
)
1790 IOleControlSite
* lpCSite
= NULL
;
1791 HRESULT hRet
= E_FAIL
;
1793 TRACE("(%p,%p)\n", lpUnknown
, lppDisp
);
1796 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleControlSite
,
1798 if (SUCCEEDED(hRet
) && lpCSite
)
1800 hRet
= IOleControlSite_GetExtendedControl(lpCSite
, lppDisp
);
1801 IOleControlSite_Release(lpCSite
);
1807 /*************************************************************************
1810 HRESULT WINAPI
IUnknown_HandleIRestrict(LPUNKNOWN lpUnknown
, PVOID lpArg1
,
1811 PVOID lpArg2
, PVOID lpArg3
, PVOID lpArg4
)
1813 /* FIXME: {D12F26B2-D90A-11D0-830D-00AA005B4383} - What object does this represent? */
1814 static const DWORD service_id
[] = { 0xd12f26b2, 0x11d0d90a, 0xaa000d83, 0x83435b00 };
1815 /* FIXME: {D12F26B1-D90A-11D0-830D-00AA005B4383} - Also Unknown/undocumented */
1816 static const DWORD function_id
[] = { 0xd12f26b1, 0x11d0d90a, 0xaa000d83, 0x83435b00 };
1817 HRESULT hRet
= E_INVALIDARG
;
1818 LPUNKNOWN lpUnkInner
= NULL
; /* FIXME: Real type is unknown */
1820 TRACE("(%p,%p,%p,%p,%p)\n", lpUnknown
, lpArg1
, lpArg2
, lpArg3
, lpArg4
);
1822 if (lpUnknown
&& lpArg4
)
1824 hRet
= IUnknown_QueryService(lpUnknown
, (REFGUID
)service_id
,
1825 (REFGUID
)function_id
, (void**)&lpUnkInner
);
1827 if (SUCCEEDED(hRet
) && lpUnkInner
)
1829 /* FIXME: The type of service object requested is unknown, however
1830 * testing shows that its first method is called with 4 parameters.
1831 * Fake this by using IParseDisplayName_ParseDisplayName since the
1832 * signature and position in the vtable matches our unknown object type.
1834 hRet
= IParseDisplayName_ParseDisplayName((LPPARSEDISPLAYNAME
)lpUnkInner
,
1835 lpArg1
, lpArg2
, lpArg3
, lpArg4
);
1836 IUnknown_Release(lpUnkInner
);
1842 /*************************************************************************
1845 * Get a sub-menu from a menu item.
1848 * hMenu [I] Menu to get sub-menu from
1849 * uID [I] ID of menu item containing sub-menu
1852 * The sub-menu of the item, or a NULL handle if any parameters are invalid.
1854 HMENU WINAPI
SHGetMenuFromID(HMENU hMenu
, UINT uID
)
1858 TRACE("(%p,%u)\n", hMenu
, uID
);
1860 mi
.cbSize
= sizeof(mi
);
1861 mi
.fMask
= MIIM_SUBMENU
;
1863 if (!GetMenuItemInfoW(hMenu
, uID
, FALSE
, &mi
))
1869 /*************************************************************************
1872 * Get the color depth of the primary display.
1878 * The color depth of the primary display.
1880 DWORD WINAPI
SHGetCurColorRes(void)
1888 ret
= GetDeviceCaps(hdc
, BITSPIXEL
) * GetDeviceCaps(hdc
, PLANES
);
1893 /*************************************************************************
1896 * Wait for a message to arrive, with a timeout.
1899 * hand [I] Handle to query
1900 * dwTimeout [I] Timeout in ticks or INFINITE to never timeout
1903 * STATUS_TIMEOUT if no message is received before dwTimeout ticks passes.
1904 * Otherwise returns the value from MsgWaitForMultipleObjectsEx when a
1905 * message is available.
1907 DWORD WINAPI
SHWaitForSendMessageThread(HANDLE hand
, DWORD dwTimeout
)
1909 DWORD dwEndTicks
= GetTickCount() + dwTimeout
;
1912 while ((dwRet
= MsgWaitForMultipleObjectsEx(1, &hand
, dwTimeout
, QS_SENDMESSAGE
, 0)) == 1)
1916 PeekMessageW(&msg
, NULL
, 0, 0, PM_NOREMOVE
);
1918 if (dwTimeout
!= INFINITE
)
1920 if ((int)(dwTimeout
= dwEndTicks
- GetTickCount()) <= 0)
1921 return WAIT_TIMEOUT
;
1928 /*************************************************************************
1931 * Determine if a shell folder can be expanded.
1934 * lpFolder [I] Parent folder containing the object to test.
1935 * pidl [I] Id of the object to test.
1938 * Success: S_OK, if the object is expandable, S_FALSE otherwise.
1939 * Failure: E_INVALIDARG, if any argument is invalid.
1942 * If the object to be tested does not expose the IQueryInfo() interface it
1943 * will not be identified as an expandable folder.
1945 HRESULT WINAPI
SHIsExpandableFolder(LPSHELLFOLDER lpFolder
, LPCITEMIDLIST pidl
)
1947 HRESULT hRet
= E_INVALIDARG
;
1950 if (lpFolder
&& pidl
)
1952 hRet
= IShellFolder_GetUIObjectOf(lpFolder
, NULL
, 1, &pidl
, &IID_IQueryInfo
,
1953 NULL
, (void**)&lpInfo
);
1955 hRet
= S_FALSE
; /* Doesn't expose IQueryInfo */
1960 /* MSDN states of IQueryInfo_GetInfoFlags() that "This method is not
1961 * currently used". Really? You wouldn't be holding out on me would you?
1963 hRet
= IQueryInfo_GetInfoFlags(lpInfo
, &dwFlags
);
1965 if (SUCCEEDED(hRet
))
1967 /* 0x2 is an undocumented flag apparently indicating expandability */
1968 hRet
= dwFlags
& 0x2 ? S_OK
: S_FALSE
;
1971 IQueryInfo_Release(lpInfo
);
1977 /*************************************************************************
1980 * Blank out a region of text by drawing the background only.
1983 * hDC [I] Device context to draw in
1984 * pRect [I] Area to draw in
1985 * cRef [I] Color to draw in
1990 DWORD WINAPI
SHFillRectClr(HDC hDC
, LPCRECT pRect
, COLORREF cRef
)
1992 COLORREF cOldColor
= SetBkColor(hDC
, cRef
);
1993 ExtTextOutA(hDC
, 0, 0, ETO_OPAQUE
, pRect
, 0, 0, 0);
1994 SetBkColor(hDC
, cOldColor
);
1998 /*************************************************************************
2001 * Return the value asociated with a key in a map.
2004 * lpKeys [I] A list of keys of length iLen
2005 * lpValues [I] A list of values associated with lpKeys, of length iLen
2006 * iLen [I] Length of both lpKeys and lpValues
2007 * iKey [I] The key value to look up in lpKeys
2010 * The value in lpValues associated with iKey, or -1 if iKey is not
2014 * - If two elements in the map share the same key, this function returns
2015 * the value closest to the start of the map
2016 * - The native version of this function crashes if lpKeys or lpValues is NULL.
2018 int WINAPI
SHSearchMapInt(const int *lpKeys
, const int *lpValues
, int iLen
, int iKey
)
2020 if (lpKeys
&& lpValues
)
2026 if (lpKeys
[i
] == iKey
)
2027 return lpValues
[i
]; /* Found */
2031 return -1; /* Not found */
2035 /*************************************************************************
2038 * Copy an interface pointer
2041 * lppDest [O] Destination for copy
2042 * lpUnknown [I] Source for copy
2047 VOID WINAPI
IUnknown_Set(IUnknown
**lppDest
, IUnknown
*lpUnknown
)
2049 TRACE("(%p,%p)\n", lppDest
, lpUnknown
);
2052 IUnknown_AtomicRelease(lppDest
); /* Release existing interface */
2057 IUnknown_AddRef(lpUnknown
);
2058 *lppDest
= lpUnknown
;
2062 /*************************************************************************
2066 HRESULT WINAPI
MayQSForward(IUnknown
* lpUnknown
, PVOID lpReserved
,
2067 REFGUID riidCmdGrp
, ULONG cCmds
,
2068 OLECMD
*prgCmds
, OLECMDTEXT
* pCmdText
)
2070 FIXME("(%p,%p,%p,%d,%p,%p) - stub\n",
2071 lpUnknown
, lpReserved
, riidCmdGrp
, cCmds
, prgCmds
, pCmdText
);
2073 /* FIXME: Calls IsQSForward & IUnknown_QueryStatus */
2074 return DRAGDROP_E_NOTREGISTERED
;
2077 /*************************************************************************
2081 HRESULT WINAPI
MayExecForward(IUnknown
* lpUnknown
, INT iUnk
, REFGUID pguidCmdGroup
,
2082 DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
* pvaIn
,
2085 FIXME("(%p,%d,%p,%d,%d,%p,%p) - stub!\n", lpUnknown
, iUnk
, pguidCmdGroup
,
2086 nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2087 return DRAGDROP_E_NOTREGISTERED
;
2090 /*************************************************************************
2094 HRESULT WINAPI
IsQSForward(REFGUID pguidCmdGroup
,ULONG cCmds
, OLECMD
*prgCmds
)
2096 FIXME("(%p,%d,%p) - stub!\n", pguidCmdGroup
, cCmds
, prgCmds
);
2097 return DRAGDROP_E_NOTREGISTERED
;
2100 /*************************************************************************
2103 * Determine if a window is not a child of another window.
2106 * hParent [I] Suspected parent window
2107 * hChild [I] Suspected child window
2110 * TRUE: If hChild is a child window of hParent
2111 * FALSE: If hChild is not a child window of hParent, or they are equal
2113 BOOL WINAPI
SHIsChildOrSelf(HWND hParent
, HWND hChild
)
2115 TRACE("(%p,%p)\n", hParent
, hChild
);
2117 if (!hParent
|| !hChild
)
2119 else if(hParent
== hChild
)
2121 return !IsChild(hParent
, hChild
);
2124 /*************************************************************************
2125 * FDSA functions. Manage a dynamic array of fixed size memory blocks.
2130 DWORD num_items
; /* Number of elements inserted */
2131 void *mem
; /* Ptr to array */
2132 DWORD blocks_alloced
; /* Number of elements allocated */
2133 BYTE inc
; /* Number of elements to grow by when we need to expand */
2134 BYTE block_size
; /* Size in bytes of an element */
2135 BYTE flags
; /* Flags */
2138 #define FDSA_FLAG_INTERNAL_ALLOC 0x01 /* When set we have allocated mem internally */
2140 /*************************************************************************
2143 * Initialize an FDSA arrary.
2145 BOOL WINAPI
FDSA_Initialize(DWORD block_size
, DWORD inc
, FDSA_info
*info
, void *mem
,
2148 TRACE("(0x%08x 0x%08x %p %p 0x%08x)\n", block_size
, inc
, info
, mem
, init_blocks
);
2154 memset(mem
, 0, block_size
* init_blocks
);
2156 info
->num_items
= 0;
2159 info
->blocks_alloced
= init_blocks
;
2160 info
->block_size
= block_size
;
2166 /*************************************************************************
2169 * Destroy an FDSA array
2171 BOOL WINAPI
FDSA_Destroy(FDSA_info
*info
)
2173 TRACE("(%p)\n", info
);
2175 if(info
->flags
& FDSA_FLAG_INTERNAL_ALLOC
)
2177 HeapFree(GetProcessHeap(), 0, info
->mem
);
2184 /*************************************************************************
2187 * Insert element into an FDSA array
2189 DWORD WINAPI
FDSA_InsertItem(FDSA_info
*info
, DWORD where
, const void *block
)
2191 TRACE("(%p 0x%08x %p)\n", info
, where
, block
);
2192 if(where
> info
->num_items
)
2193 where
= info
->num_items
;
2195 if(info
->num_items
>= info
->blocks_alloced
)
2197 DWORD size
= (info
->blocks_alloced
+ info
->inc
) * info
->block_size
;
2198 if(info
->flags
& 0x1)
2199 info
->mem
= HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, info
->mem
, size
);
2202 void *old_mem
= info
->mem
;
2203 info
->mem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
2204 memcpy(info
->mem
, old_mem
, info
->blocks_alloced
* info
->block_size
);
2206 info
->blocks_alloced
+= info
->inc
;
2210 if(where
< info
->num_items
)
2212 memmove((char*)info
->mem
+ (where
+ 1) * info
->block_size
,
2213 (char*)info
->mem
+ where
* info
->block_size
,
2214 (info
->num_items
- where
) * info
->block_size
);
2216 memcpy((char*)info
->mem
+ where
* info
->block_size
, block
, info
->block_size
);
2222 /*************************************************************************
2225 * Delete an element from an FDSA array.
2227 BOOL WINAPI
FDSA_DeleteItem(FDSA_info
*info
, DWORD where
)
2229 TRACE("(%p 0x%08x)\n", info
, where
);
2231 if(where
>= info
->num_items
)
2234 if(where
< info
->num_items
- 1)
2236 memmove((char*)info
->mem
+ where
* info
->block_size
,
2237 (char*)info
->mem
+ (where
+ 1) * info
->block_size
,
2238 (info
->num_items
- where
- 1) * info
->block_size
);
2240 memset((char*)info
->mem
+ (info
->num_items
- 1) * info
->block_size
,
2241 0, info
->block_size
);
2252 /*************************************************************************
2255 * Call IUnknown_QueryInterface() on a table of objects.
2259 * Failure: E_POINTER or E_NOINTERFACE.
2261 HRESULT WINAPI
QISearch(
2262 LPVOID w
, /* [in] Table of interfaces */
2263 IFACE_INDEX_TBL
*x
, /* [in] Array of REFIIDs and indexes into the table */
2264 REFIID riid
, /* [in] REFIID to get interface for */
2265 LPVOID
*ppv
) /* [out] Destination for interface pointer */
2269 IFACE_INDEX_TBL
*xmove
;
2271 TRACE("(%p %p %s %p)\n", w
,x
,debugstr_guid(riid
),ppv
);
2274 while (xmove
->refid
) {
2275 TRACE("trying (indx %d) %s\n", xmove
->indx
, debugstr_guid(xmove
->refid
));
2276 if (IsEqualIID(riid
, xmove
->refid
)) {
2277 a_vtbl
= (IUnknown
*)(xmove
->indx
+ (LPBYTE
)w
);
2278 TRACE("matched, returning (%p)\n", a_vtbl
);
2279 *ppv
= (LPVOID
)a_vtbl
;
2280 IUnknown_AddRef(a_vtbl
);
2286 if (IsEqualIID(riid
, &IID_IUnknown
)) {
2287 a_vtbl
= (IUnknown
*)(x
->indx
+ (LPBYTE
)w
);
2288 TRACE("returning first for IUnknown (%p)\n", a_vtbl
);
2289 *ppv
= (LPVOID
)a_vtbl
;
2290 IUnknown_AddRef(a_vtbl
);
2294 ret
= E_NOINTERFACE
;
2298 TRACE("-- 0x%08x\n", ret
);
2302 /*************************************************************************
2305 * Remove the "PropDlgFont" property from a window.
2308 * hWnd [I] Window to remove the property from
2311 * A handle to the removed property, or NULL if it did not exist.
2313 HANDLE WINAPI
SHRemoveDefaultDialogFont(HWND hWnd
)
2317 TRACE("(%p)\n", hWnd
);
2319 hProp
= GetPropA(hWnd
, "PropDlgFont");
2323 DeleteObject(hProp
);
2324 hProp
= RemovePropA(hWnd
, "PropDlgFont");
2329 /*************************************************************************
2332 * Load the in-process server of a given GUID.
2335 * refiid [I] GUID of the server to load.
2338 * Success: A handle to the loaded server dll.
2339 * Failure: A NULL handle.
2341 HMODULE WINAPI
SHPinDllOfCLSID(REFIID refiid
)
2345 CHAR value
[MAX_PATH
], string
[MAX_PATH
];
2347 strcpy(string
, "CLSID\\");
2348 SHStringFromGUIDA(refiid
, string
+ 6, sizeof(string
)/sizeof(char) - 6);
2349 strcat(string
, "\\InProcServer32");
2352 RegOpenKeyExA(HKEY_CLASSES_ROOT
, string
, 0, 1, &newkey
);
2353 RegQueryValueExA(newkey
, 0, 0, &type
, (PBYTE
)value
, &count
);
2354 RegCloseKey(newkey
);
2355 return LoadLibraryExA(value
, 0, 0);
2358 /*************************************************************************
2361 * Unicode version of SHLWAPI_183.
2363 DWORD WINAPI
SHRegisterClassW(WNDCLASSW
* lpWndClass
)
2367 TRACE("(%p %s)\n",lpWndClass
->hInstance
, debugstr_w(lpWndClass
->lpszClassName
));
2369 if (GetClassInfoW(lpWndClass
->hInstance
, lpWndClass
->lpszClassName
, &WndClass
))
2371 return RegisterClassW(lpWndClass
);
2374 /*************************************************************************
2377 * Unregister a list of classes.
2380 * hInst [I] Application instance that registered the classes
2381 * lppClasses [I] List of class names
2382 * iCount [I] Number of names in lppClasses
2387 void WINAPI
SHUnregisterClassesA(HINSTANCE hInst
, LPCSTR
*lppClasses
, INT iCount
)
2391 TRACE("(%p,%p,%d)\n", hInst
, lppClasses
, iCount
);
2395 if (GetClassInfoA(hInst
, *lppClasses
, &WndClass
))
2396 UnregisterClassA(*lppClasses
, hInst
);
2402 /*************************************************************************
2405 * Unicode version of SHUnregisterClassesA.
2407 void WINAPI
SHUnregisterClassesW(HINSTANCE hInst
, LPCWSTR
*lppClasses
, INT iCount
)
2411 TRACE("(%p,%p,%d)\n", hInst
, lppClasses
, iCount
);
2415 if (GetClassInfoW(hInst
, *lppClasses
, &WndClass
))
2416 UnregisterClassW(*lppClasses
, hInst
);
2422 /*************************************************************************
2425 * Call The correct (Ascii/Unicode) default window procedure for a window.
2428 * hWnd [I] Window to call the default procedure for
2429 * uMessage [I] Message ID
2430 * wParam [I] WPARAM of message
2431 * lParam [I] LPARAM of message
2434 * The result of calling DefWindowProcA() or DefWindowProcW().
2436 LRESULT CALLBACK
SHDefWindowProc(HWND hWnd
, UINT uMessage
, WPARAM wParam
, LPARAM lParam
)
2438 if (IsWindowUnicode(hWnd
))
2439 return DefWindowProcW(hWnd
, uMessage
, wParam
, lParam
);
2440 return DefWindowProcA(hWnd
, uMessage
, wParam
, lParam
);
2443 /*************************************************************************
2446 HRESULT WINAPI
IUnknown_GetSite(LPUNKNOWN lpUnknown
, REFIID iid
, PVOID
*lppSite
)
2448 HRESULT hRet
= E_INVALIDARG
;
2449 LPOBJECTWITHSITE lpSite
= NULL
;
2451 TRACE("(%p,%s,%p)\n", lpUnknown
, debugstr_guid(iid
), lppSite
);
2453 if (lpUnknown
&& iid
&& lppSite
)
2455 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IObjectWithSite
,
2457 if (SUCCEEDED(hRet
) && lpSite
)
2459 hRet
= IObjectWithSite_GetSite(lpSite
, iid
, lppSite
);
2460 IObjectWithSite_Release(lpSite
);
2466 /*************************************************************************
2469 * Create a worker window using CreateWindowExA().
2472 * wndProc [I] Window procedure
2473 * hWndParent [I] Parent window
2474 * dwExStyle [I] Extra style flags
2475 * dwStyle [I] Style flags
2476 * hMenu [I] Window menu
2480 * Success: The window handle of the newly created window.
2483 HWND WINAPI
SHCreateWorkerWindowA(LONG wndProc
, HWND hWndParent
, DWORD dwExStyle
,
2484 DWORD dwStyle
, HMENU hMenu
, LONG z
)
2486 static const char szClass
[] = "WorkerA";
2490 TRACE("(0x%08x,%p,0x%08x,0x%08x,%p,0x%08x)\n",
2491 wndProc
, hWndParent
, dwExStyle
, dwStyle
, hMenu
, z
);
2493 /* Create Window class */
2495 wc
.lpfnWndProc
= DefWindowProcA
;
2498 wc
.hInstance
= shlwapi_hInstance
;
2500 wc
.hCursor
= LoadCursorA(NULL
, (LPSTR
)IDC_ARROW
);
2501 wc
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
2502 wc
.lpszMenuName
= NULL
;
2503 wc
.lpszClassName
= szClass
;
2505 SHRegisterClassA(&wc
); /* Register class */
2507 /* FIXME: Set extra bits in dwExStyle */
2509 hWnd
= CreateWindowExA(dwExStyle
, szClass
, 0, dwStyle
, 0, 0, 0, 0,
2510 hWndParent
, hMenu
, shlwapi_hInstance
, 0);
2513 SetWindowLongPtrW(hWnd
, DWLP_MSGRESULT
, z
);
2516 SetWindowLongPtrA(hWnd
, GWLP_WNDPROC
, wndProc
);
2521 typedef struct tagPOLICYDATA
2523 DWORD policy
; /* flags value passed to SHRestricted */
2524 LPCWSTR appstr
; /* application str such as "Explorer" */
2525 LPCWSTR keystr
; /* name of the actual registry key / policy */
2526 } POLICYDATA
, *LPPOLICYDATA
;
2528 #define SHELL_NO_POLICY 0xffffffff
2530 /* default shell policy registry key */
2531 static const WCHAR strRegistryPolicyW
[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o',
2532 's','o','f','t','\\','W','i','n','d','o','w','s','\\',
2533 'C','u','r','r','e','n','t','V','e','r','s','i','o','n',
2534 '\\','P','o','l','i','c','i','e','s',0};
2536 /*************************************************************************
2539 * Retrieve a policy value from the registry.
2542 * lpSubKey [I] registry key name
2543 * lpSubName [I] subname of registry key
2544 * lpValue [I] value name of registry value
2547 * the value associated with the registry key or 0 if not found
2549 DWORD WINAPI
SHGetRestriction(LPCWSTR lpSubKey
, LPCWSTR lpSubName
, LPCWSTR lpValue
)
2551 DWORD retval
, datsize
= sizeof(retval
);
2555 lpSubKey
= strRegistryPolicyW
;
2557 retval
= RegOpenKeyW(HKEY_LOCAL_MACHINE
, lpSubKey
, &hKey
);
2558 if (retval
!= ERROR_SUCCESS
)
2559 retval
= RegOpenKeyW(HKEY_CURRENT_USER
, lpSubKey
, &hKey
);
2560 if (retval
!= ERROR_SUCCESS
)
2563 SHGetValueW(hKey
, lpSubName
, lpValue
, NULL
, (LPBYTE
)&retval
, &datsize
);
2568 /*************************************************************************
2571 * Helper function to retrieve the possibly cached value for a specific policy
2574 * policy [I] The policy to look for
2575 * initial [I] Main registry key to open, if NULL use default
2576 * polTable [I] Table of known policies, 0 terminated
2577 * polArr [I] Cache array of policy values
2580 * The retrieved policy value or 0 if not successful
2583 * This function is used by the native SHRestricted function to search for the
2584 * policy and cache it once retrieved. The current Wine implementation uses a
2585 * different POLICYDATA structure and implements a similar algorithme adapted to
2588 DWORD WINAPI
SHRestrictionLookup(
2591 LPPOLICYDATA polTable
,
2594 TRACE("(0x%08x %s %p %p)\n", policy
, debugstr_w(initial
), polTable
, polArr
);
2596 if (!polTable
|| !polArr
)
2599 for (;polTable
->policy
; polTable
++, polArr
++)
2601 if (policy
== polTable
->policy
)
2603 /* we have a known policy */
2605 /* check if this policy has been cached */
2606 if (*polArr
== SHELL_NO_POLICY
)
2607 *polArr
= SHGetRestriction(initial
, polTable
->appstr
, polTable
->keystr
);
2611 /* we don't know this policy, return 0 */
2612 TRACE("unknown policy: (%08x)\n", policy
);
2616 /*************************************************************************
2619 * Get an interface from an object.
2622 * Success: S_OK. ppv contains the requested interface.
2623 * Failure: An HRESULT error code.
2626 * This QueryInterface asks the inner object for an interface. In case
2627 * of aggregation this request would be forwarded by the inner to the
2628 * outer object. This function asks the inner object directly for the
2629 * interface circumventing the forwarding to the outer object.
2631 HRESULT WINAPI
SHWeakQueryInterface(
2632 IUnknown
* pUnk
, /* [in] Outer object */
2633 IUnknown
* pInner
, /* [in] Inner object */
2634 IID
* riid
, /* [in] Interface GUID to query for */
2635 LPVOID
* ppv
) /* [out] Destination for queried interface */
2637 HRESULT hret
= E_NOINTERFACE
;
2638 TRACE("(pUnk=%p pInner=%p\n\tIID: %s %p)\n",pUnk
,pInner
,debugstr_guid(riid
), ppv
);
2641 if(pUnk
&& pInner
) {
2642 hret
= IUnknown_QueryInterface(pInner
, riid
, (LPVOID
*)ppv
);
2643 if (SUCCEEDED(hret
)) IUnknown_Release(pUnk
);
2645 TRACE("-- 0x%08x\n", hret
);
2649 /*************************************************************************
2652 * Move a reference from one interface to another.
2655 * lpDest [O] Destination to receive the reference
2656 * lppUnknown [O] Source to give up the reference to lpDest
2661 VOID WINAPI
SHWeakReleaseInterface(IUnknown
*lpDest
, IUnknown
**lppUnknown
)
2663 TRACE("(%p,%p)\n", lpDest
, lppUnknown
);
2668 IUnknown_AddRef(lpDest
);
2669 IUnknown_AtomicRelease(lppUnknown
); /* Release existing interface */
2673 /*************************************************************************
2676 * Convert an ASCII string of a CLSID into a CLSID.
2679 * idstr [I] String representing a CLSID in registry format
2680 * id [O] Destination for the converted CLSID
2683 * Success: TRUE. id contains the converted CLSID.
2686 BOOL WINAPI
GUIDFromStringA(LPCSTR idstr
, CLSID
*id
)
2689 MultiByteToWideChar(CP_ACP
, 0, idstr
, -1, wClsid
, sizeof(wClsid
)/sizeof(WCHAR
));
2690 return SUCCEEDED(CLSIDFromString(wClsid
, id
));
2693 /*************************************************************************
2696 * Unicode version of GUIDFromStringA.
2698 BOOL WINAPI
GUIDFromStringW(LPCWSTR idstr
, CLSID
*id
)
2700 return SUCCEEDED(CLSIDFromString((LPOLESTR
)idstr
, id
));
2703 /*************************************************************************
2706 * Determine if the browser is integrated into the shell, and set a registry
2713 * 1, If the browser is not integrated.
2714 * 2, If the browser is integrated.
2717 * The key "HKLM\Software\Microsoft\Internet Explorer\IntegratedBrowser" is
2718 * either set to TRUE, or removed depending on whether the browser is deemed
2721 DWORD WINAPI
WhichPlatform(void)
2723 static const char szIntegratedBrowser
[] = "IntegratedBrowser";
2724 static DWORD dwState
= 0;
2726 DWORD dwRet
, dwData
, dwSize
;
2732 /* If shell32 exports DllGetVersion(), the browser is integrated */
2734 hshell32
= LoadLibraryA("shell32.dll");
2737 FARPROC pDllGetVersion
;
2738 pDllGetVersion
= GetProcAddress(hshell32
, "DllGetVersion");
2739 dwState
= pDllGetVersion
? 2 : 1;
2740 FreeLibrary(hshell32
);
2743 /* Set or delete the key accordingly */
2744 dwRet
= RegOpenKeyExA(HKEY_LOCAL_MACHINE
,
2745 "Software\\Microsoft\\Internet Explorer", 0,
2746 KEY_ALL_ACCESS
, &hKey
);
2749 dwRet
= RegQueryValueExA(hKey
, szIntegratedBrowser
, 0, 0,
2750 (LPBYTE
)&dwData
, &dwSize
);
2752 if (!dwRet
&& dwState
== 1)
2754 /* Value exists but browser is not integrated */
2755 RegDeleteValueA(hKey
, szIntegratedBrowser
);
2757 else if (dwRet
&& dwState
== 2)
2759 /* Browser is integrated but value does not exist */
2761 RegSetValueExA(hKey
, szIntegratedBrowser
, 0, REG_DWORD
,
2762 (LPBYTE
)&dwData
, sizeof(dwData
));
2769 /*************************************************************************
2772 * Unicode version of SHCreateWorkerWindowA.
2774 HWND WINAPI
SHCreateWorkerWindowW(LONG wndProc
, HWND hWndParent
, DWORD dwExStyle
,
2775 DWORD dwStyle
, HMENU hMenu
, LONG z
)
2777 static const WCHAR szClass
[] = { 'W', 'o', 'r', 'k', 'e', 'r', 'W', '\0' };
2781 TRACE("(0x%08x,%p,0x%08x,0x%08x,%p,0x%08x)\n",
2782 wndProc
, hWndParent
, dwExStyle
, dwStyle
, hMenu
, z
);
2784 /* If our OS is natively ASCII, use the ASCII version */
2785 if (!(GetVersion() & 0x80000000)) /* NT */
2786 return SHCreateWorkerWindowA(wndProc
, hWndParent
, dwExStyle
, dwStyle
, hMenu
, z
);
2788 /* Create Window class */
2790 wc
.lpfnWndProc
= DefWindowProcW
;
2793 wc
.hInstance
= shlwapi_hInstance
;
2795 wc
.hCursor
= LoadCursorW(NULL
, (LPWSTR
)IDC_ARROW
);
2796 wc
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
2797 wc
.lpszMenuName
= NULL
;
2798 wc
.lpszClassName
= szClass
;
2800 SHRegisterClassW(&wc
); /* Register class */
2802 /* FIXME: Set extra bits in dwExStyle */
2804 hWnd
= CreateWindowExW(dwExStyle
, szClass
, 0, dwStyle
, 0, 0, 0, 0,
2805 hWndParent
, hMenu
, shlwapi_hInstance
, 0);
2808 SetWindowLongPtrW(hWnd
, DWLP_MSGRESULT
, z
);
2811 SetWindowLongPtrW(hWnd
, GWLP_WNDPROC
, wndProc
);
2816 /*************************************************************************
2819 * Get and show a context menu from a shell folder.
2822 * hWnd [I] Window displaying the shell folder
2823 * lpFolder [I] IShellFolder interface
2824 * lpApidl [I] Id for the particular folder desired
2828 * Failure: An HRESULT error code indicating the error.
2830 HRESULT WINAPI
SHInvokeDefaultCommand(HWND hWnd
, IShellFolder
* lpFolder
, LPCITEMIDLIST lpApidl
)
2832 return SHInvokeCommand(hWnd
, lpFolder
, lpApidl
, FALSE
);
2835 /*************************************************************************
2838 * _SHPackDispParamsV
2840 HRESULT WINAPI
SHPackDispParamsV(LPVOID w
, LPVOID x
, LPVOID y
, LPVOID z
)
2842 FIXME("%p %p %p %p\n",w
,x
,y
,z
);
2846 /*************************************************************************
2849 * This function seems to be a forward to SHPackDispParamsV (whatever THAT
2850 * function does...).
2852 HRESULT WINAPI
SHPackDispParams(LPVOID w
, LPVOID x
, LPVOID y
, LPVOID z
)
2854 FIXME("%p %p %p %p\n", w
, x
, y
, z
);
2858 /*************************************************************************
2859 * SHLWAPI_InvokeByIID
2861 * This helper function calls IDispatch::Invoke for each sink
2862 * which implements given iid or IDispatch.
2865 static HRESULT
SHLWAPI_InvokeByIID(
2866 IConnectionPoint
* iCP
,
2869 DISPPARAMS
* dispParams
)
2871 IEnumConnections
*enumerator
;
2874 HRESULT result
= IConnectionPoint_EnumConnections(iCP
, &enumerator
);
2878 while(IEnumConnections_Next(enumerator
, 1, &rgcd
, NULL
)==S_OK
)
2880 IDispatch
*dispIface
;
2881 if (SUCCEEDED(IUnknown_QueryInterface(rgcd
.pUnk
, iid
, (LPVOID
*)&dispIface
)) ||
2882 SUCCEEDED(IUnknown_QueryInterface(rgcd
.pUnk
, &IID_IDispatch
, (LPVOID
*)&dispIface
)))
2884 IDispatch_Invoke(dispIface
, dispId
, &IID_NULL
, 0, DISPATCH_METHOD
, dispParams
, NULL
, NULL
, NULL
);
2885 IDispatch_Release(dispIface
);
2889 IEnumConnections_Release(enumerator
);
2894 /*************************************************************************
2897 * IConnectionPoint_SimpleInvoke
2899 HRESULT WINAPI
IConnectionPoint_SimpleInvoke(
2900 IConnectionPoint
* iCP
,
2902 DISPPARAMS
* dispParams
)
2907 TRACE("(%p)->(0x%x %p)\n",iCP
,dispId
,dispParams
);
2909 result
= IConnectionPoint_GetConnectionInterface(iCP
, &iid
);
2910 if (SUCCEEDED(result
))
2911 result
= SHLWAPI_InvokeByIID(iCP
, &iid
, dispId
, dispParams
);
2916 /*************************************************************************
2919 * Notify an IConnectionPoint object of changes.
2922 * lpCP [I] Object to notify
2927 * Failure: E_NOINTERFACE, if lpCP is NULL or does not support the
2928 * IConnectionPoint interface.
2930 HRESULT WINAPI
IConnectionPoint_OnChanged(IConnectionPoint
* lpCP
, DISPID dispID
)
2932 IEnumConnections
*lpEnum
;
2933 HRESULT hRet
= E_NOINTERFACE
;
2935 TRACE("(%p,0x%8X)\n", lpCP
, dispID
);
2937 /* Get an enumerator for the connections */
2939 hRet
= IConnectionPoint_EnumConnections(lpCP
, &lpEnum
);
2941 if (SUCCEEDED(hRet
))
2943 IPropertyNotifySink
*lpSink
;
2944 CONNECTDATA connData
;
2947 /* Call OnChanged() for every notify sink in the connection point */
2948 while (IEnumConnections_Next(lpEnum
, 1, &connData
, &ulFetched
) == S_OK
)
2950 if (SUCCEEDED(IUnknown_QueryInterface(connData
.pUnk
, &IID_IPropertyNotifySink
, (void**)&lpSink
)) &&
2953 IPropertyNotifySink_OnChanged(lpSink
, dispID
);
2954 IPropertyNotifySink_Release(lpSink
);
2956 IUnknown_Release(connData
.pUnk
);
2959 IEnumConnections_Release(lpEnum
);
2964 /*************************************************************************
2967 * IUnknown_CPContainerInvokeParam
2969 HRESULT WINAPIV
IUnknown_CPContainerInvokeParam(
2970 IUnknown
*container
,
2977 IConnectionPoint
*iCP
;
2978 IConnectionPointContainer
*iCPC
;
2981 return E_NOINTERFACE
;
2983 result
= IUnknown_QueryInterface(container
, &IID_IConnectionPointContainer
,(LPVOID
*) &iCPC
);
2984 if (SUCCEEDED(result
))
2986 result
= IConnectionPointContainer_FindConnectionPoint(iCPC
, riid
, &iCP
);
2987 IConnectionPointContainer_Release(iCPC
);
2990 if (SUCCEEDED(result
))
2993 VARIANTARG
*curvar
= buffer
+cParams
-1;
2994 DISPPARAMS dispParams
= {buffer
, NULL
, cParams
, 0};
2997 va_start(valist
, cParams
);
2998 for(cnt
=cParams
;cnt
>0;cnt
--,curvar
--) /* backwards for some reason */
3000 enum VARENUM vt
= va_arg(valist
, enum VARENUM
);
3001 memset(curvar
, 0, sizeof(*curvar
));
3005 V_BYREF(curvar
) = va_arg(valist
, LPVOID
);
3011 V_BSTR(curvar
) = va_arg(valist
, BSTR
);
3015 V_DISPATCH(curvar
) = va_arg(valist
, IDispatch
*);
3019 V_BOOL(curvar
) = va_arg(valist
, int);
3023 V_UNKNOWN(curvar
) = va_arg(valist
, IUnknown
*);
3027 V_VT(curvar
) = VT_I4
;
3028 V_I4(curvar
) = va_arg(valist
, LONG
);
3034 result
= SHLWAPI_InvokeByIID(iCP
, riid
, dispId
, &dispParams
);
3035 IConnectionPoint_Release(iCP
);
3041 /*************************************************************************
3044 * Notify an IConnectionPointContainer object of changes.
3047 * lpUnknown [I] Object to notify
3052 * Failure: E_NOINTERFACE, if lpUnknown is NULL or does not support the
3053 * IConnectionPointContainer interface.
3055 HRESULT WINAPI
IUnknown_CPContainerOnChanged(IUnknown
*lpUnknown
, DISPID dispID
)
3057 IConnectionPointContainer
* lpCPC
= NULL
;
3058 HRESULT hRet
= E_NOINTERFACE
;
3060 TRACE("(%p,0x%8X)\n", lpUnknown
, dispID
);
3063 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IConnectionPointContainer
, (void**)&lpCPC
);
3065 if (SUCCEEDED(hRet
))
3067 IConnectionPoint
* lpCP
;
3069 hRet
= IConnectionPointContainer_FindConnectionPoint(lpCPC
, &IID_IPropertyNotifySink
, &lpCP
);
3070 IConnectionPointContainer_Release(lpCPC
);
3072 hRet
= IConnectionPoint_OnChanged(lpCP
, dispID
);
3073 IConnectionPoint_Release(lpCP
);
3078 /*************************************************************************
3083 BOOL WINAPI
PlaySoundWrapW(LPCWSTR pszSound
, HMODULE hmod
, DWORD fdwSound
)
3085 return PlaySoundW(pszSound
, hmod
, fdwSound
);
3088 /*************************************************************************
3091 BOOL WINAPI
SHGetIniStringW(LPSTR str1
, LPSTR str2
, LPSTR pStr
, DWORD some_len
, LPCSTR lpStr2
)
3094 * str1: "I" "I" pushl esp+0x20
3095 * str2: "U" "I" pushl 0x77c93810
3096 * (is "I" and "U" "integer" and "unsigned" ??)
3098 * pStr: "" "" pushl eax
3099 * some_len: 0x824 0x104 pushl 0x824
3100 * lpStr2: "%l" "%l" pushl esp+0xc
3102 * shlwapi. StrCpyNW(lpStr2, irrelevant_var, 0x104);
3103 * LocalAlloc(0x00, some_len) -> irrelevant_var
3104 * LocalAlloc(0x40, irrelevant_len) -> pStr
3105 * shlwapi.294(str1, str2, pStr, some_len, lpStr2);
3106 * shlwapi.PathRemoveBlanksW(pStr);
3108 FIXME("('%s', '%s', '%s', %08x, '%s'): stub!\n", str1
, str2
, pStr
, some_len
, lpStr2
);
3112 /*************************************************************************
3115 * Called by ICQ2000b install via SHDOCVW:
3116 * str1: "InternetShortcut"
3117 * x: some unknown pointer
3118 * str2: "http://free.aol.com/tryaolfree/index.adp?139269"
3119 * str3: "C:\\WINDOWS\\Desktop.new2\\Free AOL & Unlimited Internet.url"
3121 * In short: this one maybe creates a desktop link :-)
3123 BOOL WINAPI
SHSetIniStringW(LPWSTR str1
, LPVOID x
, LPWSTR str2
, LPWSTR str3
)
3125 FIXME("(%s, %p, %s, %s), stub.\n", debugstr_w(str1
), x
, debugstr_w(str2
), debugstr_w(str3
));
3129 /*************************************************************************
3132 * See SHGetFileInfoW.
3134 DWORD WINAPI
SHGetFileInfoWrapW(LPCWSTR path
, DWORD dwFileAttributes
,
3135 SHFILEINFOW
*psfi
, UINT sizeofpsfi
, UINT flags
)
3137 return SHGetFileInfoW(path
, dwFileAttributes
, psfi
, sizeofpsfi
, flags
);
3140 /*************************************************************************
3143 * See DragQueryFileW.
3145 UINT WINAPI
DragQueryFileWrapW(HDROP hDrop
, UINT lFile
, LPWSTR lpszFile
, UINT lLength
)
3147 return DragQueryFileW(hDrop
, lFile
, lpszFile
, lLength
);
3150 /*************************************************************************
3153 * See SHBrowseForFolderW.
3155 LPITEMIDLIST WINAPI
SHBrowseForFolderWrapW(LPBROWSEINFOW lpBi
)
3157 return SHBrowseForFolderW(lpBi
);
3160 /*************************************************************************
3163 * See SHGetPathFromIDListW.
3165 BOOL WINAPI
SHGetPathFromIDListWrapW(LPCITEMIDLIST pidl
,LPWSTR pszPath
)
3167 return SHGetPathFromIDListW(pidl
, pszPath
);
3170 /*************************************************************************
3173 * See ShellExecuteExW.
3175 BOOL WINAPI
ShellExecuteExWrapW(LPSHELLEXECUTEINFOW lpExecInfo
)
3177 return ShellExecuteExW(lpExecInfo
);
3180 /*************************************************************************
3183 * See SHFileOperationW.
3185 INT WINAPI
SHFileOperationWrapW(LPSHFILEOPSTRUCTW lpFileOp
)
3187 return SHFileOperationW(lpFileOp
);
3190 /*************************************************************************
3194 PVOID WINAPI
SHInterlockedCompareExchange( PVOID
*dest
, PVOID xchg
, PVOID compare
)
3196 return InterlockedCompareExchangePointer( dest
, xchg
, compare
);
3199 /*************************************************************************
3202 * See GetFileVersionInfoSizeW.
3204 DWORD WINAPI
GetFileVersionInfoSizeWrapW( LPCWSTR filename
, LPDWORD handle
)
3206 return GetFileVersionInfoSizeW( filename
, handle
);
3209 /*************************************************************************
3212 * See GetFileVersionInfoW.
3214 BOOL WINAPI
GetFileVersionInfoWrapW( LPCWSTR filename
, DWORD handle
,
3215 DWORD datasize
, LPVOID data
)
3217 return GetFileVersionInfoW( filename
, handle
, datasize
, data
);
3220 /*************************************************************************
3223 * See VerQueryValueW.
3225 WORD WINAPI
VerQueryValueWrapW( LPVOID pBlock
, LPCWSTR lpSubBlock
,
3226 LPVOID
*lplpBuffer
, UINT
*puLen
)
3228 return VerQueryValueW( pBlock
, lpSubBlock
, lplpBuffer
, puLen
);
3231 #define IsIface(type) SUCCEEDED((hRet = IUnknown_QueryInterface(lpUnknown, &IID_##type, (void**)&lpObj)))
3232 #define IShellBrowser_EnableModeless IShellBrowser_EnableModelessSB
3233 #define EnableModeless(type) type##_EnableModeless((type*)lpObj, bModeless)
3235 /*************************************************************************
3238 * Change the modality of a shell object.
3241 * lpUnknown [I] Object to make modeless
3242 * bModeless [I] TRUE=Make modeless, FALSE=Make modal
3245 * Success: S_OK. The modality lpUnknown is changed.
3246 * Failure: An HRESULT error code indicating the error.
3249 * lpUnknown must support the IOleInPlaceFrame interface, the
3250 * IInternetSecurityMgrSite interface, the IShellBrowser interface
3251 * the IDocHostUIHandler interface, or the IOleInPlaceActiveObject interface,
3252 * or this call will fail.
3254 HRESULT WINAPI
IUnknown_EnableModeless(IUnknown
*lpUnknown
, BOOL bModeless
)
3259 TRACE("(%p,%d)\n", lpUnknown
, bModeless
);
3264 if (IsIface(IOleInPlaceActiveObject
))
3265 EnableModeless(IOleInPlaceActiveObject
);
3266 else if (IsIface(IOleInPlaceFrame
))
3267 EnableModeless(IOleInPlaceFrame
);
3268 else if (IsIface(IShellBrowser
))
3269 EnableModeless(IShellBrowser
);
3271 /* FIXME: Wine has no headers for these objects yet */
3272 else if (IsIface(IInternetSecurityMgrSite
))
3273 EnableModeless(IInternetSecurityMgrSite
);
3274 else if (IsIface(IDocHostUIHandler
))
3275 EnableModeless(IDocHostUIHandler
);
3280 IUnknown_Release(lpObj
);
3284 /*************************************************************************
3287 * See SHGetNewLinkInfoW.
3289 BOOL WINAPI
SHGetNewLinkInfoWrapW(LPCWSTR pszLinkTo
, LPCWSTR pszDir
, LPWSTR pszName
,
3290 BOOL
*pfMustCopy
, UINT uFlags
)
3292 return SHGetNewLinkInfoW(pszLinkTo
, pszDir
, pszName
, pfMustCopy
, uFlags
);
3295 /*************************************************************************
3298 * See SHDefExtractIconW.
3300 UINT WINAPI
SHDefExtractIconWrapW(LPCWSTR pszIconFile
, int iIndex
, UINT uFlags
, HICON
* phiconLarge
,
3301 HICON
* phiconSmall
, UINT nIconSize
)
3303 return SHDefExtractIconW(pszIconFile
, iIndex
, uFlags
, phiconLarge
, phiconSmall
, nIconSize
);
3306 /*************************************************************************
3309 * Get and show a context menu from a shell folder.
3312 * hWnd [I] Window displaying the shell folder
3313 * lpFolder [I] IShellFolder interface
3314 * lpApidl [I] Id for the particular folder desired
3315 * bInvokeDefault [I] Whether to invoke the default menu item
3318 * Success: S_OK. If bInvokeDefault is TRUE, the default menu action was
3320 * Failure: An HRESULT error code indicating the error.
3322 HRESULT WINAPI
SHInvokeCommand(HWND hWnd
, IShellFolder
* lpFolder
, LPCITEMIDLIST lpApidl
, BOOL bInvokeDefault
)
3324 IContextMenu
*iContext
;
3325 HRESULT hRet
= E_FAIL
;
3327 TRACE("(%p,%p,%p,%d)\n", hWnd
, lpFolder
, lpApidl
, bInvokeDefault
);
3332 /* Get the context menu from the shell folder */
3333 hRet
= IShellFolder_GetUIObjectOf(lpFolder
, hWnd
, 1, &lpApidl
,
3334 &IID_IContextMenu
, 0, (void**)&iContext
);
3335 if (SUCCEEDED(hRet
))
3338 if ((hMenu
= CreatePopupMenu()))
3341 DWORD dwDefaultId
= 0;
3343 /* Add the context menu entries to the popup */
3344 hQuery
= IContextMenu_QueryContextMenu(iContext
, hMenu
, 0, 1, 0x7FFF,
3345 bInvokeDefault
? CMF_NORMAL
: CMF_DEFAULTONLY
);
3347 if (SUCCEEDED(hQuery
))
3349 if (bInvokeDefault
&&
3350 (dwDefaultId
= GetMenuDefaultItem(hMenu
, 0, 0)) != 0xFFFFFFFF)
3352 CMINVOKECOMMANDINFO cmIci
;
3353 /* Invoke the default item */
3354 memset(&cmIci
,0,sizeof(cmIci
));
3355 cmIci
.cbSize
= sizeof(cmIci
);
3356 cmIci
.fMask
= CMIC_MASK_ASYNCOK
;
3358 cmIci
.lpVerb
= MAKEINTRESOURCEA(dwDefaultId
);
3359 cmIci
.nShow
= SW_SCROLLCHILDREN
;
3361 hRet
= IContextMenu_InvokeCommand(iContext
, &cmIci
);
3366 IContextMenu_Release(iContext
);
3371 /*************************************************************************
3376 HICON WINAPI
ExtractIconWrapW(HINSTANCE hInstance
, LPCWSTR lpszExeFileName
,
3379 return ExtractIconW(hInstance
, lpszExeFileName
, nIconIndex
);
3382 /*************************************************************************
3385 * Load a library from the directory of a particular process.
3388 * new_mod [I] Library name
3389 * inst_hwnd [I] Module whose directory is to be used
3390 * dwCrossCodePage [I] Should be FALSE (currently ignored)
3393 * Success: A handle to the loaded module
3394 * Failure: A NULL handle.
3396 HMODULE WINAPI
MLLoadLibraryA(LPCSTR new_mod
, HMODULE inst_hwnd
, DWORD dwCrossCodePage
)
3398 /* FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for
3400 * FIXME: Native shows calls to:
3401 * SHRegGetUSValue for "Software\Microsoft\Internet Explorer\International"
3403 * RegOpenKeyExA for "HKLM\Software\Microsoft\Internet Explorer"
3404 * RegQueryValueExA for "LPKInstalled"
3406 * RegOpenKeyExA for "HKCU\Software\Microsoft\Internet Explorer\International"
3407 * RegQueryValueExA for "ResourceLocale"
3409 * RegOpenKeyExA for "HKLM\Software\Microsoft\Active Setup\Installed Components\{guid}"
3410 * RegQueryValueExA for "Locale"
3412 * and then tests the Locale ("en" for me).
3414 * after the code then a DPA_Create (first time) and DPA_InsertPtr are done.
3416 CHAR mod_path
[2*MAX_PATH
];
3420 FIXME("(%s,%p,%d) semi-stub!\n", debugstr_a(new_mod
), inst_hwnd
, dwCrossCodePage
);
3421 len
= GetModuleFileNameA(inst_hwnd
, mod_path
, sizeof(mod_path
));
3422 if (!len
|| len
>= sizeof(mod_path
)) return NULL
;
3424 ptr
= strrchr(mod_path
, '\\');
3426 strcpy(ptr
+1, new_mod
);
3427 TRACE("loading %s\n", debugstr_a(mod_path
));
3428 return LoadLibraryA(mod_path
);
3433 /*************************************************************************
3436 * Unicode version of MLLoadLibraryA.
3438 HMODULE WINAPI
MLLoadLibraryW(LPCWSTR new_mod
, HMODULE inst_hwnd
, DWORD dwCrossCodePage
)
3440 WCHAR mod_path
[2*MAX_PATH
];
3444 FIXME("(%s,%p,%d) semi-stub!\n", debugstr_w(new_mod
), inst_hwnd
, dwCrossCodePage
);
3445 len
= GetModuleFileNameW(inst_hwnd
, mod_path
, sizeof(mod_path
) / sizeof(WCHAR
));
3446 if (!len
|| len
>= sizeof(mod_path
) / sizeof(WCHAR
)) return NULL
;
3448 ptr
= strrchrW(mod_path
, '\\');
3450 strcpyW(ptr
+1, new_mod
);
3451 TRACE("loading %s\n", debugstr_w(mod_path
));
3452 return LoadLibraryW(mod_path
);
3457 /*************************************************************************
3458 * ColorAdjustLuma [SHLWAPI.@]
3460 * Adjust the luminosity of a color
3463 * cRGB [I] RGB value to convert
3464 * dwLuma [I] Luma adjustment
3465 * bUnknown [I] Unknown
3468 * The adjusted RGB color.
3470 COLORREF WINAPI
ColorAdjustLuma(COLORREF cRGB
, int dwLuma
, BOOL bUnknown
)
3472 TRACE("(0x%8x,%d,%d)\n", cRGB
, dwLuma
, bUnknown
);
3478 ColorRGBToHLS(cRGB
, &wH
, &wL
, &wS
);
3480 FIXME("Ignoring luma adjustment\n");
3482 /* FIXME: The ajdustment is not linear */
3484 cRGB
= ColorHLSToRGB(wH
, wL
, wS
);
3489 /*************************************************************************
3492 * See GetSaveFileNameW.
3494 BOOL WINAPI
GetSaveFileNameWrapW(LPOPENFILENAMEW ofn
)
3496 return GetSaveFileNameW(ofn
);
3499 /*************************************************************************
3502 * See WNetRestoreConnectionW.
3504 DWORD WINAPI
WNetRestoreConnectionWrapW(HWND hwndOwner
, LPWSTR lpszDevice
)
3506 return WNetRestoreConnectionW(hwndOwner
, lpszDevice
);
3509 /*************************************************************************
3512 * See WNetGetLastErrorW.
3514 DWORD WINAPI
WNetGetLastErrorWrapW(LPDWORD lpError
, LPWSTR lpErrorBuf
, DWORD nErrorBufSize
,
3515 LPWSTR lpNameBuf
, DWORD nNameBufSize
)
3517 return WNetGetLastErrorW(lpError
, lpErrorBuf
, nErrorBufSize
, lpNameBuf
, nNameBufSize
);
3520 /*************************************************************************
3523 * See PageSetupDlgW.
3525 BOOL WINAPI
PageSetupDlgWrapW(LPPAGESETUPDLGW pagedlg
)
3527 return PageSetupDlgW(pagedlg
);
3530 /*************************************************************************
3535 BOOL WINAPI
PrintDlgWrapW(LPPRINTDLGW printdlg
)
3537 return PrintDlgW(printdlg
);
3540 /*************************************************************************
3543 * See GetOpenFileNameW.
3545 BOOL WINAPI
GetOpenFileNameWrapW(LPOPENFILENAMEW ofn
)
3547 return GetOpenFileNameW(ofn
);
3550 /*************************************************************************
3553 HRESULT WINAPI
IUnknown_EnumObjects(LPSHELLFOLDER lpFolder
, HWND hwnd
, SHCONTF flags
, IEnumIDList
**ppenum
)
3558 hr
= IShellFolder_QueryInterface(lpFolder
, &IID_IPersist
, (LPVOID
)&persist
);
3562 hr
= IPersist_GetClassID(persist
, &clsid
);
3565 if(IsEqualCLSID(&clsid
, &CLSID_ShellFSFolder
))
3566 hr
= IShellFolder_EnumObjects(lpFolder
, hwnd
, flags
, ppenum
);
3570 IPersist_Release(persist
);
3575 /* INTERNAL: Map from HLS color space to RGB */
3576 static WORD WINAPI
ConvertHue(int wHue
, WORD wMid1
, WORD wMid2
)
3578 wHue
= wHue
> 240 ? wHue
- 240 : wHue
< 0 ? wHue
+ 240 : wHue
;
3582 else if (wHue
> 120)
3587 return ((wHue
* (wMid2
- wMid1
) + 20) / 40) + wMid1
;
3590 /* Convert to RGB and scale into RGB range (0..255) */
3591 #define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240
3593 /*************************************************************************
3594 * ColorHLSToRGB [SHLWAPI.@]
3596 * Convert from hls color space into an rgb COLORREF.
3599 * wHue [I] Hue amount
3600 * wLuminosity [I] Luminosity amount
3601 * wSaturation [I] Saturation amount
3604 * A COLORREF representing the converted color.
3607 * Input hls values are constrained to the range (0..240).
3609 COLORREF WINAPI
ColorHLSToRGB(WORD wHue
, WORD wLuminosity
, WORD wSaturation
)
3615 WORD wGreen
, wBlue
, wMid1
, wMid2
;
3617 if (wLuminosity
> 120)
3618 wMid2
= wSaturation
+ wLuminosity
- (wSaturation
* wLuminosity
+ 120) / 240;
3620 wMid2
= ((wSaturation
+ 240) * wLuminosity
+ 120) / 240;
3622 wMid1
= wLuminosity
* 2 - wMid2
;
3624 wRed
= GET_RGB(wHue
+ 80);
3625 wGreen
= GET_RGB(wHue
);
3626 wBlue
= GET_RGB(wHue
- 80);
3628 return RGB(wRed
, wGreen
, wBlue
);
3631 wRed
= wLuminosity
* 255 / 240;
3632 return RGB(wRed
, wRed
, wRed
);
3635 /*************************************************************************
3638 * Get the current docking status of the system.
3641 * dwFlags [I] DOCKINFO_ flags from "winbase.h", unused
3644 * One of DOCKINFO_UNDOCKED, DOCKINFO_UNDOCKED, or 0 if the system is not
3647 DWORD WINAPI
SHGetMachineInfo(DWORD dwFlags
)
3649 HW_PROFILE_INFOA hwInfo
;
3651 TRACE("(0x%08x)\n", dwFlags
);
3653 GetCurrentHwProfileA(&hwInfo
);
3654 switch (hwInfo
.dwDockInfo
& (DOCKINFO_DOCKED
|DOCKINFO_UNDOCKED
))
3656 case DOCKINFO_DOCKED
:
3657 case DOCKINFO_UNDOCKED
:
3658 return hwInfo
.dwDockInfo
& (DOCKINFO_DOCKED
|DOCKINFO_UNDOCKED
);
3664 /*************************************************************************
3667 * Function seems to do FreeLibrary plus other things.
3669 * FIXME native shows the following calls:
3670 * RtlEnterCriticalSection
3672 * GetProcAddress(Comctl32??, 150L)
3674 * RtlLeaveCriticalSection
3675 * followed by the FreeLibrary.
3676 * The above code may be related to .377 above.
3678 BOOL WINAPI
MLFreeLibrary(HMODULE hModule
)
3680 FIXME("(%p) semi-stub\n", hModule
);
3681 return FreeLibrary(hModule
);
3684 /*************************************************************************
3687 BOOL WINAPI
SHFlushSFCacheWrap(void) {
3692 /*************************************************************************
3695 BOOL WINAPI
DeleteMenuWrap(HMENU hmenu
, UINT pos
, UINT flags
)
3697 /* FIXME: This should do more than simply call DeleteMenu */
3698 FIXME("%p %08x %08x): semi-stub\n", hmenu
, pos
, flags
);
3699 return DeleteMenu(hmenu
, pos
, flags
);
3702 /*************************************************************************
3704 * FIXME I have no idea what this function does or what its arguments are.
3706 BOOL WINAPI
MLIsMLHInstance(HINSTANCE hInst
)
3708 FIXME("(%p) stub\n", hInst
);
3713 /*************************************************************************
3716 DWORD WINAPI
MLSetMLHInstance(HINSTANCE hInst
, HANDLE hHeap
)
3718 FIXME("(%p,%p) stub\n", hInst
, hHeap
);
3719 return E_FAIL
; /* This is what is used if shlwapi not loaded */
3722 /*************************************************************************
3725 DWORD WINAPI
MLClearMLHInstance(DWORD x
)
3727 FIXME("(0x%08x)stub\n", x
);
3731 /*************************************************************************
3734 * Convert an Unicode string CLSID into a CLSID.
3737 * idstr [I] string containing a CLSID in text form
3738 * id [O] CLSID extracted from the string
3741 * S_OK on success or E_INVALIDARG on failure
3743 HRESULT WINAPI
CLSIDFromStringWrap(LPCWSTR idstr
, CLSID
*id
)
3745 return CLSIDFromString((LPOLESTR
)idstr
, id
);
3748 /*************************************************************************
3751 * Determine if the OS supports a given feature.
3754 * dwFeature [I] Feature requested (undocumented)
3757 * TRUE If the feature is available.
3758 * FALSE If the feature is not available.
3760 BOOL WINAPI
IsOS(DWORD feature
)
3762 OSVERSIONINFOA osvi
;
3763 DWORD platform
, majorv
, minorv
;
3765 osvi
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFOA
);
3766 if(!GetVersionExA(&osvi
)) {
3767 ERR("GetVersionEx failed\n");
3771 majorv
= osvi
.dwMajorVersion
;
3772 minorv
= osvi
.dwMinorVersion
;
3773 platform
= osvi
.dwPlatformId
;
3775 #define ISOS_RETURN(x) \
3776 TRACE("(0x%x) ret=%d\n",feature,(x)); \
3780 case OS_WIN32SORGREATER
:
3781 ISOS_RETURN(platform
== VER_PLATFORM_WIN32s
3782 || platform
== VER_PLATFORM_WIN32_WINDOWS
)
3784 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3785 case OS_WIN95ORGREATER
:
3786 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
)
3787 case OS_NT4ORGREATER
:
3788 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 4)
3789 case OS_WIN2000ORGREATER_ALT
:
3790 case OS_WIN2000ORGREATER
:
3791 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5)
3792 case OS_WIN98ORGREATER
:
3793 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
&& minorv
>= 10)
3795 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
&& minorv
== 10)
3797 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5)
3798 case OS_WIN2000SERVER
:
3799 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& (minorv
== 0 || minorv
== 1))
3800 case OS_WIN2000ADVSERVER
:
3801 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& (minorv
== 0 || minorv
== 1))
3802 case OS_WIN2000DATACENTER
:
3803 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& (minorv
== 0 || minorv
== 1))
3804 case OS_WIN2000TERMINAL
:
3805 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& (minorv
== 0 || minorv
== 1))
3807 FIXME("(OS_EMBEDDED) What should we return here?\n");
3809 case OS_TERMINALCLIENT
:
3810 FIXME("(OS_TERMINALCLIENT) What should we return here?\n");
3812 case OS_TERMINALREMOTEADMIN
:
3813 FIXME("(OS_TERMINALREMOTEADMIN) What should we return here?\n");
3816 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
&& minorv
== 0)
3817 case OS_MEORGREATER
:
3818 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
&& minorv
>= 90)
3819 case OS_XPORGREATER
:
3820 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5 && minorv
>= 1)
3822 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5 && minorv
>= 1)
3823 case OS_PROFESSIONAL
:
3824 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3826 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3828 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5)
3830 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3831 case OS_TERMINALSERVER
:
3832 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3833 case OS_PERSONALTERMINALSERVER
:
3834 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& minorv
>= 1 && majorv
>= 5)
3835 case OS_FASTUSERSWITCHING
:
3836 FIXME("(OS_FASTUSERSWITCHING) What should we return here?\n");
3838 case OS_WELCOMELOGONUI
:
3839 FIXME("(OS_WELCOMELOGONUI) What should we return here?\n");
3841 case OS_DOMAINMEMBER
:
3842 FIXME("(OS_DOMAINMEMBER) What should we return here?\n");
3845 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3847 FIXME("(OS_WOW6432) Should we check this?\n");
3850 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3851 case OS_SMALLBUSINESSSERVER
:
3852 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3854 FIXME("(OS_TABLEPC) What should we return here?\n");
3856 case OS_SERVERADMINUI
:
3857 FIXME("(OS_SERVERADMINUI) What should we return here?\n");
3859 case OS_MEDIACENTER
:
3860 FIXME("(OS_MEDIACENTER) What should we return here?\n");
3863 FIXME("(OS_APPLIANCE) What should we return here?\n");
3869 WARN("(0x%x) unknown parameter\n",feature
);
3874 /*************************************************************************
3877 HRESULT WINAPI
SHLoadRegUIStringW(HKEY hkey
, LPCWSTR value
, LPWSTR buf
, DWORD size
)
3879 DWORD type
, sz
= size
;
3881 if(RegQueryValueExW(hkey
, value
, NULL
, &type
, (LPBYTE
)buf
, &sz
) != ERROR_SUCCESS
)
3884 return SHLoadIndirectString(buf
, buf
, size
, NULL
);
3887 /*************************************************************************
3890 * Call IInputObject_TranslateAcceleratorIO() on an object.
3893 * lpUnknown [I] Object supporting the IInputObject interface.
3894 * lpMsg [I] Key message to be processed.
3898 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
3900 HRESULT WINAPI
IUnknown_TranslateAcceleratorIO(IUnknown
*lpUnknown
, LPMSG lpMsg
)
3902 IInputObject
* lpInput
= NULL
;
3903 HRESULT hRet
= E_INVALIDARG
;
3905 TRACE("(%p,%p)\n", lpUnknown
, lpMsg
);
3908 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IInputObject
,
3910 if (SUCCEEDED(hRet
) && lpInput
)
3912 hRet
= IInputObject_TranslateAcceleratorIO(lpInput
, lpMsg
);
3913 IInputObject_Release(lpInput
);
3919 /*************************************************************************
3922 * Call IInputObject_HasFocusIO() on an object.
3925 * lpUnknown [I] Object supporting the IInputObject interface.
3928 * Success: S_OK, if lpUnknown is an IInputObject object and has the focus,
3929 * or S_FALSE otherwise.
3930 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
3932 HRESULT WINAPI
IUnknown_HasFocusIO(IUnknown
*lpUnknown
)
3934 IInputObject
* lpInput
= NULL
;
3935 HRESULT hRet
= E_INVALIDARG
;
3937 TRACE("(%p)\n", lpUnknown
);
3940 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IInputObject
,
3942 if (SUCCEEDED(hRet
) && lpInput
)
3944 hRet
= IInputObject_HasFocusIO(lpInput
);
3945 IInputObject_Release(lpInput
);
3951 /*************************************************************************
3952 * ColorRGBToHLS [SHLWAPI.@]
3954 * Convert an rgb COLORREF into the hls color space.
3957 * cRGB [I] Source rgb value
3958 * pwHue [O] Destination for converted hue
3959 * pwLuminance [O] Destination for converted luminance
3960 * pwSaturation [O] Destination for converted saturation
3963 * Nothing. pwHue, pwLuminance and pwSaturation are set to the converted
3967 * Output HLS values are constrained to the range (0..240).
3968 * For Achromatic conversions, Hue is set to 160.
3970 VOID WINAPI
ColorRGBToHLS(COLORREF cRGB
, LPWORD pwHue
,
3971 LPWORD pwLuminance
, LPWORD pwSaturation
)
3973 int wR
, wG
, wB
, wMax
, wMin
, wHue
, wLuminosity
, wSaturation
;
3975 TRACE("(%08x,%p,%p,%p)\n", cRGB
, pwHue
, pwLuminance
, pwSaturation
);
3977 wR
= GetRValue(cRGB
);
3978 wG
= GetGValue(cRGB
);
3979 wB
= GetBValue(cRGB
);
3981 wMax
= max(wR
, max(wG
, wB
));
3982 wMin
= min(wR
, min(wG
, wB
));
3985 wLuminosity
= ((wMax
+ wMin
) * 240 + 255) / 510;
3989 /* Achromatic case */
3991 /* Hue is now unrepresentable, but this is what native returns... */
3996 /* Chromatic case */
3997 int wDelta
= wMax
- wMin
, wRNorm
, wGNorm
, wBNorm
;
4000 if (wLuminosity
<= 120)
4001 wSaturation
= ((wMax
+ wMin
)/2 + wDelta
* 240) / (wMax
+ wMin
);
4003 wSaturation
= ((510 - wMax
- wMin
)/2 + wDelta
* 240) / (510 - wMax
- wMin
);
4006 wRNorm
= (wDelta
/2 + wMax
* 40 - wR
* 40) / wDelta
;
4007 wGNorm
= (wDelta
/2 + wMax
* 40 - wG
* 40) / wDelta
;
4008 wBNorm
= (wDelta
/2 + wMax
* 40 - wB
* 40) / wDelta
;
4011 wHue
= wBNorm
- wGNorm
;
4012 else if (wG
== wMax
)
4013 wHue
= 80 + wRNorm
- wBNorm
;
4015 wHue
= 160 + wGNorm
- wRNorm
;
4018 else if (wHue
> 240)
4024 *pwLuminance
= wLuminosity
;
4026 *pwSaturation
= wSaturation
;
4029 /*************************************************************************
4030 * SHCreateShellPalette [SHLWAPI.@]
4032 HPALETTE WINAPI
SHCreateShellPalette(HDC hdc
)
4035 return CreateHalftonePalette(hdc
);
4038 /*************************************************************************
4039 * SHGetInverseCMAP (SHLWAPI.@)
4041 * Get an inverse color map table.
4044 * lpCmap [O] Destination for color map
4045 * dwSize [I] Size of memory pointed to by lpCmap
4049 * Failure: E_POINTER, If lpCmap is invalid.
4050 * E_INVALIDARG, If dwFlags is invalid
4051 * E_OUTOFMEMORY, If there is no memory available
4054 * dwSize may only be CMAP_PTR_SIZE (4) or CMAP_SIZE (8192).
4055 * If dwSize = CMAP_PTR_SIZE, *lpCmap is set to the address of this DLL's
4057 * If dwSize = CMAP_SIZE, lpCmap is filled with a copy of the data from
4058 * this DLL's internal CMap.
4060 HRESULT WINAPI
SHGetInverseCMAP(LPDWORD dest
, DWORD dwSize
)
4063 FIXME(" - returning bogus address for SHGetInverseCMAP\n");
4064 *dest
= (DWORD
)0xabba1249;
4067 FIXME("(%p, %#x) stub\n", dest
, dwSize
);
4071 /*************************************************************************
4072 * SHIsLowMemoryMachine [SHLWAPI.@]
4074 * Determine if the current computer has low memory.
4080 * TRUE if the users machine has 16 Megabytes of memory or less,
4083 BOOL WINAPI
SHIsLowMemoryMachine (DWORD x
)
4085 FIXME("(0x%08x) stub\n", x
);
4089 /*************************************************************************
4090 * GetMenuPosFromID [SHLWAPI.@]
4092 * Return the position of a menu item from its Id.
4095 * hMenu [I] Menu containing the item
4096 * wID [I] Id of the menu item
4099 * Success: The index of the menu item in hMenu.
4100 * Failure: -1, If the item is not found.
4102 INT WINAPI
GetMenuPosFromID(HMENU hMenu
, UINT wID
)
4105 INT nCount
= GetMenuItemCount(hMenu
), nIter
= 0;
4107 while (nIter
< nCount
)
4109 mi
.cbSize
= sizeof(mi
);
4111 if (GetMenuItemInfoW(hMenu
, nIter
, TRUE
, &mi
) && mi
.wID
== wID
)
4118 /*************************************************************************
4121 * Same as SHLWAPI.GetMenuPosFromID
4123 DWORD WINAPI
SHMenuIndexFromID(HMENU hMenu
, UINT uID
)
4125 return GetMenuPosFromID(hMenu
, uID
);
4129 /*************************************************************************
4132 VOID WINAPI
FixSlashesAndColonW(LPWSTR lpwstr
)
4143 /*************************************************************************
4146 DWORD WINAPI
SHGetAppCompatFlags(DWORD dwUnknown
)
4148 FIXME("(0x%08x) stub\n", dwUnknown
);
4153 /*************************************************************************
4156 HRESULT WINAPI
SHCoCreateInstanceAC(REFCLSID rclsid
, LPUNKNOWN pUnkOuter
,
4157 DWORD dwClsContext
, REFIID iid
, LPVOID
*ppv
)
4159 return CoCreateInstance(rclsid
, pUnkOuter
, dwClsContext
, iid
, ppv
);
4162 /*************************************************************************
4163 * SHSkipJunction [SHLWAPI.@]
4165 * Determine if a bind context can be bound to an object
4168 * pbc [I] Bind context to check
4169 * pclsid [I] CLSID of object to be bound to
4172 * TRUE: If it is safe to bind
4173 * FALSE: If pbc is invalid or binding would not be safe
4176 BOOL WINAPI
SHSkipJunction(IBindCtx
*pbc
, const CLSID
*pclsid
)
4178 static WCHAR szSkipBinding
[] = { 'S','k','i','p',' ',
4179 'B','i','n','d','i','n','g',' ','C','L','S','I','D','\0' };
4186 if (SUCCEEDED(IBindCtx_GetObjectParam(pbc
, (LPOLESTR
)szSkipBinding
, &lpUnk
)))
4190 if (SUCCEEDED(IUnknown_GetClassID(lpUnk
, &clsid
)) &&
4191 IsEqualGUID(pclsid
, &clsid
))
4194 IUnknown_Release(lpUnk
);
4200 /***********************************************************************
4201 * SHGetShellKey (SHLWAPI.@)
4203 DWORD WINAPI
SHGetShellKey(DWORD a
, DWORD b
, DWORD c
)
4205 FIXME("(%x, %x, %x): stub\n", a
, b
, c
);
4209 /***********************************************************************
4210 * SHQueueUserWorkItem (SHLWAPI.@)
4212 BOOL WINAPI
SHQueueUserWorkItem(LPTHREAD_START_ROUTINE pfnCallback
,
4213 LPVOID pContext
, LONG lPriority
, DWORD_PTR dwTag
,
4214 DWORD_PTR
*pdwId
, LPCSTR pszModule
, DWORD dwFlags
)
4216 TRACE("(%p, %p, %d, %lx, %p, %s, %08x)\n", pfnCallback
, pContext
,
4217 lPriority
, dwTag
, pdwId
, debugstr_a(pszModule
), dwFlags
);
4219 if(lPriority
|| dwTag
|| pdwId
|| pszModule
|| dwFlags
)
4220 FIXME("Unsupported arguments\n");
4222 return QueueUserWorkItem(pfnCallback
, pContext
, 0);
4225 /***********************************************************************
4226 * SHSetTimerQueueTimer (SHLWAPI.263)
4228 HANDLE WINAPI
SHSetTimerQueueTimer(HANDLE hQueue
,
4229 WAITORTIMERCALLBACK pfnCallback
, LPVOID pContext
, DWORD dwDueTime
,
4230 DWORD dwPeriod
, LPCSTR lpszLibrary
, DWORD dwFlags
)
4234 /* SHSetTimerQueueTimer flags -> CreateTimerQueueTimer flags */
4235 if (dwFlags
& TPS_LONGEXECTIME
) {
4236 dwFlags
&= ~TPS_LONGEXECTIME
;
4237 dwFlags
|= WT_EXECUTELONGFUNCTION
;
4239 if (dwFlags
& TPS_EXECUTEIO
) {
4240 dwFlags
&= ~TPS_EXECUTEIO
;
4241 dwFlags
|= WT_EXECUTEINIOTHREAD
;
4244 if (!CreateTimerQueueTimer(&hNewTimer
, hQueue
, pfnCallback
, pContext
,
4245 dwDueTime
, dwPeriod
, dwFlags
))
4251 /***********************************************************************
4252 * IUnknown_OnFocusChangeIS (SHLWAPI.@)
4254 HRESULT WINAPI
IUnknown_OnFocusChangeIS(LPUNKNOWN lpUnknown
, LPUNKNOWN pFocusObject
, BOOL bFocus
)
4256 IInputObjectSite
*pIOS
= NULL
;
4257 HRESULT hRet
= E_INVALIDARG
;
4259 TRACE("(%p, %p, %s)\n", lpUnknown
, pFocusObject
, bFocus
? "TRUE" : "FALSE");
4263 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IInputObjectSite
,
4265 if (SUCCEEDED(hRet
) && pIOS
)
4267 hRet
= IInputObjectSite_OnFocusChangeIS(pIOS
, pFocusObject
, bFocus
);
4268 IInputObjectSite_Release(pIOS
);
4274 /***********************************************************************
4275 * SHGetValueW (SHLWAPI.@)
4277 HRESULT WINAPI
SKGetValueW(DWORD a
, LPWSTR b
, LPWSTR c
, DWORD d
, DWORD e
, DWORD f
)
4279 FIXME("(%x, %s, %s, %x, %x, %x): stub\n", a
, debugstr_w(b
), debugstr_w(c
), d
, e
, f
);
4283 typedef HRESULT (WINAPI
*DllGetVersion_func
)(DLLVERSIONINFO
*);
4285 /***********************************************************************
4286 * GetUIVersion (SHLWAPI.452)
4288 DWORD WINAPI
GetUIVersion(void)
4290 static DWORD version
;
4294 DllGetVersion_func pDllGetVersion
;
4295 HMODULE dll
= LoadLibraryA("shell32.dll");
4298 pDllGetVersion
= (DllGetVersion_func
)GetProcAddress(dll
, "DllGetVersion");
4302 dvi
.cbSize
= sizeof(DLLVERSIONINFO
);
4303 if (pDllGetVersion(&dvi
) == S_OK
) version
= dvi
.dwMajorVersion
;
4306 if (!version
) version
= 3; /* old shell dlls don't have DllGetVersion */
4311 /***********************************************************************
4312 * ShellMessageBoxWrapW [SHLWAPI.388]
4314 * loads a string resource for a module, displays the string in a
4315 * message box and writes it into the logfile
4318 * mod [I] the module containing the string resource
4319 * unknown1 [I] FIXME
4320 * uId [I] the id of the string resource
4321 * title [I] the title of the message box
4322 * unknown2 [I] FIXME
4323 * filename [I] name of the logfile
4328 BOOL WINAPI
ShellMessageBoxWrapW(HMODULE mod
, DWORD unknown1
, UINT uId
,
4329 LPCWSTR title
, DWORD unknown2
, LPCWSTR filename
)
4331 FIXME("%p %x %d %s %x %s\n",
4332 mod
, unknown1
, uId
, debugstr_w(title
), unknown2
, debugstr_w(filename
));
4336 HRESULT WINAPI
IUnknown_QueryServiceExec(IUnknown
*unk
, REFIID service
, REFIID clsid
,
4337 DWORD x1
, DWORD x2
, DWORD x3
, void **ppvOut
)
4339 FIXME("%p %s %s %08x %08x %08x %p\n", unk
,
4340 debugstr_guid(service
), debugstr_guid(clsid
), x1
, x2
, x3
, ppvOut
);
4344 HRESULT WINAPI
IUnknown_ProfferService(IUnknown
*unk
, void *x0
, void *x1
, void *x2
)
4346 FIXME("%p %p %p %p\n", unk
, x0
, x1
, x2
);
4350 /***********************************************************************
4351 * ZoneComputePaneSize [SHLWAPI.382]
4353 UINT WINAPI
ZoneComputePaneSize(HWND hwnd
)
4359 void WINAPI
SHChangeNotify(LONG wEventId
, UINT uFlags
, LPCVOID dwItem1
, LPCVOID dwItem2
)
4361 SHChangeNotify(wEventId
, uFlags
, dwItem1
, dwItem2
);
4364 typedef struct SHELL_USER_SID
{ /* according to MSDN this should be in shlobj.h... */
4365 SID_IDENTIFIER_AUTHORITY sidAuthority
;
4366 DWORD dwUserGroupID
;
4368 } SHELL_USER_SID
, *PSHELL_USER_SID
;
4370 typedef struct SHELL_USER_PERMISSION
{ /* ...and this should be in shlwapi.h */
4371 SHELL_USER_SID susID
;
4375 DWORD dwInheritMask
;
4376 DWORD dwInheritAccessMask
;
4377 } SHELL_USER_PERMISSION
, *PSHELL_USER_PERMISSION
;
4379 /***********************************************************************
4380 * GetShellSecurityDescriptor [SHLWAPI.475]
4382 * prepares SECURITY_DESCRIPTOR from a set of ACEs
4385 * apUserPerm [I] array of pointers to SHELL_USER_PERMISSION structures,
4386 * each of which describes permissions to apply
4387 * cUserPerm [I] number of entries in apUserPerm array
4390 * success: pointer to SECURITY_DESCRIPTOR
4394 * Call should free returned descriptor with LocalFree
4396 SECURITY_DESCRIPTOR
* WINAPI
GetShellSecurityDescriptor(PSHELL_USER_PERMISSION
*apUserPerm
, int cUserPerm
)
4399 PSID cur_user
= NULL
;
4403 PSECURITY_DESCRIPTOR psd
= NULL
;
4405 TRACE("%p %d\n", apUserPerm
, cUserPerm
);
4407 if (apUserPerm
== NULL
|| cUserPerm
<= 0)
4410 sidlist
= HeapAlloc(GetProcessHeap(), 0, cUserPerm
* sizeof(PSID
));
4414 acl_size
= sizeof(ACL
);
4416 for(sid_count
= 0; sid_count
< cUserPerm
; sid_count
++)
4418 static SHELL_USER_SID null_sid
= {{SECURITY_NULL_SID_AUTHORITY
}, 0, 0};
4419 PSHELL_USER_PERMISSION perm
= apUserPerm
[sid_count
];
4420 PSHELL_USER_SID sid
= &perm
->susID
;
4424 if (!memcmp((void*)sid
, (void*)&null_sid
, sizeof(SHELL_USER_SID
)))
4425 { /* current user's SID */
4429 DWORD bufsize
= sizeof(tuUser
);
4431 ret
= OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY
, &Token
);
4434 ret
= GetTokenInformation(Token
, TokenUser
, (void*)tuUser
, bufsize
, &bufsize
);
4436 cur_user
= ((PTOKEN_USER
)&tuUser
)->User
.Sid
;
4441 } else if (sid
->dwUserID
==0) /* one sub-authority */
4442 ret
= AllocateAndInitializeSid(&sid
->sidAuthority
, 1, sid
->dwUserGroupID
, 0,
4443 0, 0, 0, 0, 0, 0, &pSid
);
4445 ret
= AllocateAndInitializeSid(&sid
->sidAuthority
, 2, sid
->dwUserGroupID
, sid
->dwUserID
,
4446 0, 0, 0, 0, 0, 0, &pSid
);
4450 sidlist
[sid_count
] = pSid
;
4451 /* increment acl_size (1 ACE for non-inheritable and 2 ACEs for inheritable records */
4452 acl_size
+= (sizeof(ACCESS_ALLOWED_ACE
)-sizeof(DWORD
) + GetLengthSid(pSid
)) * (perm
->fInherit
? 2 : 1);
4455 psd
= LocalAlloc(0, sizeof(SECURITY_DESCRIPTOR
) + acl_size
);
4459 PACL pAcl
= (PACL
)(((BYTE
*)psd
)+sizeof(SECURITY_DESCRIPTOR
));
4461 if (!InitializeSecurityDescriptor(psd
, SECURITY_DESCRIPTOR_REVISION
))
4464 if (!InitializeAcl(pAcl
, acl_size
, ACL_REVISION
))
4467 for(i
= 0; i
< sid_count
; i
++)
4469 PSHELL_USER_PERMISSION sup
= apUserPerm
[i
];
4470 PSID sid
= sidlist
[i
];
4472 switch(sup
->dwAccessType
)
4474 case ACCESS_ALLOWED_ACE_TYPE
:
4475 if (!AddAccessAllowedAce(pAcl
, ACL_REVISION
, sup
->dwAccessMask
, sid
))
4477 if (sup
->fInherit
&& !AddAccessAllowedAceEx(pAcl
, ACL_REVISION
,
4478 (BYTE
)sup
->dwInheritMask
, sup
->dwInheritAccessMask
, sid
))
4481 case ACCESS_DENIED_ACE_TYPE
:
4482 if (!AddAccessDeniedAce(pAcl
, ACL_REVISION
, sup
->dwAccessMask
, sid
))
4484 if (sup
->fInherit
&& !AddAccessDeniedAceEx(pAcl
, ACL_REVISION
,
4485 (BYTE
)sup
->dwInheritMask
, sup
->dwInheritAccessMask
, sid
))
4493 if (!SetSecurityDescriptorDacl(psd
, TRUE
, pAcl
, FALSE
))
4502 for(i
= 0; i
< sid_count
; i
++)
4504 if (!cur_user
|| sidlist
[i
] != cur_user
)
4505 FreeSid(sidlist
[i
]);
4507 HeapFree(GetProcessHeap(), 0, sidlist
);