2 * SHLWAPI ordinal functions
4 * Copyright 1997 Marcus Meissner
6 * 2001-2003 Jon Griffiths
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "wine/port.h"
31 #define NONAMELESSUNION
32 #define NONAMELESSSTRUCT
46 #include "wine/unicode.h"
48 #include "wine/debug.h"
52 WINE_DEFAULT_DEBUG_CHANNEL(shell);
54 /* Get a function pointer from a DLL handle */
55 #define GET_FUNC(func, module, name, fail) \
58 if (!SHLWAPI_h##module && !(SHLWAPI_h##module = LoadLibraryA(#module ".dll"))) return fail; \
59 func = (fn##func)GetProcAddress(SHLWAPI_h##module, name); \
60 if (!func) return fail; \
64 /* DLL handles for late bound calls */
65 extern HINSTANCE shlwapi_hInstance;
66 extern HMODULE SHLWAPI_hshell32;
67 extern HMODULE SHLWAPI_hwinmm;
68 extern HMODULE SHLWAPI_hcomdlg32;
69 extern HMODULE SHLWAPI_hcomctl32;
70 extern HMODULE SHLWAPI_hmpr;
71 extern HMODULE SHLWAPI_hurlmon;
72 extern HMODULE SHLWAPI_hversion;
74 extern DWORD SHLWAPI_ThreadRef_index;
76 /* Function pointers for GET_FUNC macro; these need to be global because of gcc bug */
77 typedef LPITEMIDLIST (WINAPI *fnpSHBrowseForFolderW)(LPBROWSEINFOW);
78 static fnpSHBrowseForFolderW pSHBrowseForFolderW;
79 typedef BOOL (WINAPI *fnpPlaySoundW)(LPCWSTR, HMODULE, DWORD);
80 static fnpPlaySoundW pPlaySoundW;
81 typedef DWORD (WINAPI *fnpSHGetFileInfoW)(LPCWSTR,DWORD,SHFILEINFOW*,UINT,UINT);
82 static fnpSHGetFileInfoW pSHGetFileInfoW;
83 typedef UINT (WINAPI *fnpDragQueryFileW)(HDROP, UINT, LPWSTR, UINT);
84 static fnpDragQueryFileW pDragQueryFileW;
85 typedef BOOL (WINAPI *fnpSHGetPathFromIDListW)(LPCITEMIDLIST, LPWSTR);
86 static fnpSHGetPathFromIDListW pSHGetPathFromIDListW;
87 typedef BOOL (WINAPI *fnpShellExecuteExW)(LPSHELLEXECUTEINFOW);
88 static fnpShellExecuteExW pShellExecuteExW;
89 typedef HICON (WINAPI *fnpSHFileOperationW)(LPSHFILEOPSTRUCTW);
90 static fnpSHFileOperationW pSHFileOperationW;
91 typedef UINT (WINAPI *fnpExtractIconExW)(LPCWSTR, INT,HICON *,HICON *, UINT);
92 static fnpExtractIconExW pExtractIconExW;
93 typedef BOOL (WINAPI *fnpSHGetNewLinkInfoW)(LPCWSTR, LPCWSTR, LPCWSTR, BOOL*, UINT);
94 static fnpSHGetNewLinkInfoW pSHGetNewLinkInfoW;
95 typedef HRESULT (WINAPI *fnpSHDefExtractIconW)(LPCWSTR, int, UINT, HICON*, HICON*, UINT);
96 static fnpSHDefExtractIconW pSHDefExtractIconW;
97 typedef HICON (WINAPI *fnpExtractIconW)(HINSTANCE, LPCWSTR, UINT);
98 static fnpExtractIconW pExtractIconW;
99 typedef BOOL (WINAPI *fnpGetSaveFileNameW)(LPOPENFILENAMEW);
100 static fnpGetSaveFileNameW pGetSaveFileNameW;
101 typedef DWORD (WINAPI *fnpWNetRestoreConnectionW)(HWND, LPWSTR);
102 static fnpWNetRestoreConnectionW pWNetRestoreConnectionW;
103 typedef DWORD (WINAPI *fnpWNetGetLastErrorW)(LPDWORD, LPWSTR, DWORD, LPWSTR, DWORD);
104 static fnpWNetGetLastErrorW pWNetGetLastErrorW;
105 typedef BOOL (WINAPI *fnpPageSetupDlgW)(LPPAGESETUPDLGW);
106 static fnpPageSetupDlgW pPageSetupDlgW;
107 typedef BOOL (WINAPI *fnpPrintDlgW)(LPPRINTDLGW);
108 static fnpPrintDlgW pPrintDlgW;
109 typedef BOOL (WINAPI *fnpGetOpenFileNameW)(LPOPENFILENAMEW);
110 static fnpGetOpenFileNameW pGetOpenFileNameW;
111 typedef DWORD (WINAPI *fnpGetFileVersionInfoSizeW)(LPCWSTR,LPDWORD);
112 static fnpGetFileVersionInfoSizeW pGetFileVersionInfoSizeW;
113 typedef BOOL (WINAPI *fnpGetFileVersionInfoW)(LPCWSTR,DWORD,DWORD,LPVOID);
114 static fnpGetFileVersionInfoW pGetFileVersionInfoW;
115 typedef WORD (WINAPI *fnpVerQueryValueW)(LPVOID,LPCWSTR,LPVOID*,UINT*);
116 static fnpVerQueryValueW pVerQueryValueW;
117 typedef BOOL (WINAPI *fnpCOMCTL32_417)(HDC,INT,INT,UINT,const RECT*,LPCWSTR,UINT,const INT*);
118 static fnpCOMCTL32_417 pCOMCTL32_417;
119 typedef HRESULT (WINAPI *fnpDllGetVersion)(DLLVERSIONINFO*);
120 static fnpDllGetVersion pDllGetVersion;
121 typedef HRESULT (WINAPI *fnpCreateFormatEnumerator)(UINT,FORMATETC*,IEnumFORMATETC**);
122 static fnpCreateFormatEnumerator pCreateFormatEnumerator;
123 typedef HRESULT (WINAPI *fnpRegisterFormatEnumerator)(LPBC,IEnumFORMATETC*,DWORD);
124 static fnpRegisterFormatEnumerator pRegisterFormatEnumerator;
126 HRESULT WINAPI IUnknown_QueryService(IUnknown*,REFGUID,REFIID,LPVOID*);
127 HRESULT WINAPI SHInvokeCommand(HWND,IShellFolder*,LPCITEMIDLIST,BOOL);
128 HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR,CLSID*);
129 BOOL WINAPI SHAboutInfoW(LPWSTR,DWORD);
132 NOTES: Most functions exported by ordinal seem to be superflous.
133 The reason for these functions to be there is to provide a wrapper
134 for unicode functions to provide these functions on systems without
135 unicode functions eg. win95/win98. Since we have such functions we just
136 call these. If running Wine with native DLLs, some late bound calls may
137 fail. However, it is better to implement the functions in the forward DLL
138 and recommend the builtin rather than reimplementing the calls here!
141 /*************************************************************************
142 * SHLWAPI_DupSharedHandle
144 * Internal implemetation of SHLWAPI_11.
147 HANDLE WINAPI SHLWAPI_DupSharedHandle(HANDLE hShared, DWORD dwDstProcId,
148 DWORD dwSrcProcId, DWORD dwAccess,
152 DWORD dwMyProcId = GetCurrentProcessId();
155 TRACE("(%p,%d,%d,%08x,%08x)\n", hShared, dwDstProcId, dwSrcProcId,
156 dwAccess, dwOptions);
158 /* Get dest process handle */
159 if (dwDstProcId == dwMyProcId)
160 hDst = GetCurrentProcess();
162 hDst = OpenProcess(PROCESS_DUP_HANDLE, 0, dwDstProcId);
166 /* Get src process handle */
167 if (dwSrcProcId == dwMyProcId)
168 hSrc = GetCurrentProcess();
170 hSrc = OpenProcess(PROCESS_DUP_HANDLE, 0, dwSrcProcId);
174 /* Make handle available to dest process */
175 if (!DuplicateHandle(hDst, hShared, hSrc, &hRet,
176 dwAccess, 0, dwOptions | DUPLICATE_SAME_ACCESS))
179 if (dwSrcProcId != dwMyProcId)
183 if (dwDstProcId != dwMyProcId)
187 TRACE("Returning handle %p\n", hRet);
191 /*************************************************************************
194 * Create a block of sharable memory and initialise it with data.
197 * lpvData [I] Pointer to data to write
198 * dwSize [I] Size of data
199 * dwProcId [I] ID of process owning data
202 * Success: A shared memory handle
206 * Ordinals 7-11 provide a set of calls to create shared memory between a
207 * group of processes. The shared memory is treated opaquely in that its size
208 * is not exposed to clients who map it. This is accomplished by storing
209 * the size of the map as the first DWORD of mapped data, and then offsetting
210 * the view pointer returned by this size.
213 HANDLE WINAPI SHAllocShared(LPCVOID lpvData, DWORD dwSize, DWORD dwProcId)
219 TRACE("(%p,%d,%d)\n", lpvData, dwSize, dwProcId);
221 /* Create file mapping of the correct length */
222 hMap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, FILE_MAP_READ, 0,
223 dwSize + sizeof(dwSize), NULL);
227 /* Get a view in our process address space */
228 pMapped = MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
232 /* Write size of data, followed by the data, to the view */
233 *((DWORD*)pMapped) = dwSize;
235 memcpy((char *) pMapped + sizeof(dwSize), lpvData, dwSize);
237 /* Release view. All further views mapped will be opaque */
238 UnmapViewOfFile(pMapped);
239 hRet = SHLWAPI_DupSharedHandle(hMap, dwProcId,
240 GetCurrentProcessId(), FILE_MAP_ALL_ACCESS,
241 DUPLICATE_SAME_ACCESS);
248 /*************************************************************************
251 * Get a pointer to a block of shared memory from a shared memory handle.
254 * hShared [I] Shared memory handle
255 * dwProcId [I] ID of process owning hShared
258 * Success: A pointer to the shared memory
262 PVOID WINAPI SHLockShared(HANDLE hShared, DWORD dwProcId)
267 TRACE("(%p %d)\n", hShared, dwProcId);
269 /* Get handle to shared memory for current process */
270 hDup = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
271 FILE_MAP_ALL_ACCESS, 0);
273 pMapped = MapViewOfFile(hDup, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
277 return (char *) pMapped + sizeof(DWORD); /* Hide size */
281 /*************************************************************************
284 * Release a pointer to a block of shared memory.
287 * lpView [I] Shared memory pointer
294 BOOL WINAPI SHUnlockShared(LPVOID lpView)
296 TRACE("(%p)\n", lpView);
297 return UnmapViewOfFile((char *) lpView - sizeof(DWORD)); /* Include size */
300 /*************************************************************************
303 * Destroy a block of sharable memory.
306 * hShared [I] Shared memory handle
307 * dwProcId [I] ID of process owning hShared
314 BOOL WINAPI SHFreeShared(HANDLE hShared, DWORD dwProcId)
318 TRACE("(%p %d)\n", hShared, dwProcId);
320 /* Get a copy of the handle for our process, closing the source handle */
321 hClose = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
322 FILE_MAP_ALL_ACCESS,DUPLICATE_CLOSE_SOURCE);
323 /* Close local copy */
324 return CloseHandle(hClose);
327 /*************************************************************************
330 * Copy a sharable memory handle from one process to another.
333 * hShared [I] Shared memory handle to duplicate
334 * dwDstProcId [I] ID of the process wanting the duplicated handle
335 * dwSrcProcId [I] ID of the process owning hShared
336 * dwAccess [I] Desired DuplicateHandle() access
337 * dwOptions [I] Desired DuplicateHandle() options
340 * Success: A handle suitable for use by the dwDstProcId process.
341 * Failure: A NULL handle.
344 HANDLE WINAPI SHMapHandle(HANDLE hShared, DWORD dwDstProcId, DWORD dwSrcProcId,
345 DWORD dwAccess, DWORD dwOptions)
349 hRet = SHLWAPI_DupSharedHandle(hShared, dwDstProcId, dwSrcProcId,
350 dwAccess, dwOptions);
354 /*************************************************************************
357 * Create and register a clipboard enumerator for a web browser.
360 * lpBC [I] Binding context
361 * lpUnknown [I] An object exposing the IWebBrowserApp interface
365 * Failure: An HRESULT error code.
368 * The enumerator is stored as a property of the web browser. If it does not
369 * yet exist, it is created and set before being registered.
371 HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown)
373 static const WCHAR szProperty[] = { '{','D','0','F','C','A','4','2','0',
374 '-','D','3','F','5','-','1','1','C','F', '-','B','2','1','1','-','0',
375 '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 property = SysAllocString(szProperty);
393 hRet = IWebBrowserApp_GetProperty(pBrowser, property, &var);
394 SysFreeString(property);
398 if (V_VT(&var) == VT_EMPTY)
400 /* Iterate through accepted documents and RegisterClipBoardFormatA() them */
401 char szKeyBuff[128], szValueBuff[128];
402 DWORD dwKeySize, dwValueSize, dwRet = 0, dwCount = 0, dwNumValues, dwType;
403 FORMATETC* formatList, *format;
406 TRACE("Registering formats and creating IEnumFORMATETC instance\n");
408 if (!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\Current"
409 "Version\\Internet Settings\\Accepted Documents", &hDocs))
412 /* Get count of values in key */
415 dwKeySize = sizeof(szKeyBuff);
416 dwRet = RegEnumValueA(hDocs,dwCount,szKeyBuff,&dwKeySize,0,&dwType,0,0);
420 dwNumValues = dwCount;
422 /* Note: dwCount = number of items + 1; The extra item is the end node */
423 format = formatList = HeapAlloc(GetProcessHeap(), 0, dwCount * sizeof(FORMATETC));
425 return E_OUTOFMEMORY;
434 /* Register clipboard formats for the values and populate format list */
435 while(!dwRet && dwCount < dwNumValues)
437 dwKeySize = sizeof(szKeyBuff);
438 dwValueSize = sizeof(szValueBuff);
439 dwRet = RegEnumValueA(hDocs, dwCount, szKeyBuff, &dwKeySize, 0, &dwType,
440 (PBYTE)szValueBuff, &dwValueSize);
444 format->cfFormat = RegisterClipboardFormatA(szValueBuff);
446 format->dwAspect = 1;
455 /* Terminate the (maybe empty) list, last entry has a cfFormat of 0 */
456 format->cfFormat = 0;
458 format->dwAspect = 1;
462 /* Create a clipboard enumerator */
463 GET_FUNC(pCreateFormatEnumerator, urlmon, "CreateFormatEnumerator", E_FAIL);
464 hRet = pCreateFormatEnumerator(dwNumValues, formatList, &pIEnumFormatEtc);
466 if (FAILED(hRet) || !pIEnumFormatEtc)
469 /* Set our enumerator as the browsers property */
470 V_VT(&var) = VT_UNKNOWN;
471 V_UNKNOWN(&var) = (IUnknown*)pIEnumFormatEtc;
473 hRet = IWebBrowserApp_PutProperty(pBrowser, (BSTR)szProperty, var);
476 IEnumFORMATETC_Release(pIEnumFormatEtc);
477 goto RegisterDefaultAcceptHeaders_Exit;
481 if (V_VT(&var) == VT_UNKNOWN)
483 /* Our variant is holding the clipboard enumerator */
484 IUnknown* pIUnknown = V_UNKNOWN(&var);
485 IEnumFORMATETC* pClone = NULL;
487 TRACE("Retrieved IEnumFORMATETC property\n");
489 /* Get an IEnumFormatEtc interface from the variants value */
490 pIEnumFormatEtc = NULL;
491 hRet = IUnknown_QueryInterface(pIUnknown, &IID_IEnumFORMATETC,
492 (PVOID)&pIEnumFormatEtc);
493 if (!hRet && pIEnumFormatEtc)
495 /* Clone and register the enumerator */
496 hRet = IEnumFORMATETC_Clone(pIEnumFormatEtc, &pClone);
499 GET_FUNC(pRegisterFormatEnumerator, urlmon, "RegisterFormatEnumerator", E_FAIL);
500 pRegisterFormatEnumerator(lpBC, pClone, 0);
502 IEnumFORMATETC_Release(pClone);
505 /* Release the IEnumFormatEtc interface */
506 IEnumFORMATETC_Release(pIUnknown);
508 IUnknown_Release(V_UNKNOWN(&var));
511 RegisterDefaultAcceptHeaders_Exit:
512 IWebBrowserApp_Release(pBrowser);
516 /*************************************************************************
519 * Get Explorers "AcceptLanguage" setting.
522 * langbuf [O] Destination for language string
523 * buflen [I] Length of langbuf
524 * [0] Success: used length of langbuf
527 * Success: S_OK. langbuf is set to the language string found.
528 * Failure: E_FAIL, If any arguments are invalid, error occurred, or Explorer
529 * does not contain the setting.
530 * E_INVALIDARG, If the buffer is not big enough
532 HRESULT WINAPI GetAcceptLanguagesW( LPWSTR langbuf, LPDWORD buflen)
534 static const WCHAR szkeyW[] = {
535 'S','o','f','t','w','a','r','e','\\',
536 'M','i','c','r','o','s','o','f','t','\\',
537 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
538 'I','n','t','e','r','n','a','t','i','o','n','a','l',0};
539 static const WCHAR valueW[] = {
540 'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0};
541 static const WCHAR enusW[] = {'e','n','-','u','s',0};
542 DWORD mystrlen, mytype;
548 if(!langbuf || !buflen || !*buflen)
551 mystrlen = (*buflen > 20) ? *buflen : 20 ;
552 mystr = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * mystrlen);
553 RegOpenKeyW(HKEY_CURRENT_USER, szkeyW, &mykey);
554 if(RegQueryValueExW(mykey, valueW, 0, &mytype, (PBYTE)mystr, &mystrlen)) {
555 /* Did not find value */
556 mylcid = GetUserDefaultLCID();
557 /* somehow the mylcid translates into "en-us"
558 * this is similar to "LOCALE_SABBREVLANGNAME"
559 * which could be gotten via GetLocaleInfo.
560 * The only problem is LOCALE_SABBREVLANGUAGE" is
561 * a 3 char string (first 2 are country code and third is
562 * letter for "sublanguage", which does not come close to
565 lstrcpyW(mystr, enusW);
566 mystrlen = lstrlenW(mystr);
568 /* handle returned string */
569 FIXME("missing code\n");
571 memcpy( langbuf, mystr, min(*buflen,strlenW(mystr)+1)*sizeof(WCHAR) );
573 if(*buflen > strlenW(mystr)) {
574 *buflen = strlenW(mystr);
578 retval = E_INVALIDARG;
579 SetLastError(ERROR_INSUFFICIENT_BUFFER);
582 HeapFree(GetProcessHeap(), 0, mystr);
586 /*************************************************************************
589 * Ascii version of GetAcceptLanguagesW.
591 HRESULT WINAPI GetAcceptLanguagesA( LPSTR langbuf, LPDWORD buflen)
594 DWORD buflenW, convlen;
597 if(!langbuf || !buflen || !*buflen) return E_FAIL;
600 langbufW = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * buflenW);
601 retval = GetAcceptLanguagesW(langbufW, &buflenW);
603 /* FIXME: this is wrong, the string may not be null-terminated */
604 convlen = WideCharToMultiByte(CP_ACP, 0, langbufW, -1, langbuf,
605 *buflen, NULL, NULL);
606 *buflen = buflenW ? convlen : 0;
608 HeapFree(GetProcessHeap(), 0, langbufW);
612 /*************************************************************************
615 * Convert a GUID to a string.
618 * guid [I] GUID to convert
619 * lpszDest [O] Destination for string
620 * cchMax [I] Length of output buffer
623 * The length of the string created.
625 INT WINAPI SHStringFromGUIDA(REFGUID guid, LPSTR lpszDest, INT cchMax)
630 TRACE("(%s,%p,%d)\n", debugstr_guid(guid), lpszDest, cchMax);
632 sprintf(xguid, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
633 guid->Data1, guid->Data2, guid->Data3,
634 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
635 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
637 iLen = strlen(xguid) + 1;
641 memcpy(lpszDest, xguid, iLen);
645 /*************************************************************************
648 * Convert a GUID to a string.
651 * guid [I] GUID to convert
652 * str [O] Destination for string
653 * cmax [I] Length of output buffer
656 * The length of the string created.
658 INT WINAPI SHStringFromGUIDW(REFGUID guid, LPWSTR lpszDest, INT cchMax)
662 static const WCHAR wszFormat[] = {'{','%','0','8','l','X','-','%','0','4','X','-','%','0','4','X','-',
663 '%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','%','0','2','X','%','0','2',
664 'X','%','0','2','X','%','0','2','X','}',0};
666 TRACE("(%s,%p,%d)\n", debugstr_guid(guid), lpszDest, cchMax);
668 sprintfW(xguid, wszFormat, guid->Data1, guid->Data2, guid->Data3,
669 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
670 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
672 iLen = strlenW(xguid) + 1;
676 memcpy(lpszDest, xguid, iLen*sizeof(WCHAR));
680 /*************************************************************************
683 * Determine if a Unicode character is a space.
686 * wc [I] Character to check.
689 * TRUE, if wc is a space,
692 BOOL WINAPI IsCharSpaceW(WCHAR wc)
696 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_SPACE);
699 /*************************************************************************
702 * Determine if a Unicode character is a blank.
705 * wc [I] Character to check.
708 * TRUE, if wc is a blank,
712 BOOL WINAPI IsCharBlankW(WCHAR wc)
716 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_BLANK);
719 /*************************************************************************
722 * Determine if a Unicode character is punctuation.
725 * wc [I] Character to check.
728 * TRUE, if wc is punctuation,
731 BOOL WINAPI IsCharPunctW(WCHAR wc)
735 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_PUNCT);
738 /*************************************************************************
741 * Determine if a Unicode character is a control character.
744 * wc [I] Character to check.
747 * TRUE, if wc is a control character,
750 BOOL WINAPI IsCharCntrlW(WCHAR wc)
754 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_CNTRL);
757 /*************************************************************************
760 * Determine if a Unicode character is a digit.
763 * wc [I] Character to check.
766 * TRUE, if wc is a digit,
769 BOOL WINAPI IsCharDigitW(WCHAR wc)
773 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_DIGIT);
776 /*************************************************************************
779 * Determine if a Unicode character is a hex digit.
782 * wc [I] Character to check.
785 * TRUE, if wc is a hex digit,
788 BOOL WINAPI IsCharXDigitW(WCHAR wc)
792 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_XDIGIT);
795 /*************************************************************************
799 BOOL WINAPI GetStringType3ExW(LPWSTR lpszStr, DWORD dwLen, LPVOID p3)
801 FIXME("(%s,0x%08x,%p): stub\n", debugstr_w(lpszStr), dwLen, p3);
805 /*************************************************************************
808 * Insert a bitmap menu item at the bottom of a menu.
811 * hMenu [I] Menu to insert into
812 * flags [I] Flags for insertion
813 * id [I] Menu ID of the item
814 * str [I] Menu text for the item
817 * Success: TRUE, the item is inserted into the menu
818 * Failure: FALSE, if any parameter is invalid
820 BOOL WINAPI AppendMenuWrapW(HMENU hMenu, UINT flags, UINT id, LPCWSTR str)
822 TRACE("(%p,0x%08x,0x%08x,%s)\n",hMenu, flags, id, debugstr_w(str));
823 return InsertMenuW(hMenu, -1, flags | MF_BITMAP, id, str);
826 /*************************************************************************
829 * Get the text from a given dialog item.
832 * hWnd [I] Handle of dialog
833 * nItem [I] Index of item
834 * lpsDest [O] Buffer for receiving window text
835 * nDestLen [I] Length of buffer.
838 * Success: The length of the returned text.
841 INT WINAPI GetDlgItemTextWrapW(HWND hWnd, INT nItem, LPWSTR lpsDest,INT nDestLen)
843 HWND hItem = GetDlgItem(hWnd, nItem);
846 return GetWindowTextW(hItem, lpsDest, nDestLen);
848 *lpsDest = (WCHAR)'\0';
852 /*************************************************************************
855 * Set the text of a given dialog item.
858 * hWnd [I] Handle of dialog
859 * iItem [I] Index of item
860 * lpszText [O] Text to set
863 * Success: TRUE. The text of the dialog is set to lpszText.
864 * Failure: FALSE, Otherwise.
866 BOOL WINAPI SetDlgItemTextWrapW(HWND hWnd, INT iItem, LPCWSTR lpszText)
868 HWND hWndItem = GetDlgItem(hWnd, iItem);
870 return SetWindowTextW(hWndItem, lpszText);
874 /*************************************************************************
877 * Compare two Ascii strings up to a given length.
880 * lpszSrc [I] Source string
881 * lpszCmp [I] String to compare to lpszSrc
882 * len [I] Maximum length
885 * A number greater than, less than or equal to 0 depending on whether
886 * lpszSrc is greater than, less than or equal to lpszCmp.
888 DWORD WINAPI StrCmpNCA(LPCSTR lpszSrc, LPCSTR lpszCmp, INT len)
890 return strncmp(lpszSrc, lpszCmp, len);
893 /*************************************************************************
896 * Unicode version of StrCmpNCA.
898 DWORD WINAPI StrCmpNCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, INT len)
900 return strncmpW(lpszSrc, lpszCmp, len);
903 /*************************************************************************
906 * Compare two Ascii strings up to a given length, ignoring case.
909 * lpszSrc [I] Source string
910 * lpszCmp [I] String to compare to lpszSrc
911 * len [I] Maximum length
914 * A number greater than, less than or equal to 0 depending on whether
915 * lpszSrc is greater than, less than or equal to lpszCmp.
917 DWORD WINAPI StrCmpNICA(LPCSTR lpszSrc, LPCSTR lpszCmp, DWORD len)
919 return strncasecmp(lpszSrc, lpszCmp, len);
922 /*************************************************************************
925 * Unicode version of StrCmpNICA.
927 DWORD WINAPI StrCmpNICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp, DWORD len)
929 return strncmpiW(lpszSrc, lpszCmp, len);
932 /*************************************************************************
935 * Compare two Ascii strings.
938 * lpszSrc [I] Source string
939 * lpszCmp [I] String to compare to lpszSrc
942 * A number greater than, less than or equal to 0 depending on whether
943 * lpszSrc is greater than, less than or equal to lpszCmp.
945 DWORD WINAPI StrCmpCA(LPCSTR lpszSrc, LPCSTR lpszCmp)
947 return strcmp(lpszSrc, lpszCmp);
950 /*************************************************************************
953 * Unicode version of StrCmpCA.
955 DWORD WINAPI StrCmpCW(LPCWSTR lpszSrc, LPCWSTR lpszCmp)
957 return strcmpW(lpszSrc, lpszCmp);
960 /*************************************************************************
963 * Compare two Ascii strings, ignoring case.
966 * lpszSrc [I] Source string
967 * lpszCmp [I] String to compare to lpszSrc
970 * A number greater than, less than or equal to 0 depending on whether
971 * lpszSrc is greater than, less than or equal to lpszCmp.
973 DWORD WINAPI StrCmpICA(LPCSTR lpszSrc, LPCSTR lpszCmp)
975 return strcasecmp(lpszSrc, lpszCmp);
978 /*************************************************************************
981 * Unicode version of StrCmpICA.
983 DWORD WINAPI StrCmpICW(LPCWSTR lpszSrc, LPCWSTR lpszCmp)
985 return strcmpiW(lpszSrc, lpszCmp);
988 /*************************************************************************
991 * Get an identification string for the OS and explorer.
994 * lpszDest [O] Destination for Id string
995 * dwDestLen [I] Length of lpszDest
998 * TRUE, If the string was created successfully
1001 BOOL WINAPI SHAboutInfoA(LPSTR lpszDest, DWORD dwDestLen)
1005 TRACE("(%p,%d)\n", lpszDest, dwDestLen);
1007 if (lpszDest && SHAboutInfoW(buff, dwDestLen))
1009 WideCharToMultiByte(CP_ACP, 0, buff, -1, lpszDest, dwDestLen, NULL, NULL);
1015 /*************************************************************************
1018 * Unicode version of SHAboutInfoA.
1020 BOOL WINAPI SHAboutInfoW(LPWSTR lpszDest, DWORD dwDestLen)
1022 static const WCHAR szIEKey[] = { 'S','O','F','T','W','A','R','E','\\',
1023 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
1024 ' ','E','x','p','l','o','r','e','r','\0' };
1025 static const WCHAR szWinNtKey[] = { 'S','O','F','T','W','A','R','E','\\',
1026 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s',' ',
1027 'N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
1028 static const WCHAR szWinKey[] = { 'S','O','F','T','W','A','R','E','\\',
1029 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
1030 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
1031 static const WCHAR szRegKey[] = { 'S','O','F','T','W','A','R','E','\\',
1032 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
1033 ' ','E','x','p','l','o','r','e','r','\\',
1034 'R','e','g','i','s','t','r','a','t','i','o','n','\0' };
1035 static const WCHAR szVersion[] = { 'V','e','r','s','i','o','n','\0' };
1036 static const WCHAR szCustomized[] = { 'C','u','s','t','o','m','i','z','e','d',
1037 'V','e','r','s','i','o','n','\0' };
1038 static const WCHAR szOwner[] = { 'R','e','g','i','s','t','e','r','e','d',
1039 'O','w','n','e','r','\0' };
1040 static const WCHAR szOrg[] = { 'R','e','g','i','s','t','e','r','e','d',
1041 'O','r','g','a','n','i','z','a','t','i','o','n','\0' };
1042 static const WCHAR szProduct[] = { 'P','r','o','d','u','c','t','I','d','\0' };
1043 static const WCHAR szUpdate[] = { 'I','E','A','K',
1044 'U','p','d','a','t','e','U','r','l','\0' };
1045 static const WCHAR szHelp[] = { 'I','E','A','K',
1046 'H','e','l','p','S','t','r','i','n','g','\0' };
1049 DWORD dwType, dwLen;
1051 TRACE("(%p,%d)\n", lpszDest, dwDestLen);
1058 /* Try the NT key first, followed by 95/98 key */
1059 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinNtKey, 0, KEY_READ, &hReg) &&
1060 RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinKey, 0, KEY_READ, &hReg))
1066 if (!SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey, szVersion, &dwType, buff, &dwLen))
1068 DWORD dwStrLen = strlenW(buff);
1069 dwLen = 30 - dwStrLen;
1070 SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey,
1071 szCustomized, &dwType, buff+dwStrLen, &dwLen);
1073 StrCatBuffW(lpszDest, buff, dwDestLen);
1075 /* ~Registered Owner */
1078 if (SHGetValueW(hReg, szOwner, 0, &dwType, buff+1, &dwLen))
1080 StrCatBuffW(lpszDest, buff, dwDestLen);
1082 /* ~Registered Organization */
1084 if (SHGetValueW(hReg, szOrg, 0, &dwType, buff+1, &dwLen))
1086 StrCatBuffW(lpszDest, buff, dwDestLen);
1088 /* FIXME: Not sure where this number comes from */
1092 StrCatBuffW(lpszDest, buff, dwDestLen);
1096 if (SHGetValueW(HKEY_LOCAL_MACHINE, szRegKey, szProduct, &dwType, buff+1, &dwLen))
1098 StrCatBuffW(lpszDest, buff, dwDestLen);
1100 /* ~IE Update Url */
1102 if(SHGetValueW(HKEY_LOCAL_MACHINE, szWinKey, szUpdate, &dwType, buff+1, &dwLen))
1104 StrCatBuffW(lpszDest, buff, dwDestLen);
1106 /* ~IE Help String */
1108 if(SHGetValueW(hReg, szHelp, 0, &dwType, buff+1, &dwLen))
1110 StrCatBuffW(lpszDest, buff, dwDestLen);
1116 /*************************************************************************
1119 * Call IOleCommandTarget_QueryStatus() on an object.
1122 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1123 * pguidCmdGroup [I] GUID for the command group
1125 * prgCmds [O] Commands
1126 * pCmdText [O] Command text
1130 * Failure: E_FAIL, if lpUnknown is NULL.
1131 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1132 * Otherwise, an error code from IOleCommandTarget_QueryStatus().
1134 HRESULT WINAPI IUnknown_QueryStatus(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
1135 ULONG cCmds, OLECMD *prgCmds, OLECMDTEXT* pCmdText)
1137 HRESULT hRet = E_FAIL;
1139 TRACE("(%p,%p,%d,%p,%p)\n",lpUnknown, pguidCmdGroup, cCmds, prgCmds, pCmdText);
1143 IOleCommandTarget* lpOle;
1145 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
1148 if (SUCCEEDED(hRet) && lpOle)
1150 hRet = IOleCommandTarget_QueryStatus(lpOle, pguidCmdGroup, cCmds,
1152 IOleCommandTarget_Release(lpOle);
1158 /*************************************************************************
1161 * Call IOleCommandTarget_Exec() on an object.
1164 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1165 * pguidCmdGroup [I] GUID for the command group
1169 * Failure: E_FAIL, if lpUnknown is NULL.
1170 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1171 * Otherwise, an error code from IOleCommandTarget_Exec().
1173 HRESULT WINAPI IUnknown_Exec(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
1174 DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
1177 HRESULT hRet = E_FAIL;
1179 TRACE("(%p,%p,%d,%d,%p,%p)\n",lpUnknown, pguidCmdGroup, nCmdID,
1180 nCmdexecopt, pvaIn, pvaOut);
1184 IOleCommandTarget* lpOle;
1186 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
1188 if (SUCCEEDED(hRet) && lpOle)
1190 hRet = IOleCommandTarget_Exec(lpOle, pguidCmdGroup, nCmdID,
1191 nCmdexecopt, pvaIn, pvaOut);
1192 IOleCommandTarget_Release(lpOle);
1198 /*************************************************************************
1201 * Retrieve, modify, and re-set a value from a window.
1204 * hWnd [I] Window to get value from
1205 * offset [I] Offset of value
1206 * wMask [I] Mask for uiFlags
1207 * wFlags [I] Bits to set in window value
1210 * The new value as it was set, or 0 if any parameter is invalid.
1213 * Any bits set in uiMask are cleared from the value, then any bits set in
1214 * uiFlags are set in the value.
1216 LONG WINAPI SHSetWindowBits(HWND hwnd, INT offset, UINT wMask, UINT wFlags)
1218 LONG ret = GetWindowLongA(hwnd, offset);
1219 LONG newFlags = (wFlags & wMask) | (ret & ~wFlags);
1221 if (newFlags != ret)
1222 ret = SetWindowLongA(hwnd, offset, newFlags);
1226 /*************************************************************************
1229 * Change a window's parent.
1232 * hWnd [I] Window to change parent of
1233 * hWndParent [I] New parent window
1236 * The old parent of hWnd.
1239 * If hWndParent is NULL (desktop), the window style is changed to WS_POPUP.
1240 * If hWndParent is NOT NULL then we set the WS_CHILD style.
1242 HWND WINAPI SHSetParentHwnd(HWND hWnd, HWND hWndParent)
1244 TRACE("%p, %p\n", hWnd, hWndParent);
1246 if(GetParent(hWnd) == hWndParent)
1250 SHSetWindowBits(hWnd, GWL_STYLE, WS_CHILD, WS_CHILD);
1252 SHSetWindowBits(hWnd, GWL_STYLE, WS_POPUP, WS_POPUP);
1254 return SetParent(hWnd, hWndParent);
1257 /*************************************************************************
1260 * Locate and advise a connection point in an IConnectionPointContainer object.
1263 * lpUnkSink [I] Sink for the connection point advise call
1264 * riid [I] REFIID of connection point to advise
1265 * bAdviseOnly [I] TRUE = Advise only, FALSE = Unadvise first
1266 * lpUnknown [I] Object supporting the IConnectionPointContainer interface
1267 * lpCookie [O] Pointer to connection point cookie
1268 * lppCP [O] Destination for the IConnectionPoint found
1271 * Success: S_OK. If lppCP is non-NULL, it is filled with the IConnectionPoint
1272 * that was advised. The caller is responsible for releasing it.
1273 * Failure: E_FAIL, if any arguments are invalid.
1274 * E_NOINTERFACE, if lpUnknown isn't an IConnectionPointContainer,
1275 * Or an HRESULT error code if any call fails.
1277 HRESULT WINAPI ConnectToConnectionPoint(IUnknown* lpUnkSink, REFIID riid, BOOL bAdviseOnly,
1278 IUnknown* lpUnknown, LPDWORD lpCookie,
1279 IConnectionPoint **lppCP)
1282 IConnectionPointContainer* lpContainer;
1283 IConnectionPoint *lpCP;
1285 if(!lpUnknown || (bAdviseOnly && !lpUnkSink))
1291 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer,
1292 (void**)&lpContainer);
1293 if (SUCCEEDED(hRet))
1295 hRet = IConnectionPointContainer_FindConnectionPoint(lpContainer, riid, &lpCP);
1297 if (SUCCEEDED(hRet))
1300 hRet = IConnectionPoint_Unadvise(lpCP, *lpCookie);
1301 hRet = IConnectionPoint_Advise(lpCP, lpUnkSink, lpCookie);
1306 if (lppCP && SUCCEEDED(hRet))
1307 *lppCP = lpCP; /* Caller keeps the interface */
1309 IConnectionPoint_Release(lpCP); /* Release it */
1312 IUnknown_Release(lpContainer);
1317 /*************************************************************************
1320 * Release an interface.
1323 * lpUnknown [I] Object to release
1328 DWORD WINAPI IUnknown_AtomicRelease(IUnknown ** lpUnknown)
1332 TRACE("(%p)\n",lpUnknown);
1334 if(!lpUnknown || !*((LPDWORD)lpUnknown)) return 0;
1338 TRACE("doing Release\n");
1340 return IUnknown_Release(temp);
1343 /*************************************************************************
1346 * Skip '//' if present in a string.
1349 * lpszSrc [I] String to check for '//'
1352 * Success: The next character after the '//' or the string if not present
1353 * Failure: NULL, if lpszStr is NULL.
1355 LPCSTR WINAPI PathSkipLeadingSlashesA(LPCSTR lpszSrc)
1357 if (lpszSrc && lpszSrc[0] == '/' && lpszSrc[1] == '/')
1362 /*************************************************************************
1365 * Check if two interfaces come from the same object.
1368 * lpInt1 [I] Interface to check against lpInt2.
1369 * lpInt2 [I] Interface to check against lpInt1.
1372 * TRUE, If the interfaces come from the same object.
1375 BOOL WINAPI SHIsSameObject(IUnknown* lpInt1, IUnknown* lpInt2)
1377 LPVOID lpUnknown1, lpUnknown2;
1379 TRACE("%p %p\n", lpInt1, lpInt2);
1381 if (!lpInt1 || !lpInt2)
1384 if (lpInt1 == lpInt2)
1387 if (!SUCCEEDED(IUnknown_QueryInterface(lpInt1, &IID_IUnknown,
1388 (LPVOID *)&lpUnknown1)))
1391 if (!SUCCEEDED(IUnknown_QueryInterface(lpInt2, &IID_IUnknown,
1392 (LPVOID *)&lpUnknown2)))
1395 if (lpUnknown1 == lpUnknown2)
1401 /*************************************************************************
1404 * Get the window handle of an object.
1407 * lpUnknown [I] Object to get the window handle of
1408 * lphWnd [O] Destination for window handle
1411 * Success: S_OK. lphWnd contains the objects window handle.
1412 * Failure: An HRESULT error code.
1415 * lpUnknown is expected to support one of the following interfaces:
1416 * IOleWindow(), IInternetSecurityMgrSite(), or IShellView().
1418 HRESULT WINAPI IUnknown_GetWindow(IUnknown *lpUnknown, HWND *lphWnd)
1420 /* FIXME: Wine has no header for this object */
1421 static const GUID IID_IInternetSecurityMgrSite = { 0x79eac9ed,
1422 0xbaf9, 0x11ce, { 0x8c, 0x82, 0x00, 0xaa, 0x00, 0x4b, 0xa9, 0x0b }};
1424 HRESULT hRet = E_FAIL;
1426 TRACE("(%p,%p)\n", lpUnknown, lphWnd);
1431 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleWindow, (void**)&lpOle);
1435 hRet = IUnknown_QueryInterface(lpUnknown,&IID_IShellView, (void**)&lpOle);
1439 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInternetSecurityMgrSite,
1444 if (SUCCEEDED(hRet))
1446 /* Lazyness here - Since GetWindow() is the first method for the above 3
1447 * interfaces, we use the same call for them all.
1449 hRet = IOleWindow_GetWindow((IOleWindow*)lpOle, lphWnd);
1450 IUnknown_Release(lpOle);
1452 TRACE("Returning HWND=%p\n", *lphWnd);
1458 /*************************************************************************
1461 * Call a method on as as yet unidentified object.
1464 * pUnk [I] Object supporting the unidentified interface,
1465 * arg [I] Argument for the call on the object.
1470 HRESULT WINAPI IUnknown_SetOwner(IUnknown *pUnk, ULONG arg)
1472 static const GUID guid_173 = {
1473 0x5836fb00, 0x8187, 0x11cf, { 0xa1,0x2b,0x00,0xaa,0x00,0x4a,0xe8,0x37 }
1477 TRACE("(%p,%d)\n", pUnk, arg);
1479 /* Note: arg may not be a ULONG and pUnk2 is for sure not an IMalloc -
1480 * We use this interface as its vtable entry is compatible with the
1481 * object in question.
1482 * FIXME: Find out what this object is and where it should be defined.
1485 SUCCEEDED(IUnknown_QueryInterface(pUnk, &guid_173, (void**)&pUnk2)))
1487 IMalloc_Alloc(pUnk2, arg); /* Faked call!! */
1488 IMalloc_Release(pUnk2);
1493 /*************************************************************************
1496 * Call either IObjectWithSite_SetSite() or IInternetSecurityManager_SetSecuritySite() on
1500 HRESULT WINAPI IUnknown_SetSite(
1501 IUnknown *obj, /* [in] OLE object */
1502 IUnknown *site) /* [in] Site interface */
1505 IObjectWithSite *iobjwithsite;
1506 IInternetSecurityManager *isecmgr;
1508 if (!obj) return E_FAIL;
1510 hr = IUnknown_QueryInterface(obj, &IID_IObjectWithSite, (LPVOID *)&iobjwithsite);
1511 TRACE("IID_IObjectWithSite QI ret=%08x, %p\n", hr, iobjwithsite);
1514 hr = IObjectWithSite_SetSite(iobjwithsite, site);
1515 TRACE("done IObjectWithSite_SetSite ret=%08x\n", hr);
1516 IUnknown_Release(iobjwithsite);
1520 hr = IUnknown_QueryInterface(obj, &IID_IInternetSecurityManager, (LPVOID *)&isecmgr);
1521 TRACE("IID_IInternetSecurityManager QI ret=%08x, %p\n", hr, isecmgr);
1522 if (FAILED(hr)) return hr;
1524 hr = IInternetSecurityManager_SetSecuritySite(isecmgr, (IInternetSecurityMgrSite *)site);
1525 TRACE("done IInternetSecurityManager_SetSecuritySite ret=%08x\n", hr);
1526 IUnknown_Release(isecmgr);
1531 /*************************************************************************
1534 * Call IPersist_GetClassID() on an object.
1537 * lpUnknown [I] Object supporting the IPersist interface
1538 * lpClassId [O] Destination for Class Id
1541 * Success: S_OK. lpClassId contains the Class Id requested.
1542 * Failure: E_FAIL, If lpUnknown is NULL,
1543 * E_NOINTERFACE If lpUnknown does not support IPersist,
1544 * Or an HRESULT error code.
1546 HRESULT WINAPI IUnknown_GetClassID(IUnknown *lpUnknown, CLSID* lpClassId)
1548 IPersist* lpPersist;
1549 HRESULT hRet = E_FAIL;
1551 TRACE("(%p,%p)\n", lpUnknown, debugstr_guid(lpClassId));
1555 hRet = IUnknown_QueryInterface(lpUnknown,&IID_IPersist,(void**)&lpPersist);
1556 if (SUCCEEDED(hRet))
1558 IPersist_GetClassID(lpPersist, lpClassId);
1559 IPersist_Release(lpPersist);
1565 /*************************************************************************
1568 * Retrieve a Service Interface from an object.
1571 * lpUnknown [I] Object to get an IServiceProvider interface from
1572 * sid [I] Service ID for IServiceProvider_QueryService() call
1573 * riid [I] Function requested for QueryService call
1574 * lppOut [O] Destination for the service interface pointer
1577 * Success: S_OK. lppOut contains an object providing the requested service
1578 * Failure: An HRESULT error code
1581 * lpUnknown is expected to support the IServiceProvider interface.
1583 HRESULT WINAPI IUnknown_QueryService(IUnknown* lpUnknown, REFGUID sid, REFIID riid,
1586 IServiceProvider* pService = NULL;
1597 /* Get an IServiceProvider interface from the object */
1598 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IServiceProvider,
1599 (LPVOID*)&pService);
1601 if (!hRet && pService)
1603 TRACE("QueryInterface returned (IServiceProvider*)%p\n", pService);
1605 /* Get a Service interface from the object */
1606 hRet = IServiceProvider_QueryService(pService, sid, riid, lppOut);
1608 TRACE("(IServiceProvider*)%p returned (IUnknown*)%p\n", pService, *lppOut);
1610 /* Release the IServiceProvider interface */
1611 IUnknown_Release(pService);
1616 /*************************************************************************
1619 * Loads a popup menu.
1622 * hInst [I] Instance handle
1623 * szName [I] Menu name
1629 BOOL WINAPI SHLoadMenuPopup(HINSTANCE hInst, LPCWSTR szName)
1631 HMENU hMenu, hSubMenu;
1633 if ((hMenu = LoadMenuW(hInst, szName)))
1635 if ((hSubMenu = GetSubMenu(hMenu, 0)))
1636 RemoveMenu(hMenu, 0, MF_BYPOSITION);
1644 typedef struct _enumWndData
1649 LRESULT (WINAPI *pfnPost)(HWND,UINT,WPARAM,LPARAM);
1652 /* Callback for SHLWAPI_178 */
1653 static BOOL CALLBACK SHLWAPI_EnumChildProc(HWND hWnd, LPARAM lParam)
1655 enumWndData *data = (enumWndData *)lParam;
1657 TRACE("(%p,%p)\n", hWnd, data);
1658 data->pfnPost(hWnd, data->uiMsgId, data->wParam, data->lParam);
1662 /*************************************************************************
1665 * Send or post a message to every child of a window.
1668 * hWnd [I] Window whose children will get the messages
1669 * uiMsgId [I] Message Id
1670 * wParam [I] WPARAM of message
1671 * lParam [I] LPARAM of message
1672 * bSend [I] TRUE = Use SendMessageA(), FALSE = Use PostMessageA()
1678 * The appropriate ASCII or Unicode function is called for the window.
1680 void WINAPI SHPropagateMessage(HWND hWnd, UINT uiMsgId, WPARAM wParam, LPARAM lParam, BOOL bSend)
1684 TRACE("(%p,%u,%d,%ld,%d)\n", hWnd, uiMsgId, wParam, lParam, bSend);
1688 data.uiMsgId = uiMsgId;
1689 data.wParam = wParam;
1690 data.lParam = lParam;
1693 data.pfnPost = IsWindowUnicode(hWnd) ? (void*)SendMessageW : (void*)SendMessageA;
1695 data.pfnPost = IsWindowUnicode(hWnd) ? (void*)PostMessageW : (void*)PostMessageA;
1697 EnumChildWindows(hWnd, SHLWAPI_EnumChildProc, (LPARAM)&data);
1701 /*************************************************************************
1704 * Remove all sub-menus from a menu.
1707 * hMenu [I] Menu to remove sub-menus from
1710 * Success: 0. All sub-menus under hMenu are removed
1711 * Failure: -1, if any parameter is invalid
1713 DWORD WINAPI SHRemoveAllSubMenus(HMENU hMenu)
1715 int iItemCount = GetMenuItemCount(hMenu) - 1;
1716 while (iItemCount >= 0)
1718 HMENU hSubMenu = GetSubMenu(hMenu, iItemCount);
1720 RemoveMenu(hMenu, iItemCount, MF_BYPOSITION);
1726 /*************************************************************************
1729 * Enable or disable a menu item.
1732 * hMenu [I] Menu holding menu item
1733 * uID [I] ID of menu item to enable/disable
1734 * bEnable [I] Whether to enable (TRUE) or disable (FALSE) the item.
1737 * The return code from EnableMenuItem.
1739 UINT WINAPI SHEnableMenuItem(HMENU hMenu, UINT wItemID, BOOL bEnable)
1741 return EnableMenuItem(hMenu, wItemID, bEnable ? MF_ENABLED : MF_GRAYED);
1744 /*************************************************************************
1747 * Check or uncheck a menu item.
1750 * hMenu [I] Menu holding menu item
1751 * uID [I] ID of menu item to check/uncheck
1752 * bCheck [I] Whether to check (TRUE) or uncheck (FALSE) the item.
1755 * The return code from CheckMenuItem.
1757 DWORD WINAPI SHCheckMenuItem(HMENU hMenu, UINT uID, BOOL bCheck)
1759 return CheckMenuItem(hMenu, uID, bCheck ? MF_CHECKED : MF_UNCHECKED);
1762 /*************************************************************************
1765 * Register a window class if it isn't already.
1768 * lpWndClass [I] Window class to register
1771 * The result of the RegisterClassA call.
1773 DWORD WINAPI SHRegisterClassA(WNDCLASSA *wndclass)
1776 if (GetClassInfoA(wndclass->hInstance, wndclass->lpszClassName, &wca))
1778 return (DWORD)RegisterClassA(wndclass);
1781 /*************************************************************************
1784 BOOL WINAPI SHSimulateDrop(IDropTarget *pDrop, IDataObject *pDataObj,
1785 DWORD grfKeyState, PPOINTL lpPt, DWORD* pdwEffect)
1787 DWORD dwEffect = DROPEFFECT_LINK | DROPEFFECT_MOVE | DROPEFFECT_COPY;
1788 POINTL pt = { 0, 0 };
1794 pdwEffect = &dwEffect;
1796 IDropTarget_DragEnter(pDrop, pDataObj, grfKeyState, *lpPt, pdwEffect);
1799 return IDropTarget_Drop(pDrop, pDataObj, grfKeyState, *lpPt, pdwEffect);
1801 IDropTarget_DragLeave(pDrop);
1805 /*************************************************************************
1808 * Call IPersistPropertyBag_Load() on an object.
1811 * lpUnknown [I] Object supporting the IPersistPropertyBag interface
1812 * lpPropBag [O] Destination for loaded IPropertyBag
1816 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1818 DWORD WINAPI SHLoadFromPropertyBag(IUnknown *lpUnknown, IPropertyBag* lpPropBag)
1820 IPersistPropertyBag* lpPPBag;
1821 HRESULT hRet = E_FAIL;
1823 TRACE("(%p,%p)\n", lpUnknown, lpPropBag);
1827 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IPersistPropertyBag,
1829 if (SUCCEEDED(hRet) && lpPPBag)
1831 hRet = IPersistPropertyBag_Load(lpPPBag, lpPropBag, NULL);
1832 IPersistPropertyBag_Release(lpPPBag);
1838 /*************************************************************************
1841 * Call IOleControlSite_TranslateAccelerator() on an object.
1844 * lpUnknown [I] Object supporting the IOleControlSite interface.
1845 * lpMsg [I] Key message to be processed.
1846 * dwModifiers [I] Flags containing the state of the modifier keys.
1850 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
1852 HRESULT WINAPI IUnknown_TranslateAcceleratorOCS(IUnknown *lpUnknown, LPMSG lpMsg, DWORD dwModifiers)
1854 IOleControlSite* lpCSite = NULL;
1855 HRESULT hRet = E_INVALIDARG;
1857 TRACE("(%p,%p,0x%08x)\n", lpUnknown, lpMsg, dwModifiers);
1860 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleControlSite,
1862 if (SUCCEEDED(hRet) && lpCSite)
1864 hRet = IOleControlSite_TranslateAccelerator(lpCSite, lpMsg, dwModifiers);
1865 IOleControlSite_Release(lpCSite);
1872 /*************************************************************************
1875 * Call IOleControlSite_GetExtendedControl() on an object.
1878 * lpUnknown [I] Object supporting the IOleControlSite interface.
1879 * lppDisp [O] Destination for resulting IDispatch.
1883 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1885 DWORD WINAPI IUnknown_OnFocusOCS(IUnknown *lpUnknown, IDispatch** lppDisp)
1887 IOleControlSite* lpCSite = NULL;
1888 HRESULT hRet = E_FAIL;
1890 TRACE("(%p,%p)\n", lpUnknown, lppDisp);
1893 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleControlSite,
1895 if (SUCCEEDED(hRet) && lpCSite)
1897 hRet = IOleControlSite_GetExtendedControl(lpCSite, lppDisp);
1898 IOleControlSite_Release(lpCSite);
1904 /*************************************************************************
1907 HRESULT WINAPI IUnknown_HandleIRestrict(LPUNKNOWN lpUnknown, PVOID lpArg1,
1908 PVOID lpArg2, PVOID lpArg3, PVOID lpArg4)
1910 /* FIXME: {D12F26B2-D90A-11D0-830D-00AA005B4383} - What object does this represent? */
1911 static const DWORD service_id[] = { 0xd12f26b2, 0x11d0d90a, 0xaa000d83, 0x83435b00 };
1912 /* FIXME: {D12F26B1-D90A-11D0-830D-00AA005B4383} - Also Unknown/undocumented */
1913 static const DWORD function_id[] = { 0xd12f26b1, 0x11d0d90a, 0xaa000d83, 0x83435b00 };
1914 HRESULT hRet = E_INVALIDARG;
1915 LPUNKNOWN lpUnkInner = NULL; /* FIXME: Real type is unknown */
1917 TRACE("(%p,%p,%p,%p,%p)\n", lpUnknown, lpArg1, lpArg2, lpArg3, lpArg4);
1919 if (lpUnknown && lpArg4)
1921 hRet = IUnknown_QueryService(lpUnknown, (REFGUID)service_id,
1922 (REFGUID)function_id, (void**)&lpUnkInner);
1924 if (SUCCEEDED(hRet) && lpUnkInner)
1926 /* FIXME: The type of service object requested is unknown, however
1927 * testing shows that its first method is called with 4 parameters.
1928 * Fake this by using IParseDisplayName_ParseDisplayName since the
1929 * signature and position in the vtable matches our unknown object type.
1931 hRet = IParseDisplayName_ParseDisplayName((LPPARSEDISPLAYNAME)lpUnkInner,
1932 lpArg1, lpArg2, lpArg3, lpArg4);
1933 IUnknown_Release(lpUnkInner);
1939 /*************************************************************************
1942 * Get a sub-menu from a menu item.
1945 * hMenu [I] Menu to get sub-menu from
1946 * uID [I] ID of menu item containing sub-menu
1949 * The sub-menu of the item, or a NULL handle if any parameters are invalid.
1951 HMENU WINAPI SHGetMenuFromID(HMENU hMenu, UINT uID)
1955 TRACE("(%p,%u)\n", hMenu, uID);
1957 mi.cbSize = sizeof(mi);
1958 mi.fMask = MIIM_SUBMENU;
1960 if (!GetMenuItemInfoW(hMenu, uID, FALSE, &mi))
1966 /*************************************************************************
1969 * Get the color depth of the primary display.
1975 * The color depth of the primary display.
1977 DWORD WINAPI SHGetCurColorRes(void)
1985 ret = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
1990 /*************************************************************************
1993 * Wait for a message to arrive, with a timeout.
1996 * hand [I] Handle to query
1997 * dwTimeout [I] Timeout in ticks or INFINITE to never timeout
2000 * STATUS_TIMEOUT if no message is received before dwTimeout ticks passes.
2001 * Otherwise returns the value from MsgWaitForMultipleObjectsEx when a
2002 * message is available.
2004 DWORD WINAPI SHWaitForSendMessageThread(HANDLE hand, DWORD dwTimeout)
2006 DWORD dwEndTicks = GetTickCount() + dwTimeout;
2009 while ((dwRet = MsgWaitForMultipleObjectsEx(1, &hand, dwTimeout, QS_SENDMESSAGE, 0)) == 1)
2013 PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE);
2015 if (dwTimeout != INFINITE)
2017 if ((int)(dwTimeout = dwEndTicks - GetTickCount()) <= 0)
2018 return WAIT_TIMEOUT;
2025 /*************************************************************************
2028 * Determine if a shell folder can be expanded.
2031 * lpFolder [I] Parent folder containing the object to test.
2032 * pidl [I] Id of the object to test.
2035 * Success: S_OK, if the object is expandable, S_FALSE otherwise.
2036 * Failure: E_INVALIDARG, if any argument is invalid.
2039 * If the object to be tested does not expose the IQueryInfo() interface it
2040 * will not be identified as an expandable folder.
2042 HRESULT WINAPI SHIsExpandableFolder(LPSHELLFOLDER lpFolder, LPCITEMIDLIST pidl)
2044 HRESULT hRet = E_INVALIDARG;
2047 if (lpFolder && pidl)
2049 hRet = IShellFolder_GetUIObjectOf(lpFolder, NULL, 1, &pidl, &IID_IQueryInfo,
2050 NULL, (void**)&lpInfo);
2052 hRet = S_FALSE; /* Doesn't expose IQueryInfo */
2057 /* MSDN states of IQueryInfo_GetInfoFlags() that "This method is not
2058 * currently used". Really? You wouldn't be holding out on me would you?
2060 hRet = IQueryInfo_GetInfoFlags(lpInfo, &dwFlags);
2062 if (SUCCEEDED(hRet))
2064 /* 0x2 is an undocumented flag apparently indicating expandability */
2065 hRet = dwFlags & 0x2 ? S_OK : S_FALSE;
2068 IQueryInfo_Release(lpInfo);
2074 /*************************************************************************
2077 * Blank out a region of text by drawing the background only.
2080 * hDC [I] Device context to draw in
2081 * pRect [I] Area to draw in
2082 * cRef [I] Color to draw in
2087 DWORD WINAPI SHFillRectClr(HDC hDC, LPCRECT pRect, COLORREF cRef)
2089 COLORREF cOldColor = SetBkColor(hDC, cRef);
2090 ExtTextOutA(hDC, 0, 0, ETO_OPAQUE, pRect, 0, 0, 0);
2091 SetBkColor(hDC, cOldColor);
2095 /*************************************************************************
2098 * Return the value asociated with a key in a map.
2101 * lpKeys [I] A list of keys of length iLen
2102 * lpValues [I] A list of values associated with lpKeys, of length iLen
2103 * iLen [I] Length of both lpKeys and lpValues
2104 * iKey [I] The key value to look up in lpKeys
2107 * The value in lpValues associated with iKey, or -1 if iKey is not
2111 * - If two elements in the map share the same key, this function returns
2112 * the value closest to the start of the map
2113 * - The native version of this function crashes if lpKeys or lpValues is NULL.
2115 int WINAPI SHSearchMapInt(const int *lpKeys, const int *lpValues, int iLen, int iKey)
2117 if (lpKeys && lpValues)
2123 if (lpKeys[i] == iKey)
2124 return lpValues[i]; /* Found */
2128 return -1; /* Not found */
2132 /*************************************************************************
2135 * Copy an interface pointer
2138 * lppDest [O] Destination for copy
2139 * lpUnknown [I] Source for copy
2144 VOID WINAPI IUnknown_Set(IUnknown **lppDest, IUnknown *lpUnknown)
2146 TRACE("(%p,%p)\n", lppDest, lpUnknown);
2149 IUnknown_AtomicRelease(lppDest); /* Release existing interface */
2154 IUnknown_AddRef(lpUnknown);
2155 *lppDest = lpUnknown;
2159 /*************************************************************************
2163 HRESULT WINAPI MayQSForward(IUnknown* lpUnknown, PVOID lpReserved,
2164 REFGUID riidCmdGrp, ULONG cCmds,
2165 OLECMD *prgCmds, OLECMDTEXT* pCmdText)
2167 FIXME("(%p,%p,%p,%d,%p,%p) - stub\n",
2168 lpUnknown, lpReserved, riidCmdGrp, cCmds, prgCmds, pCmdText);
2170 /* FIXME: Calls IsQSForward & IUnknown_QueryStatus */
2171 return DRAGDROP_E_NOTREGISTERED;
2174 /*************************************************************************
2178 HRESULT WINAPI MayExecForward(IUnknown* lpUnknown, INT iUnk, REFGUID pguidCmdGroup,
2179 DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
2182 FIXME("(%p,%d,%p,%d,%d,%p,%p) - stub!\n", lpUnknown, iUnk, pguidCmdGroup,
2183 nCmdID, nCmdexecopt, pvaIn, pvaOut);
2184 return DRAGDROP_E_NOTREGISTERED;
2187 /*************************************************************************
2191 HRESULT WINAPI IsQSForward(REFGUID pguidCmdGroup,ULONG cCmds, OLECMD *prgCmds)
2193 FIXME("(%p,%d,%p) - stub!\n", pguidCmdGroup, cCmds, prgCmds);
2194 return DRAGDROP_E_NOTREGISTERED;
2197 /*************************************************************************
2200 * Determine if a window is not a child of another window.
2203 * hParent [I] Suspected parent window
2204 * hChild [I] Suspected child window
2207 * TRUE: If hChild is a child window of hParent
2208 * FALSE: If hChild is not a child window of hParent, or they are equal
2210 BOOL WINAPI SHIsChildOrSelf(HWND hParent, HWND hChild)
2212 TRACE("(%p,%p)\n", hParent, hChild);
2214 if (!hParent || !hChild)
2216 else if(hParent == hChild)
2218 return !IsChild(hParent, hChild);
2221 /*************************************************************************
2222 * FDSA functions. Manage a dynamic array of fixed size memory blocks.
2227 DWORD num_items; /* Number of elements inserted */
2228 void *mem; /* Ptr to array */
2229 DWORD blocks_alloced; /* Number of elements allocated */
2230 BYTE inc; /* Number of elements to grow by when we need to expand */
2231 BYTE block_size; /* Size in bytes of an element */
2232 BYTE flags; /* Flags */
2235 #define FDSA_FLAG_INTERNAL_ALLOC 0x01 /* When set we have allocated mem internally */
2237 /*************************************************************************
2240 * Initialize an FDSA arrary.
2242 BOOL WINAPI FDSA_Initialize(DWORD block_size, DWORD inc, FDSA_info *info, void *mem,
2245 TRACE("(0x%08x 0x%08x %p %p 0x%08x)\n", block_size, inc, info, mem, init_blocks);
2251 memset(mem, 0, block_size * init_blocks);
2253 info->num_items = 0;
2256 info->blocks_alloced = init_blocks;
2257 info->block_size = block_size;
2263 /*************************************************************************
2266 * Destroy an FDSA array
2268 BOOL WINAPI FDSA_Destroy(FDSA_info *info)
2270 TRACE("(%p)\n", info);
2272 if(info->flags & FDSA_FLAG_INTERNAL_ALLOC)
2274 HeapFree(GetProcessHeap(), 0, info->mem);
2281 /*************************************************************************
2284 * Insert element into an FDSA array
2286 DWORD WINAPI FDSA_InsertItem(FDSA_info *info, DWORD where, const void *block)
2288 TRACE("(%p 0x%08x %p)\n", info, where, block);
2289 if(where > info->num_items)
2290 where = info->num_items;
2292 if(info->num_items >= info->blocks_alloced)
2294 DWORD size = (info->blocks_alloced + info->inc) * info->block_size;
2295 if(info->flags & 0x1)
2296 info->mem = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->mem, size);
2299 void *old_mem = info->mem;
2300 info->mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
2301 memcpy(info->mem, old_mem, info->blocks_alloced * info->block_size);
2303 info->blocks_alloced += info->inc;
2307 if(where < info->num_items)
2309 memmove((char*)info->mem + (where + 1) * info->block_size,
2310 (char*)info->mem + where * info->block_size,
2311 (info->num_items - where) * info->block_size);
2313 memcpy((char*)info->mem + where * info->block_size, block, info->block_size);
2319 /*************************************************************************
2322 * Delete an element from an FDSA array.
2324 BOOL WINAPI FDSA_DeleteItem(FDSA_info *info, DWORD where)
2326 TRACE("(%p 0x%08x)\n", info, where);
2328 if(where >= info->num_items)
2331 if(where < info->num_items - 1)
2333 memmove((char*)info->mem + where * info->block_size,
2334 (char*)info->mem + (where + 1) * info->block_size,
2335 (info->num_items - where - 1) * info->block_size);
2337 memset((char*)info->mem + (info->num_items - 1) * info->block_size,
2338 0, info->block_size);
2349 /*************************************************************************
2352 * Call IUnknown_QueryInterface() on a table of objects.
2356 * Failure: E_POINTER or E_NOINTERFACE.
2358 HRESULT WINAPI QISearch(
2359 LPVOID w, /* [in] Table of interfaces */
2360 IFACE_INDEX_TBL *x, /* [in] Array of REFIIDs and indexes into the table */
2361 REFIID riid, /* [in] REFIID to get interface for */
2362 LPVOID *ppv) /* [out] Destination for interface pointer */
2366 IFACE_INDEX_TBL *xmove;
2368 TRACE("(%p %p %s %p)\n", w,x,debugstr_guid(riid),ppv);
2371 while (xmove->refid) {
2372 TRACE("trying (indx %d) %s\n", xmove->indx, debugstr_guid(xmove->refid));
2373 if (IsEqualIID(riid, xmove->refid)) {
2374 a_vtbl = (IUnknown*)(xmove->indx + (LPBYTE)w);
2375 TRACE("matched, returning (%p)\n", a_vtbl);
2376 *ppv = (LPVOID)a_vtbl;
2377 IUnknown_AddRef(a_vtbl);
2383 if (IsEqualIID(riid, &IID_IUnknown)) {
2384 a_vtbl = (IUnknown*)(x->indx + (LPBYTE)w);
2385 TRACE("returning first for IUnknown (%p)\n", a_vtbl);
2386 *ppv = (LPVOID)a_vtbl;
2387 IUnknown_AddRef(a_vtbl);
2391 ret = E_NOINTERFACE;
2395 TRACE("-- 0x%08x\n", ret);
2399 /*************************************************************************
2402 * Remove the "PropDlgFont" property from a window.
2405 * hWnd [I] Window to remove the property from
2408 * A handle to the removed property, or NULL if it did not exist.
2410 HANDLE WINAPI SHRemoveDefaultDialogFont(HWND hWnd)
2414 TRACE("(%p)\n", hWnd);
2416 hProp = GetPropA(hWnd, "PropDlgFont");
2420 DeleteObject(hProp);
2421 hProp = RemovePropA(hWnd, "PropDlgFont");
2426 /*************************************************************************
2429 * Load the in-process server of a given GUID.
2432 * refiid [I] GUID of the server to load.
2435 * Success: A handle to the loaded server dll.
2436 * Failure: A NULL handle.
2438 HMODULE WINAPI SHPinDllOfCLSID(REFIID refiid)
2442 CHAR value[MAX_PATH], string[MAX_PATH];
2444 strcpy(string, "CLSID\\");
2445 SHStringFromGUIDA(refiid, string + 6, sizeof(string)/sizeof(char) - 6);
2446 strcat(string, "\\InProcServer32");
2449 RegOpenKeyExA(HKEY_CLASSES_ROOT, string, 0, 1, &newkey);
2450 RegQueryValueExA(newkey, 0, 0, &type, (PBYTE)value, &count);
2451 RegCloseKey(newkey);
2452 return LoadLibraryExA(value, 0, 0);
2455 /*************************************************************************
2458 * Unicode version of SHLWAPI_183.
2460 DWORD WINAPI SHRegisterClassW(WNDCLASSW * lpWndClass)
2464 TRACE("(%p %s)\n",lpWndClass->hInstance, debugstr_w(lpWndClass->lpszClassName));
2466 if (GetClassInfoW(lpWndClass->hInstance, lpWndClass->lpszClassName, &WndClass))
2468 return RegisterClassW(lpWndClass);
2471 /*************************************************************************
2474 * Unregister a list of classes.
2477 * hInst [I] Application instance that registered the classes
2478 * lppClasses [I] List of class names
2479 * iCount [I] Number of names in lppClasses
2484 void WINAPI SHUnregisterClassesA(HINSTANCE hInst, LPCSTR *lppClasses, INT iCount)
2488 TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);
2492 if (GetClassInfoA(hInst, *lppClasses, &WndClass))
2493 UnregisterClassA(*lppClasses, hInst);
2499 /*************************************************************************
2502 * Unicode version of SHUnregisterClassesA.
2504 void WINAPI SHUnregisterClassesW(HINSTANCE hInst, LPCWSTR *lppClasses, INT iCount)
2508 TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);
2512 if (GetClassInfoW(hInst, *lppClasses, &WndClass))
2513 UnregisterClassW(*lppClasses, hInst);
2519 /*************************************************************************
2522 * Call The correct (Ascii/Unicode) default window procedure for a window.
2525 * hWnd [I] Window to call the default procedure for
2526 * uMessage [I] Message ID
2527 * wParam [I] WPARAM of message
2528 * lParam [I] LPARAM of message
2531 * The result of calling DefWindowProcA() or DefWindowProcW().
2533 LRESULT CALLBACK SHDefWindowProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
2535 if (IsWindowUnicode(hWnd))
2536 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
2537 return DefWindowProcA(hWnd, uMessage, wParam, lParam);
2540 /*************************************************************************
2543 HRESULT WINAPI IUnknown_GetSite(LPUNKNOWN lpUnknown, REFIID iid, PVOID *lppSite)
2545 HRESULT hRet = E_INVALIDARG;
2546 LPOBJECTWITHSITE lpSite = NULL;
2548 TRACE("(%p,%s,%p)\n", lpUnknown, debugstr_guid(iid), lppSite);
2550 if (lpUnknown && iid && lppSite)
2552 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IObjectWithSite,
2554 if (SUCCEEDED(hRet) && lpSite)
2556 hRet = IObjectWithSite_GetSite(lpSite, iid, lppSite);
2557 IObjectWithSite_Release(lpSite);
2563 /*************************************************************************
2566 * Create a worker window using CreateWindowExA().
2569 * wndProc [I] Window procedure
2570 * hWndParent [I] Parent window
2571 * dwExStyle [I] Extra style flags
2572 * dwStyle [I] Style flags
2573 * hMenu [I] Window menu
2577 * Success: The window handle of the newly created window.
2580 HWND WINAPI SHCreateWorkerWindowA(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
2581 DWORD dwStyle, HMENU hMenu, LONG z)
2583 static const char szClass[] = "WorkerA";
2587 TRACE("(0x%08x,%p,0x%08x,0x%08x,%p,0x%08x)\n",
2588 wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2590 /* Create Window class */
2592 wc.lpfnWndProc = DefWindowProcA;
2595 wc.hInstance = shlwapi_hInstance;
2597 wc.hCursor = LoadCursorA(NULL, (LPSTR)IDC_ARROW);
2598 wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
2599 wc.lpszMenuName = NULL;
2600 wc.lpszClassName = szClass;
2602 SHRegisterClassA(&wc); /* Register class */
2604 /* FIXME: Set extra bits in dwExStyle */
2606 hWnd = CreateWindowExA(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
2607 hWndParent, hMenu, shlwapi_hInstance, 0);
2610 SetWindowLongPtrW(hWnd, DWLP_MSGRESULT, z);
2613 SetWindowLongPtrA(hWnd, GWLP_WNDPROC, wndProc);
2618 typedef struct tagPOLICYDATA
2620 DWORD policy; /* flags value passed to SHRestricted */
2621 LPCWSTR appstr; /* application str such as "Explorer" */
2622 LPCWSTR keystr; /* name of the actual registry key / policy */
2623 } POLICYDATA, *LPPOLICYDATA;
2625 #define SHELL_NO_POLICY 0xffffffff
2627 /* default shell policy registry key */
2628 static const WCHAR strRegistryPolicyW[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o',
2629 's','o','f','t','\\','W','i','n','d','o','w','s','\\',
2630 'C','u','r','r','e','n','t','V','e','r','s','i','o','n',
2631 '\\','P','o','l','i','c','i','e','s',0};
2633 /*************************************************************************
2636 * Retrieve a policy value from the registry.
2639 * lpSubKey [I] registry key name
2640 * lpSubName [I] subname of registry key
2641 * lpValue [I] value name of registry value
2644 * the value associated with the registry key or 0 if not found
2646 DWORD WINAPI SHGetRestriction(LPCWSTR lpSubKey, LPCWSTR lpSubName, LPCWSTR lpValue)
2648 DWORD retval, datsize = sizeof(retval);
2652 lpSubKey = strRegistryPolicyW;
2654 retval = RegOpenKeyW(HKEY_LOCAL_MACHINE, lpSubKey, &hKey);
2655 if (retval != ERROR_SUCCESS)
2656 retval = RegOpenKeyW(HKEY_CURRENT_USER, lpSubKey, &hKey);
2657 if (retval != ERROR_SUCCESS)
2660 SHGetValueW(hKey, lpSubName, lpValue, NULL, (LPBYTE)&retval, &datsize);
2665 /*************************************************************************
2668 * Helper function to retrieve the possibly cached value for a specific policy
2671 * policy [I] The policy to look for
2672 * initial [I] Main registry key to open, if NULL use default
2673 * polTable [I] Table of known policies, 0 terminated
2674 * polArr [I] Cache array of policy values
2677 * The retrieved policy value or 0 if not successful
2680 * This function is used by the native SHRestricted function to search for the
2681 * policy and cache it once retrieved. The current Wine implementation uses a
2682 * different POLICYDATA structure and implements a similar algorithme adapted to
2685 DWORD WINAPI SHRestrictionLookup(
2688 LPPOLICYDATA polTable,
2691 TRACE("(0x%08x %s %p %p)\n", policy, debugstr_w(initial), polTable, polArr);
2693 if (!polTable || !polArr)
2696 for (;polTable->policy; polTable++, polArr++)
2698 if (policy == polTable->policy)
2700 /* we have a known policy */
2702 /* check if this policy has been cached */
2703 if (*polArr == SHELL_NO_POLICY)
2704 *polArr = SHGetRestriction(initial, polTable->appstr, polTable->keystr);
2708 /* we don't know this policy, return 0 */
2709 TRACE("unknown policy: (%08x)\n", policy);
2713 /*************************************************************************
2716 * Get an interface from an object.
2719 * Success: S_OK. ppv contains the requested interface.
2720 * Failure: An HRESULT error code.
2723 * This QueryInterface asks the inner object for an interface. In case
2724 * of aggregation this request would be forwarded by the inner to the
2725 * outer object. This function asks the inner object directly for the
2726 * interface circumventing the forwarding to the outer object.
2728 HRESULT WINAPI SHWeakQueryInterface(
2729 IUnknown * pUnk, /* [in] Outer object */
2730 IUnknown * pInner, /* [in] Inner object */
2731 IID * riid, /* [in] Interface GUID to query for */
2732 LPVOID* ppv) /* [out] Destination for queried interface */
2734 HRESULT hret = E_NOINTERFACE;
2735 TRACE("(pUnk=%p pInner=%p\n\tIID: %s %p)\n",pUnk,pInner,debugstr_guid(riid), ppv);
2738 if(pUnk && pInner) {
2739 hret = IUnknown_QueryInterface(pInner, riid, (LPVOID*)ppv);
2740 if (SUCCEEDED(hret)) IUnknown_Release(pUnk);
2742 TRACE("-- 0x%08x\n", hret);
2746 /*************************************************************************
2749 * Move a reference from one interface to another.
2752 * lpDest [O] Destination to receive the reference
2753 * lppUnknown [O] Source to give up the reference to lpDest
2758 VOID WINAPI SHWeakReleaseInterface(IUnknown *lpDest, IUnknown **lppUnknown)
2760 TRACE("(%p,%p)\n", lpDest, lppUnknown);
2765 IUnknown_AddRef(lpDest);
2766 IUnknown_AtomicRelease(lppUnknown); /* Release existing interface */
2770 /*************************************************************************
2773 * Convert an ASCII string of a CLSID into a CLSID.
2776 * idstr [I] String representing a CLSID in registry format
2777 * id [O] Destination for the converted CLSID
2780 * Success: TRUE. id contains the converted CLSID.
2783 BOOL WINAPI GUIDFromStringA(LPCSTR idstr, CLSID *id)
2786 MultiByteToWideChar(CP_ACP, 0, idstr, -1, wClsid, sizeof(wClsid)/sizeof(WCHAR));
2787 return SUCCEEDED(CLSIDFromStringWrap(wClsid, id));
2790 /*************************************************************************
2793 * Unicode version of GUIDFromStringA.
2795 BOOL WINAPI GUIDFromStringW(LPCWSTR idstr, CLSID *id)
2797 return SUCCEEDED(CLSIDFromStringWrap(idstr, id));
2800 /*************************************************************************
2803 * Determine if the browser is integrated into the shell, and set a registry
2810 * 1, If the browser is not integrated.
2811 * 2, If the browser is integrated.
2814 * The key "HKLM\Software\Microsoft\Internet Explorer\IntegratedBrowser" is
2815 * either set to TRUE, or removed depending on whether the browser is deemed
2818 DWORD WINAPI WhichPlatform(void)
2820 static const char szIntegratedBrowser[] = "IntegratedBrowser";
2821 static DWORD dwState = 0;
2823 DWORD dwRet, dwData, dwSize;
2828 /* If shell32 exports DllGetVersion(), the browser is integrated */
2829 GET_FUNC(pDllGetVersion, shell32, "DllGetVersion", 1);
2830 dwState = pDllGetVersion ? 2 : 1;
2832 /* Set or delete the key accordingly */
2833 dwRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
2834 "Software\\Microsoft\\Internet Explorer", 0,
2835 KEY_ALL_ACCESS, &hKey);
2838 dwRet = RegQueryValueExA(hKey, szIntegratedBrowser, 0, 0,
2839 (LPBYTE)&dwData, &dwSize);
2841 if (!dwRet && dwState == 1)
2843 /* Value exists but browser is not integrated */
2844 RegDeleteValueA(hKey, szIntegratedBrowser);
2846 else if (dwRet && dwState == 2)
2848 /* Browser is integrated but value does not exist */
2850 RegSetValueExA(hKey, szIntegratedBrowser, 0, REG_DWORD,
2851 (LPBYTE)&dwData, sizeof(dwData));
2858 /*************************************************************************
2861 * Unicode version of SHCreateWorkerWindowA.
2863 HWND WINAPI SHCreateWorkerWindowW(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
2864 DWORD dwStyle, HMENU hMenu, LONG z)
2866 static const WCHAR szClass[] = { 'W', 'o', 'r', 'k', 'e', 'r', 'W', '\0' };
2870 TRACE("(0x%08x,%p,0x%08x,0x%08x,%p,0x%08x)\n",
2871 wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2873 /* If our OS is natively ASCII, use the ASCII version */
2874 if (!(GetVersion() & 0x80000000)) /* NT */
2875 return SHCreateWorkerWindowA(wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2877 /* Create Window class */
2879 wc.lpfnWndProc = DefWindowProcW;
2882 wc.hInstance = shlwapi_hInstance;
2884 wc.hCursor = LoadCursorW(NULL, (LPWSTR)IDC_ARROW);
2885 wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
2886 wc.lpszMenuName = NULL;
2887 wc.lpszClassName = szClass;
2889 SHRegisterClassW(&wc); /* Register class */
2891 /* FIXME: Set extra bits in dwExStyle */
2893 hWnd = CreateWindowExW(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
2894 hWndParent, hMenu, shlwapi_hInstance, 0);
2897 SetWindowLongPtrW(hWnd, DWLP_MSGRESULT, z);
2900 SetWindowLongPtrW(hWnd, GWLP_WNDPROC, wndProc);
2905 /*************************************************************************
2908 * Get and show a context menu from a shell folder.
2911 * hWnd [I] Window displaying the shell folder
2912 * lpFolder [I] IShellFolder interface
2913 * lpApidl [I] Id for the particular folder desired
2917 * Failure: An HRESULT error code indicating the error.
2919 HRESULT WINAPI SHInvokeDefaultCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl)
2921 return SHInvokeCommand(hWnd, lpFolder, lpApidl, FALSE);
2924 /*************************************************************************
2927 * _SHPackDispParamsV
2929 HRESULT WINAPI SHPackDispParamsV(LPVOID w, LPVOID x, LPVOID y, LPVOID z)
2931 FIXME("%p %p %p %p\n",w,x,y,z);
2935 /*************************************************************************
2938 * This function seems to be a forward to SHPackDispParamsV (whatever THAT
2939 * function does...).
2941 HRESULT WINAPI SHPackDispParams(LPVOID w, LPVOID x, LPVOID y, LPVOID z)
2943 FIXME("%p %p %p %p\n", w, x, y, z);
2947 /*************************************************************************
2950 * _IConnectionPoint_SimpleInvoke
2952 DWORD WINAPI IConnectionPoint_SimpleInvoke(
2957 FIXME("(%p %p %p) stub\n",x,y,z);
2961 /*************************************************************************
2964 * Notify an IConnectionPoint object of changes.
2967 * lpCP [I] Object to notify
2972 * Failure: E_NOINTERFACE, if lpCP is NULL or does not support the
2973 * IConnectionPoint interface.
2975 HRESULT WINAPI IConnectionPoint_OnChanged(IConnectionPoint* lpCP, DISPID dispID)
2977 IEnumConnections *lpEnum;
2978 HRESULT hRet = E_NOINTERFACE;
2980 TRACE("(%p,0x%8X)\n", lpCP, dispID);
2982 /* Get an enumerator for the connections */
2984 hRet = IConnectionPoint_EnumConnections(lpCP, &lpEnum);
2986 if (SUCCEEDED(hRet))
2988 IPropertyNotifySink *lpSink;
2989 CONNECTDATA connData;
2992 /* Call OnChanged() for every notify sink in the connection point */
2993 while (IEnumConnections_Next(lpEnum, 1, &connData, &ulFetched) == S_OK)
2995 if (SUCCEEDED(IUnknown_QueryInterface(connData.pUnk, &IID_IPropertyNotifySink, (void**)&lpSink)) &&
2998 IPropertyNotifySink_OnChanged(lpSink, dispID);
2999 IPropertyNotifySink_Release(lpSink);
3001 IUnknown_Release(connData.pUnk);
3004 IEnumConnections_Release(lpEnum);
3009 /*************************************************************************
3012 * Notify an IConnectionPointContainer object of changes.
3015 * lpUnknown [I] Object to notify
3020 * Failure: E_NOINTERFACE, if lpUnknown is NULL or does not support the
3021 * IConnectionPointContainer interface.
3023 HRESULT WINAPI IUnknown_CPContainerOnChanged(IUnknown *lpUnknown, DISPID dispID)
3025 IConnectionPointContainer* lpCPC = NULL;
3026 HRESULT hRet = E_NOINTERFACE;
3028 TRACE("(%p,0x%8X)\n", lpUnknown, dispID);
3031 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer, (void**)&lpCPC);
3033 if (SUCCEEDED(hRet))
3035 IConnectionPoint* lpCP;
3037 hRet = IConnectionPointContainer_FindConnectionPoint(lpCPC, &IID_IPropertyNotifySink, &lpCP);
3038 IConnectionPointContainer_Release(lpCPC);
3040 hRet = IConnectionPoint_OnChanged(lpCP, dispID);
3041 IConnectionPoint_Release(lpCP);
3046 /*************************************************************************
3051 BOOL WINAPI PlaySoundWrapW(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
3053 GET_FUNC(pPlaySoundW, winmm, "PlaySoundW", FALSE);
3054 return pPlaySoundW(pszSound, hmod, fdwSound);
3057 /*************************************************************************
3060 BOOL WINAPI SHGetIniStringW(LPSTR str1, LPSTR str2, LPSTR pStr, DWORD some_len, LPCSTR lpStr2)
3063 * str1: "I" "I" pushl esp+0x20
3064 * str2: "U" "I" pushl 0x77c93810
3065 * (is "I" and "U" "integer" and "unsigned" ??)
3067 * pStr: "" "" pushl eax
3068 * some_len: 0x824 0x104 pushl 0x824
3069 * lpStr2: "%l" "%l" pushl esp+0xc
3071 * shlwapi. StrCpyNW(lpStr2, irrelevant_var, 0x104);
3072 * LocalAlloc(0x00, some_len) -> irrelevant_var
3073 * LocalAlloc(0x40, irrelevant_len) -> pStr
3074 * shlwapi.294(str1, str2, pStr, some_len, lpStr2);
3075 * shlwapi.PathRemoveBlanksW(pStr);
3077 FIXME("('%s', '%s', '%s', %08x, '%s'): stub!\n", str1, str2, pStr, some_len, lpStr2);
3081 /*************************************************************************
3084 * Called by ICQ2000b install via SHDOCVW:
3085 * str1: "InternetShortcut"
3086 * x: some unknown pointer
3087 * str2: "http://free.aol.com/tryaolfree/index.adp?139269"
3088 * str3: "C:\\WINDOWS\\Desktop.new2\\Free AOL & Unlimited Internet.url"
3090 * In short: this one maybe creates a desktop link :-)
3092 BOOL WINAPI SHSetIniStringW(LPWSTR str1, LPVOID x, LPWSTR str2, LPWSTR str3)
3094 FIXME("('%s', %p, '%s', '%s'), stub.\n", debugstr_w(str1), x, debugstr_w(str2), debugstr_w(str3));
3098 /*************************************************************************
3103 BOOL WINAPI ExtTextOutWrapW(HDC hdc, INT x, INT y, UINT flags, const RECT *lprect,
3104 LPCWSTR str, UINT count, const INT *lpDx)
3106 GET_FUNC(pCOMCTL32_417, comctl32, (LPCSTR)417, FALSE);
3107 return pCOMCTL32_417(hdc, x, y, flags, lprect, str, count, lpDx);
3110 /*************************************************************************
3113 * See SHGetFileInfoW.
3115 DWORD WINAPI SHGetFileInfoWrapW(LPCWSTR path, DWORD dwFileAttributes,
3116 SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
3118 GET_FUNC(pSHGetFileInfoW, shell32, "SHGetFileInfoW", 0);
3119 return pSHGetFileInfoW(path, dwFileAttributes, psfi, sizeofpsfi, flags);
3122 /*************************************************************************
3125 * See DragQueryFileW.
3127 UINT WINAPI DragQueryFileWrapW(HDROP hDrop, UINT lFile, LPWSTR lpszFile, UINT lLength)
3129 GET_FUNC(pDragQueryFileW, shell32, "DragQueryFileW", 0);
3130 return pDragQueryFileW(hDrop, lFile, lpszFile, lLength);
3133 /*************************************************************************
3136 * See SHBrowseForFolderW.
3138 LPITEMIDLIST WINAPI SHBrowseForFolderWrapW(LPBROWSEINFOW lpBi)
3140 GET_FUNC(pSHBrowseForFolderW, shell32, "SHBrowseForFolderW", NULL);
3141 return pSHBrowseForFolderW(lpBi);
3144 /*************************************************************************
3147 * See SHGetPathFromIDListW.
3149 BOOL WINAPI SHGetPathFromIDListWrapW(LPCITEMIDLIST pidl,LPWSTR pszPath)
3151 GET_FUNC(pSHGetPathFromIDListW, shell32, "SHGetPathFromIDListW", 0);
3152 return pSHGetPathFromIDListW(pidl, pszPath);
3155 /*************************************************************************
3158 * See ShellExecuteExW.
3160 BOOL WINAPI ShellExecuteExWrapW(LPSHELLEXECUTEINFOW lpExecInfo)
3162 GET_FUNC(pShellExecuteExW, shell32, "ShellExecuteExW", FALSE);
3163 return pShellExecuteExW(lpExecInfo);
3166 /*************************************************************************
3169 * See SHFileOperationW.
3171 HICON WINAPI SHFileOperationWrapW(LPSHFILEOPSTRUCTW lpFileOp)
3173 GET_FUNC(pSHFileOperationW, shell32, "SHFileOperationW", 0);
3174 return pSHFileOperationW(lpFileOp);
3177 /*************************************************************************
3180 * See ExtractIconExW.
3182 UINT WINAPI ExtractIconExWrapW(LPCWSTR lpszFile, INT nIconIndex, HICON *phiconLarge,
3183 HICON *phiconSmall, UINT nIcons)
3185 GET_FUNC(pExtractIconExW, shell32, "ExtractIconExW", 0);
3186 return pExtractIconExW(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
3189 /*************************************************************************
3193 LONG WINAPI SHInterlockedCompareExchange( PLONG dest, LONG xchg, LONG compare)
3195 return InterlockedCompareExchange(dest, xchg, compare);
3198 /*************************************************************************
3201 * See GetFileVersionInfoSizeW.
3203 DWORD WINAPI GetFileVersionInfoSizeWrapW(
3209 GET_FUNC(pGetFileVersionInfoSizeW, version, "GetFileVersionInfoSizeW", 0);
3210 ret = pGetFileVersionInfoSizeW(x, y);
3214 /*************************************************************************
3217 * See GetFileVersionInfoW.
3219 BOOL WINAPI GetFileVersionInfoWrapW(
3220 LPWSTR w, /* [in] path to dll */
3221 DWORD x, /* [in] parm 2 to GetFileVersionInfoA */
3222 DWORD y, /* [in] return value from SHLWAPI_350() - assume length */
3223 LPVOID z) /* [in/out] buffer (+0x208 sent to GetFileVersionInfoA()) */
3225 GET_FUNC(pGetFileVersionInfoW, version, "GetFileVersionInfoW", 0);
3226 return pGetFileVersionInfoW(w, x, y-0x208, (char*)z+0x208);
3229 /*************************************************************************
3232 * See VerQueryValueW.
3234 WORD WINAPI VerQueryValueWrapW(
3235 LPVOID w, /* [in] Buffer from SHLWAPI_351() */
3236 LPWSTR x, /* [in] Value to retrieve - converted and passed to VerQueryValueA() as #2 */
3237 LPVOID y, /* [out] Ver buffer - passed to VerQueryValueA as #3 */
3238 UINT* z) /* [in] Ver length - passed to VerQueryValueA as #4 */
3240 GET_FUNC(pVerQueryValueW, version, "VerQueryValueW", 0);
3241 return pVerQueryValueW((char*)w+0x208, x, y, z);
3244 #define IsIface(type) SUCCEEDED((hRet = IUnknown_QueryInterface(lpUnknown, &IID_##type, (void**)&lpObj)))
3245 #define IShellBrowser_EnableModeless IShellBrowser_EnableModelessSB
3246 #define EnableModeless(type) type##_EnableModeless((type*)lpObj, bModeless)
3248 /*************************************************************************
3251 * Change the modality of a shell object.
3254 * lpUnknown [I] Object to make modeless
3255 * bModeless [I] TRUE=Make modeless, FALSE=Make modal
3258 * Success: S_OK. The modality lpUnknown is changed.
3259 * Failure: An HRESULT error code indicating the error.
3262 * lpUnknown must support the IOleInPlaceFrame interface, the
3263 * IInternetSecurityMgrSite interface, the IShellBrowser interface
3264 * the IDocHostUIHandler interface, or the IOleInPlaceActiveObject interface,
3265 * or this call will fail.
3267 HRESULT WINAPI IUnknown_EnableModeless(IUnknown *lpUnknown, BOOL bModeless)
3272 TRACE("(%p,%d)\n", lpUnknown, bModeless);
3277 if (IsIface(IOleInPlaceActiveObject))
3278 EnableModeless(IOleInPlaceActiveObject);
3279 else if (IsIface(IOleInPlaceFrame))
3280 EnableModeless(IOleInPlaceFrame);
3281 else if (IsIface(IShellBrowser))
3282 EnableModeless(IShellBrowser);
3284 /* FIXME: Wine has no headers for these objects yet */
3285 else if (IsIface(IInternetSecurityMgrSite))
3286 EnableModeless(IInternetSecurityMgrSite);
3287 else if (IsIface(IDocHostUIHandler))
3288 EnableModeless(IDocHostUIHandler);
3293 IUnknown_Release(lpObj);
3297 /*************************************************************************
3300 * See SHGetNewLinkInfoW.
3302 BOOL WINAPI SHGetNewLinkInfoWrapW(LPCWSTR pszLinkTo, LPCWSTR pszDir, LPWSTR pszName,
3303 BOOL *pfMustCopy, UINT uFlags)
3305 GET_FUNC(pSHGetNewLinkInfoW, shell32, "SHGetNewLinkInfoW", FALSE);
3306 return pSHGetNewLinkInfoW(pszLinkTo, pszDir, pszName, pfMustCopy, uFlags);
3309 /*************************************************************************
3312 * See SHDefExtractIconW.
3314 UINT WINAPI SHDefExtractIconWrapW(LPCWSTR pszIconFile, int iIndex, UINT uFlags, HICON* phiconLarge,
3315 HICON* phiconSmall, UINT nIconSize)
3317 GET_FUNC(pSHDefExtractIconW, shell32, "SHDefExtractIconW", 0);
3318 return pSHDefExtractIconW(pszIconFile, iIndex, uFlags, phiconLarge, phiconSmall, nIconSize);
3321 /*************************************************************************
3324 * Get and show a context menu from a shell folder.
3327 * hWnd [I] Window displaying the shell folder
3328 * lpFolder [I] IShellFolder interface
3329 * lpApidl [I] Id for the particular folder desired
3330 * bInvokeDefault [I] Whether to invoke the default menu item
3333 * Success: S_OK. If bInvokeDefault is TRUE, the default menu action was
3335 * Failure: An HRESULT error code indicating the error.
3337 HRESULT WINAPI SHInvokeCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl, BOOL bInvokeDefault)
3339 IContextMenu *iContext;
3340 HRESULT hRet = E_FAIL;
3342 TRACE("(%p,%p,%p,%d)\n", hWnd, lpFolder, lpApidl, bInvokeDefault);
3347 /* Get the context menu from the shell folder */
3348 hRet = IShellFolder_GetUIObjectOf(lpFolder, hWnd, 1, &lpApidl,
3349 &IID_IContextMenu, 0, (void**)&iContext);
3350 if (SUCCEEDED(hRet))
3353 if ((hMenu = CreatePopupMenu()))
3356 DWORD dwDefaultId = 0;
3358 /* Add the context menu entries to the popup */
3359 hQuery = IContextMenu_QueryContextMenu(iContext, hMenu, 0, 1, 0x7FFF,
3360 bInvokeDefault ? CMF_NORMAL : CMF_DEFAULTONLY);
3362 if (SUCCEEDED(hQuery))
3364 if (bInvokeDefault &&
3365 (dwDefaultId = GetMenuDefaultItem(hMenu, 0, 0)) != 0xFFFFFFFF)
3367 CMINVOKECOMMANDINFO cmIci;
3368 /* Invoke the default item */
3369 memset(&cmIci,0,sizeof(cmIci));
3370 cmIci.cbSize = sizeof(cmIci);
3371 cmIci.fMask = CMIC_MASK_ASYNCOK;
3373 cmIci.lpVerb = MAKEINTRESOURCEA(dwDefaultId);
3374 cmIci.nShow = SW_SCROLLCHILDREN;
3376 hRet = IContextMenu_InvokeCommand(iContext, &cmIci);
3381 IContextMenu_Release(iContext);
3386 /*************************************************************************
3391 HICON WINAPI ExtractIconWrapW(HINSTANCE hInstance, LPCWSTR lpszExeFileName,
3394 GET_FUNC(pExtractIconW, shell32, "ExtractIconW", NULL);
3395 return pExtractIconW(hInstance, lpszExeFileName, nIconIndex);
3398 /*************************************************************************
3401 * Load a library from the directory of a particular process.
3404 * new_mod [I] Library name
3405 * inst_hwnd [I] Module whose directory is to be used
3406 * bCrossCodePage [I] Should be FALSE (currently ignored)
3409 * Success: A handle to the loaded module
3410 * Failure: A NULL handle.
3412 HMODULE WINAPI MLLoadLibraryA(LPCSTR new_mod, HMODULE inst_hwnd, BOOL bCrossCodePage)
3414 /* FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for
3416 * FIXME: Native shows calls to:
3417 * SHRegGetUSValue for "Software\Microsoft\Internet Explorer\International"
3419 * RegOpenKeyExA for "HKLM\Software\Microsoft\Internet Explorer"
3420 * RegQueryValueExA for "LPKInstalled"
3422 * RegOpenKeyExA for "HKCU\Software\Microsoft\Internet Explorer\International"
3423 * RegQueryValueExA for "ResourceLocale"
3425 * RegOpenKeyExA for "HKLM\Software\Microsoft\Active Setup\Installed Components\{guid}"
3426 * RegQueryValueExA for "Locale"
3428 * and then tests the Locale ("en" for me).
3430 * after the code then a DPA_Create (first time) and DPA_InsertPtr are done.
3432 CHAR mod_path[2*MAX_PATH];
3436 FIXME("(%s,%p,%d) semi-stub!\n", debugstr_a(new_mod), inst_hwnd, bCrossCodePage);
3437 len = GetModuleFileNameA(inst_hwnd, mod_path, sizeof(mod_path));
3438 if (!len || len >= sizeof(mod_path)) return NULL;
3440 ptr = strrchr(mod_path, '\\');
3442 strcpy(ptr+1, new_mod);
3443 TRACE("loading %s\n", debugstr_a(mod_path));
3444 return LoadLibraryA(mod_path);
3449 /*************************************************************************
3452 * Unicode version of MLLoadLibraryA.
3454 HMODULE WINAPI MLLoadLibraryW(LPCWSTR new_mod, HMODULE inst_hwnd, BOOL bCrossCodePage)
3456 WCHAR mod_path[2*MAX_PATH];
3460 FIXME("(%s,%p,%d) semi-stub!\n", debugstr_w(new_mod), inst_hwnd, bCrossCodePage);
3461 len = GetModuleFileNameW(inst_hwnd, mod_path, sizeof(mod_path) / sizeof(WCHAR));
3462 if (!len || len >= sizeof(mod_path) / sizeof(WCHAR)) return NULL;
3464 ptr = strrchrW(mod_path, '\\');
3466 strcpyW(ptr+1, new_mod);
3467 TRACE("loading %s\n", debugstr_w(mod_path));
3468 return LoadLibraryW(mod_path);
3473 /*************************************************************************
3474 * ColorAdjustLuma [SHLWAPI.@]
3476 * Adjust the luminosity of a color
3479 * cRGB [I] RGB value to convert
3480 * dwLuma [I] Luma adjustment
3481 * bUnknown [I] Unknown
3484 * The adjusted RGB color.
3486 COLORREF WINAPI ColorAdjustLuma(COLORREF cRGB, int dwLuma, BOOL bUnknown)
3488 TRACE("(0x%8x,%d,%d)\n", cRGB, dwLuma, bUnknown);
3494 ColorRGBToHLS(cRGB, &wH, &wL, &wS);
3496 FIXME("Ignoring luma adjustment\n");
3498 /* FIXME: The ajdustment is not linear */
3500 cRGB = ColorHLSToRGB(wH, wL, wS);
3505 /*************************************************************************
3508 * See GetSaveFileNameW.
3510 BOOL WINAPI GetSaveFileNameWrapW(LPOPENFILENAMEW ofn)
3512 GET_FUNC(pGetSaveFileNameW, comdlg32, "GetSaveFileNameW", FALSE);
3513 return pGetSaveFileNameW(ofn);
3516 /*************************************************************************
3519 * See WNetRestoreConnectionW.
3521 DWORD WINAPI WNetRestoreConnectionWrapW(HWND hwndOwner, LPWSTR lpszDevice)
3523 GET_FUNC(pWNetRestoreConnectionW, mpr, "WNetRestoreConnectionW", 0);
3524 return pWNetRestoreConnectionW(hwndOwner, lpszDevice);
3527 /*************************************************************************
3530 * See WNetGetLastErrorW.
3532 DWORD WINAPI WNetGetLastErrorWrapW(LPDWORD lpError, LPWSTR lpErrorBuf, DWORD nErrorBufSize,
3533 LPWSTR lpNameBuf, DWORD nNameBufSize)
3535 GET_FUNC(pWNetGetLastErrorW, mpr, "WNetGetLastErrorW", 0);
3536 return pWNetGetLastErrorW(lpError, lpErrorBuf, nErrorBufSize, lpNameBuf, nNameBufSize);
3539 /*************************************************************************
3542 * See PageSetupDlgW.
3544 BOOL WINAPI PageSetupDlgWrapW(LPPAGESETUPDLGW pagedlg)
3546 GET_FUNC(pPageSetupDlgW, comdlg32, "PageSetupDlgW", FALSE);
3547 return pPageSetupDlgW(pagedlg);
3550 /*************************************************************************
3555 BOOL WINAPI PrintDlgWrapW(LPPRINTDLGW printdlg)
3557 GET_FUNC(pPrintDlgW, comdlg32, "PrintDlgW", FALSE);
3558 return pPrintDlgW(printdlg);
3561 /*************************************************************************
3564 * See GetOpenFileNameW.
3566 BOOL WINAPI GetOpenFileNameWrapW(LPOPENFILENAMEW ofn)
3568 GET_FUNC(pGetOpenFileNameW, comdlg32, "GetOpenFileNameW", FALSE);
3569 return pGetOpenFileNameW(ofn);
3572 /*************************************************************************
3575 HRESULT WINAPI IUnknown_EnumObjects(LPSHELLFOLDER lpFolder, HWND hwnd, SHCONTF flags, IEnumIDList **ppenum)
3580 hr = IShellFolder_QueryInterface(lpFolder, &IID_IPersist, (LPVOID)&persist);
3584 hr = IPersist_GetClassID(persist, &clsid);
3587 if(IsEqualCLSID(&clsid, &CLSID_ShellFSFolder))
3588 hr = IShellFolder_EnumObjects(lpFolder, hwnd, flags, ppenum);
3592 IPersist_Release(persist);
3597 /* INTERNAL: Map from HLS color space to RGB */
3598 static WORD WINAPI ConvertHue(int wHue, WORD wMid1, WORD wMid2)
3600 wHue = wHue > 240 ? wHue - 240 : wHue < 0 ? wHue + 240 : wHue;
3604 else if (wHue > 120)
3609 return ((wHue * (wMid2 - wMid1) + 20) / 40) + wMid1;
3612 /* Convert to RGB and scale into RGB range (0..255) */
3613 #define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240
3615 /*************************************************************************
3616 * ColorHLSToRGB [SHLWAPI.@]
3618 * Convert from hls color space into an rgb COLORREF.
3621 * wHue [I] Hue amount
3622 * wLuminosity [I] Luminosity amount
3623 * wSaturation [I] Saturation amount
3626 * A COLORREF representing the converted color.
3629 * Input hls values are constrained to the range (0..240).
3631 COLORREF WINAPI ColorHLSToRGB(WORD wHue, WORD wLuminosity, WORD wSaturation)
3637 WORD wGreen, wBlue, wMid1, wMid2;
3639 if (wLuminosity > 120)
3640 wMid2 = wSaturation + wLuminosity - (wSaturation * wLuminosity + 120) / 240;
3642 wMid2 = ((wSaturation + 240) * wLuminosity + 120) / 240;
3644 wMid1 = wLuminosity * 2 - wMid2;
3646 wRed = GET_RGB(wHue + 80);
3647 wGreen = GET_RGB(wHue);
3648 wBlue = GET_RGB(wHue - 80);
3650 return RGB(wRed, wGreen, wBlue);
3653 wRed = wLuminosity * 255 / 240;
3654 return RGB(wRed, wRed, wRed);
3657 /*************************************************************************
3660 * Get the current docking status of the system.
3663 * dwFlags [I] DOCKINFO_ flags from "winbase.h", unused
3666 * One of DOCKINFO_UNDOCKED, DOCKINFO_UNDOCKED, or 0 if the system is not
3669 DWORD WINAPI SHGetMachineInfo(DWORD dwFlags)
3671 HW_PROFILE_INFOA hwInfo;
3673 TRACE("(0x%08x)\n", dwFlags);
3675 GetCurrentHwProfileA(&hwInfo);
3676 switch (hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED))
3678 case DOCKINFO_DOCKED:
3679 case DOCKINFO_UNDOCKED:
3680 return hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED);
3686 /*************************************************************************
3689 * Function seems to do FreeLibrary plus other things.
3691 * FIXME native shows the following calls:
3692 * RtlEnterCriticalSection
3694 * GetProcAddress(Comctl32??, 150L)
3696 * RtlLeaveCriticalSection
3697 * followed by the FreeLibrary.
3698 * The above code may be related to .377 above.
3700 BOOL WINAPI MLFreeLibrary(HMODULE hModule)
3702 FIXME("(%p) semi-stub\n", hModule);
3703 return FreeLibrary(hModule);
3706 /*************************************************************************
3709 BOOL WINAPI SHFlushSFCacheWrap(void) {
3714 /*************************************************************************
3717 BOOL WINAPI DeleteMenuWrap(HMENU hmenu, UINT pos, UINT flags)
3719 /* FIXME: This should do more than simply call DeleteMenu */
3720 FIXME("%p %08x %08x): semi-stub\n", hmenu, pos, flags);
3721 return DeleteMenu(hmenu, pos, flags);
3724 /*************************************************************************
3726 * FIXME I have no idea what this function does or what its arguments are.
3728 BOOL WINAPI MLIsMLHInstance(HINSTANCE hInst)
3730 FIXME("(%p) stub\n", hInst);
3735 /*************************************************************************
3738 DWORD WINAPI MLSetMLHInstance(HINSTANCE hInst, HANDLE hHeap)
3740 FIXME("(%p,%p) stub\n", hInst, hHeap);
3741 return E_FAIL; /* This is what is used if shlwapi not loaded */
3744 /*************************************************************************
3747 DWORD WINAPI MLClearMLHInstance(DWORD x)
3749 FIXME("(0x%08x)stub\n", x);
3753 /*************************************************************************
3756 * Convert an Unicode string CLSID into a CLSID.
3759 * idstr [I] string containing a CLSID in text form
3760 * id [O] CLSID extracted from the string
3763 * S_OK on success or E_INVALIDARG on failure
3766 * This is really CLSIDFromString() which is exported by ole32.dll,
3767 * however the native shlwapi.dll does *not* import ole32. Nor does
3768 * ole32.dll import this ordinal from shlwapi. Therefore we must conclude
3769 * that MS duplicated the code for CLSIDFromString(), and yes they did, only
3770 * it returns an E_INVALIDARG error code on failure.
3771 * This is a duplicate (with changes for Unicode) of CLSIDFromString16()
3772 * in "dlls/ole32/compobj.c".
3774 HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR idstr, CLSID *id)
3782 memset(id, 0, sizeof(CLSID));
3785 else { /* validate the CLSID string */
3787 if (strlenW(s) != 38)
3788 return E_INVALIDARG;
3790 if ((s[0]!=L'{') || (s[9]!=L'-') || (s[14]!=L'-') || (s[19]!=L'-') || (s[24]!=L'-') || (s[37]!=L'}'))
3791 return E_INVALIDARG;
3793 for (i=1; i<37; i++)
3795 if ((i == 9)||(i == 14)||(i == 19)||(i == 24))
3797 if (!(((s[i] >= L'0') && (s[i] <= L'9')) ||
3798 ((s[i] >= L'a') && (s[i] <= L'f')) ||
3799 ((s[i] >= L'A') && (s[i] <= L'F')))
3801 return E_INVALIDARG;
3805 TRACE("%s -> %p\n", debugstr_w(s), id);
3807 /* quick lookup table */
3808 memset(table, 0, 256*sizeof(WCHAR));
3810 for (i = 0; i < 10; i++) {
3813 for (i = 0; i < 6; i++) {
3814 table['A' + i] = i+10;
3815 table['a' + i] = i+10;
3818 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
3822 s++; /* skip leading brace */
3823 for (i = 0; i < 4; i++) {
3824 p[3 - i] = table[*s]<<4 | table[*(s+1)];
3830 for (i = 0; i < 2; i++) {
3831 p[1-i] = table[*s]<<4 | table[*(s+1)];
3837 for (i = 0; i < 2; i++) {
3838 p[1-i] = table[*s]<<4 | table[*(s+1)];
3844 /* these are just sequential bytes */
3845 for (i = 0; i < 2; i++) {
3846 *p++ = table[*s]<<4 | table[*(s+1)];
3851 for (i = 0; i < 6; i++) {
3852 *p++ = table[*s]<<4 | table[*(s+1)];
3859 /*************************************************************************
3862 * Determine if the OS supports a given feature.
3865 * dwFeature [I] Feature requested (undocumented)
3868 * TRUE If the feature is available.
3869 * FALSE If the feature is not available.
3871 BOOL WINAPI IsOS(DWORD feature)
3873 OSVERSIONINFOA osvi;
3874 DWORD platform, majorv, minorv;
3876 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
3877 if(!GetVersionExA(&osvi)) {
3878 ERR("GetVersionEx failed\n");
3882 majorv = osvi.dwMajorVersion;
3883 minorv = osvi.dwMinorVersion;
3884 platform = osvi.dwPlatformId;
3886 #define ISOS_RETURN(x) \
3887 TRACE("(0x%x) ret=%d\n",feature,(x)); \
3891 case OS_WIN32SORGREATER:
3892 ISOS_RETURN(platform == VER_PLATFORM_WIN32s
3893 || platform == VER_PLATFORM_WIN32_WINDOWS)
3895 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3896 case OS_WIN95ORGREATER:
3897 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS)
3898 case OS_NT4ORGREATER:
3899 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 4)
3900 case OS_WIN2000ORGREATER_ALT:
3901 case OS_WIN2000ORGREATER:
3902 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5)
3903 case OS_WIN98ORGREATER:
3904 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv >= 10)
3906 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv == 10)
3908 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5)
3909 case OS_WIN2000SERVER:
3910 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3911 case OS_WIN2000ADVSERVER:
3912 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3913 case OS_WIN2000DATACENTER:
3914 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3915 case OS_WIN2000TERMINAL:
3916 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1))
3918 FIXME("(OS_EMBEDDED) What should we return here?\n");
3920 case OS_TERMINALCLIENT:
3921 FIXME("(OS_TERMINALCLIENT) What should we return here?\n");
3923 case OS_TERMINALREMOTEADMIN:
3924 FIXME("(OS_TERMINALREMOTEADMIN) What should we return here?\n");
3927 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv == 0)
3928 case OS_MEORGREATER:
3929 ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv >= 90)
3930 case OS_XPORGREATER:
3931 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5 && minorv >= 1)
3933 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5 && minorv >= 1)
3934 case OS_PROFESSIONAL:
3935 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3937 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3939 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5)
3941 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3942 case OS_TERMINALSERVER:
3943 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3944 case OS_PERSONALTERMINALSERVER:
3945 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && minorv >= 1 && majorv >= 5)
3946 case OS_FASTUSERSWITCHING:
3947 FIXME("(OS_FASTUSERSWITCHING) What should we return here?\n");
3949 case OS_WELCOMELOGONUI:
3950 FIXME("(OS_WELCOMELOGONUI) What should we return here?\n");
3952 case OS_DOMAINMEMBER:
3953 FIXME("(OS_DOMAINMEMBER) What should we return here?\n");
3956 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3958 FIXME("(OS_WOW6432) Should we check this?\n");
3961 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3962 case OS_SMALLBUSINESSSERVER:
3963 ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT)
3965 FIXME("(OS_TABLEPC) What should we return here?\n");
3967 case OS_SERVERADMINUI:
3968 FIXME("(OS_SERVERADMINUI) What should we return here?\n");
3970 case OS_MEDIACENTER:
3971 FIXME("(OS_MEDIACENTER) What should we return here?\n");
3974 FIXME("(OS_APPLIANCE) What should we return here?\n");
3980 WARN("(0x%x) unknown parameter\n",feature);
3985 /*************************************************************************
3988 HRESULT WINAPI SHLoadRegUIStringW(HKEY hkey, LPCWSTR value, LPWSTR buf, DWORD size)
3990 DWORD type, sz = size;
3992 if(RegQueryValueExW(hkey, value, NULL, &type, (LPBYTE)buf, &sz) != ERROR_SUCCESS)
3995 return SHLoadIndirectString(buf, buf, size, NULL);
3998 /*************************************************************************
4001 * Call IInputObject_TranslateAcceleratorIO() on an object.
4004 * lpUnknown [I] Object supporting the IInputObject interface.
4005 * lpMsg [I] Key message to be processed.
4009 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
4011 HRESULT WINAPI IUnknown_TranslateAcceleratorIO(IUnknown *lpUnknown, LPMSG lpMsg)
4013 IInputObject* lpInput = NULL;
4014 HRESULT hRet = E_INVALIDARG;
4016 TRACE("(%p,%p)\n", lpUnknown, lpMsg);
4019 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInputObject,
4021 if (SUCCEEDED(hRet) && lpInput)
4023 hRet = IInputObject_TranslateAcceleratorIO(lpInput, lpMsg);
4024 IInputObject_Release(lpInput);
4030 /*************************************************************************
4033 * Call IInputObject_HasFocusIO() on an object.
4036 * lpUnknown [I] Object supporting the IInputObject interface.
4039 * Success: S_OK, if lpUnknown is an IInputObject object and has the focus,
4040 * or S_FALSE otherwise.
4041 * Failure: An HRESULT error code, or E_INVALIDARG if lpUnknown is NULL.
4043 HRESULT WINAPI IUnknown_HasFocusIO(IUnknown *lpUnknown)
4045 IInputObject* lpInput = NULL;
4046 HRESULT hRet = E_INVALIDARG;
4048 TRACE("(%p)\n", lpUnknown);
4051 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInputObject,
4053 if (SUCCEEDED(hRet) && lpInput)
4055 hRet = IInputObject_HasFocusIO(lpInput);
4056 IInputObject_Release(lpInput);
4062 /*************************************************************************
4063 * ColorRGBToHLS [SHLWAPI.@]
4065 * Convert an rgb COLORREF into the hls color space.
4068 * cRGB [I] Source rgb value
4069 * pwHue [O] Destination for converted hue
4070 * pwLuminance [O] Destination for converted luminance
4071 * pwSaturation [O] Destination for converted saturation
4074 * Nothing. pwHue, pwLuminance and pwSaturation are set to the converted
4078 * Output HLS values are constrained to the range (0..240).
4079 * For Achromatic conversions, Hue is set to 160.
4081 VOID WINAPI ColorRGBToHLS(COLORREF cRGB, LPWORD pwHue,
4082 LPWORD pwLuminance, LPWORD pwSaturation)
4084 int wR, wG, wB, wMax, wMin, wHue, wLuminosity, wSaturation;
4086 TRACE("(%08x,%p,%p,%p)\n", cRGB, pwHue, pwLuminance, pwSaturation);
4088 wR = GetRValue(cRGB);
4089 wG = GetGValue(cRGB);
4090 wB = GetBValue(cRGB);
4092 wMax = max(wR, max(wG, wB));
4093 wMin = min(wR, min(wG, wB));
4096 wLuminosity = ((wMax + wMin) * 240 + 255) / 510;
4100 /* Achromatic case */
4102 /* Hue is now unrepresentable, but this is what native returns... */
4107 /* Chromatic case */
4108 int wDelta = wMax - wMin, wRNorm, wGNorm, wBNorm;
4111 if (wLuminosity <= 120)
4112 wSaturation = ((wMax + wMin)/2 + wDelta * 240) / (wMax + wMin);
4114 wSaturation = ((510 - wMax - wMin)/2 + wDelta * 240) / (510 - wMax - wMin);
4117 wRNorm = (wDelta/2 + wMax * 40 - wR * 40) / wDelta;
4118 wGNorm = (wDelta/2 + wMax * 40 - wG * 40) / wDelta;
4119 wBNorm = (wDelta/2 + wMax * 40 - wB * 40) / wDelta;
4122 wHue = wBNorm - wGNorm;
4123 else if (wG == wMax)
4124 wHue = 80 + wRNorm - wBNorm;
4126 wHue = 160 + wGNorm - wRNorm;
4129 else if (wHue > 240)
4135 *pwLuminance = wLuminosity;
4137 *pwSaturation = wSaturation;
4140 /*************************************************************************
4141 * SHCreateShellPalette [SHLWAPI.@]
4143 HPALETTE WINAPI SHCreateShellPalette(HDC hdc)
4146 return CreateHalftonePalette(hdc);
4149 /*************************************************************************
4150 * SHGetInverseCMAP (SHLWAPI.@)
4152 * Get an inverse color map table.
4155 * lpCmap [O] Destination for color map
4156 * dwSize [I] Size of memory pointed to by lpCmap
4160 * Failure: E_POINTER, If lpCmap is invalid.
4161 * E_INVALIDARG, If dwFlags is invalid
4162 * E_OUTOFMEMORY, If there is no memory available
4165 * dwSize may only be CMAP_PTR_SIZE (4) or CMAP_SIZE (8192).
4166 * If dwSize = CMAP_PTR_SIZE, *lpCmap is set to the address of this DLL's
4168 * If dwSize = CMAP_SIZE, lpCmap is filled with a copy of the data from
4169 * this DLL's internal CMap.
4171 HRESULT WINAPI SHGetInverseCMAP(LPDWORD dest, DWORD dwSize)
4174 FIXME(" - returning bogus address for SHGetInverseCMAP\n");
4175 *dest = (DWORD)0xabba1249;
4178 FIXME("(%p, %#x) stub\n", dest, dwSize);
4182 /*************************************************************************
4183 * SHIsLowMemoryMachine [SHLWAPI.@]
4185 * Determine if the current computer has low memory.
4191 * TRUE if the users machine has 16 Megabytes of memory or less,
4194 BOOL WINAPI SHIsLowMemoryMachine (DWORD x)
4196 FIXME("(0x%08x) stub\n", x);
4200 /*************************************************************************
4201 * GetMenuPosFromID [SHLWAPI.@]
4203 * Return the position of a menu item from its Id.
4206 * hMenu [I] Menu containing the item
4207 * wID [I] Id of the menu item
4210 * Success: The index of the menu item in hMenu.
4211 * Failure: -1, If the item is not found.
4213 INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID)
4216 INT nCount = GetMenuItemCount(hMenu), nIter = 0;
4218 while (nIter < nCount)
4220 mi.cbSize = sizeof(mi);
4222 if (GetMenuItemInfoW(hMenu, nIter, TRUE, &mi) && mi.wID == wID)
4229 /*************************************************************************
4232 * Same as SHLWAPI.GetMenuPosFromID
4234 DWORD WINAPI SHMenuIndexFromID(HMENU hMenu, UINT uID)
4236 return GetMenuPosFromID(hMenu, uID);
4240 /*************************************************************************
4243 VOID WINAPI FixSlashesAndColonW(LPWSTR lpwstr)
4254 /*************************************************************************
4257 DWORD WINAPI SHGetAppCompatFlags(DWORD dwUnknown)
4259 FIXME("(0x%08x) stub\n", dwUnknown);
4264 /*************************************************************************
4267 HRESULT WINAPI SHCoCreateInstanceAC(REFCLSID rclsid, LPUNKNOWN pUnkOuter,
4268 DWORD dwClsContext, REFIID iid, LPVOID *ppv)
4270 return CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, ppv);
4273 /*************************************************************************
4274 * SHSkipJunction [SHLWAPI.@]
4276 * Determine if a bind context can be bound to an object
4279 * pbc [I] Bind context to check
4280 * pclsid [I] CLSID of object to be bound to
4283 * TRUE: If it is safe to bind
4284 * FALSE: If pbc is invalid or binding would not be safe
4287 BOOL WINAPI SHSkipJunction(IBindCtx *pbc, const CLSID *pclsid)
4289 static WCHAR szSkipBinding[] = { 'S','k','i','p',' ',
4290 'B','i','n','d','i','n','g',' ','C','L','S','I','D','\0' };
4297 if (SUCCEEDED(IBindCtx_GetObjectParam(pbc, (LPOLESTR)szSkipBinding, &lpUnk)))
4301 if (SUCCEEDED(IUnknown_GetClassID(lpUnk, &clsid)) &&
4302 IsEqualGUID(pclsid, &clsid))
4305 IUnknown_Release(lpUnk);
4311 /***********************************************************************
4312 * SHGetShellKey (SHLWAPI.@)
4314 DWORD WINAPI SHGetShellKey(DWORD a, DWORD b, DWORD c)
4316 FIXME("(%x, %x, %x): stub\n", a, b, c);
4320 /***********************************************************************
4321 * SHQueueUserWorkItem (SHLWAPI.@)
4323 BOOL WINAPI SHQueueUserWorkItem(LPTHREAD_START_ROUTINE pfnCallback,
4324 LPVOID pContext, LONG lPriority, DWORD_PTR dwTag,
4325 DWORD_PTR *pdwId, LPCSTR pszModule, DWORD dwFlags)
4327 TRACE("(%p, %p, %d, %lx, %p, %s, %08x)\n", pfnCallback, pContext,
4328 lPriority, dwTag, pdwId, debugstr_a(pszModule), dwFlags);
4330 if(lPriority || dwTag || pdwId || pszModule || dwFlags)
4331 FIXME("Unsupported arguments\n");
4333 return QueueUserWorkItem(pfnCallback, pContext, 0);
4336 /***********************************************************************
4337 * IUnknown_OnFocusChangeIS (SHLWAPI.@)
4339 HRESULT WINAPI IUnknown_OnFocusChangeIS(LPUNKNOWN lpUnknown, LPUNKNOWN pFocusObject, BOOL bFocus)
4341 IInputObjectSite *pIOS = NULL;
4342 HRESULT hRet = E_INVALIDARG;
4344 TRACE("(%p, %p, %s)\n", lpUnknown, pFocusObject, bFocus ? "TRUE" : "FALSE");
4348 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInputObjectSite,
4350 if (SUCCEEDED(hRet) && pIOS)
4352 hRet = IInputObjectSite_OnFocusChangeIS(pIOS, pFocusObject, bFocus);
4353 IInputObjectSite_Release(pIOS);
4359 /***********************************************************************
4360 * SHGetValueW (SHLWAPI.@)
4362 HRESULT WINAPI SKGetValueW(DWORD a, LPWSTR b, LPWSTR c, DWORD d, DWORD e, DWORD f)
4364 FIXME("(%x, %s, %s, %x, %x, %x): stub\n", a, debugstr_w(b), debugstr_w(c), d, e, f);
4368 typedef HRESULT (WINAPI *DllGetVersion_func)(DLLVERSIONINFO *);
4370 /***********************************************************************
4371 * GetUIVersion (SHLWAPI.452)
4373 DWORD WINAPI GetUIVersion(void)
4375 static DWORD version;
4379 DllGetVersion_func pDllGetVersion;
4380 HMODULE dll = LoadLibraryA("shell32.dll");
4383 pDllGetVersion = (DllGetVersion_func)GetProcAddress(dll, "DllGetVersion");
4387 dvi.cbSize = sizeof(DLLVERSIONINFO);
4388 if (pDllGetVersion(&dvi) == S_OK) version = dvi.dwMajorVersion;
4391 if (!version) version = 3; /* old shell dlls don't have DllGetVersion */
4396 /***********************************************************************
4397 * ShellMessageBoxWrapW [SHLWAPI.388]
4399 * loads a string resource for a module, displays the string in a
4400 * message box and writes it into the logfile
4403 * mod [I] the module containing the string resource
4404 * unknown1 [I] FIXME
4405 * uId [I] the id of the string resource
4406 * title [I] the title of the message box
4407 * unknown2 [I] FIXME
4408 * filename [I] name of the logfile
4413 BOOL WINAPI ShellMessageBoxWrapW(HMODULE mod, DWORD unknown1, UINT uId,
4414 LPCWSTR title, DWORD unknown2, LPCWSTR filename)
4416 FIXME("%p %x %d %s %x %s\n",
4417 mod, unknown1, uId, debugstr_w(title), unknown2, debugstr_w(filename));
4421 HRESULT WINAPI IUnknown_QueryServiceExec(IUnknown *unk, REFIID service, REFIID clsid,
4422 DWORD x1, DWORD x2, DWORD x3, void **ppvOut)
4424 FIXME("%p %s %s %08x %08x %08x %p\n", unk,
4425 debugstr_guid(service), debugstr_guid(clsid), x1, x2, x3, ppvOut);
4429 HRESULT WINAPI IUnknown_ProfferService(IUnknown *unk, void *x0, void *x1, void *x2)
4431 FIXME("%p %p %p %p\n", unk, x0, x1, x2);
4435 /***********************************************************************
4436 * ZoneComputePaneSize [SHLWAPI.382]
4438 UINT WINAPI ZoneComputePaneSize(HWND hwnd)
4444 typedef void (WINAPI *fnSHChangeNotify)(LONG, UINT, LPCVOID, LPCVOID);
4446 void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
4448 static fnSHChangeNotify fn;
4453 hshell32 = LoadLibraryA("shell32");
4455 fn = (fnSHChangeNotify) GetProcAddress(hshell32, "SHChangeNotify");
4457 fn(wEventId, uFlags, dwItem1, dwItem2);
4460 typedef struct SHELL_USER_SID { /* according to MSDN this should be in shlobj.h... */
4461 SID_IDENTIFIER_AUTHORITY sidAuthority;
4462 DWORD dwUserGroupID;
4464 } SHELL_USER_SID, *PSHELL_USER_SID;
4466 typedef struct SHELL_USER_PERMISSION { /* ...and this should be in shlwapi.h */
4467 SHELL_USER_SID susID;
4471 DWORD dwInheritMask;
4472 DWORD dwInheritAccessMask;
4473 } SHELL_USER_PERMISSION, *PSHELL_USER_PERMISSION;
4475 /***********************************************************************
4476 * GetShellSecurityDescriptor [SHLWAPI.475]
4478 * prepares SECURITY_DESCRIPTOR from a set of ACEs
4481 * apUserPerm [I] array of pointers to SHELL_USER_PERMISSION structures,
4482 * each of which describes permissions to apply
4483 * cUserPerm [I] number of entries in apUserPerm array
4486 * success: pointer to SECURITY_DESCRIPTOR
4490 * Call should free returned descriptor with LocalFree
4492 SECURITY_DESCRIPTOR * WINAPI GetShellSecurityDescriptor(PSHELL_USER_PERMISSION *apUserPerm, int cUserPerm)
4495 PSID cur_user = NULL;
4499 PSECURITY_DESCRIPTOR psd = NULL;
4501 TRACE("%p %d\n", apUserPerm, cUserPerm);
4503 if (apUserPerm == NULL || cUserPerm <= 0)
4506 sidlist = HeapAlloc(GetProcessHeap(), 0, cUserPerm * sizeof(PSID));
4510 acl_size = sizeof(ACL);
4512 for(sid_count = 0; sid_count < cUserPerm; sid_count++)
4514 static SHELL_USER_SID null_sid = {{SECURITY_NULL_SID_AUTHORITY}, 0, 0};
4515 PSHELL_USER_PERMISSION perm = apUserPerm[sid_count];
4516 PSHELL_USER_SID sid = &perm->susID;
4520 if (!memcmp((void*)sid, (void*)&null_sid, sizeof(SHELL_USER_SID)))
4521 { /* current user's SID */
4525 DWORD bufsize = sizeof(tuUser);
4527 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &Token);
4530 ret = GetTokenInformation(Token, TokenUser, (void*)tuUser, bufsize, &bufsize );
4532 cur_user = ((PTOKEN_USER)&tuUser)->User.Sid;
4537 } else if (sid->dwUserID==0) /* one sub-authority */
4538 ret = AllocateAndInitializeSid(&sid->sidAuthority, 1, sid->dwUserGroupID, 0,
4539 0, 0, 0, 0, 0, 0, &pSid);
4541 ret = AllocateAndInitializeSid(&sid->sidAuthority, 2, sid->dwUserGroupID, sid->dwUserID,
4542 0, 0, 0, 0, 0, 0, &pSid);
4546 sidlist[sid_count] = pSid;
4547 /* increment acl_size (1 ACE for non-inheritable and 2 ACEs for inheritable records */
4548 acl_size += (sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD) + GetLengthSid(pSid)) * (perm->fInherit ? 2 : 1);
4551 psd = LocalAlloc(0, sizeof(SECURITY_DESCRIPTOR) + acl_size);
4555 PACL pAcl = (PACL)(((BYTE*)psd)+sizeof(SECURITY_DESCRIPTOR));
4557 if (!InitializeSecurityDescriptor(psd, SECURITY_DESCRIPTOR_REVISION))
4560 if (!InitializeAcl(pAcl, acl_size, ACL_REVISION))
4563 for(i = 0; i < sid_count; i++)
4565 PSHELL_USER_PERMISSION sup = apUserPerm[i];
4566 PSID sid = sidlist[i];
4568 switch(sup->dwAccessType)
4570 case ACCESS_ALLOWED_ACE_TYPE:
4571 if (!AddAccessAllowedAce(pAcl, ACL_REVISION, sup->dwAccessMask, sid))
4573 if (sup->fInherit && !AddAccessAllowedAceEx(pAcl, ACL_REVISION,
4574 (BYTE)sup->dwInheritMask, sup->dwInheritAccessMask, sid))
4577 case ACCESS_DENIED_ACE_TYPE:
4578 if (!AddAccessDeniedAce(pAcl, ACL_REVISION, sup->dwAccessMask, sid))
4580 if (sup->fInherit && !AddAccessDeniedAceEx(pAcl, ACL_REVISION,
4581 (BYTE)sup->dwInheritMask, sup->dwInheritAccessMask, sid))
4589 if (!SetSecurityDescriptorDacl(psd, TRUE, pAcl, FALSE))
4598 for(i = 0; i < sid_count; i++)
4600 if (!cur_user || sidlist[i] != cur_user)
4601 FreeSid(sidlist[i]);
4603 HeapFree(GetProcessHeap(), 0, sidlist);