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
23 #define COM_NO_WINDOWS_H
25 #include "wine/port.h"
32 #define NONAMELESSUNION
33 #define NONAMELESSSTRUCT
47 #include "wine/unicode.h"
49 #include "wine/debug.h"
53 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
55 /* Get a function pointer from a DLL handle */
56 #define GET_FUNC(func, module, name, fail) \
59 if (!SHLWAPI_h##module && !(SHLWAPI_h##module = LoadLibraryA(#module ".dll"))) return fail; \
60 func = (fn##func)GetProcAddress(SHLWAPI_h##module, name); \
61 if (!func) return fail; \
65 /* DLL handles for late bound calls */
66 extern HINSTANCE shlwapi_hInstance
;
67 extern HMODULE SHLWAPI_hshell32
;
68 extern HMODULE SHLWAPI_hwinmm
;
69 extern HMODULE SHLWAPI_hcomdlg32
;
70 extern HMODULE SHLWAPI_hcomctl32
;
71 extern HMODULE SHLWAPI_hmpr
;
72 extern HMODULE SHLWAPI_hurlmon
;
73 extern HMODULE SHLWAPI_hversion
;
75 extern DWORD SHLWAPI_ThreadRef_index
;
77 /* Function pointers for GET_FUNC macro; these need to be global because of gcc bug */
78 typedef LPITEMIDLIST (WINAPI
*fnpSHBrowseForFolderW
)(LPBROWSEINFOW
);
79 static fnpSHBrowseForFolderW pSHBrowseForFolderW
;
80 typedef BOOL (WINAPI
*fnpPlaySoundW
)(LPCWSTR
, HMODULE
, DWORD
);
81 static fnpPlaySoundW pPlaySoundW
;
82 typedef DWORD (WINAPI
*fnpSHGetFileInfoW
)(LPCWSTR
,DWORD
,SHFILEINFOW
*,UINT
,UINT
);
83 static fnpSHGetFileInfoW pSHGetFileInfoW
;
84 typedef UINT (WINAPI
*fnpDragQueryFileW
)(HDROP
, UINT
, LPWSTR
, UINT
);
85 static fnpDragQueryFileW pDragQueryFileW
;
86 typedef BOOL (WINAPI
*fnpSHGetPathFromIDListW
)(LPCITEMIDLIST
, LPWSTR
);
87 static fnpSHGetPathFromIDListW pSHGetPathFromIDListW
;
88 typedef BOOL (WINAPI
*fnpShellExecuteExW
)(LPSHELLEXECUTEINFOW
);
89 static fnpShellExecuteExW pShellExecuteExW
;
90 typedef HICON (WINAPI
*fnpSHFileOperationW
)(LPSHFILEOPSTRUCTW
);
91 static fnpSHFileOperationW pSHFileOperationW
;
92 typedef UINT (WINAPI
*fnpExtractIconExW
)(LPCWSTR
, INT
,HICON
*,HICON
*, UINT
);
93 static fnpExtractIconExW pExtractIconExW
;
94 typedef BOOL (WINAPI
*fnpSHGetNewLinkInfoW
)(LPCWSTR
, LPCWSTR
, LPCWSTR
, BOOL
*, UINT
);
95 static fnpSHGetNewLinkInfoW pSHGetNewLinkInfoW
;
96 typedef HRESULT (WINAPI
*fnpSHDefExtractIconW
)(LPCWSTR
, int, UINT
, HICON
*, HICON
*, UINT
);
97 static fnpSHDefExtractIconW pSHDefExtractIconW
;
98 typedef HICON (WINAPI
*fnpExtractIconW
)(HINSTANCE
, LPCWSTR
, UINT
);
99 static fnpExtractIconW pExtractIconW
;
100 typedef BOOL (WINAPI
*fnpGetSaveFileNameW
)(LPOPENFILENAMEW
);
101 static fnpGetSaveFileNameW pGetSaveFileNameW
;
102 typedef DWORD (WINAPI
*fnpWNetRestoreConnectionW
)(HWND
, LPWSTR
);
103 static fnpWNetRestoreConnectionW pWNetRestoreConnectionW
;
104 typedef DWORD (WINAPI
*fnpWNetGetLastErrorW
)(LPDWORD
, LPWSTR
, DWORD
, LPWSTR
, DWORD
);
105 static fnpWNetGetLastErrorW pWNetGetLastErrorW
;
106 typedef BOOL (WINAPI
*fnpPageSetupDlgW
)(LPPAGESETUPDLGW
);
107 static fnpPageSetupDlgW pPageSetupDlgW
;
108 typedef BOOL (WINAPI
*fnpPrintDlgW
)(LPPRINTDLGW
);
109 static fnpPrintDlgW pPrintDlgW
;
110 typedef BOOL (WINAPI
*fnpGetOpenFileNameW
)(LPOPENFILENAMEW
);
111 static fnpGetOpenFileNameW pGetOpenFileNameW
;
112 typedef DWORD (WINAPI
*fnpGetFileVersionInfoSizeW
)(LPCWSTR
,LPDWORD
);
113 static fnpGetFileVersionInfoSizeW pGetFileVersionInfoSizeW
;
114 typedef BOOL (WINAPI
*fnpGetFileVersionInfoW
)(LPCWSTR
,DWORD
,DWORD
,LPVOID
);
115 static fnpGetFileVersionInfoW pGetFileVersionInfoW
;
116 typedef WORD (WINAPI
*fnpVerQueryValueW
)(LPVOID
,LPCWSTR
,LPVOID
*,UINT
*);
117 static fnpVerQueryValueW pVerQueryValueW
;
118 typedef BOOL (WINAPI
*fnpCOMCTL32_417
)(HDC
,INT
,INT
,UINT
,const RECT
*,LPCWSTR
,UINT
,const INT
*);
119 static fnpCOMCTL32_417 pCOMCTL32_417
;
120 typedef HRESULT (WINAPI
*fnpDllGetVersion
)(DLLVERSIONINFO
*);
121 static fnpDllGetVersion pDllGetVersion
;
122 typedef HRESULT (WINAPI
*fnpCreateFormatEnumerator
)(UINT
,FORMATETC
*,IEnumFORMATETC
**);
123 static fnpCreateFormatEnumerator pCreateFormatEnumerator
;
124 typedef HRESULT (WINAPI
*fnpRegisterFormatEnumerator
)(LPBC
,IEnumFORMATETC
*,DWORD
);
125 static fnpRegisterFormatEnumerator pRegisterFormatEnumerator
;
127 HRESULT WINAPI
IUnknown_QueryService(IUnknown
*,REFGUID
,REFIID
,LPVOID
*);
128 HRESULT WINAPI
SHInvokeCommand(HWND
,IShellFolder
*,LPCITEMIDLIST
,BOOL
);
129 HRESULT WINAPI
CLSIDFromStringWrap(LPCWSTR
,CLSID
*);
130 BOOL WINAPI
SHAboutInfoW(LPWSTR
,DWORD
);
133 NOTES: Most functions exported by ordinal seem to be superflous.
134 The reason for these functions to be there is to provide a wrapper
135 for unicode functions to provide these functions on systems without
136 unicode functions eg. win95/win98. Since we have such functions we just
137 call these. If running Wine with native DLLs, some late bound calls may
138 fail. However, it is better to implement the functions in the forward DLL
139 and recommend the builtin rather than reimplementing the calls here!
142 /*************************************************************************
143 * SHLWAPI_DupSharedHandle
145 * Internal implemetation of SHLWAPI_11.
148 HANDLE WINAPI
SHLWAPI_DupSharedHandle(HANDLE hShared
, DWORD dwDstProcId
,
149 DWORD dwSrcProcId
, DWORD dwAccess
,
153 DWORD dwMyProcId
= GetCurrentProcessId();
156 TRACE("(%p,%ld,%ld,%08lx,%08lx)\n", hShared
, dwDstProcId
, dwSrcProcId
,
157 dwAccess
, dwOptions
);
159 /* Get dest process handle */
160 if (dwDstProcId
== dwMyProcId
)
161 hDst
= GetCurrentProcess();
163 hDst
= OpenProcess(PROCESS_DUP_HANDLE
, 0, dwDstProcId
);
167 /* Get src process handle */
168 if (dwSrcProcId
== dwMyProcId
)
169 hSrc
= GetCurrentProcess();
171 hSrc
= OpenProcess(PROCESS_DUP_HANDLE
, 0, dwSrcProcId
);
175 /* Make handle available to dest process */
176 if (!DuplicateHandle(hDst
, hShared
, hSrc
, &hRet
,
177 dwAccess
, 0, dwOptions
| DUPLICATE_SAME_ACCESS
))
180 if (dwSrcProcId
!= dwMyProcId
)
184 if (dwDstProcId
!= dwMyProcId
)
188 TRACE("Returning handle %p\n", hRet
);
192 /*************************************************************************
195 * Create a block of sharable memory and initialise it with data.
198 * lpvData [I] Pointer to data to write
199 * dwSize [I] Size of data
200 * dwProcId [I] ID of process owning data
203 * Success: A shared memory handle
207 * Ordinals 7-11 provide a set of calls to create shared memory between a
208 * group of processes. The shared memory is treated opaquely in that its size
209 * is not exposed to clients who map it. This is accomplished by storing
210 * the size of the map as the first DWORD of mapped data, and then offsetting
211 * the view pointer returned by this size.
214 HANDLE WINAPI
SHAllocShared(LPCVOID lpvData
, DWORD dwSize
, DWORD dwProcId
)
220 TRACE("(%p,%ld,%ld)\n", lpvData
, dwSize
, dwProcId
);
222 /* Create file mapping of the correct length */
223 hMap
= CreateFileMappingA(INVALID_HANDLE_VALUE
, NULL
, FILE_MAP_READ
, 0,
224 dwSize
+ sizeof(dwSize
), NULL
);
228 /* Get a view in our process address space */
229 pMapped
= MapViewOfFile(hMap
, FILE_MAP_READ
| FILE_MAP_WRITE
, 0, 0, 0);
233 /* Write size of data, followed by the data, to the view */
234 *((DWORD
*)pMapped
) = dwSize
;
236 memcpy((char *) pMapped
+ sizeof(dwSize
), lpvData
, dwSize
);
238 /* Release view. All further views mapped will be opaque */
239 UnmapViewOfFile(pMapped
);
240 hRet
= SHLWAPI_DupSharedHandle(hMap
, dwProcId
,
241 GetCurrentProcessId(), FILE_MAP_ALL_ACCESS
,
242 DUPLICATE_SAME_ACCESS
);
249 /*************************************************************************
252 * Get a pointer to a block of shared memory from a shared memory handle.
255 * hShared [I] Shared memory handle
256 * dwProcId [I] ID of process owning hShared
259 * Success: A pointer to the shared memory
263 PVOID WINAPI
SHLockShared(HANDLE hShared
, DWORD dwProcId
)
268 TRACE("(%p %ld)\n", hShared
, dwProcId
);
270 /* Get handle to shared memory for current process */
271 hDup
= SHLWAPI_DupSharedHandle(hShared
, dwProcId
, GetCurrentProcessId(),
272 FILE_MAP_ALL_ACCESS
, 0);
274 pMapped
= MapViewOfFile(hDup
, FILE_MAP_READ
| FILE_MAP_WRITE
, 0, 0, 0);
278 return (char *) pMapped
+ sizeof(DWORD
); /* Hide size */
282 /*************************************************************************
285 * Release a pointer to a block of shared memory.
288 * lpView [I] Shared memory pointer
295 BOOL WINAPI
SHUnlockShared(LPVOID lpView
)
297 TRACE("(%p)\n", lpView
);
298 return UnmapViewOfFile((char *) lpView
- sizeof(DWORD
)); /* Include size */
301 /*************************************************************************
304 * Destroy a block of sharable memory.
307 * hShared [I] Shared memory handle
308 * dwProcId [I] ID of process owning hShared
315 BOOL WINAPI
SHFreeShared(HANDLE hShared
, DWORD dwProcId
)
319 TRACE("(%p %ld)\n", hShared
, dwProcId
);
321 /* Get a copy of the handle for our process, closing the source handle */
322 hClose
= SHLWAPI_DupSharedHandle(hShared
, dwProcId
, GetCurrentProcessId(),
323 FILE_MAP_ALL_ACCESS
,DUPLICATE_CLOSE_SOURCE
);
324 /* Close local copy */
325 return CloseHandle(hClose
);
328 /*************************************************************************
331 * Copy a sharable memory handle from one process to another.
334 * hShared [I] Shared memory handle to duplicate
335 * dwDstProcId [I] ID of the process wanting the duplicated handle
336 * dwSrcProcId [I] ID of the process owning hShared
337 * dwAccess [I] Desired DuplicateHandle() access
338 * dwOptions [I] Desired DuplicateHandle() options
341 * Success: A handle suitable for use by the dwDstProcId process.
342 * Failure: A NULL handle.
345 HANDLE WINAPI
SHMapHandle(HANDLE hShared
, DWORD dwDstProcId
, DWORD dwSrcProcId
,
346 DWORD dwAccess
, DWORD dwOptions
)
350 hRet
= SHLWAPI_DupSharedHandle(hShared
, dwDstProcId
, dwSrcProcId
,
351 dwAccess
, dwOptions
);
355 /*************************************************************************
358 * Create and register a clipboard enumerator for a web browser.
361 * lpBC [I] Binding context
362 * lpUnknown [I] An object exposing the IWebBrowserApp interface
366 * Failure: An HRESULT error code.
369 * The enumerator is stored as a property of the web browser. If it does not
370 * yet exist, it is created and set before being registered.
372 HRESULT WINAPI
RegisterDefaultAcceptHeaders(LPBC lpBC
, IUnknown
*lpUnknown
)
374 static const WCHAR szProperty
[] = { '{','D','0','F','C','A','4','2','0',
375 '-','D','3','F','5','-','1','1','C','F', '-','B','2','1','1','-','0',
376 '0','A','A','0','0','4','A','E','8','3','7','}','\0' };
377 IEnumFORMATETC
* pIEnumFormatEtc
= NULL
;
380 IWebBrowserApp
* pBrowser
= NULL
;
382 TRACE("(%p, %p)\n", lpBC
, lpUnknown
);
384 /* Get An IWebBrowserApp interface from lpUnknown */
385 hRet
= IUnknown_QueryService(lpUnknown
, &IID_IWebBrowserApp
, &IID_IWebBrowserApp
, (PVOID
)&pBrowser
);
386 if (FAILED(hRet
) || !pBrowser
)
387 return E_NOINTERFACE
;
389 V_VT(&var
) = VT_EMPTY
;
391 /* The property we get is the browsers clipboard enumerator */
392 hRet
= IWebBrowserApp_GetProperty(pBrowser
, (BSTR
)szProperty
, &var
);
396 if (V_VT(&var
) == VT_EMPTY
)
398 /* Iterate through accepted documents and RegisterClipBoardFormatA() them */
399 char szKeyBuff
[128], szValueBuff
[128];
400 DWORD dwKeySize
, dwValueSize
, dwRet
= 0, dwCount
= 0, dwNumValues
, dwType
;
401 FORMATETC
* formatList
, *format
;
404 TRACE("Registering formats and creating IEnumFORMATETC instance\n");
406 if (!RegOpenKeyA(HKEY_LOCAL_MACHINE
, "Software\\Microsoft\\Windows\\Current"
407 "Version\\Internet Settings\\Accepted Documents", &hDocs
))
410 /* Get count of values in key */
413 dwKeySize
= sizeof(szKeyBuff
);
414 dwRet
= RegEnumValueA(hDocs
,dwCount
,szKeyBuff
,&dwKeySize
,0,&dwType
,0,0);
418 dwNumValues
= dwCount
;
420 /* Note: dwCount = number of items + 1; The extra item is the end node */
421 format
= formatList
= HeapAlloc(GetProcessHeap(), 0, dwCount
* sizeof(FORMATETC
));
423 return E_OUTOFMEMORY
;
432 /* Register clipboard formats for the values and populate format list */
433 while(!dwRet
&& dwCount
< dwNumValues
)
435 dwKeySize
= sizeof(szKeyBuff
);
436 dwValueSize
= sizeof(szValueBuff
);
437 dwRet
= RegEnumValueA(hDocs
, dwCount
, szKeyBuff
, &dwKeySize
, 0, &dwType
,
438 (PBYTE
)szValueBuff
, &dwValueSize
);
442 format
->cfFormat
= RegisterClipboardFormatA(szValueBuff
);
444 format
->dwAspect
= 1;
453 /* Terminate the (maybe empty) list, last entry has a cfFormat of 0 */
454 format
->cfFormat
= 0;
456 format
->dwAspect
= 1;
460 /* Create a clipboard enumerator */
461 GET_FUNC(pCreateFormatEnumerator
, urlmon
, "CreateFormatEnumerator", E_FAIL
);
462 hRet
= pCreateFormatEnumerator(dwNumValues
, formatList
, &pIEnumFormatEtc
);
464 if (FAILED(hRet
) || !pIEnumFormatEtc
)
467 /* Set our enumerator as the browsers property */
468 V_VT(&var
) = VT_UNKNOWN
;
469 V_UNKNOWN(&var
) = (IUnknown
*)pIEnumFormatEtc
;
471 hRet
= IWebBrowserApp_PutProperty(pBrowser
, (BSTR
)szProperty
, var
);
474 IEnumFORMATETC_Release(pIEnumFormatEtc
);
475 goto RegisterDefaultAcceptHeaders_Exit
;
479 if (V_VT(&var
) == VT_UNKNOWN
)
481 /* Our variant is holding the clipboard enumerator */
482 IUnknown
* pIUnknown
= V_UNKNOWN(&var
);
483 IEnumFORMATETC
* pClone
= NULL
;
485 TRACE("Retrieved IEnumFORMATETC property\n");
487 /* Get an IEnumFormatEtc interface from the variants value */
488 pIEnumFormatEtc
= NULL
;
489 hRet
= IUnknown_QueryInterface(pIUnknown
, &IID_IEnumFORMATETC
,
490 (PVOID
)&pIEnumFormatEtc
);
491 if (!hRet
&& pIEnumFormatEtc
)
493 /* Clone and register the enumerator */
494 hRet
= IEnumFORMATETC_Clone(pIEnumFormatEtc
, &pClone
);
497 GET_FUNC(pRegisterFormatEnumerator
, urlmon
, "RegisterFormatEnumerator", E_FAIL
);
498 pRegisterFormatEnumerator(lpBC
, pClone
, 0);
500 IEnumFORMATETC_Release(pClone
);
503 /* Release the IEnumFormatEtc interface */
504 IEnumFORMATETC_Release(pIUnknown
);
506 IUnknown_Release(V_UNKNOWN(&var
));
509 RegisterDefaultAcceptHeaders_Exit
:
510 IWebBrowserApp_Release(pBrowser
);
514 /*************************************************************************
517 * Get Explorers "AcceptLanguage" setting.
520 * langbuf [O] Destination for language string
521 * buflen [I] Length of langbuf
522 * [0] Success: used length of langbuf
525 * Success: S_OK. langbuf is set to the language string found.
526 * Failure: E_FAIL, If any arguments are invalid, error occurred, or Explorer
527 * does not contain the setting.
528 * E_INVALIDARG, If the buffer is not big enough
530 HRESULT WINAPI
GetAcceptLanguagesW( LPWSTR langbuf
, LPDWORD buflen
)
532 static const WCHAR szkeyW
[] = {
533 'S','o','f','t','w','a','r','e','\\',
534 'M','i','c','r','o','s','o','f','t','\\',
535 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
536 'I','n','t','e','r','n','a','t','i','o','n','a','l',0};
537 static const WCHAR valueW
[] = {
538 'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0};
539 static const WCHAR enusW
[] = {'e','n','-','u','s',0};
540 DWORD mystrlen
, mytype
;
546 if(!langbuf
|| !buflen
|| !*buflen
)
549 mystrlen
= (*buflen
> 20) ? *buflen
: 20 ;
550 mystr
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
) * mystrlen
);
551 RegOpenKeyW(HKEY_CURRENT_USER
, szkeyW
, &mykey
);
552 if(RegQueryValueExW(mykey
, valueW
, 0, &mytype
, (PBYTE
)mystr
, &mystrlen
)) {
553 /* Did not find value */
554 mylcid
= GetUserDefaultLCID();
555 /* somehow the mylcid translates into "en-us"
556 * this is similar to "LOCALE_SABBREVLANGNAME"
557 * which could be gotten via GetLocaleInfo.
558 * The only problem is LOCALE_SABBREVLANGUAGE" is
559 * a 3 char string (first 2 are country code and third is
560 * letter for "sublanguage", which does not come close to
563 lstrcpyW(mystr
, enusW
);
564 mystrlen
= lstrlenW(mystr
);
566 /* handle returned string */
567 FIXME("missing code\n");
569 memcpy( langbuf
, mystr
, min(*buflen
,strlenW(mystr
)+1)*sizeof(WCHAR
) );
571 if(*buflen
> strlenW(mystr
)) {
572 *buflen
= strlenW(mystr
);
576 retval
= E_INVALIDARG
;
577 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
580 HeapFree(GetProcessHeap(), 0, mystr
);
584 /*************************************************************************
587 * Ascii version of GetAcceptLanguagesW.
589 HRESULT WINAPI
GetAcceptLanguagesA( LPSTR langbuf
, LPDWORD buflen
)
592 DWORD buflenW
, convlen
;
595 if(!langbuf
|| !buflen
|| !*buflen
) return E_FAIL
;
598 langbufW
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
) * buflenW
);
599 retval
= GetAcceptLanguagesW(langbufW
, &buflenW
);
601 /* FIXME: this is wrong, the string may not be null-terminated */
602 convlen
= WideCharToMultiByte(CP_ACP
, 0, langbufW
, -1, langbuf
,
603 *buflen
, NULL
, NULL
);
604 *buflen
= buflenW
? convlen
: 0;
606 HeapFree(GetProcessHeap(), 0, langbufW
);
610 /*************************************************************************
613 * Convert a GUID to a string.
616 * guid [I] GUID to convert
617 * lpszDest [O] Destination for string
618 * cchMax [I] Length of output buffer
621 * The length of the string created.
623 INT WINAPI
SHStringFromGUIDA(REFGUID guid
, LPSTR lpszDest
, INT cchMax
)
628 TRACE("(%s,%p,%d)\n", debugstr_guid(guid
), lpszDest
, cchMax
);
630 sprintf(xguid
, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
631 guid
->Data1
, guid
->Data2
, guid
->Data3
,
632 guid
->Data4
[0], guid
->Data4
[1], guid
->Data4
[2], guid
->Data4
[3],
633 guid
->Data4
[4], guid
->Data4
[5], guid
->Data4
[6], guid
->Data4
[7]);
635 iLen
= strlen(xguid
) + 1;
639 memcpy(lpszDest
, xguid
, iLen
);
643 /*************************************************************************
646 * Convert a GUID to a string.
649 * guid [I] GUID to convert
650 * str [O] Destination for string
651 * cmax [I] Length of output buffer
654 * The length of the string created.
656 INT WINAPI
SHStringFromGUIDW(REFGUID guid
, LPWSTR lpszDest
, INT cchMax
)
660 static const WCHAR wszFormat
[] = {'{','%','0','8','l','X','-','%','0','4','X','-','%','0','4','X','-',
661 '%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','%','0','2','X','%','0','2',
662 'X','%','0','2','X','%','0','2','X','}',0};
664 TRACE("(%s,%p,%d)\n", debugstr_guid(guid
), lpszDest
, cchMax
);
666 sprintfW(xguid
, wszFormat
, guid
->Data1
, guid
->Data2
, guid
->Data3
,
667 guid
->Data4
[0], guid
->Data4
[1], guid
->Data4
[2], guid
->Data4
[3],
668 guid
->Data4
[4], guid
->Data4
[5], guid
->Data4
[6], guid
->Data4
[7]);
670 iLen
= strlenW(xguid
) + 1;
674 memcpy(lpszDest
, xguid
, iLen
*sizeof(WCHAR
));
678 /*************************************************************************
681 * Determine if a Unicode character is a space.
684 * wc [I] Character to check.
687 * TRUE, if wc is a space,
690 BOOL WINAPI
IsCharSpaceW(WCHAR wc
)
694 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_SPACE
);
697 /*************************************************************************
700 * Determine if a Unicode character is a blank.
703 * wc [I] Character to check.
706 * TRUE, if wc is a blank,
710 BOOL WINAPI
IsCharBlankW(WCHAR wc
)
714 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_BLANK
);
717 /*************************************************************************
720 * Determine if a Unicode character is punctuation.
723 * wc [I] Character to check.
726 * TRUE, if wc is punctuation,
729 BOOL WINAPI
IsCharPunctW(WCHAR wc
)
733 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_PUNCT
);
736 /*************************************************************************
739 * Determine if a Unicode character is a control character.
742 * wc [I] Character to check.
745 * TRUE, if wc is a control character,
748 BOOL WINAPI
IsCharCntrlW(WCHAR wc
)
752 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_CNTRL
);
755 /*************************************************************************
758 * Determine if a Unicode character is a digit.
761 * wc [I] Character to check.
764 * TRUE, if wc is a digit,
767 BOOL WINAPI
IsCharDigitW(WCHAR wc
)
771 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_DIGIT
);
774 /*************************************************************************
777 * Determine if a Unicode character is a hex digit.
780 * wc [I] Character to check.
783 * TRUE, if wc is a hex digit,
786 BOOL WINAPI
IsCharXDigitW(WCHAR wc
)
790 return GetStringTypeW(CT_CTYPE1
, &wc
, 1, &CharType
) && (CharType
& C1_XDIGIT
);
793 /*************************************************************************
797 BOOL WINAPI
GetStringType3ExW(LPWSTR lpszStr
, DWORD dwLen
, LPVOID p3
)
799 FIXME("(%s,0x%08lx,%p): stub\n", debugstr_w(lpszStr
), dwLen
, p3
);
803 /*************************************************************************
806 * Insert a bitmap menu item at the bottom of a menu.
809 * hMenu [I] Menu to insert into
810 * flags [I] Flags for insertion
811 * id [I] Menu ID of the item
812 * str [I] Menu text for the item
815 * Success: TRUE, the item is inserted into the menu
816 * Failure: FALSE, if any parameter is invalid
818 BOOL WINAPI
AppendMenuWrapW(HMENU hMenu
, UINT flags
, UINT id
, LPCWSTR str
)
820 TRACE("(%p,0x%08x,0x%08x,%s)\n",hMenu
, flags
, id
, debugstr_w(str
));
821 return InsertMenuW(hMenu
, -1, flags
| MF_BITMAP
, id
, str
);
824 /*************************************************************************
827 * Get the text from a given dialog item.
830 * hWnd [I] Handle of dialog
831 * nItem [I] Index of item
832 * lpsDest [O] Buffer for receiving window text
833 * nDestLen [I] Length of buffer.
836 * Success: The length of the returned text.
839 INT WINAPI
GetDlgItemTextWrapW(HWND hWnd
, INT nItem
, LPWSTR lpsDest
,INT nDestLen
)
841 HWND hItem
= GetDlgItem(hWnd
, nItem
);
844 return GetWindowTextW(hItem
, lpsDest
, nDestLen
);
846 *lpsDest
= (WCHAR
)'\0';
850 /*************************************************************************
853 * Set the text of a given dialog item.
856 * hWnd [I] Handle of dialog
857 * iItem [I] Index of item
858 * lpszText [O] Text to set
861 * Success: TRUE. The text of the dialog is set to lpszText.
862 * Failure: FALSE, Otherwise.
864 BOOL WINAPI
SetDlgItemTextWrapW(HWND hWnd
, INT iItem
, LPCWSTR lpszText
)
866 HWND hWndItem
= GetDlgItem(hWnd
, iItem
);
868 return SetWindowTextW(hWndItem
, lpszText
);
872 /*************************************************************************
875 * Compare two Ascii strings up to a given length.
878 * lpszSrc [I] Source string
879 * lpszCmp [I] String to compare to lpszSrc
880 * len [I] Maximum length
883 * A number greater than, less than or equal to 0 depending on whether
884 * lpszSrc is greater than, less than or equal to lpszCmp.
886 DWORD WINAPI
StrCmpNCA(LPCSTR lpszSrc
, LPCSTR lpszCmp
, INT len
)
888 return strncmp(lpszSrc
, lpszCmp
, len
);
891 /*************************************************************************
894 * Unicode version of StrCmpNCA.
896 DWORD WINAPI
StrCmpNCW(LPCWSTR lpszSrc
, LPCWSTR lpszCmp
, INT len
)
898 return strncmpW(lpszSrc
, lpszCmp
, len
);
901 /*************************************************************************
904 * Compare two Ascii strings up to a given length, ignoring case.
907 * lpszSrc [I] Source string
908 * lpszCmp [I] String to compare to lpszSrc
909 * len [I] Maximum length
912 * A number greater than, less than or equal to 0 depending on whether
913 * lpszSrc is greater than, less than or equal to lpszCmp.
915 DWORD WINAPI
StrCmpNICA(LPCSTR lpszSrc
, LPCSTR lpszCmp
, DWORD len
)
917 return strncasecmp(lpszSrc
, lpszCmp
, len
);
920 /*************************************************************************
923 * Unicode version of StrCmpNICA.
925 DWORD WINAPI
StrCmpNICW(LPCWSTR lpszSrc
, LPCWSTR lpszCmp
, DWORD len
)
927 return strncmpiW(lpszSrc
, lpszCmp
, len
);
930 /*************************************************************************
933 * Compare two Ascii strings.
936 * lpszSrc [I] Source string
937 * lpszCmp [I] String to compare to lpszSrc
940 * A number greater than, less than or equal to 0 depending on whether
941 * lpszSrc is greater than, less than or equal to lpszCmp.
943 DWORD WINAPI
StrCmpCA(LPCSTR lpszSrc
, LPCSTR lpszCmp
)
945 return strcmp(lpszSrc
, lpszCmp
);
948 /*************************************************************************
951 * Unicode version of StrCmpCA.
953 DWORD WINAPI
StrCmpCW(LPCWSTR lpszSrc
, LPCWSTR lpszCmp
)
955 return strcmpW(lpszSrc
, lpszCmp
);
958 /*************************************************************************
961 * Compare two Ascii strings, ignoring case.
964 * lpszSrc [I] Source string
965 * lpszCmp [I] String to compare to lpszSrc
968 * A number greater than, less than or equal to 0 depending on whether
969 * lpszSrc is greater than, less than or equal to lpszCmp.
971 DWORD WINAPI
StrCmpICA(LPCSTR lpszSrc
, LPCSTR lpszCmp
)
973 return strcasecmp(lpszSrc
, lpszCmp
);
976 /*************************************************************************
979 * Unicode version of StrCmpICA.
981 DWORD WINAPI
StrCmpICW(LPCWSTR lpszSrc
, LPCWSTR lpszCmp
)
983 return strcmpiW(lpszSrc
, lpszCmp
);
986 /*************************************************************************
989 * Get an identification string for the OS and explorer.
992 * lpszDest [O] Destination for Id string
993 * dwDestLen [I] Length of lpszDest
996 * TRUE, If the string was created successfully
999 BOOL WINAPI
SHAboutInfoA(LPSTR lpszDest
, DWORD dwDestLen
)
1003 TRACE("(%p,%ld)\n", lpszDest
, dwDestLen
);
1005 if (lpszDest
&& SHAboutInfoW(buff
, dwDestLen
))
1007 WideCharToMultiByte(CP_ACP
, 0, buff
, -1, lpszDest
, dwDestLen
, NULL
, NULL
);
1013 /*************************************************************************
1016 * Unicode version of SHAboutInfoA.
1018 BOOL WINAPI
SHAboutInfoW(LPWSTR lpszDest
, DWORD dwDestLen
)
1020 static const WCHAR szIEKey
[] = { 'S','O','F','T','W','A','R','E','\\',
1021 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
1022 ' ','E','x','p','l','o','r','e','r','\0' };
1023 static const WCHAR szWinNtKey
[] = { 'S','O','F','T','W','A','R','E','\\',
1024 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s',' ',
1025 'N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
1026 static const WCHAR szWinKey
[] = { 'S','O','F','T','W','A','R','E','\\',
1027 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
1028 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
1029 static const WCHAR szRegKey
[] = { 'S','O','F','T','W','A','R','E','\\',
1030 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
1031 ' ','E','x','p','l','o','r','e','r','\\',
1032 'R','e','g','i','s','t','r','a','t','i','o','n','\0' };
1033 static const WCHAR szVersion
[] = { 'V','e','r','s','i','o','n','\0' };
1034 static const WCHAR szCustomized
[] = { 'C','u','s','t','o','m','i','z','e','d',
1035 'V','e','r','s','i','o','n','\0' };
1036 static const WCHAR szOwner
[] = { 'R','e','g','i','s','t','e','r','e','d',
1037 'O','w','n','e','r','\0' };
1038 static const WCHAR szOrg
[] = { 'R','e','g','i','s','t','e','r','e','d',
1039 'O','r','g','a','n','i','z','a','t','i','o','n','\0' };
1040 static const WCHAR szProduct
[] = { 'P','r','o','d','u','c','t','I','d','\0' };
1041 static const WCHAR szUpdate
[] = { 'I','E','A','K',
1042 'U','p','d','a','t','e','U','r','l','\0' };
1043 static const WCHAR szHelp
[] = { 'I','E','A','K',
1044 'H','e','l','p','S','t','r','i','n','g','\0' };
1047 DWORD dwType
, dwLen
;
1049 TRACE("(%p,%ld)\n", lpszDest
, dwDestLen
);
1056 /* Try the NT key first, followed by 95/98 key */
1057 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szWinNtKey
, 0, KEY_READ
, &hReg
) &&
1058 RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szWinKey
, 0, KEY_READ
, &hReg
))
1064 if (!SHGetValueW(HKEY_LOCAL_MACHINE
, szIEKey
, szVersion
, &dwType
, buff
, &dwLen
))
1066 DWORD dwStrLen
= strlenW(buff
);
1067 dwLen
= 30 - dwStrLen
;
1068 SHGetValueW(HKEY_LOCAL_MACHINE
, szIEKey
,
1069 szCustomized
, &dwType
, buff
+dwStrLen
, &dwLen
);
1071 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
1073 /* ~Registered Owner */
1076 if (SHGetValueW(hReg
, szOwner
, 0, &dwType
, buff
+1, &dwLen
))
1078 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
1080 /* ~Registered Organization */
1082 if (SHGetValueW(hReg
, szOrg
, 0, &dwType
, buff
+1, &dwLen
))
1084 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
1086 /* FIXME: Not sure where this number comes from */
1090 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
1094 if (SHGetValueW(HKEY_LOCAL_MACHINE
, szRegKey
, szProduct
, &dwType
, buff
+1, &dwLen
))
1096 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
1098 /* ~IE Update Url */
1100 if(SHGetValueW(HKEY_LOCAL_MACHINE
, szWinKey
, szUpdate
, &dwType
, buff
+1, &dwLen
))
1102 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
1104 /* ~IE Help String */
1106 if(SHGetValueW(hReg
, szHelp
, 0, &dwType
, buff
+1, &dwLen
))
1108 StrCatBuffW(lpszDest
, buff
, dwDestLen
);
1114 /*************************************************************************
1117 * Call IOleCommandTarget_QueryStatus() on an object.
1120 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1121 * pguidCmdGroup [I] GUID for the command group
1123 * prgCmds [O] Commands
1124 * pCmdText [O] Command text
1128 * Failure: E_FAIL, if lpUnknown is NULL.
1129 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1130 * Otherwise, an error code from IOleCommandTarget_QueryStatus().
1132 HRESULT WINAPI
IUnknown_QueryStatus(IUnknown
* lpUnknown
, REFGUID pguidCmdGroup
,
1133 ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
* pCmdText
)
1135 HRESULT hRet
= E_FAIL
;
1137 TRACE("(%p,%p,%ld,%p,%p)\n",lpUnknown
, pguidCmdGroup
, cCmds
, prgCmds
, pCmdText
);
1141 IOleCommandTarget
* lpOle
;
1143 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleCommandTarget
,
1146 if (SUCCEEDED(hRet
) && lpOle
)
1148 hRet
= IOleCommandTarget_QueryStatus(lpOle
, pguidCmdGroup
, cCmds
,
1150 IOleCommandTarget_Release(lpOle
);
1156 /*************************************************************************
1159 * Call IOleCommandTarget_Exec() on an object.
1162 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1163 * pguidCmdGroup [I] GUID for the command group
1167 * Failure: E_FAIL, if lpUnknown is NULL.
1168 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1169 * Otherwise, an error code from IOleCommandTarget_Exec().
1171 HRESULT WINAPI
IUnknown_Exec(IUnknown
* lpUnknown
, REFGUID pguidCmdGroup
,
1172 DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
* pvaIn
,
1175 HRESULT hRet
= E_FAIL
;
1177 TRACE("(%p,%p,%ld,%ld,%p,%p)\n",lpUnknown
, pguidCmdGroup
, nCmdID
,
1178 nCmdexecopt
, pvaIn
, pvaOut
);
1182 IOleCommandTarget
* lpOle
;
1184 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleCommandTarget
,
1186 if (SUCCEEDED(hRet
) && lpOle
)
1188 hRet
= IOleCommandTarget_Exec(lpOle
, pguidCmdGroup
, nCmdID
,
1189 nCmdexecopt
, pvaIn
, pvaOut
);
1190 IOleCommandTarget_Release(lpOle
);
1196 /*************************************************************************
1199 * Retrieve, modify, and re-set a value from a window.
1202 * hWnd [I] Window to get value from
1203 * offset [I] Offset of value
1204 * wMask [I] Mask for uiFlags
1205 * wFlags [I] Bits to set in window value
1208 * The new value as it was set, or 0 if any parameter is invalid.
1211 * Any bits set in uiMask are cleared from the value, then any bits set in
1212 * uiFlags are set in the value.
1214 LONG WINAPI
SHSetWindowBits(HWND hwnd
, INT offset
, UINT wMask
, UINT wFlags
)
1216 LONG ret
= GetWindowLongA(hwnd
, offset
);
1217 LONG newFlags
= (wFlags
& wMask
) | (ret
& ~wFlags
);
1219 if (newFlags
!= ret
)
1220 ret
= SetWindowLongA(hwnd
, offset
, newFlags
);
1224 /*************************************************************************
1227 * Change a window's parent.
1230 * hWnd [I] Window to change parent of
1231 * hWndParent [I] New parent window
1234 * The old parent of hWnd.
1237 * If hWndParent is NULL (desktop), the window style is changed to WS_POPUP.
1238 * If hWndParent is NOT NULL then we set the WS_CHILD style.
1240 HWND WINAPI
SHSetParentHwnd(HWND hWnd
, HWND hWndParent
)
1242 TRACE("%p, %p\n", hWnd
, hWndParent
);
1244 if(GetParent(hWnd
) == hWndParent
)
1248 SHSetWindowBits(hWnd
, GWL_STYLE
, WS_CHILD
, WS_CHILD
);
1250 SHSetWindowBits(hWnd
, GWL_STYLE
, WS_POPUP
, WS_POPUP
);
1252 return SetParent(hWnd
, hWndParent
);
1255 /*************************************************************************
1258 * Locate and advise a connection point in an IConnectionPointContainer object.
1261 * lpUnkSink [I] Sink for the connection point advise call
1262 * riid [I] REFIID of connection point to advise
1263 * bAdviseOnly [I] TRUE = Advise only, FALSE = Unadvise first
1264 * lpUnknown [I] Object supporting the IConnectionPointContainer interface
1265 * lpCookie [O] Pointer to connection point cookie
1266 * lppCP [O] Destination for the IConnectionPoint found
1269 * Success: S_OK. If lppCP is non-NULL, it is filled with the IConnectionPoint
1270 * that was advised. The caller is responsible for releasing it.
1271 * Failure: E_FAIL, if any arguments are invalid.
1272 * E_NOINTERFACE, if lpUnknown isn't an IConnectionPointContainer,
1273 * Or an HRESULT error code if any call fails.
1275 HRESULT WINAPI
ConnectToConnectionPoint(IUnknown
* lpUnkSink
, REFIID riid
, BOOL bAdviseOnly
,
1276 IUnknown
* lpUnknown
, LPDWORD lpCookie
,
1277 IConnectionPoint
**lppCP
)
1280 IConnectionPointContainer
* lpContainer
;
1281 IConnectionPoint
*lpCP
;
1283 if(!lpUnknown
|| (bAdviseOnly
&& !lpUnkSink
))
1289 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IConnectionPointContainer
,
1290 (void**)&lpContainer
);
1291 if (SUCCEEDED(hRet
))
1293 hRet
= IConnectionPointContainer_FindConnectionPoint(lpContainer
, riid
, &lpCP
);
1295 if (SUCCEEDED(hRet
))
1298 hRet
= IConnectionPoint_Unadvise(lpCP
, *lpCookie
);
1299 hRet
= IConnectionPoint_Advise(lpCP
, lpUnkSink
, lpCookie
);
1304 if (lppCP
&& SUCCEEDED(hRet
))
1305 *lppCP
= lpCP
; /* Caller keeps the interface */
1307 IConnectionPoint_Release(lpCP
); /* Release it */
1310 IUnknown_Release(lpContainer
);
1315 /*************************************************************************
1318 * Release an interface.
1321 * lpUnknown [I] Object to release
1326 DWORD WINAPI
IUnknown_AtomicRelease(IUnknown
** lpUnknown
)
1330 TRACE("(%p)\n",lpUnknown
);
1332 if(!lpUnknown
|| !*((LPDWORD
)lpUnknown
)) return 0;
1336 TRACE("doing Release\n");
1338 return IUnknown_Release(temp
);
1341 /*************************************************************************
1344 * Skip '//' if present in a string.
1347 * lpszSrc [I] String to check for '//'
1350 * Success: The next character after the '//' or the string if not present
1351 * Failure: NULL, if lpszStr is NULL.
1353 LPCSTR WINAPI
PathSkipLeadingSlashesA(LPCSTR lpszSrc
)
1355 if (lpszSrc
&& lpszSrc
[0] == '/' && lpszSrc
[1] == '/')
1360 /*************************************************************************
1363 * Check if two interfaces come from the same object.
1366 * lpInt1 [I] Interface to check against lpInt2.
1367 * lpInt2 [I] Interface to check against lpInt1.
1370 * TRUE, If the interfaces come from the same object.
1373 BOOL WINAPI
SHIsSameObject(IUnknown
* lpInt1
, IUnknown
* lpInt2
)
1375 LPVOID lpUnknown1
, lpUnknown2
;
1377 TRACE("%p %p\n", lpInt1
, lpInt2
);
1379 if (!lpInt1
|| !lpInt2
)
1382 if (lpInt1
== lpInt2
)
1385 if (!SUCCEEDED(IUnknown_QueryInterface(lpInt1
, &IID_IUnknown
,
1386 (LPVOID
*)&lpUnknown1
)))
1389 if (!SUCCEEDED(IUnknown_QueryInterface(lpInt2
, &IID_IUnknown
,
1390 (LPVOID
*)&lpUnknown2
)))
1393 if (lpUnknown1
== lpUnknown2
)
1399 /*************************************************************************
1402 * Get the window handle of an object.
1405 * lpUnknown [I] Object to get the window handle of
1406 * lphWnd [O] Destination for window handle
1409 * Success: S_OK. lphWnd contains the objects window handle.
1410 * Failure: An HRESULT error code.
1413 * lpUnknown is expected to support one of the following interfaces:
1414 * IOleWindow(), IInternetSecurityMgrSite(), or IShellView().
1416 HRESULT WINAPI
IUnknown_GetWindow(IUnknown
*lpUnknown
, HWND
*lphWnd
)
1418 /* FIXME: Wine has no header for this object */
1419 static const GUID IID_IInternetSecurityMgrSite
= { 0x79eac9ed,
1420 0xbaf9, 0x11ce, { 0x8c, 0x82, 0x00, 0xaa, 0x00, 0x4b, 0xa9, 0x0b }};
1422 HRESULT hRet
= E_FAIL
;
1424 TRACE("(%p,%p)\n", lpUnknown
, lphWnd
);
1429 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleWindow
, (void**)&lpOle
);
1433 hRet
= IUnknown_QueryInterface(lpUnknown
,&IID_IShellView
, (void**)&lpOle
);
1437 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IInternetSecurityMgrSite
,
1442 if (SUCCEEDED(hRet
))
1444 /* Lazyness here - Since GetWindow() is the first method for the above 3
1445 * interfaces, we use the same call for them all.
1447 hRet
= IOleWindow_GetWindow((IOleWindow
*)lpOle
, lphWnd
);
1448 IUnknown_Release(lpOle
);
1450 TRACE("Returning HWND=%p\n", *lphWnd
);
1456 /*************************************************************************
1459 * Call a method on as as yet unidentified object.
1462 * pUnk [I] Object supporting the unidentified interface,
1463 * arg [I] Argument for the call on the object.
1468 HRESULT WINAPI
IUnknown_SetOwner(IUnknown
*pUnk
, ULONG arg
)
1470 static const GUID guid_173
= {
1471 0x5836fb00, 0x8187, 0x11cf, { 0xa1,0x2b,0x00,0xaa,0x00,0x4a,0xe8,0x37 }
1475 TRACE("(%p,%ld)\n", pUnk
, arg
);
1477 /* Note: arg may not be a ULONG and pUnk2 is for sure not an IMalloc -
1478 * We use this interface as its vtable entry is compatible with the
1479 * object in question.
1480 * FIXME: Find out what this object is and where it should be defined.
1483 SUCCEEDED(IUnknown_QueryInterface(pUnk
, &guid_173
, (void**)&pUnk2
)))
1485 IMalloc_Alloc(pUnk2
, arg
); /* Faked call!! */
1486 IMalloc_Release(pUnk2
);
1491 /*************************************************************************
1494 * Call either IObjectWithSite_SetSite() or IInternetSecurityManager_SetSecuritySite() on
1498 HRESULT WINAPI
IUnknown_SetSite(
1499 IUnknown
*obj
, /* [in] OLE object */
1500 IUnknown
*site
) /* [in] Site interface */
1503 IObjectWithSite
*iobjwithsite
;
1504 IInternetSecurityManager
*isecmgr
;
1506 if (!obj
) return E_FAIL
;
1508 hr
= IUnknown_QueryInterface(obj
, &IID_IObjectWithSite
, (LPVOID
*)&iobjwithsite
);
1509 TRACE("IID_IObjectWithSite QI ret=%08lx, %p\n", hr
, iobjwithsite
);
1512 hr
= IObjectWithSite_SetSite(iobjwithsite
, site
);
1513 TRACE("done IObjectWithSite_SetSite ret=%08lx\n", hr
);
1514 IUnknown_Release(iobjwithsite
);
1518 hr
= IUnknown_QueryInterface(obj
, &IID_IInternetSecurityManager
, (LPVOID
*)&isecmgr
);
1519 TRACE("IID_IInternetSecurityManager QI ret=%08lx, %p\n", hr
, isecmgr
);
1520 if (FAILED(hr
)) return hr
;
1522 hr
= IInternetSecurityManager_SetSecuritySite(isecmgr
, (IInternetSecurityMgrSite
*)site
);
1523 TRACE("done IInternetSecurityManager_SetSecuritySite ret=%08lx\n", hr
);
1524 IUnknown_Release(isecmgr
);
1529 /*************************************************************************
1532 * Call IPersist_GetClassID() on an object.
1535 * lpUnknown [I] Object supporting the IPersist interface
1536 * lpClassId [O] Destination for Class Id
1539 * Success: S_OK. lpClassId contains the Class Id requested.
1540 * Failure: E_FAIL, If lpUnknown is NULL,
1541 * E_NOINTERFACE If lpUnknown does not support IPersist,
1542 * Or an HRESULT error code.
1544 HRESULT WINAPI
IUnknown_GetClassID(IUnknown
*lpUnknown
, CLSID
* lpClassId
)
1546 IPersist
* lpPersist
;
1547 HRESULT hRet
= E_FAIL
;
1549 TRACE("(%p,%p)\n", lpUnknown
, debugstr_guid(lpClassId
));
1553 hRet
= IUnknown_QueryInterface(lpUnknown
,&IID_IPersist
,(void**)&lpPersist
);
1554 if (SUCCEEDED(hRet
))
1556 IPersist_GetClassID(lpPersist
, lpClassId
);
1557 IPersist_Release(lpPersist
);
1563 /*************************************************************************
1566 * Retrieve a Service Interface from an object.
1569 * lpUnknown [I] Object to get an IServiceProvider interface from
1570 * sid [I] Service ID for IServiceProvider_QueryService() call
1571 * riid [I] Function requested for QueryService call
1572 * lppOut [O] Destination for the service interface pointer
1575 * Success: S_OK. lppOut contains an object providing the requested service
1576 * Failure: An HRESULT error code
1579 * lpUnknown is expected to support the IServiceProvider interface.
1581 HRESULT WINAPI
IUnknown_QueryService(IUnknown
* lpUnknown
, REFGUID sid
, REFIID riid
,
1584 IServiceProvider
* pService
= NULL
;
1595 /* Get an IServiceProvider interface from the object */
1596 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IServiceProvider
,
1597 (LPVOID
*)&pService
);
1599 if (!hRet
&& pService
)
1601 TRACE("QueryInterface returned (IServiceProvider*)%p\n", pService
);
1603 /* Get a Service interface from the object */
1604 hRet
= IServiceProvider_QueryService(pService
, sid
, riid
, lppOut
);
1606 TRACE("(IServiceProvider*)%p returned (IUnknown*)%p\n", pService
, *lppOut
);
1608 /* Release the IServiceProvider interface */
1609 IUnknown_Release(pService
);
1614 /*************************************************************************
1617 * Loads a popup menu.
1620 * hInst [I] Instance handle
1621 * szName [I] Menu name
1627 BOOL WINAPI
SHLoadMenuPopup(HINSTANCE hInst
, LPCWSTR szName
)
1629 HMENU hMenu
, hSubMenu
;
1631 if ((hMenu
= LoadMenuW(hInst
, szName
)))
1633 if ((hSubMenu
= GetSubMenu(hMenu
, 0)))
1634 RemoveMenu(hMenu
, 0, MF_BYPOSITION
);
1642 typedef struct _enumWndData
1647 LRESULT (WINAPI
*pfnPost
)(HWND
,UINT
,WPARAM
,LPARAM
);
1650 /* Callback for SHLWAPI_178 */
1651 static BOOL CALLBACK
SHLWAPI_EnumChildProc(HWND hWnd
, LPARAM lParam
)
1653 enumWndData
*data
= (enumWndData
*)lParam
;
1655 TRACE("(%p,%p)\n", hWnd
, data
);
1656 data
->pfnPost(hWnd
, data
->uiMsgId
, data
->wParam
, data
->lParam
);
1660 /*************************************************************************
1663 * Send or post a message to every child of a window.
1666 * hWnd [I] Window whose children will get the messages
1667 * uiMsgId [I] Message Id
1668 * wParam [I] WPARAM of message
1669 * lParam [I] LPARAM of message
1670 * bSend [I] TRUE = Use SendMessageA(), FALSE = Use PostMessageA()
1676 * The appropriate ASCII or Unicode function is called for the window.
1678 void WINAPI
SHPropagateMessage(HWND hWnd
, UINT uiMsgId
, WPARAM wParam
, LPARAM lParam
, BOOL bSend
)
1682 TRACE("(%p,%u,%d,%ld,%d)\n", hWnd
, uiMsgId
, wParam
, lParam
, bSend
);
1686 data
.uiMsgId
= uiMsgId
;
1687 data
.wParam
= wParam
;
1688 data
.lParam
= lParam
;
1691 data
.pfnPost
= IsWindowUnicode(hWnd
) ? (void*)SendMessageW
: (void*)SendMessageA
;
1693 data
.pfnPost
= IsWindowUnicode(hWnd
) ? (void*)PostMessageW
: (void*)PostMessageA
;
1695 EnumChildWindows(hWnd
, SHLWAPI_EnumChildProc
, (LPARAM
)&data
);
1699 /*************************************************************************
1702 * Remove all sub-menus from a menu.
1705 * hMenu [I] Menu to remove sub-menus from
1708 * Success: 0. All sub-menus under hMenu are removed
1709 * Failure: -1, if any parameter is invalid
1711 DWORD WINAPI
SHRemoveAllSubMenus(HMENU hMenu
)
1713 int iItemCount
= GetMenuItemCount(hMenu
) - 1;
1714 while (iItemCount
>= 0)
1716 HMENU hSubMenu
= GetSubMenu(hMenu
, iItemCount
);
1718 RemoveMenu(hMenu
, iItemCount
, MF_BYPOSITION
);
1724 /*************************************************************************
1727 * Enable or disable a menu item.
1730 * hMenu [I] Menu holding menu item
1731 * uID [I] ID of menu item to enable/disable
1732 * bEnable [I] Whether to enable (TRUE) or disable (FALSE) the item.
1735 * The return code from EnableMenuItem.
1737 UINT WINAPI
SHEnableMenuItem(HMENU hMenu
, UINT wItemID
, BOOL bEnable
)
1739 return EnableMenuItem(hMenu
, wItemID
, bEnable
? MF_ENABLED
: MF_GRAYED
);
1742 /*************************************************************************
1745 * Check or uncheck a menu item.
1748 * hMenu [I] Menu holding menu item
1749 * uID [I] ID of menu item to check/uncheck
1750 * bCheck [I] Whether to check (TRUE) or uncheck (FALSE) the item.
1753 * The return code from CheckMenuItem.
1755 DWORD WINAPI
SHCheckMenuItem(HMENU hMenu
, UINT uID
, BOOL bCheck
)
1757 return CheckMenuItem(hMenu
, uID
, bCheck
? MF_CHECKED
: MF_UNCHECKED
);
1760 /*************************************************************************
1763 * Register a window class if it isn't already.
1766 * lpWndClass [I] Window class to register
1769 * The result of the RegisterClassA call.
1771 DWORD WINAPI
SHRegisterClassA(WNDCLASSA
*wndclass
)
1774 if (GetClassInfoA(wndclass
->hInstance
, wndclass
->lpszClassName
, &wca
))
1776 return (DWORD
)RegisterClassA(wndclass
);
1779 /*************************************************************************
1782 BOOL WINAPI
SHSimulateDrop(IDropTarget
*pDrop
, IDataObject
*pDataObj
,
1783 DWORD grfKeyState
, PPOINTL lpPt
, DWORD
* pdwEffect
)
1785 DWORD dwEffect
= DROPEFFECT_LINK
| DROPEFFECT_MOVE
| DROPEFFECT_COPY
;
1786 POINTL pt
= { 0, 0 };
1792 pdwEffect
= &dwEffect
;
1794 IDropTarget_DragEnter(pDrop
, pDataObj
, grfKeyState
, *lpPt
, pdwEffect
);
1797 return IDropTarget_Drop(pDrop
, pDataObj
, grfKeyState
, *lpPt
, pdwEffect
);
1799 IDropTarget_DragLeave(pDrop
);
1803 /*************************************************************************
1806 * Call IPersistPropertyBag_Load() on an object.
1809 * lpUnknown [I] Object supporting the IPersistPropertyBag interface
1810 * lpPropBag [O] Destination for loaded IPropertyBag
1814 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1816 DWORD WINAPI
SHLoadFromPropertyBag(IUnknown
*lpUnknown
, IPropertyBag
* lpPropBag
)
1818 IPersistPropertyBag
* lpPPBag
;
1819 HRESULT hRet
= E_FAIL
;
1821 TRACE("(%p,%p)\n", lpUnknown
, lpPropBag
);
1825 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IPersistPropertyBag
,
1827 if (SUCCEEDED(hRet
) && lpPPBag
)
1829 hRet
= IPersistPropertyBag_Load(lpPPBag
, lpPropBag
, NULL
);
1830 IPersistPropertyBag_Release(lpPPBag
);
1836 /*************************************************************************
1839 * Call IOleControlSite_TranslateAccelerator() on an object.
1842 * lpUnknown [I] Object supporting the IOleControlSite interface.
1843 * lpMsg [I] Key message to be processed.
1844 * dwModifiers [I] Flags containing the state of the modifier keys.
1848 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
1850 HRESULT WINAPI
IUnknown_TranslateAcceleratorOCS(IUnknown
*lpUnknown
, LPMSG lpMsg
, DWORD dwModifiers
)
1852 IOleControlSite
* lpCSite
= NULL
;
1853 HRESULT hRet
= E_INVALIDARG
;
1855 TRACE("(%p,%p,0x%08lx)\n", lpUnknown
, lpMsg
, dwModifiers
);
1858 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleControlSite
,
1860 if (SUCCEEDED(hRet
) && lpCSite
)
1862 hRet
= IOleControlSite_TranslateAccelerator(lpCSite
, lpMsg
, dwModifiers
);
1863 IOleControlSite_Release(lpCSite
);
1870 /*************************************************************************
1873 * Call IOleControlSite_GetExtendedControl() on an object.
1876 * lpUnknown [I] Object supporting the IOleControlSite interface.
1877 * lppDisp [O] Destination for resulting IDispatch.
1881 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1883 DWORD WINAPI
IUnknown_OnFocusOCS(IUnknown
*lpUnknown
, IDispatch
** lppDisp
)
1885 IOleControlSite
* lpCSite
= NULL
;
1886 HRESULT hRet
= E_FAIL
;
1888 TRACE("(%p,%p)\n", lpUnknown
, lppDisp
);
1891 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IOleControlSite
,
1893 if (SUCCEEDED(hRet
) && lpCSite
)
1895 hRet
= IOleControlSite_GetExtendedControl(lpCSite
, lppDisp
);
1896 IOleControlSite_Release(lpCSite
);
1902 /*************************************************************************
1905 HRESULT WINAPI
IUnknown_HandleIRestrict(LPUNKNOWN lpUnknown
, PVOID lpArg1
,
1906 PVOID lpArg2
, PVOID lpArg3
, PVOID lpArg4
)
1908 /* FIXME: {D12F26B2-D90A-11D0-830D-00AA005B4383} - What object does this represent? */
1909 static const DWORD service_id
[] = { 0xd12f26b2, 0x11d0d90a, 0xaa000d83, 0x83435b00 };
1910 /* FIXME: {D12F26B1-D90A-11D0-830D-00AA005B4383} - Also Unknown/undocumented */
1911 static const DWORD function_id
[] = { 0xd12f26b1, 0x11d0d90a, 0xaa000d83, 0x83435b00 };
1912 HRESULT hRet
= E_INVALIDARG
;
1913 LPUNKNOWN lpUnkInner
= NULL
; /* FIXME: Real type is unknown */
1915 TRACE("(%p,%p,%p,%p,%p)\n", lpUnknown
, lpArg1
, lpArg2
, lpArg3
, lpArg4
);
1917 if (lpUnknown
&& lpArg4
)
1919 hRet
= IUnknown_QueryService(lpUnknown
, (REFGUID
)service_id
,
1920 (REFGUID
)function_id
, (void**)&lpUnkInner
);
1922 if (SUCCEEDED(hRet
) && lpUnkInner
)
1924 /* FIXME: The type of service object requested is unknown, however
1925 * testing shows that its first method is called with 4 parameters.
1926 * Fake this by using IParseDisplayName_ParseDisplayName since the
1927 * signature and position in the vtable matches our unknown object type.
1929 hRet
= IParseDisplayName_ParseDisplayName((LPPARSEDISPLAYNAME
)lpUnkInner
,
1930 lpArg1
, lpArg2
, lpArg3
, lpArg4
);
1931 IUnknown_Release(lpUnkInner
);
1937 /*************************************************************************
1940 * Get a sub-menu from a menu item.
1943 * hMenu [I] Menu to get sub-menu from
1944 * uID [I] ID of menu item containing sub-menu
1947 * The sub-menu of the item, or a NULL handle if any parameters are invalid.
1949 HMENU WINAPI
SHGetMenuFromID(HMENU hMenu
, UINT uID
)
1953 TRACE("(%p,%u)\n", hMenu
, uID
);
1955 mi
.cbSize
= sizeof(mi
);
1956 mi
.fMask
= MIIM_SUBMENU
;
1958 if (!GetMenuItemInfoW(hMenu
, uID
, FALSE
, &mi
))
1964 /*************************************************************************
1967 * Get the color depth of the primary display.
1973 * The color depth of the primary display.
1975 DWORD WINAPI
SHGetCurColorRes(void)
1983 ret
= GetDeviceCaps(hdc
, BITSPIXEL
) * GetDeviceCaps(hdc
, PLANES
);
1988 /*************************************************************************
1991 * Wait for a message to arrive, with a timeout.
1994 * hand [I] Handle to query
1995 * dwTimeout [I] Timeout in ticks or INFINITE to never timeout
1998 * STATUS_TIMEOUT if no message is received before dwTimeout ticks passes.
1999 * Otherwise returns the value from MsgWaitForMultipleObjectsEx when a
2000 * message is available.
2002 DWORD WINAPI
SHWaitForSendMessageThread(HANDLE hand
, DWORD dwTimeout
)
2004 DWORD dwEndTicks
= GetTickCount() + dwTimeout
;
2007 while ((dwRet
= MsgWaitForMultipleObjectsEx(1, &hand
, dwTimeout
, QS_SENDMESSAGE
, 0)) == 1)
2011 PeekMessageW(&msg
, NULL
, 0, 0, PM_NOREMOVE
);
2013 if (dwTimeout
!= INFINITE
)
2015 if ((int)(dwTimeout
= dwEndTicks
- GetTickCount()) <= 0)
2016 return WAIT_TIMEOUT
;
2023 /*************************************************************************
2026 * Determine if a shell folder can be expanded.
2029 * lpFolder [I] Parent folder containing the object to test.
2030 * pidl [I] Id of the object to test.
2033 * Success: S_OK, if the object is expandable, S_FALSE otherwise.
2034 * Failure: E_INVALIDARG, if any argument is invalid.
2037 * If the object to be tested does not expose the IQueryInfo() interface it
2038 * will not be identified as an expandable folder.
2040 HRESULT WINAPI
SHIsExpandableFolder(LPSHELLFOLDER lpFolder
, LPCITEMIDLIST pidl
)
2042 HRESULT hRet
= E_INVALIDARG
;
2045 if (lpFolder
&& pidl
)
2047 hRet
= IShellFolder_GetUIObjectOf(lpFolder
, NULL
, 1, &pidl
, &IID_IQueryInfo
,
2048 NULL
, (void**)&lpInfo
);
2050 hRet
= S_FALSE
; /* Doesn't expose IQueryInfo */
2055 /* MSDN states of IQueryInfo_GetInfoFlags() that "This method is not
2056 * currently used". Really? You wouldn't be holding out on me would you?
2058 hRet
= IQueryInfo_GetInfoFlags(lpInfo
, &dwFlags
);
2060 if (SUCCEEDED(hRet
))
2062 /* 0x2 is an undocumented flag apparently indicating expandability */
2063 hRet
= dwFlags
& 0x2 ? S_OK
: S_FALSE
;
2066 IQueryInfo_Release(lpInfo
);
2072 /*************************************************************************
2075 * Blank out a region of text by drawing the background only.
2078 * hDC [I] Device context to draw in
2079 * pRect [I] Area to draw in
2080 * cRef [I] Color to draw in
2085 DWORD WINAPI
SHFillRectClr(HDC hDC
, LPCRECT pRect
, COLORREF cRef
)
2087 COLORREF cOldColor
= SetBkColor(hDC
, cRef
);
2088 ExtTextOutA(hDC
, 0, 0, ETO_OPAQUE
, pRect
, 0, 0, 0);
2089 SetBkColor(hDC
, cOldColor
);
2093 /*************************************************************************
2096 * Return the value asociated with a key in a map.
2099 * lpKeys [I] A list of keys of length iLen
2100 * lpValues [I] A list of values associated with lpKeys, of length iLen
2101 * iLen [I] Length of both lpKeys and lpValues
2102 * iKey [I] The key value to look up in lpKeys
2105 * The value in lpValues associated with iKey, or -1 if iKey is not
2109 * - If two elements in the map share the same key, this function returns
2110 * the value closest to the start of the map
2111 * - The native version of this function crashes if lpKeys or lpValues is NULL.
2113 int WINAPI
SHSearchMapInt(const int *lpKeys
, const int *lpValues
, int iLen
, int iKey
)
2115 if (lpKeys
&& lpValues
)
2121 if (lpKeys
[i
] == iKey
)
2122 return lpValues
[i
]; /* Found */
2126 return -1; /* Not found */
2130 /*************************************************************************
2133 * Copy an interface pointer
2136 * lppDest [O] Destination for copy
2137 * lpUnknown [I] Source for copy
2142 VOID WINAPI
IUnknown_Set(IUnknown
**lppDest
, IUnknown
*lpUnknown
)
2144 TRACE("(%p,%p)\n", lppDest
, lpUnknown
);
2147 IUnknown_AtomicRelease(lppDest
); /* Release existing interface */
2152 IUnknown_AddRef(lpUnknown
);
2153 *lppDest
= lpUnknown
;
2157 /*************************************************************************
2161 HRESULT WINAPI
MayQSForward(IUnknown
* lpUnknown
, PVOID lpReserved
,
2162 REFGUID riidCmdGrp
, ULONG cCmds
,
2163 OLECMD
*prgCmds
, OLECMDTEXT
* pCmdText
)
2165 FIXME("(%p,%p,%p,%ld,%p,%p) - stub\n",
2166 lpUnknown
, lpReserved
, riidCmdGrp
, cCmds
, prgCmds
, pCmdText
);
2168 /* FIXME: Calls IsQSForward & IUnknown_QueryStatus */
2169 return DRAGDROP_E_NOTREGISTERED
;
2172 /*************************************************************************
2176 HRESULT WINAPI
MayExecForward(IUnknown
* lpUnknown
, INT iUnk
, REFGUID pguidCmdGroup
,
2177 DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
* pvaIn
,
2180 FIXME("(%p,%d,%p,%ld,%ld,%p,%p) - stub!\n", lpUnknown
, iUnk
, pguidCmdGroup
,
2181 nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2182 return DRAGDROP_E_NOTREGISTERED
;
2185 /*************************************************************************
2189 HRESULT WINAPI
IsQSForward(REFGUID pguidCmdGroup
,ULONG cCmds
, OLECMD
*prgCmds
)
2191 FIXME("(%p,%ld,%p) - stub!\n", pguidCmdGroup
, cCmds
, prgCmds
);
2192 return DRAGDROP_E_NOTREGISTERED
;
2195 /*************************************************************************
2198 * Determine if a window is not a child of another window.
2201 * hParent [I] Suspected parent window
2202 * hChild [I] Suspected child window
2205 * TRUE: If hChild is a child window of hParent
2206 * FALSE: If hChild is not a child window of hParent, or they are equal
2208 BOOL WINAPI
SHIsChildOrSelf(HWND hParent
, HWND hChild
)
2210 TRACE("(%p,%p)\n", hParent
, hChild
);
2212 if (!hParent
|| !hChild
)
2214 else if(hParent
== hChild
)
2216 return !IsChild(hParent
, hChild
);
2219 /*************************************************************************
2220 * FDSA functions. Manage a dynamic array of fixed size memory blocks.
2225 DWORD num_items
; /* Number of elements inserted */
2226 void *mem
; /* Ptr to array */
2227 DWORD blocks_alloced
; /* Number of elements allocated */
2228 BYTE inc
; /* Number of elements to grow by when we need to expand */
2229 BYTE block_size
; /* Size in bytes of an element */
2230 BYTE flags
; /* Flags */
2233 #define FDSA_FLAG_INTERNAL_ALLOC 0x01 /* When set we have allocated mem internally */
2235 /*************************************************************************
2238 * Initialize an FDSA arrary.
2240 BOOL WINAPI
FDSA_Initialize(DWORD block_size
, DWORD inc
, FDSA_info
*info
, void *mem
,
2243 TRACE("(0x%08lx 0x%08lx %p %p 0x%08lx)\n", block_size
, inc
, info
, mem
, init_blocks
);
2249 memset(mem
, 0, block_size
* init_blocks
);
2251 info
->num_items
= 0;
2254 info
->blocks_alloced
= init_blocks
;
2255 info
->block_size
= block_size
;
2261 /*************************************************************************
2264 * Destroy an FDSA array
2266 BOOL WINAPI
FDSA_Destroy(FDSA_info
*info
)
2268 TRACE("(%p)\n", info
);
2270 if(info
->flags
& FDSA_FLAG_INTERNAL_ALLOC
)
2272 HeapFree(GetProcessHeap(), 0, info
->mem
);
2279 /*************************************************************************
2282 * Insert element into an FDSA array
2284 DWORD WINAPI
FDSA_InsertItem(FDSA_info
*info
, DWORD where
, void *block
)
2286 TRACE("(%p 0x%08lx %p)\n", info
, where
, block
);
2287 if(where
> info
->num_items
)
2288 where
= info
->num_items
;
2290 if(info
->num_items
>= info
->blocks_alloced
)
2292 DWORD size
= (info
->blocks_alloced
+ info
->inc
) * info
->block_size
;
2293 if(info
->flags
& 0x1)
2294 info
->mem
= HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, info
->mem
, size
);
2297 void *old_mem
= info
->mem
;
2298 info
->mem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
2299 memcpy(info
->mem
, old_mem
, info
->blocks_alloced
* info
->block_size
);
2301 info
->blocks_alloced
+= info
->inc
;
2305 if(where
< info
->num_items
)
2307 memmove((char*)info
->mem
+ (where
+ 1) * info
->block_size
,
2308 (char*)info
->mem
+ where
* info
->block_size
,
2309 (info
->num_items
- where
) * info
->block_size
);
2311 memcpy((char*)info
->mem
+ where
* info
->block_size
, block
, info
->block_size
);
2317 /*************************************************************************
2320 * Delete an element from an FDSA array.
2322 BOOL WINAPI
FDSA_DeleteItem(FDSA_info
*info
, DWORD where
)
2324 TRACE("(%p 0x%08lx)\n", info
, where
);
2326 if(where
>= info
->num_items
)
2329 if(where
< info
->num_items
- 1)
2331 memmove((char*)info
->mem
+ where
* info
->block_size
,
2332 (char*)info
->mem
+ (where
+ 1) * info
->block_size
,
2333 (info
->num_items
- where
- 1) * info
->block_size
);
2335 memset((char*)info
->mem
+ (info
->num_items
- 1) * info
->block_size
,
2336 0, info
->block_size
);
2347 /*************************************************************************
2350 * Call IUnknown_QueryInterface() on a table of objects.
2354 * Failure: E_POINTER or E_NOINTERFACE.
2356 HRESULT WINAPI
QISearch(
2357 LPVOID w
, /* [in] Table of interfaces */
2358 IFACE_INDEX_TBL
*x
, /* [in] Array of REFIIDs and indexes into the table */
2359 REFIID riid
, /* [in] REFIID to get interface for */
2360 LPVOID
*ppv
) /* [out] Destination for interface pointer */
2364 IFACE_INDEX_TBL
*xmove
;
2366 TRACE("(%p %p %s %p)\n", w
,x
,debugstr_guid(riid
),ppv
);
2369 while (xmove
->refid
) {
2370 TRACE("trying (indx %ld) %s\n", xmove
->indx
, debugstr_guid(xmove
->refid
));
2371 if (IsEqualIID(riid
, xmove
->refid
)) {
2372 a_vtbl
= (IUnknown
*)(xmove
->indx
+ (LPBYTE
)w
);
2373 TRACE("matched, returning (%p)\n", a_vtbl
);
2374 *ppv
= (LPVOID
)a_vtbl
;
2375 IUnknown_AddRef(a_vtbl
);
2381 if (IsEqualIID(riid
, &IID_IUnknown
)) {
2382 a_vtbl
= (IUnknown
*)(x
->indx
+ (LPBYTE
)w
);
2383 TRACE("returning first for IUnknown (%p)\n", a_vtbl
);
2384 *ppv
= (LPVOID
)a_vtbl
;
2385 IUnknown_AddRef(a_vtbl
);
2389 ret
= E_NOINTERFACE
;
2393 TRACE("-- 0x%08lx\n", ret
);
2397 /*************************************************************************
2400 * Remove the "PropDlgFont" property from a window.
2403 * hWnd [I] Window to remove the property from
2406 * A handle to the removed property, or NULL if it did not exist.
2408 HANDLE WINAPI
SHRemoveDefaultDialogFont(HWND hWnd
)
2412 TRACE("(%p)\n", hWnd
);
2414 hProp
= GetPropA(hWnd
, "PropDlgFont");
2418 DeleteObject(hProp
);
2419 hProp
= RemovePropA(hWnd
, "PropDlgFont");
2424 /*************************************************************************
2427 * Load the in-process server of a given GUID.
2430 * refiid [I] GUID of the server to load.
2433 * Success: A handle to the loaded server dll.
2434 * Failure: A NULL handle.
2436 HMODULE WINAPI
SHPinDllOfCLSID(REFIID refiid
)
2440 CHAR value
[MAX_PATH
], string
[MAX_PATH
];
2442 strcpy(string
, "CLSID\\");
2443 SHStringFromGUIDA(refiid
, string
+ 6, sizeof(string
)/sizeof(char) - 6);
2444 strcat(string
, "\\InProcServer32");
2447 RegOpenKeyExA(HKEY_CLASSES_ROOT
, string
, 0, 1, &newkey
);
2448 RegQueryValueExA(newkey
, 0, 0, &type
, (PBYTE
)value
, &count
);
2449 RegCloseKey(newkey
);
2450 return LoadLibraryExA(value
, 0, 0);
2453 /*************************************************************************
2456 * Unicode version of SHLWAPI_183.
2458 DWORD WINAPI
SHRegisterClassW(WNDCLASSW
* lpWndClass
)
2462 TRACE("(%p %s)\n",lpWndClass
->hInstance
, debugstr_w(lpWndClass
->lpszClassName
));
2464 if (GetClassInfoW(lpWndClass
->hInstance
, lpWndClass
->lpszClassName
, &WndClass
))
2466 return RegisterClassW(lpWndClass
);
2469 /*************************************************************************
2472 * Unregister a list of classes.
2475 * hInst [I] Application instance that registered the classes
2476 * lppClasses [I] List of class names
2477 * iCount [I] Number of names in lppClasses
2482 void WINAPI
SHUnregisterClassesA(HINSTANCE hInst
, LPCSTR
*lppClasses
, INT iCount
)
2486 TRACE("(%p,%p,%d)\n", hInst
, lppClasses
, iCount
);
2490 if (GetClassInfoA(hInst
, *lppClasses
, &WndClass
))
2491 UnregisterClassA(*lppClasses
, hInst
);
2497 /*************************************************************************
2500 * Unicode version of SHUnregisterClassesA.
2502 void WINAPI
SHUnregisterClassesW(HINSTANCE hInst
, LPCWSTR
*lppClasses
, INT iCount
)
2506 TRACE("(%p,%p,%d)\n", hInst
, lppClasses
, iCount
);
2510 if (GetClassInfoW(hInst
, *lppClasses
, &WndClass
))
2511 UnregisterClassW(*lppClasses
, hInst
);
2517 /*************************************************************************
2520 * Call The correct (Ascii/Unicode) default window procedure for a window.
2523 * hWnd [I] Window to call the default procedure for
2524 * uMessage [I] Message ID
2525 * wParam [I] WPARAM of message
2526 * lParam [I] LPARAM of message
2529 * The result of calling DefWindowProcA() or DefWindowProcW().
2531 LRESULT CALLBACK
SHDefWindowProc(HWND hWnd
, UINT uMessage
, WPARAM wParam
, LPARAM lParam
)
2533 if (IsWindowUnicode(hWnd
))
2534 return DefWindowProcW(hWnd
, uMessage
, wParam
, lParam
);
2535 return DefWindowProcA(hWnd
, uMessage
, wParam
, lParam
);
2538 /*************************************************************************
2541 HRESULT WINAPI
IUnknown_GetSite(LPUNKNOWN lpUnknown
, REFIID iid
, PVOID
*lppSite
)
2543 HRESULT hRet
= E_INVALIDARG
;
2544 LPOBJECTWITHSITE lpSite
= NULL
;
2546 TRACE("(%p,%s,%p)\n", lpUnknown
, debugstr_guid(iid
), lppSite
);
2548 if (lpUnknown
&& iid
&& lppSite
)
2550 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IObjectWithSite
,
2552 if (SUCCEEDED(hRet
) && lpSite
)
2554 hRet
= IObjectWithSite_GetSite(lpSite
, iid
, lppSite
);
2555 IObjectWithSite_Release(lpSite
);
2561 /*************************************************************************
2564 * Create a worker window using CreateWindowExA().
2567 * wndProc [I] Window procedure
2568 * hWndParent [I] Parent window
2569 * dwExStyle [I] Extra style flags
2570 * dwStyle [I] Style flags
2571 * hMenu [I] Window menu
2575 * Success: The window handle of the newly created window.
2578 HWND WINAPI
SHCreateWorkerWindowA(LONG wndProc
, HWND hWndParent
, DWORD dwExStyle
,
2579 DWORD dwStyle
, HMENU hMenu
, LONG z
)
2581 static const char* szClass
= "WorkerA";
2585 TRACE("(0x%08lx,%p,0x%08lx,0x%08lx,%p,0x%08lx)\n",
2586 wndProc
, hWndParent
, dwExStyle
, dwStyle
, hMenu
, z
);
2588 /* Create Window class */
2590 wc
.lpfnWndProc
= DefWindowProcA
;
2593 wc
.hInstance
= shlwapi_hInstance
;
2595 wc
.hCursor
= LoadCursorA(NULL
, (LPSTR
)IDC_ARROW
);
2596 wc
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
2597 wc
.lpszMenuName
= NULL
;
2598 wc
.lpszClassName
= szClass
;
2600 SHRegisterClassA(&wc
); /* Register class */
2602 /* FIXME: Set extra bits in dwExStyle */
2604 hWnd
= CreateWindowExA(dwExStyle
, szClass
, 0, dwStyle
, 0, 0, 0, 0,
2605 hWndParent
, hMenu
, shlwapi_hInstance
, 0);
2608 SetWindowLongPtrW(hWnd
, DWLP_MSGRESULT
, z
);
2611 SetWindowLongPtrA(hWnd
, GWLP_WNDPROC
, wndProc
);
2616 typedef struct tagPOLICYDATA
2618 DWORD policy
; /* flags value passed to SHRestricted */
2619 LPCWSTR appstr
; /* application str such as "Explorer" */
2620 LPCWSTR keystr
; /* name of the actual registry key / policy */
2621 } POLICYDATA
, *LPPOLICYDATA
;
2623 #define SHELL_NO_POLICY 0xffffffff
2625 /* default shell policy registry key */
2626 static const WCHAR strRegistryPolicyW
[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o',
2627 's','o','f','t','\\','W','i','n','d','o','w','s','\\',
2628 'C','u','r','r','e','n','t','V','e','r','s','i','o','n',
2629 '\\','P','o','l','i','c','i','e','s',0};
2631 /*************************************************************************
2634 * Retrieve a policy value from the registry.
2637 * lpSubKey [I] registry key name
2638 * lpSubName [I] subname of registry key
2639 * lpValue [I] value name of registry value
2642 * the value associated with the registry key or 0 if not found
2644 DWORD WINAPI
SHGetRestriction(LPCWSTR lpSubKey
, LPCWSTR lpSubName
, LPCWSTR lpValue
)
2646 DWORD retval
, datsize
= sizeof(retval
);
2650 lpSubKey
= strRegistryPolicyW
;
2652 retval
= RegOpenKeyW(HKEY_LOCAL_MACHINE
, lpSubKey
, &hKey
);
2653 if (retval
!= ERROR_SUCCESS
)
2654 retval
= RegOpenKeyW(HKEY_CURRENT_USER
, lpSubKey
, &hKey
);
2655 if (retval
!= ERROR_SUCCESS
)
2658 SHGetValueW(hKey
, lpSubName
, lpValue
, NULL
, (LPBYTE
)&retval
, &datsize
);
2663 /*************************************************************************
2666 * Helper function to retrieve the possibly cached value for a specific policy
2669 * policy [I] The policy to look for
2670 * initial [I] Main registry key to open, if NULL use default
2671 * polTable [I] Table of known policies, 0 terminated
2672 * polArr [I] Cache array of policy values
2675 * The retrieved policy value or 0 if not successful
2678 * This function is used by the native SHRestricted function to search for the
2679 * policy and cache it once retrieved. The current Wine implementation uses a
2680 * different POLICYDATA structure and implements a similar algorithme adapted to
2683 DWORD WINAPI
SHRestrictionLookup(
2686 LPPOLICYDATA polTable
,
2689 TRACE("(0x%08lx %s %p %p)\n", policy
, debugstr_w(initial
), polTable
, polArr
);
2691 if (!polTable
|| !polArr
)
2694 for (;polTable
->policy
; polTable
++, polArr
++)
2696 if (policy
== polTable
->policy
)
2698 /* we have a known policy */
2700 /* check if this policy has been cached */
2701 if (*polArr
== SHELL_NO_POLICY
)
2702 *polArr
= SHGetRestriction(initial
, polTable
->appstr
, polTable
->keystr
);
2706 /* we don't know this policy, return 0 */
2707 TRACE("unknown policy: (%08lx)\n", policy
);
2711 /*************************************************************************
2714 * Get an interface from an object.
2717 * Success: S_OK. ppv contains the requested interface.
2718 * Failure: An HRESULT error code.
2721 * This QueryInterface asks the inner object for an interface. In case
2722 * of aggregation this request would be forwarded by the inner to the
2723 * outer object. This function asks the inner object directly for the
2724 * interface circumventing the forwarding to the outer object.
2726 HRESULT WINAPI
SHWeakQueryInterface(
2727 IUnknown
* pUnk
, /* [in] Outer object */
2728 IUnknown
* pInner
, /* [in] Inner object */
2729 IID
* riid
, /* [in] Interface GUID to query for */
2730 LPVOID
* ppv
) /* [out] Destination for queried interface */
2732 HRESULT hret
= E_NOINTERFACE
;
2733 TRACE("(pUnk=%p pInner=%p\n\tIID: %s %p)\n",pUnk
,pInner
,debugstr_guid(riid
), ppv
);
2736 if(pUnk
&& pInner
) {
2737 hret
= IUnknown_QueryInterface(pInner
, riid
, (LPVOID
*)ppv
);
2738 if (SUCCEEDED(hret
)) IUnknown_Release(pUnk
);
2740 TRACE("-- 0x%08lx\n", hret
);
2744 /*************************************************************************
2747 * Move a reference from one interface to another.
2750 * lpDest [O] Destination to receive the reference
2751 * lppUnknown [O] Source to give up the reference to lpDest
2756 VOID WINAPI
SHWeakReleaseInterface(IUnknown
*lpDest
, IUnknown
**lppUnknown
)
2758 TRACE("(%p,%p)\n", lpDest
, lppUnknown
);
2763 IUnknown_AddRef(lpDest
);
2764 IUnknown_AtomicRelease(lppUnknown
); /* Release existing interface */
2768 /*************************************************************************
2771 * Convert an ASCII string of a CLSID into a CLSID.
2774 * idstr [I] String representing a CLSID in registry format
2775 * id [O] Destination for the converted CLSID
2778 * Success: TRUE. id contains the converted CLSID.
2781 BOOL WINAPI
GUIDFromStringA(LPCSTR idstr
, CLSID
*id
)
2784 MultiByteToWideChar(CP_ACP
, 0, idstr
, -1, wClsid
, sizeof(wClsid
)/sizeof(WCHAR
));
2785 return SUCCEEDED(CLSIDFromStringWrap(wClsid
, id
));
2788 /*************************************************************************
2791 * Unicode version of GUIDFromStringA.
2793 BOOL WINAPI
GUIDFromStringW(LPCWSTR idstr
, CLSID
*id
)
2795 return SUCCEEDED(CLSIDFromStringWrap(idstr
, id
));
2798 /*************************************************************************
2801 * Determine if the browser is integrated into the shell, and set a registry
2808 * 1, If the browser is not integrated.
2809 * 2, If the browser is integrated.
2812 * The key "HKLM\Software\Microsoft\Internet Explorer\IntegratedBrowser" is
2813 * either set to TRUE, or removed depending on whether the browser is deemed
2816 DWORD WINAPI
WhichPlatform(void)
2818 static LPCSTR szIntegratedBrowser
= "IntegratedBrowser";
2819 static DWORD dwState
= 0;
2821 DWORD dwRet
, dwData
, dwSize
;
2826 /* If shell32 exports DllGetVersion(), the browser is integrated */
2827 GET_FUNC(pDllGetVersion
, shell32
, "DllGetVersion", 1);
2828 dwState
= pDllGetVersion
? 2 : 1;
2830 /* Set or delete the key accordingly */
2831 dwRet
= RegOpenKeyExA(HKEY_LOCAL_MACHINE
,
2832 "Software\\Microsoft\\Internet Explorer", 0,
2833 KEY_ALL_ACCESS
, &hKey
);
2836 dwRet
= RegQueryValueExA(hKey
, szIntegratedBrowser
, 0, 0,
2837 (LPBYTE
)&dwData
, &dwSize
);
2839 if (!dwRet
&& dwState
== 1)
2841 /* Value exists but browser is not integrated */
2842 RegDeleteValueA(hKey
, szIntegratedBrowser
);
2844 else if (dwRet
&& dwState
== 2)
2846 /* Browser is integrated but value does not exist */
2848 RegSetValueExA(hKey
, szIntegratedBrowser
, 0, REG_DWORD
,
2849 (LPBYTE
)&dwData
, sizeof(dwData
));
2856 /*************************************************************************
2859 * Unicode version of SHCreateWorkerWindowA.
2861 HWND WINAPI
SHCreateWorkerWindowW(LONG wndProc
, HWND hWndParent
, DWORD dwExStyle
,
2862 DWORD dwStyle
, HMENU hMenu
, LONG z
)
2864 static const WCHAR szClass
[] = { 'W', 'o', 'r', 'k', 'e', 'r', 'W', '\0' };
2868 TRACE("(0x%08lx,%p,0x%08lx,0x%08lx,%p,0x%08lx)\n",
2869 wndProc
, hWndParent
, dwExStyle
, dwStyle
, hMenu
, z
);
2871 /* If our OS is natively ASCII, use the ASCII version */
2872 if (!(GetVersion() & 0x80000000)) /* NT */
2873 return SHCreateWorkerWindowA(wndProc
, hWndParent
, dwExStyle
, dwStyle
, hMenu
, z
);
2875 /* Create Window class */
2877 wc
.lpfnWndProc
= DefWindowProcW
;
2880 wc
.hInstance
= shlwapi_hInstance
;
2882 wc
.hCursor
= LoadCursorW(NULL
, (LPWSTR
)IDC_ARROW
);
2883 wc
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
2884 wc
.lpszMenuName
= NULL
;
2885 wc
.lpszClassName
= szClass
;
2887 SHRegisterClassW(&wc
); /* Register class */
2889 /* FIXME: Set extra bits in dwExStyle */
2891 hWnd
= CreateWindowExW(dwExStyle
, szClass
, 0, dwStyle
, 0, 0, 0, 0,
2892 hWndParent
, hMenu
, shlwapi_hInstance
, 0);
2895 SetWindowLongPtrW(hWnd
, DWLP_MSGRESULT
, z
);
2898 SetWindowLongPtrW(hWnd
, GWLP_WNDPROC
, wndProc
);
2903 /*************************************************************************
2906 * Get and show a context menu from a shell folder.
2909 * hWnd [I] Window displaying the shell folder
2910 * lpFolder [I] IShellFolder interface
2911 * lpApidl [I] Id for the particular folder desired
2915 * Failure: An HRESULT error code indicating the error.
2917 HRESULT WINAPI
SHInvokeDefaultCommand(HWND hWnd
, IShellFolder
* lpFolder
, LPCITEMIDLIST lpApidl
)
2919 return SHInvokeCommand(hWnd
, lpFolder
, lpApidl
, FALSE
);
2922 /*************************************************************************
2925 * _SHPackDispParamsV
2927 HRESULT WINAPI
SHPackDispParamsV(LPVOID w
, LPVOID x
, LPVOID y
, LPVOID z
)
2929 FIXME("%p %p %p %p\n",w
,x
,y
,z
);
2933 /*************************************************************************
2936 * This function seems to be a forward to SHPackDispParamsV (whatever THAT
2937 * function does...).
2939 HRESULT WINAPI
SHPackDispParams(LPVOID w
, LPVOID x
, LPVOID y
, LPVOID z
)
2941 FIXME("%p %p %p %p\n", w
, x
, y
, z
);
2945 /*************************************************************************
2948 * _IConnectionPoint_SimpleInvoke
2950 DWORD WINAPI
IConnectionPoint_SimpleInvoke(
2955 FIXME("(%p %p %p) stub\n",x
,y
,z
);
2959 /*************************************************************************
2962 * Notify an IConnectionPoint object of changes.
2965 * lpCP [I] Object to notify
2970 * Failure: E_NOINTERFACE, if lpCP is NULL or does not support the
2971 * IConnectionPoint interface.
2973 HRESULT WINAPI
IConnectionPoint_OnChanged(IConnectionPoint
* lpCP
, DISPID dispID
)
2975 IEnumConnections
*lpEnum
;
2976 HRESULT hRet
= E_NOINTERFACE
;
2978 TRACE("(%p,0x%8lX)\n", lpCP
, dispID
);
2980 /* Get an enumerator for the connections */
2982 hRet
= IConnectionPoint_EnumConnections(lpCP
, &lpEnum
);
2984 if (SUCCEEDED(hRet
))
2986 IPropertyNotifySink
*lpSink
;
2987 CONNECTDATA connData
;
2990 /* Call OnChanged() for every notify sink in the connection point */
2991 while (IEnumConnections_Next(lpEnum
, 1, &connData
, &ulFetched
) == S_OK
)
2993 if (SUCCEEDED(IUnknown_QueryInterface(connData
.pUnk
, &IID_IPropertyNotifySink
, (void**)&lpSink
)) &&
2996 IPropertyNotifySink_OnChanged(lpSink
, dispID
);
2997 IPropertyNotifySink_Release(lpSink
);
2999 IUnknown_Release(connData
.pUnk
);
3002 IEnumConnections_Release(lpEnum
);
3007 /*************************************************************************
3010 * Notify an IConnectionPointContainer object of changes.
3013 * lpUnknown [I] Object to notify
3018 * Failure: E_NOINTERFACE, if lpUnknown is NULL or does not support the
3019 * IConnectionPointContainer interface.
3021 HRESULT WINAPI
IUnknown_CPContainerOnChanged(IUnknown
*lpUnknown
, DISPID dispID
)
3023 IConnectionPointContainer
* lpCPC
= NULL
;
3024 HRESULT hRet
= E_NOINTERFACE
;
3026 TRACE("(%p,0x%8lX)\n", lpUnknown
, dispID
);
3029 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IConnectionPointContainer
, (void**)&lpCPC
);
3031 if (SUCCEEDED(hRet
))
3033 IConnectionPoint
* lpCP
;
3035 hRet
= IConnectionPointContainer_FindConnectionPoint(lpCPC
, &IID_IPropertyNotifySink
, &lpCP
);
3036 IConnectionPointContainer_Release(lpCPC
);
3038 hRet
= IConnectionPoint_OnChanged(lpCP
, dispID
);
3039 IConnectionPoint_Release(lpCP
);
3044 /*************************************************************************
3049 BOOL WINAPI
PlaySoundWrapW(LPCWSTR pszSound
, HMODULE hmod
, DWORD fdwSound
)
3051 GET_FUNC(pPlaySoundW
, winmm
, "PlaySoundW", FALSE
);
3052 return pPlaySoundW(pszSound
, hmod
, fdwSound
);
3055 /*************************************************************************
3058 BOOL WINAPI
SHGetIniStringW(LPSTR str1
, LPSTR str2
, LPSTR pStr
, DWORD some_len
, LPCSTR lpStr2
)
3061 * str1: "I" "I" pushl esp+0x20
3062 * str2: "U" "I" pushl 0x77c93810
3063 * (is "I" and "U" "integer" and "unsigned" ??)
3065 * pStr: "" "" pushl eax
3066 * some_len: 0x824 0x104 pushl 0x824
3067 * lpStr2: "%l" "%l" pushl esp+0xc
3069 * shlwapi. StrCpyNW(lpStr2, irrelevant_var, 0x104);
3070 * LocalAlloc(0x00, some_len) -> irrelevant_var
3071 * LocalAlloc(0x40, irrelevant_len) -> pStr
3072 * shlwapi.294(str1, str2, pStr, some_len, lpStr2);
3073 * shlwapi.PathRemoveBlanksW(pStr);
3075 FIXME("('%s', '%s', '%s', %08lx, '%s'): stub!\n", str1
, str2
, pStr
, some_len
, lpStr2
);
3079 /*************************************************************************
3082 * Called by ICQ2000b install via SHDOCVW:
3083 * str1: "InternetShortcut"
3084 * x: some unknown pointer
3085 * str2: "http://free.aol.com/tryaolfree/index.adp?139269"
3086 * str3: "C:\\WINDOWS\\Desktop.new2\\Free AOL & Unlimited Internet.url"
3088 * In short: this one maybe creates a desktop link :-)
3090 BOOL WINAPI
SHSetIniStringW(LPWSTR str1
, LPVOID x
, LPWSTR str2
, LPWSTR str3
)
3092 FIXME("('%s', %p, '%s', '%s'), stub.\n", debugstr_w(str1
), x
, debugstr_w(str2
), debugstr_w(str3
));
3096 /*************************************************************************
3101 BOOL WINAPI
ExtTextOutWrapW(HDC hdc
, INT x
, INT y
, UINT flags
, const RECT
*lprect
,
3102 LPCWSTR str
, UINT count
, const INT
*lpDx
)
3104 GET_FUNC(pCOMCTL32_417
, comctl32
, (LPCSTR
)417, FALSE
);
3105 return pCOMCTL32_417(hdc
, x
, y
, flags
, lprect
, str
, count
, lpDx
);
3108 /*************************************************************************
3111 * See SHGetFileInfoW.
3113 DWORD WINAPI
SHGetFileInfoWrapW(LPCWSTR path
, DWORD dwFileAttributes
,
3114 SHFILEINFOW
*psfi
, UINT sizeofpsfi
, UINT flags
)
3116 GET_FUNC(pSHGetFileInfoW
, shell32
, "SHGetFileInfoW", 0);
3117 return pSHGetFileInfoW(path
, dwFileAttributes
, psfi
, sizeofpsfi
, flags
);
3120 /*************************************************************************
3123 * See DragQueryFileW.
3125 UINT WINAPI
DragQueryFileWrapW(HDROP hDrop
, UINT lFile
, LPWSTR lpszFile
, UINT lLength
)
3127 GET_FUNC(pDragQueryFileW
, shell32
, "DragQueryFileW", 0);
3128 return pDragQueryFileW(hDrop
, lFile
, lpszFile
, lLength
);
3131 /*************************************************************************
3134 * See SHBrowseForFolderW.
3136 LPITEMIDLIST WINAPI
SHBrowseForFolderWrapW(LPBROWSEINFOW lpBi
)
3138 GET_FUNC(pSHBrowseForFolderW
, shell32
, "SHBrowseForFolderW", NULL
);
3139 return pSHBrowseForFolderW(lpBi
);
3142 /*************************************************************************
3145 * See SHGetPathFromIDListW.
3147 BOOL WINAPI
SHGetPathFromIDListWrapW(LPCITEMIDLIST pidl
,LPWSTR pszPath
)
3149 GET_FUNC(pSHGetPathFromIDListW
, shell32
, "SHGetPathFromIDListW", 0);
3150 return pSHGetPathFromIDListW(pidl
, pszPath
);
3153 /*************************************************************************
3156 * See ShellExecuteExW.
3158 BOOL WINAPI
ShellExecuteExWrapW(LPSHELLEXECUTEINFOW lpExecInfo
)
3160 GET_FUNC(pShellExecuteExW
, shell32
, "ShellExecuteExW", FALSE
);
3161 return pShellExecuteExW(lpExecInfo
);
3164 /*************************************************************************
3167 * See SHFileOperationW.
3169 HICON WINAPI
SHFileOperationWrapW(LPSHFILEOPSTRUCTW lpFileOp
)
3171 GET_FUNC(pSHFileOperationW
, shell32
, "SHFileOperationW", 0);
3172 return pSHFileOperationW(lpFileOp
);
3175 /*************************************************************************
3178 * See ExtractIconExW.
3180 UINT WINAPI
ExtractIconExWrapW(LPCWSTR lpszFile
, INT nIconIndex
, HICON
*phiconLarge
,
3181 HICON
*phiconSmall
, UINT nIcons
)
3183 GET_FUNC(pExtractIconExW
, shell32
, "ExtractIconExW", 0);
3184 return pExtractIconExW(lpszFile
, nIconIndex
, phiconLarge
, phiconSmall
, nIcons
);
3187 /*************************************************************************
3191 LONG WINAPI
SHInterlockedCompareExchange( PLONG dest
, LONG xchg
, LONG compare
)
3193 return InterlockedCompareExchange(dest
, xchg
, compare
);
3196 /*************************************************************************
3199 * See GetFileVersionInfoSizeW.
3201 DWORD WINAPI
GetFileVersionInfoSizeWrapW(
3207 GET_FUNC(pGetFileVersionInfoSizeW
, version
, "GetFileVersionInfoSizeW", 0);
3208 ret
= pGetFileVersionInfoSizeW(x
, y
);
3212 /*************************************************************************
3215 * See GetFileVersionInfoW.
3217 BOOL WINAPI
GetFileVersionInfoWrapW(
3218 LPWSTR w
, /* [in] path to dll */
3219 DWORD x
, /* [in] parm 2 to GetFileVersionInfoA */
3220 DWORD y
, /* [in] return value from SHLWAPI_350() - assume length */
3221 LPVOID z
) /* [in/out] buffer (+0x208 sent to GetFileVersionInfoA()) */
3223 GET_FUNC(pGetFileVersionInfoW
, version
, "GetFileVersionInfoW", 0);
3224 return pGetFileVersionInfoW(w
, x
, y
-0x208, (char*)z
+0x208);
3227 /*************************************************************************
3230 * See VerQueryValueW.
3232 WORD WINAPI
VerQueryValueWrapW(
3233 LPVOID w
, /* [in] Buffer from SHLWAPI_351() */
3234 LPWSTR x
, /* [in] Value to retrieve - converted and passed to VerQueryValueA() as #2 */
3235 LPVOID y
, /* [out] Ver buffer - passed to VerQueryValueA as #3 */
3236 UINT
* z
) /* [in] Ver length - passed to VerQueryValueA as #4 */
3238 GET_FUNC(pVerQueryValueW
, version
, "VerQueryValueW", 0);
3239 return pVerQueryValueW((char*)w
+0x208, x
, y
, z
);
3242 #define IsIface(type) SUCCEEDED((hRet = IUnknown_QueryInterface(lpUnknown, &IID_##type, (void**)&lpObj)))
3243 #define IShellBrowser_EnableModeless IShellBrowser_EnableModelessSB
3244 #define EnableModeless(type) type##_EnableModeless((type*)lpObj, bModeless)
3246 /*************************************************************************
3249 * Change the modality of a shell object.
3252 * lpUnknown [I] Object to make modeless
3253 * bModeless [I] TRUE=Make modeless, FALSE=Make modal
3256 * Success: S_OK. The modality lpUnknown is changed.
3257 * Failure: An HRESULT error code indicating the error.
3260 * lpUnknown must support the IOleInPlaceFrame interface, the
3261 * IInternetSecurityMgrSite interface, the IShellBrowser interface
3262 * the IDocHostUIHandler interface, or the IOleInPlaceActiveObject interface,
3263 * or this call will fail.
3265 HRESULT WINAPI
IUnknown_EnableModeless(IUnknown
*lpUnknown
, BOOL bModeless
)
3270 TRACE("(%p,%d)\n", lpUnknown
, bModeless
);
3275 if (IsIface(IOleInPlaceActiveObject
))
3276 EnableModeless(IOleInPlaceActiveObject
);
3277 else if (IsIface(IOleInPlaceFrame
))
3278 EnableModeless(IOleInPlaceFrame
);
3279 else if (IsIface(IShellBrowser
))
3280 EnableModeless(IShellBrowser
);
3282 /* FIXME: Wine has no headers for these objects yet */
3283 else if (IsIface(IInternetSecurityMgrSite
))
3284 EnableModeless(IInternetSecurityMgrSite
);
3285 else if (IsIface(IDocHostUIHandler
))
3286 EnableModeless(IDocHostUIHandler
);
3291 IUnknown_Release(lpObj
);
3295 /*************************************************************************
3298 * See SHGetNewLinkInfoW.
3300 BOOL WINAPI
SHGetNewLinkInfoWrapW(LPCWSTR pszLinkTo
, LPCWSTR pszDir
, LPWSTR pszName
,
3301 BOOL
*pfMustCopy
, UINT uFlags
)
3303 GET_FUNC(pSHGetNewLinkInfoW
, shell32
, "SHGetNewLinkInfoW", FALSE
);
3304 return pSHGetNewLinkInfoW(pszLinkTo
, pszDir
, pszName
, pfMustCopy
, uFlags
);
3307 /*************************************************************************
3310 * See SHDefExtractIconW.
3312 UINT WINAPI
SHDefExtractIconWrapW(LPCWSTR pszIconFile
, int iIndex
, UINT uFlags
, HICON
* phiconLarge
,
3313 HICON
* phiconSmall
, UINT nIconSize
)
3315 GET_FUNC(pSHDefExtractIconW
, shell32
, "SHDefExtractIconW", 0);
3316 return pSHDefExtractIconW(pszIconFile
, iIndex
, uFlags
, phiconLarge
, phiconSmall
, nIconSize
);
3319 /*************************************************************************
3322 * Get and show a context menu from a shell folder.
3325 * hWnd [I] Window displaying the shell folder
3326 * lpFolder [I] IShellFolder interface
3327 * lpApidl [I] Id for the particular folder desired
3328 * bInvokeDefault [I] Whether to invoke the default menu item
3331 * Success: S_OK. If bInvokeDefault is TRUE, the default menu action was
3333 * Failure: An HRESULT error code indicating the error.
3335 HRESULT WINAPI
SHInvokeCommand(HWND hWnd
, IShellFolder
* lpFolder
, LPCITEMIDLIST lpApidl
, BOOL bInvokeDefault
)
3337 IContextMenu
*iContext
;
3338 HRESULT hRet
= E_FAIL
;
3340 TRACE("(%p,%p,%p,%d)\n", hWnd
, lpFolder
, lpApidl
, bInvokeDefault
);
3345 /* Get the context menu from the shell folder */
3346 hRet
= IShellFolder_GetUIObjectOf(lpFolder
, hWnd
, 1, &lpApidl
,
3347 &IID_IContextMenu
, 0, (void**)&iContext
);
3348 if (SUCCEEDED(hRet
))
3351 if ((hMenu
= CreatePopupMenu()))
3354 DWORD dwDefaultId
= 0;
3356 /* Add the context menu entries to the popup */
3357 hQuery
= IContextMenu_QueryContextMenu(iContext
, hMenu
, 0, 1, 0x7FFF,
3358 bInvokeDefault
? CMF_NORMAL
: CMF_DEFAULTONLY
);
3360 if (SUCCEEDED(hQuery
))
3362 if (bInvokeDefault
&&
3363 (dwDefaultId
= GetMenuDefaultItem(hMenu
, 0, 0)) != 0xFFFFFFFF)
3365 CMINVOKECOMMANDINFO cmIci
;
3366 /* Invoke the default item */
3367 memset(&cmIci
,0,sizeof(cmIci
));
3368 cmIci
.cbSize
= sizeof(cmIci
);
3369 cmIci
.fMask
= CMIC_MASK_ASYNCOK
;
3371 cmIci
.lpVerb
= MAKEINTRESOURCEA(dwDefaultId
);
3372 cmIci
.nShow
= SW_SCROLLCHILDREN
;
3374 hRet
= IContextMenu_InvokeCommand(iContext
, &cmIci
);
3379 IContextMenu_Release(iContext
);
3384 /*************************************************************************
3389 HICON WINAPI
ExtractIconWrapW(HINSTANCE hInstance
, LPCWSTR lpszExeFileName
,
3392 GET_FUNC(pExtractIconW
, shell32
, "ExtractIconW", NULL
);
3393 return pExtractIconW(hInstance
, lpszExeFileName
, nIconIndex
);
3396 /*************************************************************************
3399 * Load a library from the directory of a particular process.
3402 * new_mod [I] Library name
3403 * inst_hwnd [I] Module whose directory is to be used
3404 * bCrossCodePage [I] Should be FALSE (currently ignored)
3407 * Success: A handle to the loaded module
3408 * Failure: A NULL handle.
3410 HMODULE WINAPI
MLLoadLibraryA(LPCSTR new_mod
, HMODULE inst_hwnd
, BOOL bCrossCodePage
)
3412 /* FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for
3414 * FIXME: Native shows calls to:
3415 * SHRegGetUSValue for "Software\Microsoft\Internet Explorer\International"
3417 * RegOpenKeyExA for "HKLM\Software\Microsoft\Internet Explorer"
3418 * RegQueryValueExA for "LPKInstalled"
3420 * RegOpenKeyExA for "HKCU\Software\Microsoft\Internet Explorer\International"
3421 * RegQueryValueExA for "ResourceLocale"
3423 * RegOpenKeyExA for "HKLM\Software\Microsoft\Active Setup\Installed Components\{guid}"
3424 * RegQueryValueExA for "Locale"
3426 * and then tests the Locale ("en" for me).
3428 * after the code then a DPA_Create (first time) and DPA_InsertPtr are done.
3430 CHAR mod_path
[2*MAX_PATH
];
3434 FIXME("(%s,%p,%d) semi-stub!\n", debugstr_a(new_mod
), inst_hwnd
, bCrossCodePage
);
3435 len
= GetModuleFileNameA(inst_hwnd
, mod_path
, sizeof(mod_path
));
3436 if (!len
|| len
>= sizeof(mod_path
)) return NULL
;
3438 ptr
= strrchr(mod_path
, '\\');
3440 strcpy(ptr
+1, new_mod
);
3441 TRACE("loading %s\n", debugstr_a(mod_path
));
3442 return LoadLibraryA(mod_path
);
3447 /*************************************************************************
3450 * Unicode version of MLLoadLibraryA.
3452 HMODULE WINAPI
MLLoadLibraryW(LPCWSTR new_mod
, HMODULE inst_hwnd
, BOOL bCrossCodePage
)
3454 WCHAR mod_path
[2*MAX_PATH
];
3458 FIXME("(%s,%p,%d) semi-stub!\n", debugstr_w(new_mod
), inst_hwnd
, bCrossCodePage
);
3459 len
= GetModuleFileNameW(inst_hwnd
, mod_path
, sizeof(mod_path
) / sizeof(WCHAR
));
3460 if (!len
|| len
>= sizeof(mod_path
) / sizeof(WCHAR
)) return NULL
;
3462 ptr
= strrchrW(mod_path
, '\\');
3464 strcpyW(ptr
+1, new_mod
);
3465 TRACE("loading %s\n", debugstr_w(mod_path
));
3466 return LoadLibraryW(mod_path
);
3471 /*************************************************************************
3472 * ColorAdjustLuma [SHLWAPI.@]
3474 * Adjust the luminosity of a color
3477 * cRGB [I] RGB value to convert
3478 * dwLuma [I] Luma adjustment
3479 * bUnknown [I] Unknown
3482 * The adjusted RGB color.
3484 COLORREF WINAPI
ColorAdjustLuma(COLORREF cRGB
, int dwLuma
, BOOL bUnknown
)
3486 TRACE("(0x%8lx,%d,%d)\n", cRGB
, dwLuma
, bUnknown
);
3492 ColorRGBToHLS(cRGB
, &wH
, &wL
, &wS
);
3494 FIXME("Ignoring luma adjustment\n");
3496 /* FIXME: The ajdustment is not linear */
3498 cRGB
= ColorHLSToRGB(wH
, wL
, wS
);
3503 /*************************************************************************
3506 * See GetSaveFileNameW.
3508 BOOL WINAPI
GetSaveFileNameWrapW(LPOPENFILENAMEW ofn
)
3510 GET_FUNC(pGetSaveFileNameW
, comdlg32
, "GetSaveFileNameW", FALSE
);
3511 return pGetSaveFileNameW(ofn
);
3514 /*************************************************************************
3517 * See WNetRestoreConnectionW.
3519 DWORD WINAPI
WNetRestoreConnectionWrapW(HWND hwndOwner
, LPWSTR lpszDevice
)
3521 GET_FUNC(pWNetRestoreConnectionW
, mpr
, "WNetRestoreConnectionW", 0);
3522 return pWNetRestoreConnectionW(hwndOwner
, lpszDevice
);
3525 /*************************************************************************
3528 * See WNetGetLastErrorW.
3530 DWORD WINAPI
WNetGetLastErrorWrapW(LPDWORD lpError
, LPWSTR lpErrorBuf
, DWORD nErrorBufSize
,
3531 LPWSTR lpNameBuf
, DWORD nNameBufSize
)
3533 GET_FUNC(pWNetGetLastErrorW
, mpr
, "WNetGetLastErrorW", 0);
3534 return pWNetGetLastErrorW(lpError
, lpErrorBuf
, nErrorBufSize
, lpNameBuf
, nNameBufSize
);
3537 /*************************************************************************
3540 * See PageSetupDlgW.
3542 BOOL WINAPI
PageSetupDlgWrapW(LPPAGESETUPDLGW pagedlg
)
3544 GET_FUNC(pPageSetupDlgW
, comdlg32
, "PageSetupDlgW", FALSE
);
3545 return pPageSetupDlgW(pagedlg
);
3548 /*************************************************************************
3553 BOOL WINAPI
PrintDlgWrapW(LPPRINTDLGW printdlg
)
3555 GET_FUNC(pPrintDlgW
, comdlg32
, "PrintDlgW", FALSE
);
3556 return pPrintDlgW(printdlg
);
3559 /*************************************************************************
3562 * See GetOpenFileNameW.
3564 BOOL WINAPI
GetOpenFileNameWrapW(LPOPENFILENAMEW ofn
)
3566 GET_FUNC(pGetOpenFileNameW
, comdlg32
, "GetOpenFileNameW", FALSE
);
3567 return pGetOpenFileNameW(ofn
);
3570 /*************************************************************************
3573 HRESULT WINAPI
IUnknown_EnumObjects(LPSHELLFOLDER lpFolder
, HWND hwnd
, SHCONTF flags
, IEnumIDList
**ppenum
)
3578 hr
= IShellFolder_QueryInterface(lpFolder
, &IID_IPersist
, (LPVOID
)&persist
);
3582 hr
= IPersist_GetClassID(persist
, &clsid
);
3585 if(IsEqualCLSID(&clsid
, &CLSID_ShellFSFolder
))
3586 hr
= IShellFolder_EnumObjects(lpFolder
, hwnd
, flags
, ppenum
);
3590 IPersist_Release(persist
);
3595 /* INTERNAL: Map from HLS color space to RGB */
3596 static WORD WINAPI
ConvertHue(int wHue
, WORD wMid1
, WORD wMid2
)
3598 wHue
= wHue
> 240 ? wHue
- 240 : wHue
< 0 ? wHue
+ 240 : wHue
;
3602 else if (wHue
> 120)
3607 return ((wHue
* (wMid2
- wMid1
) + 20) / 40) + wMid1
;
3610 /* Convert to RGB and scale into RGB range (0..255) */
3611 #define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240
3613 /*************************************************************************
3614 * ColorHLSToRGB [SHLWAPI.@]
3616 * Convert from hls color space into an rgb COLORREF.
3619 * wHue [I] Hue amount
3620 * wLuminosity [I] Luminosity amount
3621 * wSaturation [I] Saturation amount
3624 * A COLORREF representing the converted color.
3627 * Input hls values are constrained to the range (0..240).
3629 COLORREF WINAPI
ColorHLSToRGB(WORD wHue
, WORD wLuminosity
, WORD wSaturation
)
3635 WORD wGreen
, wBlue
, wMid1
, wMid2
;
3637 if (wLuminosity
> 120)
3638 wMid2
= wSaturation
+ wLuminosity
- (wSaturation
* wLuminosity
+ 120) / 240;
3640 wMid2
= ((wSaturation
+ 240) * wLuminosity
+ 120) / 240;
3642 wMid1
= wLuminosity
* 2 - wMid2
;
3644 wRed
= GET_RGB(wHue
+ 80);
3645 wGreen
= GET_RGB(wHue
);
3646 wBlue
= GET_RGB(wHue
- 80);
3648 return RGB(wRed
, wGreen
, wBlue
);
3651 wRed
= wLuminosity
* 255 / 240;
3652 return RGB(wRed
, wRed
, wRed
);
3655 /*************************************************************************
3658 * Get the current docking status of the system.
3661 * dwFlags [I] DOCKINFO_ flags from "winbase.h", unused
3664 * One of DOCKINFO_UNDOCKED, DOCKINFO_UNDOCKED, or 0 if the system is not
3667 DWORD WINAPI
SHGetMachineInfo(DWORD dwFlags
)
3669 HW_PROFILE_INFOA hwInfo
;
3671 TRACE("(0x%08lx)\n", dwFlags
);
3673 GetCurrentHwProfileA(&hwInfo
);
3674 switch (hwInfo
.dwDockInfo
& (DOCKINFO_DOCKED
|DOCKINFO_UNDOCKED
))
3676 case DOCKINFO_DOCKED
:
3677 case DOCKINFO_UNDOCKED
:
3678 return hwInfo
.dwDockInfo
& (DOCKINFO_DOCKED
|DOCKINFO_UNDOCKED
);
3684 /*************************************************************************
3687 * Function seems to do FreeLibrary plus other things.
3689 * FIXME native shows the following calls:
3690 * RtlEnterCriticalSection
3692 * GetProcAddress(Comctl32??, 150L)
3694 * RtlLeaveCriticalSection
3695 * followed by the FreeLibrary.
3696 * The above code may be related to .377 above.
3698 BOOL WINAPI
MLFreeLibrary(HMODULE hModule
)
3700 FIXME("(%p) semi-stub\n", hModule
);
3701 return FreeLibrary(hModule
);
3704 /*************************************************************************
3707 BOOL WINAPI
SHFlushSFCacheWrap(void) {
3712 /*************************************************************************
3715 BOOL WINAPI
DeleteMenuWrap(HMENU hmenu
, UINT pos
, UINT flags
)
3717 /* FIXME: This should do more than simply call DeleteMenu */
3718 FIXME("%p %08x %08x): semi-stub\n", hmenu
, pos
, flags
);
3719 return DeleteMenu(hmenu
, pos
, flags
);
3722 /*************************************************************************
3724 * FIXME I have no idea what this function does or what its arguments are.
3726 BOOL WINAPI
MLIsMLHInstance(HINSTANCE hInst
)
3728 FIXME("(%p) stub\n", hInst
);
3733 /*************************************************************************
3736 DWORD WINAPI
MLSetMLHInstance(HINSTANCE hInst
, HANDLE hHeap
)
3738 FIXME("(%p,%p) stub\n", hInst
, hHeap
);
3739 return E_FAIL
; /* This is what is used if shlwapi not loaded */
3742 /*************************************************************************
3745 DWORD WINAPI
MLClearMLHInstance(DWORD x
)
3747 FIXME("(0x%08lx)stub\n", x
);
3751 /*************************************************************************
3754 * Convert an Unicode string CLSID into a CLSID.
3757 * idstr [I] string containing a CLSID in text form
3758 * id [O] CLSID extracted from the string
3761 * S_OK on success or E_INVALIDARG on failure
3764 * This is really CLSIDFromString() which is exported by ole32.dll,
3765 * however the native shlwapi.dll does *not* import ole32. Nor does
3766 * ole32.dll import this ordinal from shlwapi. Therefore we must conclude
3767 * that MS duplicated the code for CLSIDFromString(), and yes they did, only
3768 * it returns an E_INVALIDARG error code on failure.
3769 * This is a duplicate (with changes for Unicode) of CLSIDFromString16()
3770 * in "dlls/ole32/compobj.c".
3772 HRESULT WINAPI
CLSIDFromStringWrap(LPCWSTR idstr
, CLSID
*id
)
3780 memset(id
, 0, sizeof(CLSID
));
3783 else { /* validate the CLSID string */
3785 if (strlenW(s
) != 38)
3786 return E_INVALIDARG
;
3788 if ((s
[0]!=L
'{') || (s
[9]!=L
'-') || (s
[14]!=L
'-') || (s
[19]!=L
'-') || (s
[24]!=L
'-') || (s
[37]!=L
'}'))
3789 return E_INVALIDARG
;
3791 for (i
=1; i
<37; i
++)
3793 if ((i
== 9)||(i
== 14)||(i
== 19)||(i
== 24))
3795 if (!(((s
[i
] >= L
'0') && (s
[i
] <= L
'9')) ||
3796 ((s
[i
] >= L
'a') && (s
[i
] <= L
'f')) ||
3797 ((s
[i
] >= L
'A') && (s
[i
] <= L
'F')))
3799 return E_INVALIDARG
;
3803 TRACE("%s -> %p\n", debugstr_w(s
), id
);
3805 /* quick lookup table */
3806 memset(table
, 0, 256*sizeof(WCHAR
));
3808 for (i
= 0; i
< 10; i
++) {
3811 for (i
= 0; i
< 6; i
++) {
3812 table
['A' + i
] = i
+10;
3813 table
['a' + i
] = i
+10;
3816 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
3820 s
++; /* skip leading brace */
3821 for (i
= 0; i
< 4; i
++) {
3822 p
[3 - i
] = table
[*s
]<<4 | table
[*(s
+1)];
3828 for (i
= 0; i
< 2; i
++) {
3829 p
[1-i
] = table
[*s
]<<4 | table
[*(s
+1)];
3835 for (i
= 0; i
< 2; i
++) {
3836 p
[1-i
] = table
[*s
]<<4 | table
[*(s
+1)];
3842 /* these are just sequential bytes */
3843 for (i
= 0; i
< 2; i
++) {
3844 *p
++ = table
[*s
]<<4 | table
[*(s
+1)];
3849 for (i
= 0; i
< 6; i
++) {
3850 *p
++ = table
[*s
]<<4 | table
[*(s
+1)];
3857 /*************************************************************************
3860 * Determine if the OS supports a given feature.
3863 * dwFeature [I] Feature requested (undocumented)
3866 * TRUE If the feature is available.
3867 * FALSE If the feature is not available.
3869 BOOL WINAPI
IsOS(DWORD feature
)
3871 OSVERSIONINFOA osvi
;
3872 DWORD platform
, majorv
, minorv
;
3874 osvi
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFOA
);
3875 if(!GetVersionExA(&osvi
)) {
3876 ERR("GetVersionEx failed");
3880 majorv
= osvi
.dwMajorVersion
;
3881 minorv
= osvi
.dwMinorVersion
;
3882 platform
= osvi
.dwPlatformId
;
3884 #define ISOS_RETURN(x) \
3885 TRACE("(0x%lx) ret=%d\n",feature,(x)); \
3889 case OS_WIN32SORGREATER
:
3890 ISOS_RETURN(platform
== VER_PLATFORM_WIN32s
3891 || platform
== VER_PLATFORM_WIN32_WINDOWS
)
3893 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3894 case OS_WIN95ORGREATER
:
3895 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
)
3896 case OS_NT4ORGREATER
:
3897 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 4)
3898 case OS_WIN2000ORGREATER_ALT
:
3899 case OS_WIN2000ORGREATER
:
3900 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5)
3901 case OS_WIN98ORGREATER
:
3902 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
&& minorv
>= 10)
3904 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
&& minorv
== 10)
3906 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5)
3907 case OS_WIN2000SERVER
:
3908 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& (minorv
== 0 || minorv
== 1))
3909 case OS_WIN2000ADVSERVER
:
3910 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& (minorv
== 0 || minorv
== 1))
3911 case OS_WIN2000DATACENTER
:
3912 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& (minorv
== 0 || minorv
== 1))
3913 case OS_WIN2000TERMINAL
:
3914 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& (minorv
== 0 || minorv
== 1))
3916 FIXME("(OS_EMBEDDED) What should we return here?\n");
3918 case OS_TERMINALCLIENT
:
3919 FIXME("(OS_TERMINALCLIENT) What should we return here?\n");
3921 case OS_TERMINALREMOTEADMIN
:
3922 FIXME("(OS_TERMINALREMOTEADMIN) What should we return here?\n");
3925 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
&& minorv
== 0)
3926 case OS_MEORGREATER
:
3927 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_WINDOWS
&& minorv
>= 90)
3928 case OS_XPORGREATER
:
3929 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5 && minorv
>= 1)
3931 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5 && minorv
>= 1)
3932 case OS_PROFESSIONAL
:
3933 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3935 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3937 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& majorv
>= 5)
3939 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3940 case OS_TERMINALSERVER
:
3941 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3942 case OS_PERSONALTERMINALSERVER
:
3943 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
&& minorv
>= 1 && majorv
>= 5)
3944 case OS_FASTUSERSWITCHING
:
3945 FIXME("(OS_FASTUSERSWITCHING) What should we return here?\n");
3947 case OS_WELCOMELOGONUI
:
3948 FIXME("(OS_WELCOMELOGONUI) What should we return here?\n");
3950 case OS_DOMAINMEMBER
:
3951 FIXME("(OS_DOMAINMEMBER) What should we return here?\n");
3954 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3956 FIXME("(OS_WOW6432) Should we check this?\n");
3959 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3960 case OS_SMALLBUSINESSSERVER
:
3961 ISOS_RETURN(platform
== VER_PLATFORM_WIN32_NT
)
3963 FIXME("(OS_TABLEPC) What should we return here?\n");
3965 case OS_SERVERADMINUI
:
3966 FIXME("(OS_SERVERADMINUI) What should we return here?\n");
3968 case OS_MEDIACENTER
:
3969 FIXME("(OS_MEDIACENTER) What should we return here?\n");
3972 FIXME("(OS_APPLIANCE) What should we return here?\n");
3978 WARN("(0x%lx) unknown parameter\n",feature
);
3983 /*************************************************************************
3986 HRESULT WINAPI
SHLoadRegUIStringW(HKEY hkey
, LPCWSTR value
, LPWSTR buf
, DWORD size
)
3988 DWORD type
, sz
= size
;
3990 if(RegQueryValueExW(hkey
, value
, NULL
, &type
, (LPBYTE
)buf
, &sz
) != ERROR_SUCCESS
)
3993 return SHLoadIndirectString(buf
, buf
, size
, NULL
);
3996 /*************************************************************************
3999 * Call IInputObject_TranslateAcceleratorIO() on an object.
4002 * lpUnknown [I] Object supporting the IInputObject interface.
4003 * lpMsg [I] Key message to be processed.
4007 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
4009 HRESULT WINAPI
IUnknown_TranslateAcceleratorIO(IUnknown
*lpUnknown
, LPMSG lpMsg
)
4011 IInputObject
* lpInput
= NULL
;
4012 HRESULT hRet
= E_INVALIDARG
;
4014 TRACE("(%p,%p)\n", lpUnknown
, lpMsg
);
4017 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IInputObject
,
4019 if (SUCCEEDED(hRet
) && lpInput
)
4021 hRet
= IInputObject_TranslateAcceleratorIO(lpInput
, lpMsg
);
4022 IInputObject_Release(lpInput
);
4028 /*************************************************************************
4031 * Call IInputObject_HasFocusIO() on an object.
4034 * lpUnknown [I] Object supporting the IInputObject interface.
4037 * Success: S_OK, if lpUnknown is an IInputObject object and has the focus,
4038 * or S_FALSE otherwise.
4039 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
4041 HRESULT WINAPI
IUnknown_HasFocusIO(IUnknown
*lpUnknown
)
4043 IInputObject
* lpInput
= NULL
;
4044 HRESULT hRet
= E_INVALIDARG
;
4046 TRACE("(%p)\n", lpUnknown
);
4049 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IInputObject
,
4051 if (SUCCEEDED(hRet
) && lpInput
)
4053 hRet
= IInputObject_HasFocusIO(lpInput
);
4054 IInputObject_Release(lpInput
);
4060 /*************************************************************************
4061 * ColorRGBToHLS [SHLWAPI.@]
4063 * Convert an rgb COLORREF into the hls color space.
4066 * cRGB [I] Source rgb value
4067 * pwHue [O] Destination for converted hue
4068 * pwLuminance [O] Destination for converted luminance
4069 * pwSaturation [O] Destination for converted saturation
4072 * Nothing. pwHue, pwLuminance and pwSaturation are set to the converted
4076 * Output HLS values are constrained to the range (0..240).
4077 * For Achromatic conversions, Hue is set to 160.
4079 VOID WINAPI
ColorRGBToHLS(COLORREF cRGB
, LPWORD pwHue
,
4080 LPWORD pwLuminance
, LPWORD pwSaturation
)
4082 int wR
, wG
, wB
, wMax
, wMin
, wHue
, wLuminosity
, wSaturation
;
4084 TRACE("(%08lx,%p,%p,%p)\n", cRGB
, pwHue
, pwLuminance
, pwSaturation
);
4086 wR
= GetRValue(cRGB
);
4087 wG
= GetGValue(cRGB
);
4088 wB
= GetBValue(cRGB
);
4090 wMax
= max(wR
, max(wG
, wB
));
4091 wMin
= min(wR
, min(wG
, wB
));
4094 wLuminosity
= ((wMax
+ wMin
) * 240 + 255) / 510;
4098 /* Achromatic case */
4100 /* Hue is now unrepresentable, but this is what native returns... */
4105 /* Chromatic case */
4106 int wDelta
= wMax
- wMin
, wRNorm
, wGNorm
, wBNorm
;
4109 if (wLuminosity
<= 120)
4110 wSaturation
= ((wMax
+ wMin
)/2 + wDelta
* 240) / (wMax
+ wMin
);
4112 wSaturation
= ((510 - wMax
- wMin
)/2 + wDelta
* 240) / (510 - wMax
- wMin
);
4115 wRNorm
= (wDelta
/2 + wMax
* 40 - wR
* 40) / wDelta
;
4116 wGNorm
= (wDelta
/2 + wMax
* 40 - wG
* 40) / wDelta
;
4117 wBNorm
= (wDelta
/2 + wMax
* 40 - wB
* 40) / wDelta
;
4120 wHue
= wBNorm
- wGNorm
;
4121 else if (wG
== wMax
)
4122 wHue
= 80 + wRNorm
- wBNorm
;
4124 wHue
= 160 + wGNorm
- wRNorm
;
4127 else if (wHue
> 240)
4133 *pwLuminance
= wLuminosity
;
4135 *pwSaturation
= wSaturation
;
4138 /*************************************************************************
4139 * SHCreateShellPalette [SHLWAPI.@]
4141 HPALETTE WINAPI
SHCreateShellPalette(HDC hdc
)
4144 return CreateHalftonePalette(hdc
);
4147 /*************************************************************************
4148 * SHGetInverseCMAP (SHLWAPI.@)
4150 * Get an inverse color map table.
4153 * lpCmap [O] Destination for color map
4154 * dwSize [I] Size of memory pointed to by lpCmap
4158 * Failure: E_POINTER, If lpCmap is invalid.
4159 * E_INVALIDARG, If dwFlags is invalid
4160 * E_OUTOFMEMORY, If there is no memory available
4163 * dwSize may only be CMAP_PTR_SIZE (4) or CMAP_SIZE (8192).
4164 * If dwSize = CMAP_PTR_SIZE, *lpCmap is set to the address of this DLL's
4166 * If dwSize = CMAP_SIZE, lpCmap is filled with a copy of the data from
4167 * this DLL's internal CMap.
4169 HRESULT WINAPI
SHGetInverseCMAP(LPDWORD dest
, DWORD dwSize
)
4172 FIXME(" - returning bogus address for SHGetInverseCMAP\n");
4173 *dest
= (DWORD
)0xabba1249;
4176 FIXME("(%p, %#lx) stub\n", dest
, dwSize
);
4180 /*************************************************************************
4181 * SHIsLowMemoryMachine [SHLWAPI.@]
4183 * Determine if the current computer has low memory.
4189 * TRUE if the users machine has 16 Megabytes of memory or less,
4192 BOOL WINAPI
SHIsLowMemoryMachine (DWORD x
)
4194 FIXME("(0x%08lx) stub\n", x
);
4198 /*************************************************************************
4199 * GetMenuPosFromID [SHLWAPI.@]
4201 * Return the position of a menu item from its Id.
4204 * hMenu [I] Menu containing the item
4205 * wID [I] Id of the menu item
4208 * Success: The index of the menu item in hMenu.
4209 * Failure: -1, If the item is not found.
4211 INT WINAPI
GetMenuPosFromID(HMENU hMenu
, UINT wID
)
4214 INT nCount
= GetMenuItemCount(hMenu
), nIter
= 0;
4216 while (nIter
< nCount
)
4218 mi
.cbSize
= sizeof(mi
);
4220 if (GetMenuItemInfoW(hMenu
, nIter
, TRUE
, &mi
) && mi
.wID
== wID
)
4227 /*************************************************************************
4230 * Same as SHLWAPI.GetMenuPosFromID
4232 DWORD WINAPI
SHMenuIndexFromID(HMENU hMenu
, UINT uID
)
4234 return GetMenuPosFromID(hMenu
, uID
);
4238 /*************************************************************************
4241 VOID WINAPI
FixSlashesAndColonW(LPWSTR lpwstr
)
4252 /*************************************************************************
4255 DWORD WINAPI
SHGetAppCompatFlags(DWORD dwUnknown
)
4257 FIXME("(0x%08lx) stub\n", dwUnknown
);
4262 /*************************************************************************
4265 HRESULT WINAPI
SHCoCreateInstanceAC(REFCLSID rclsid
, LPUNKNOWN pUnkOuter
,
4266 DWORD dwClsContext
, REFIID iid
, LPVOID
*ppv
)
4268 return CoCreateInstance(rclsid
, pUnkOuter
, dwClsContext
, iid
, ppv
);
4271 /*************************************************************************
4272 * SHSkipJunction [SHLWAPI.@]
4274 * Determine if a bind context can be bound to an object
4277 * pbc [I] Bind context to check
4278 * pclsid [I] CLSID of object to be bound to
4281 * TRUE: If it is safe to bind
4282 * FALSE: If pbc is invalid or binding would not be safe
4285 BOOL WINAPI
SHSkipJunction(IBindCtx
*pbc
, const CLSID
*pclsid
)
4287 static const WCHAR szSkipBinding
[] = { 'S','k','i','p',' ',
4288 'B','i','n','d','i','n','g',' ','C','L','S','I','D','\0' };
4295 if (SUCCEEDED(IBindCtx_GetObjectParam(pbc
, (LPOLESTR
)szSkipBinding
, &lpUnk
)))
4299 if (SUCCEEDED(IUnknown_GetClassID(lpUnk
, &clsid
)) &&
4300 IsEqualGUID(pclsid
, &clsid
))
4303 IUnknown_Release(lpUnk
);
4309 /***********************************************************************
4310 * SHGetShellKey (SHLWAPI.@)
4312 DWORD WINAPI
SHGetShellKey(DWORD a
, DWORD b
, DWORD c
)
4314 FIXME("(%lx, %lx, %lx): stub\n", a
, b
, c
);
4318 /***********************************************************************
4319 * SHQueueUserWorkItem (SHLWAPI.@)
4321 HRESULT WINAPI
SHQueueUserWorkItem(DWORD a
, DWORD b
, DWORD c
, DWORD d
, DWORD e
, DWORD f
, DWORD g
)
4323 FIXME("(%lx, %lx, %lx, %lx, %lx, %lx, %lx): stub\n", a
, b
, c
, d
, e
, f
, g
);
4327 /***********************************************************************
4328 * IUnknown_OnFocusChangeIS (SHLWAPI.@)
4330 HRESULT WINAPI
IUnknown_OnFocusChangeIS(LPUNKNOWN lpUnknown
, LPUNKNOWN pFocusObject
, BOOL bFocus
)
4332 IInputObjectSite
*pIOS
= NULL
;
4333 HRESULT hRet
= E_INVALIDARG
;
4335 TRACE("(%p, %p, %s)\n", lpUnknown
, pFocusObject
, bFocus
? "TRUE" : "FALSE");
4339 hRet
= IUnknown_QueryInterface(lpUnknown
, &IID_IInputObjectSite
,
4341 if (SUCCEEDED(hRet
) && pIOS
)
4343 hRet
= IInputObjectSite_OnFocusChangeIS(pIOS
, pFocusObject
, bFocus
);
4344 IInputObjectSite_Release(pIOS
);
4350 /***********************************************************************
4351 * SHGetValueW (SHLWAPI.@)
4353 HRESULT WINAPI
SKGetValueW(DWORD a
, LPWSTR b
, LPWSTR c
, DWORD d
, DWORD e
, DWORD f
)
4355 FIXME("(%lx, %s, %s, %lx, %lx, %lx): stub\n", a
, debugstr_w(b
), debugstr_w(c
), d
, e
, f
);
4359 typedef HRESULT (WINAPI
*DllGetVersion_func
)(DLLVERSIONINFO
*);
4361 /***********************************************************************
4362 * GetUIVersion (SHLWAPI.452)
4364 DWORD WINAPI
GetUIVersion(void)
4366 static DWORD version
;
4370 DllGetVersion_func pDllGetVersion
;
4371 HMODULE dll
= LoadLibraryA("shell32.dll");
4374 pDllGetVersion
= (DllGetVersion_func
)GetProcAddress(dll
, "DllGetVersion");
4378 dvi
.cbSize
= sizeof(DLLVERSIONINFO
);
4379 if (pDllGetVersion(&dvi
) == S_OK
) version
= dvi
.dwMajorVersion
;
4382 if (!version
) version
= 3; /* old shell dlls don't have DllGetVersion */
4387 /***********************************************************************
4388 * ShellMessageBoxWrapW [SHLWAPI.388]
4390 * loads a string resource for a module, displays the string in a
4391 * message box and writes it into the logfile
4394 * mod [I] the module containing the string resource
4395 * unknown1 [I] FIXME
4396 * uId [I] the id of the string resource
4397 * title [I] the title of the message box
4398 * unknown2 [I] FIXME
4399 * filename [I] name of the logfile
4404 BOOL WINAPI
ShellMessageBoxWrapW(HMODULE mod
, DWORD unknown1
, UINT uId
,
4405 LPCWSTR title
, DWORD unknown2
, LPCWSTR filename
)
4407 FIXME("%p %lx %d %s %lx %s\n",
4408 mod
, unknown1
, uId
, debugstr_w(title
), unknown2
, debugstr_w(filename
));
4412 HRESULT WINAPI
IUnknown_QueryServiceExec(IUnknown
*unk
, REFIID service
, REFIID clsid
,
4413 DWORD x1
, DWORD x2
, DWORD x3
, void **ppvOut
)
4415 FIXME("%p %s %s %08lx %08lx %08lx %p\n", unk
,
4416 debugstr_guid(service
), debugstr_guid(clsid
), x1
, x2
, x3
, ppvOut
);
4420 HRESULT WINAPI
IUnknown_ProfferService(IUnknown
*unk
, void *x0
, void *x1
, void *x2
)
4422 FIXME("%p %p %p %p\n", unk
, x0
, x1
, x2
);