Fixed header dependencies to be fully compatible with the Windows
[wine/multimedia.git] / dlls / shlwapi / ordinal.c
blob7b7ac6eb79172517b55e2bca82241fe501ddeed5
1 /*
2 * SHLWAPI ordinal functions
4 * Copyright 1997 Marcus Meissner
5 * 1998 Jürgen Schmied
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #define COM_NO_WINDOWS_H
24 #include "config.h"
25 #include "wine/port.h"
27 #include <stdarg.h>
28 #include <stdio.h>
29 #include <string.h>
31 #define NONAMELESSUNION
32 #define NONAMELESSSTRUCT
33 #include "windef.h"
34 #include "winbase.h"
35 #include "winuser.h"
36 #include "winnls.h"
37 #include "ddeml.h"
38 #include "docobj.h"
39 #include "exdisp.h"
40 #include "shlguid.h"
41 #include "wingdi.h"
42 #include "shlobj.h"
43 #include "olectl.h"
44 #include "shellapi.h"
45 #include "commdlg.h"
46 #include "wine/unicode.h"
47 #include "servprov.h"
48 #include "winreg.h"
49 #include "winuser.h"
50 #include "wine/debug.h"
51 #include "shlwapi.h"
54 WINE_DEFAULT_DEBUG_CHANNEL(shell);
56 /* Get a function pointer from a DLL handle */
57 #define GET_FUNC(func, module, name, fail) \
58 do { \
59 if (!func) { \
60 if (!SHLWAPI_h##module && !(SHLWAPI_h##module = LoadLibraryA(#module ".dll"))) return fail; \
61 func = (fn##func)GetProcAddress(SHLWAPI_h##module, name); \
62 if (!func) return fail; \
63 } \
64 } while (0)
66 /* DLL handles for late bound calls */
67 extern HINSTANCE shlwapi_hInstance;
68 extern HMODULE SHLWAPI_hshell32;
69 extern HMODULE SHLWAPI_hwinmm;
70 extern HMODULE SHLWAPI_hcomdlg32;
71 extern HMODULE SHLWAPI_hcomctl32;
72 extern HMODULE SHLWAPI_hmpr;
73 extern HMODULE SHLWAPI_hmlang;
74 extern HMODULE SHLWAPI_hurlmon;
75 extern HMODULE SHLWAPI_hversion;
77 extern DWORD SHLWAPI_ThreadRef_index;
79 typedef HANDLE HSHARED; /* Shared memory */
81 /* following is GUID for IObjectWithSite::SetSite -- see _174 */
82 static DWORD id1[4] = {0xfc4801a3, 0x11cf2ba9, 0xaa0029a2, 0x52733d00};
83 /* following is GUID for IPersistMoniker::GetClassID -- see _174 */
84 static DWORD id2[4] = {0x79eac9ee, 0x11cebaf9, 0xaa00828c, 0x0ba94b00};
86 /* Function pointers for GET_FUNC macro; these need to be global because of gcc bug */
87 typedef LPITEMIDLIST (WINAPI *fnpSHBrowseForFolderW)(LPBROWSEINFOW);
88 static fnpSHBrowseForFolderW pSHBrowseForFolderW;
89 typedef HRESULT (WINAPI *fnpConvertINetUnicodeToMultiByte)(LPDWORD,DWORD,LPCWSTR,LPINT,LPSTR,LPINT);
90 static fnpConvertINetUnicodeToMultiByte pConvertINetUnicodeToMultiByte;
91 typedef BOOL (WINAPI *fnpPlaySoundW)(LPCWSTR, HMODULE, DWORD);
92 static fnpPlaySoundW pPlaySoundW;
93 typedef DWORD (WINAPI *fnpSHGetFileInfoW)(LPCWSTR,DWORD,SHFILEINFOW*,UINT,UINT);
94 static fnpSHGetFileInfoW pSHGetFileInfoW;
95 typedef UINT (WINAPI *fnpDragQueryFileW)(HDROP, UINT, LPWSTR, UINT);
96 static fnpDragQueryFileW pDragQueryFileW;
97 typedef BOOL (WINAPI *fnpSHGetPathFromIDListW)(LPCITEMIDLIST, LPWSTR);
98 static fnpSHGetPathFromIDListW pSHGetPathFromIDListW;
99 typedef BOOL (WINAPI *fnpShellExecuteExW)(LPSHELLEXECUTEINFOW);
100 static fnpShellExecuteExW pShellExecuteExW;
101 typedef HICON (WINAPI *fnpSHFileOperationW)(LPSHFILEOPSTRUCTW);
102 static fnpSHFileOperationW pSHFileOperationW;
103 typedef UINT (WINAPI *fnpExtractIconExW)(LPCWSTR, INT,HICON *,HICON *, UINT);
104 static fnpExtractIconExW pExtractIconExW;
105 typedef BOOL (WINAPI *fnpSHGetNewLinkInfoW)(LPCWSTR, LPCWSTR, LPCWSTR, BOOL*, UINT);
106 static fnpSHGetNewLinkInfoW pSHGetNewLinkInfoW;
107 typedef HRESULT (WINAPI *fnpSHDefExtractIconW)(LPCWSTR, int, UINT, HICON*, HICON*, UINT);
108 static fnpSHDefExtractIconW pSHDefExtractIconW;
109 typedef HICON (WINAPI *fnpExtractIconW)(HINSTANCE, LPCWSTR, UINT);
110 static fnpExtractIconW pExtractIconW;
111 typedef BOOL (WINAPI *fnpGetSaveFileNameW)(LPOPENFILENAMEW);
112 static fnpGetSaveFileNameW pGetSaveFileNameW;
113 typedef DWORD (WINAPI *fnpWNetRestoreConnectionW)(HWND, LPWSTR);
114 static fnpWNetRestoreConnectionW pWNetRestoreConnectionW;
115 typedef DWORD (WINAPI *fnpWNetGetLastErrorW)(LPDWORD, LPWSTR, DWORD, LPWSTR, DWORD);
116 static fnpWNetGetLastErrorW pWNetGetLastErrorW;
117 typedef BOOL (WINAPI *fnpPageSetupDlgW)(LPPAGESETUPDLGW);
118 static fnpPageSetupDlgW pPageSetupDlgW;
119 typedef BOOL (WINAPI *fnpPrintDlgW)(LPPRINTDLGW);
120 static fnpPrintDlgW pPrintDlgW;
121 typedef BOOL (WINAPI *fnpGetOpenFileNameW)(LPOPENFILENAMEW);
122 static fnpGetOpenFileNameW pGetOpenFileNameW;
123 typedef DWORD (WINAPI *fnpGetFileVersionInfoSizeW)(LPCWSTR,LPDWORD);
124 static fnpGetFileVersionInfoSizeW pGetFileVersionInfoSizeW;
125 typedef BOOL (WINAPI *fnpGetFileVersionInfoW)(LPCWSTR,DWORD,DWORD,LPVOID);
126 static fnpGetFileVersionInfoW pGetFileVersionInfoW;
127 typedef WORD (WINAPI *fnpVerQueryValueW)(LPVOID,LPCWSTR,LPVOID*,UINT*);
128 static fnpVerQueryValueW pVerQueryValueW;
129 typedef BOOL (WINAPI *fnpCOMCTL32_417)(HDC,INT,INT,UINT,const RECT*,LPCWSTR,UINT,const INT*);
130 static fnpCOMCTL32_417 pCOMCTL32_417;
131 typedef HRESULT (WINAPI *fnpDllGetVersion)(DLLVERSIONINFO*);
132 static fnpDllGetVersion pDllGetVersion;
133 typedef HRESULT (WINAPI *fnpCreateFormatEnumerator)(UINT,FORMATETC*,IEnumFORMATETC**);
134 static fnpCreateFormatEnumerator pCreateFormatEnumerator;
135 typedef HRESULT (WINAPI *fnpRegisterFormatEnumerator)(LPBC,IEnumFORMATETC*,DWORD);
136 static fnpRegisterFormatEnumerator pRegisterFormatEnumerator;
138 HRESULT WINAPI SHLWAPI_176(IUnknown*,REFGUID,REFIID,LPVOID*);
139 HRESULT WINAPI SHLWAPI_363(HWND,IShellFolder*,LPCITEMIDLIST,BOOL);
140 HRESULT WINAPI SHLWAPI_436(LPCWSTR,CLSID*);
141 BOOL WINAPI SHLWAPI_161(LPWSTR,DWORD);
144 NOTES: Most functions exported by ordinal seem to be superflous.
145 The reason for these functions to be there is to provide a wrapper
146 for unicode functions to provide these functions on systems without
147 unicode functions eg. win95/win98. Since we have such functions we just
148 call these. If running Wine with native DLL's, some late bound calls may
149 fail. However, its better to implement the functions in the forward DLL
150 and recommend the builtin rather than reimplementing the calls here!
153 /*************************************************************************
154 * SHLWAPI_DupSharedHandle
156 * Internal implemetation of SHLWAPI_11.
158 static
159 HSHARED WINAPI SHLWAPI_DupSharedHandle(HSHARED hShared, DWORD dwDstProcId,
160 DWORD dwSrcProcId, DWORD dwAccess,
161 DWORD dwOptions)
163 HANDLE hDst, hSrc;
164 DWORD dwMyProcId = GetCurrentProcessId();
165 HSHARED hRet = (HSHARED)NULL;
167 TRACE("(%p,%ld,%ld,%08lx,%08lx)\n", (PVOID)hShared, dwDstProcId, dwSrcProcId,
168 dwAccess, dwOptions);
170 /* Get dest process handle */
171 if (dwDstProcId == dwMyProcId)
172 hDst = GetCurrentProcess();
173 else
174 hDst = OpenProcess(PROCESS_DUP_HANDLE, 0, dwDstProcId);
176 if (hDst)
178 /* Get src process handle */
179 if (dwSrcProcId == dwMyProcId)
180 hSrc = GetCurrentProcess();
181 else
182 hSrc = OpenProcess(PROCESS_DUP_HANDLE, 0, dwSrcProcId);
184 if (hSrc)
186 /* Make handle available to dest process */
187 if (!DuplicateHandle(hDst, (HANDLE)hShared, hSrc, &hRet,
188 dwAccess, 0, dwOptions | DUPLICATE_SAME_ACCESS))
189 hRet = (HSHARED)NULL;
191 if (dwSrcProcId != dwMyProcId)
192 CloseHandle(hSrc);
195 if (dwDstProcId != dwMyProcId)
196 CloseHandle(hDst);
199 TRACE("Returning handle %p\n", (PVOID)hRet);
200 return hRet;
203 /*************************************************************************
204 * @ [SHLWAPI.7]
206 * Create a block of sharable memory and initialise it with data.
208 * PARAMS
209 * dwProcId [I] ID of process owning data
210 * lpvData [I] Pointer to data to write
211 * dwSize [I] Size of data
213 * RETURNS
214 * Success: A shared memory handle
215 * Failure: NULL
217 * NOTES
218 * Ordinals 7-11 provide a set of calls to create shared memory between a
219 * group of processes. The shared memory is treated opaquely in that its size
220 * is not exposed to clients who map it. This is accomplished by storing
221 * the size of the map as the first DWORD of mapped data, and then offsetting
222 * the view pointer returned by this size.
224 * SHLWAPI_7()/SHLWAPI_10() - Create/Destroy the shared memory handle
225 * SHLWAPI_8()/SHLWAPI_9() - Get/Release a pointer to the shared data
226 * SHLWAPI_11() - Helper function; Duplicate cross-process handles
228 HSHARED WINAPI SHLWAPI_7 (DWORD dwProcId, DWORD dwSize, LPCVOID lpvData)
230 HANDLE hMap;
231 LPVOID pMapped;
232 HSHARED hRet = (HSHARED)NULL;
234 TRACE("(%ld,%p,%ld)\n", dwProcId, lpvData, dwSize);
236 /* Create file mapping of the correct length */
237 hMap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, FILE_MAP_READ, 0,
238 dwSize + sizeof(dwSize), NULL);
239 if (!hMap)
240 return hRet;
242 /* Get a view in our process address space */
243 pMapped = MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
245 if (pMapped)
247 /* Write size of data, followed by the data, to the view */
248 *((DWORD*)pMapped) = dwSize;
249 if (dwSize)
250 memcpy((char *) pMapped + sizeof(dwSize), lpvData, dwSize);
252 /* Release view. All further views mapped will be opaque */
253 UnmapViewOfFile(pMapped);
254 hRet = SHLWAPI_DupSharedHandle((HSHARED)hMap, dwProcId,
255 GetCurrentProcessId(), FILE_MAP_ALL_ACCESS,
256 DUPLICATE_SAME_ACCESS);
259 CloseHandle(hMap);
260 return hRet;
263 /*************************************************************************
264 * @ [SHLWAPI.8]
266 * Get a pointer to a block of shared memory from a shared memory handle.
268 * PARAMS
269 * hShared [I] Shared memory handle
270 * dwProcId [I] ID of process owning hShared
272 * RETURNS
273 * Success: A pointer to the shared memory
274 * Failure: NULL
276 * NOTES
277 * See SHLWAPI_7.
279 PVOID WINAPI SHLWAPI_8 (HSHARED hShared, DWORD dwProcId)
281 HSHARED hDup;
282 LPVOID pMapped;
284 TRACE("(%p %ld)\n", (PVOID)hShared, dwProcId);
286 /* Get handle to shared memory for current process */
287 hDup = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
288 FILE_MAP_ALL_ACCESS, 0);
289 /* Get View */
290 pMapped = MapViewOfFile((HANDLE)hDup, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
291 CloseHandle(hDup);
293 if (pMapped)
294 return (char *) pMapped + sizeof(DWORD); /* Hide size */
295 return NULL;
298 /*************************************************************************
299 * @ [SHLWAPI.9]
301 * Release a pointer to a block of shared memory.
303 * PARAMS
304 * lpView [I] Shared memory pointer
306 * RETURNS
307 * Success: TRUE
308 * Failure: FALSE
310 * NOTES
311 * See SHLWAPI_7.
313 BOOL WINAPI SHLWAPI_9 (LPVOID lpView)
315 TRACE("(%p)\n", lpView);
316 return UnmapViewOfFile((char *) lpView - sizeof(DWORD)); /* Include size */
319 /*************************************************************************
320 * @ [SHLWAPI.10]
322 * Destroy a block of sharable memory.
324 * PARAMS
325 * hShared [I] Shared memory handle
326 * dwProcId [I] ID of process owning hShared
328 * RETURNS
329 * Success: TRUE
330 * Failure: FALSE
332 * NOTES
333 * See SHLWAPI_7.
335 BOOL WINAPI SHLWAPI_10 (HSHARED hShared, DWORD dwProcId)
337 HSHARED hClose;
339 TRACE("(%p %ld)\n", (PVOID)hShared, dwProcId);
341 /* Get a copy of the handle for our process, closing the source handle */
342 hClose = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
343 FILE_MAP_ALL_ACCESS,DUPLICATE_CLOSE_SOURCE);
344 /* Close local copy */
345 return CloseHandle((HANDLE)hClose);
348 /*************************************************************************
349 * @ [SHLWAPI.11]
351 * Copy a sharable memory handle from one process to another.
353 * PARAMS
354 * hShared [I] Shared memory handle to duplicate
355 * dwDstProcId [I] ID of the process wanting the duplicated handle
356 * dwSrcProcId [I] ID of the process owning hShared
357 * dwAccess [I] Desired DuplicateHandle() access
358 * dwOptions [I] Desired DuplicateHandle() options
360 * RETURNS
361 * Success: A handle suitable for use by the dwDstProcId process.
362 * Failure: A NULL handle.
364 * NOTES
365 * See SHLWAPI_7.
367 HSHARED WINAPI SHLWAPI_11(HSHARED hShared, DWORD dwDstProcId, DWORD dwSrcProcId,
368 DWORD dwAccess, DWORD dwOptions)
370 HSHARED hRet;
372 hRet = SHLWAPI_DupSharedHandle(hShared, dwDstProcId, dwSrcProcId,
373 dwAccess, dwOptions);
374 return hRet;
377 /*************************************************************************
378 * @ [SHLWAPI.13]
380 * Create and register a clipboard enumerator for a web browser.
382 * PARAMS
383 * lpBC [I] Binding context
384 * lpUnknown [I] An object exposing the IWebBrowserApp interface
386 * RETURNS
387 * Success: S_OK.
388 * Failure: An HRESULT error code.
390 * NOTES
391 * The enumerator is stored as a property of the web browser. If it does not
392 * yet exist, it is created and set before being registered.
394 HRESULT WINAPI SHLWAPI_13(LPBC lpBC, IUnknown *lpUnknown)
396 static const WCHAR szProperty[] = { '{','D','0','F','C','A','4','2','0',
397 '-','D','3','F','5','-','1','1','C','F', '-','B','2','1','1','-','0',
398 '0','A','A','0','0','4','A','E','8','3','7','}','\0' };
399 IEnumFORMATETC* pIEnumFormatEtc = NULL;
400 VARIANTARG var;
401 HRESULT hRet;
402 IWebBrowserApp* pBrowser = NULL;
404 /* Get An IWebBrowserApp interface from lpUnknown */
405 hRet = SHLWAPI_176(lpUnknown, &IID_IWebBrowserApp, &IID_IWebBrowserApp, (PVOID)&pBrowser);
406 if (FAILED(hRet) || !pBrowser)
407 return E_NOINTERFACE;
409 V_VT(&var) = VT_EMPTY;
411 /* The property we get is the browsers clipboard enumerator */
412 hRet = IWebBrowserApp_GetProperty(pBrowser, (BSTR)szProperty, &var);
413 if (FAILED(hRet))
414 return hRet;
416 if (V_VT(&var) == VT_EMPTY)
418 /* Iterate through accepted documents and RegisterClipBoardFormatA() them */
419 char szKeyBuff[128], szValueBuff[128];
420 DWORD dwKeySize, dwValueSize, dwRet = 0, dwCount = 0, dwNumValues, dwType;
421 FORMATETC* formatList, *format;
422 HKEY hDocs;
424 TRACE("Registering formats and creating IEnumFORMATETC instance\n");
426 if (!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\Current"
427 "Version\\Internet Settings\\Accepted Documents", &hDocs))
428 return E_FAIL;
430 /* Get count of values in key */
431 while (!dwRet)
433 dwKeySize = sizeof(szKeyBuff);
434 dwRet = RegEnumValueA(hDocs,dwCount,szKeyBuff,&dwKeySize,0,&dwType,0,0);
435 dwCount++;
438 dwNumValues = dwCount;
440 /* Note: dwCount = number of items + 1; The extra item is the end node */
441 format = formatList = HeapAlloc(GetProcessHeap(), 0, dwCount * sizeof(FORMATETC));
442 if (!formatList)
443 return E_OUTOFMEMORY;
445 if (dwNumValues > 1)
447 dwRet = 0;
448 dwCount = 0;
450 dwNumValues--;
452 /* Register clipboard formats for the values and populate format list */
453 while(!dwRet && dwCount < dwNumValues)
455 dwKeySize = sizeof(szKeyBuff);
456 dwValueSize = sizeof(szValueBuff);
457 dwRet = RegEnumValueA(hDocs, dwCount, szKeyBuff, &dwKeySize, 0, &dwType,
458 (PBYTE)szValueBuff, &dwValueSize);
459 if (!dwRet)
460 return E_FAIL;
462 format->cfFormat = RegisterClipboardFormatA(szValueBuff);
463 format->ptd = NULL;
464 format->dwAspect = 1;
465 format->lindex = 4;
466 format->tymed = -1;
468 format++;
469 dwCount++;
473 /* Terminate the (maybe empty) list, last entry has a cfFormat of 0 */
474 format->cfFormat = 0;
475 format->ptd = NULL;
476 format->dwAspect = 1;
477 format->lindex = 4;
478 format->tymed = -1;
480 /* Create a clipboard enumerator */
481 GET_FUNC(pCreateFormatEnumerator, urlmon, "CreateFormatEnumerator", E_FAIL);
482 hRet = pCreateFormatEnumerator(dwNumValues, formatList, &pIEnumFormatEtc);
484 if (FAILED(hRet) || !pIEnumFormatEtc)
485 return hRet;
487 /* Set our enumerator as the browsers property */
488 V_VT(&var) = VT_UNKNOWN;
489 V_UNKNOWN(&var) = (IUnknown*)pIEnumFormatEtc;
491 hRet = IWebBrowserApp_PutProperty(pBrowser, (BSTR)szProperty, var);
492 if (FAILED(hRet))
494 IEnumFORMATETC_Release(pIEnumFormatEtc);
495 goto SHLWAPI_13_Exit;
499 if (V_VT(&var) == VT_UNKNOWN)
501 /* Our variant is holding the clipboard enumerator */
502 IUnknown* pIUnknown = V_UNKNOWN(&var);
503 IEnumFORMATETC* pClone = NULL;
505 TRACE("Retrieved IEnumFORMATETC property\n");
507 /* Get an IEnumFormatEtc interface from the variants value */
508 pIEnumFormatEtc = NULL;
509 hRet = IUnknown_QueryInterface(pIUnknown, &IID_IEnumFORMATETC,
510 (PVOID)&pIEnumFormatEtc);
511 if (!hRet && pIEnumFormatEtc)
513 /* Clone and register the enumerator */
514 hRet = IEnumFORMATETC_Clone(pIEnumFormatEtc, &pClone);
515 if (!hRet && pClone)
517 GET_FUNC(pRegisterFormatEnumerator, urlmon, "RegisterFormatEnumerator", E_FAIL);
518 pRegisterFormatEnumerator(lpBC, pClone, 0);
520 IEnumFORMATETC_Release(pClone);
523 /* Release the IEnumFormatEtc interface */
524 IEnumFORMATETC_Release(pIUnknown);
526 IUnknown_Release(V_UNKNOWN(&var));
529 SHLWAPI_13_Exit:
530 IWebBrowserApp_Release(pBrowser);
531 return hRet;
534 /*************************************************************************
535 * @ [SHLWAPI.14]
537 * Get Explorers "AcceptLanguage" setting.
539 * PARAMS
540 * langbuf [O] Destination for language string
541 * buflen [I] Length of langbuf
543 * RETURNS
544 * Success: S_OK. langbuf is set to the language string found.
545 * Failure: E_FAIL, If any arguments are invalid, error occurred, or Explorer
546 * does not contain the setting.
548 HRESULT WINAPI SHLWAPI_14 (
549 LPSTR langbuf,
550 LPDWORD buflen)
552 CHAR *mystr;
553 DWORD mystrlen, mytype;
554 HKEY mykey;
555 LCID mylcid;
557 mystrlen = (*buflen > 6) ? *buflen : 6;
558 mystr = (CHAR*)HeapAlloc(GetProcessHeap(),
559 HEAP_ZERO_MEMORY, mystrlen);
560 RegOpenKeyA(HKEY_CURRENT_USER,
561 "Software\\Microsoft\\Internet Explorer\\International",
562 &mykey);
563 if (RegQueryValueExA(mykey, "AcceptLanguage",
564 0, &mytype, (PBYTE)mystr, &mystrlen)) {
565 /* Did not find value */
566 mylcid = GetUserDefaultLCID();
567 /* somehow the mylcid translates into "en-us"
568 * this is similar to "LOCALE_SABBREVLANGNAME"
569 * which could be gotten via GetLocaleInfo.
570 * The only problem is LOCALE_SABBREVLANGUAGE" is
571 * a 3 char string (first 2 are country code and third is
572 * letter for "sublanguage", which does not come close to
573 * "en-us"
575 lstrcpyA(mystr, "en-us");
576 mystrlen = lstrlenA(mystr);
578 else {
579 /* handle returned string */
580 FIXME("missing code\n");
582 if (mystrlen > *buflen)
583 lstrcpynA(langbuf, mystr, *buflen);
584 else {
585 lstrcpyA(langbuf, mystr);
586 *buflen = lstrlenA(langbuf);
588 RegCloseKey(mykey);
589 HeapFree(GetProcessHeap(), 0, mystr);
590 TRACE("language is %s\n", debugstr_a(langbuf));
591 return 0;
594 /*************************************************************************
595 * @ [SHLWAPI.15]
597 * Unicode version of SHLWAPI_14.
599 HRESULT WINAPI SHLWAPI_15 (
600 LPWSTR langbuf,
601 LPDWORD buflen)
603 CHAR *mystr;
604 DWORD mystrlen, mytype;
605 HKEY mykey;
606 LCID mylcid;
608 mystrlen = (*buflen > 6) ? *buflen : 6;
609 mystr = (CHAR*)HeapAlloc(GetProcessHeap(),
610 HEAP_ZERO_MEMORY, mystrlen);
611 RegOpenKeyA(HKEY_CURRENT_USER,
612 "Software\\Microsoft\\Internet Explorer\\International",
613 &mykey);
614 if (RegQueryValueExA(mykey, "AcceptLanguage",
615 0, &mytype, (PBYTE)mystr, &mystrlen)) {
616 /* Did not find value */
617 mylcid = GetUserDefaultLCID();
618 /* somehow the mylcid translates into "en-us"
619 * this is similar to "LOCALE_SABBREVLANGNAME"
620 * which could be gotten via GetLocaleInfo.
621 * The only problem is LOCALE_SABBREVLANGUAGE" is
622 * a 3 char string (first 2 are country code and third is
623 * letter for "sublanguage", which does not come close to
624 * "en-us"
626 lstrcpyA(mystr, "en-us");
627 mystrlen = lstrlenA(mystr);
629 else {
630 /* handle returned string */
631 FIXME("missing code\n");
633 RegCloseKey(mykey);
634 *buflen = MultiByteToWideChar(0, 0, mystr, -1, langbuf, (*buflen)-1);
635 HeapFree(GetProcessHeap(), 0, mystr);
636 TRACE("language is %s\n", debugstr_w(langbuf));
637 return 0;
640 /*************************************************************************
641 * @ [SHLWAPI.23]
643 * Convert a GUID to a string.
645 * PARAMS
646 * guid [I] GUID to convert
647 * str [O] Destination for string
648 * cmax [I] Length of output buffer
650 * RETURNS
651 * The length of the string created.
653 INT WINAPI SHLWAPI_23(REFGUID guid, LPSTR lpszDest, INT cchMax)
655 char xguid[40];
656 INT iLen;
658 TRACE("(%s,%p,%d)\n", debugstr_guid(guid), lpszDest, cchMax);
660 sprintf(xguid, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
661 guid->Data1, guid->Data2, guid->Data3,
662 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
663 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
665 iLen = strlen(xguid) + 1;
667 if (iLen > cchMax)
668 return 0;
669 memcpy(lpszDest, xguid, iLen);
670 return iLen;
673 /*************************************************************************
674 * @ [SHLWAPI.24]
676 * Unicode version of SHLWAPI_23.
678 INT WINAPI SHLWAPI_24(REFGUID guid, LPWSTR lpszDest, INT cchMax)
680 char xguid[40];
681 INT iLen = SHLWAPI_23(guid, xguid, cchMax);
683 if (iLen)
684 MultiByteToWideChar(CP_ACP, 0, xguid, -1, lpszDest, cchMax);
685 return iLen;
688 /*************************************************************************
689 * @ [SHLWAPI.25]
691 * Determine if a Unicode character is alphabetic.
693 * PARAMS
694 * wc [I] Character to check.
696 * RETURNS
697 * TRUE, if wc is alphabetic,
698 * FALSE otherwise.
700 BOOL WINAPI SHLWAPI_25(WCHAR wc)
702 return (get_char_typeW(wc) & C1_ALPHA) != 0;
705 /*************************************************************************
706 * @ [SHLWAPI.26]
708 * Determine if a Unicode character is upper-case.
710 * PARAMS
711 * wc [I] Character to check.
713 * RETURNS
714 * TRUE, if wc is upper-case,
715 * FALSE otherwise.
717 BOOL WINAPI SHLWAPI_26(WCHAR wc)
719 return (get_char_typeW(wc) & C1_UPPER) != 0;
722 /*************************************************************************
723 * @ [SHLWAPI.27]
725 * Determine if a Unicode character is lower-case.
727 * PARAMS
728 * wc [I] Character to check.
730 * RETURNS
731 * TRUE, if wc is lower-case,
732 * FALSE otherwise.
734 BOOL WINAPI SHLWAPI_27(WCHAR wc)
736 return (get_char_typeW(wc) & C1_LOWER) != 0;
739 /*************************************************************************
740 * @ [SHLWAPI.28]
742 * Determine if a Unicode character is alphabetic or a digit.
744 * PARAMS
745 * wc [I] Character to check.
747 * RETURNS
748 * TRUE, if wc is alphabetic or a digit,
749 * FALSE otherwise.
751 BOOL WINAPI SHLWAPI_28(WCHAR wc)
753 return (get_char_typeW(wc) & (C1_ALPHA|C1_DIGIT)) != 0;
756 /*************************************************************************
757 * @ [SHLWAPI.29]
759 * Determine if a Unicode character is a space.
761 * PARAMS
762 * wc [I] Character to check.
764 * RETURNS
765 * TRUE, if wc is a space,
766 * FALSE otherwise.
768 BOOL WINAPI SHLWAPI_29(WCHAR wc)
770 return (get_char_typeW(wc) & C1_SPACE) != 0;
773 /*************************************************************************
774 * @ [SHLWAPI.30]
776 * Determine if a Unicode character is a blank.
778 * PARAMS
779 * wc [I] Character to check.
781 * RETURNS
782 * TRUE, if wc is a blank,
783 * FALSE otherwise.
786 BOOL WINAPI SHLWAPI_30(WCHAR wc)
788 return (get_char_typeW(wc) & C1_BLANK) != 0;
791 /*************************************************************************
792 * @ [SHLWAPI.31]
794 * Determine if a Unicode character is punctuation.
796 * PARAMS
797 * wc [I] Character to check.
799 * RETURNS
800 * TRUE, if wc is punctuation,
801 * FALSE otherwise.
803 BOOL WINAPI SHLWAPI_31(WCHAR wc)
805 return (get_char_typeW(wc) & C1_PUNCT) != 0;
808 /*************************************************************************
809 * @ [SHLWAPI.32]
811 * Determine if a Unicode character is a control character.
813 * PARAMS
814 * wc [I] Character to check.
816 * RETURNS
817 * TRUE, if wc is a control character,
818 * FALSE otherwise.
820 BOOL WINAPI SHLWAPI_32(WCHAR wc)
822 return (get_char_typeW(wc) & C1_CNTRL) != 0;
825 /*************************************************************************
826 * @ [SHLWAPI.33]
828 * Determine if a Unicode character is a digit.
830 * PARAMS
831 * wc [I] Character to check.
833 * RETURNS
834 * TRUE, if wc is a digit,
835 * FALSE otherwise.
837 BOOL WINAPI SHLWAPI_33(WCHAR wc)
839 return (get_char_typeW(wc) & C1_DIGIT) != 0;
842 /*************************************************************************
843 * @ [SHLWAPI.34]
845 * Determine if a Unicode character is a hex digit.
847 * PARAMS
848 * wc [I] Character to check.
850 * RETURNS
851 * TRUE, if wc is a hex digit,
852 * FALSE otherwise.
854 BOOL WINAPI SHLWAPI_34(WCHAR wc)
856 return (get_char_typeW(wc) & C1_XDIGIT) != 0;
859 /*************************************************************************
860 * @ [SHLWAPI.35]
863 BOOL WINAPI SHLWAPI_35(LPWSTR lpszStr, DWORD dwLen, LPVOID p3)
865 FIXME("(%s,0x%08lx,%p): stub\n", debugstr_w(lpszStr), dwLen, p3);
866 return TRUE;
869 /*************************************************************************
870 * @ [SHLWAPI.36]
872 * Insert a bitmap menu item at the bottom of a menu.
874 * PARAMS
875 * hMenu [I] Menu to insert into
876 * flags [I] Flags for insertion
877 * id [I] Menu ID of the item
878 * str [I] Menu text for the item
880 * RETURNS
881 * Success: TRUE, the item is inserted into the menu
882 * Failure: FALSE, if any parameter is invalid
884 BOOL WINAPI SHLWAPI_36(HMENU hMenu, UINT flags, UINT id, LPCWSTR str)
886 TRACE("(%p,0x%08x,0x%08x,%s)\n",hMenu, flags, id, debugstr_w(str));
887 return InsertMenuW(hMenu, -1, flags | MF_BITMAP, id, str);
890 /*************************************************************************
891 * @ [SHLWAPI.74]
893 * Get the text from a given dialog item.
895 * PARAMS
896 * hWnd [I] Handle of dialog
897 * nItem [I] Index of item
898 * lpsDest [O] Buffer for receiving window text
899 * nDestLen [I] Length of buffer.
901 * RETURNS
902 * Success: The length of the returned text.
903 * Failure: 0.
905 INT WINAPI SHLWAPI_74(HWND hWnd, INT nItem, LPWSTR lpsDest,INT nDestLen)
907 HWND hItem = GetDlgItem(hWnd, nItem);
909 if (hItem)
910 return GetWindowTextW(hItem, lpsDest, nDestLen);
911 if (nDestLen)
912 *lpsDest = (WCHAR)'\0';
913 return 0;
916 /*************************************************************************
917 * @ [SHLWAPI.138]
919 * Set the text of a given dialog item.
921 * PARAMS
922 * hWnd [I] Handle of dialog
923 * iItem [I] Index of item
924 * lpszText [O] Text to set
926 * RETURNS
927 * Success: TRUE. The text of the dialog is set to lpszText.
928 * Failure: FALSE, Otherwise.
930 BOOL WINAPI SHLWAPI_138(HWND hWnd, INT iItem, LPCWSTR lpszText)
932 HWND hWndItem = GetDlgItem(hWnd, iItem);
933 if (hWndItem)
934 return SetWindowTextW(hWndItem, lpszText);
935 return FALSE;
938 /*************************************************************************
939 * @ [SHLWAPI.151]
941 * Compare two Ascii strings up to a given length.
943 * PARAMS
944 * lpszSrc [I] Source string
945 * lpszCmp [I] String to compare to lpszSrc
946 * len [I] Maximum length
948 * RETURNS
949 * A number greater than, less than or equal to 0 depending on whether
950 * lpszSrc is greater than, less than or equal to lpszCmp.
952 DWORD WINAPI SHLWAPI_151(LPCSTR lpszSrc, LPCSTR lpszCmp, INT len)
954 return strncmp(lpszSrc, lpszCmp, len);
957 /*************************************************************************
958 * @ [SHLWAPI.152]
960 * Unicode version of SHLWAPI_151.
962 DWORD WINAPI SHLWAPI_152(LPCWSTR lpszSrc, LPCWSTR lpszCmp, INT len)
964 return strncmpW(lpszSrc, lpszCmp, len);
967 /*************************************************************************
968 * @ [SHLWAPI.153]
970 * Compare two Ascii strings up to a given length, ignoring case.
972 * PARAMS
973 * lpszSrc [I] Source string
974 * lpszCmp [I] String to compare to lpszSrc
975 * len [I] Maximum length
977 * RETURNS
978 * A number greater than, less than or equal to 0 depending on whether
979 * lpszSrc is greater than, less than or equal to lpszCmp.
981 DWORD WINAPI SHLWAPI_153(LPCSTR lpszSrc, LPCSTR lpszCmp, DWORD len)
983 return strncasecmp(lpszSrc, lpszCmp, len);
986 /*************************************************************************
987 * @ [SHLWAPI.154]
989 * Unicode version of SHLWAPI_153.
991 DWORD WINAPI SHLWAPI_154(LPCWSTR lpszSrc, LPCWSTR lpszCmp, DWORD len)
993 return strncmpiW(lpszSrc, lpszCmp, len);
996 /*************************************************************************
997 * @ [SHLWAPI.155]
999 * Compare two Ascii strings.
1001 * PARAMS
1002 * lpszSrc [I] Source string
1003 * lpszCmp [I] String to compare to lpszSrc
1005 * RETURNS
1006 * A number greater than, less than or equal to 0 depending on whether
1007 * lpszSrc is greater than, less than or equal to lpszCmp.
1009 DWORD WINAPI SHLWAPI_155(LPCSTR lpszSrc, LPCSTR lpszCmp)
1011 return strcmp(lpszSrc, lpszCmp);
1014 /*************************************************************************
1015 * @ [SHLWAPI.156]
1017 * Unicode version of SHLWAPI_155.
1019 DWORD WINAPI SHLWAPI_156(LPCWSTR lpszSrc, LPCWSTR lpszCmp)
1021 return strcmpW(lpszSrc, lpszCmp);
1024 /*************************************************************************
1025 * @ [SHLWAPI.157]
1027 * Compare two Ascii strings, ignoring case.
1029 * PARAMS
1030 * lpszSrc [I] Source string
1031 * lpszCmp [I] String to compare to lpszSrc
1033 * RETURNS
1034 * A number greater than, less than or equal to 0 depending on whether
1035 * lpszSrc is greater than, less than or equal to lpszCmp.
1037 DWORD WINAPI SHLWAPI_157(LPCSTR lpszSrc, LPCSTR lpszCmp)
1039 return strcasecmp(lpszSrc, lpszCmp);
1042 /*************************************************************************
1043 * @ [SHLWAPI.158]
1045 * Unicode version of SHLWAPI_157.
1047 DWORD WINAPI SHLWAPI_158 (LPCWSTR lpszSrc, LPCWSTR lpszCmp)
1049 return strcmpiW(lpszSrc, lpszCmp);
1052 /*************************************************************************
1053 * SHLWAPI_160 [SHLWAPI.160]
1055 * Get an identification string for the OS and explorer.
1057 * PARAMS
1058 * lpszDest [O] Destination for Id string
1059 * dwDestLen [I] Length of lpszDest
1061 * RETURNS
1062 * TRUE, If the string was created successfully
1063 * FALSE, Otherwise
1065 BOOL WINAPI SHLWAPI_160(LPSTR lpszDest, DWORD dwDestLen)
1067 WCHAR buff[2084];
1069 TRACE("(%p,%ld)", lpszDest, dwDestLen);
1071 if (lpszDest && SHLWAPI_161(buff, dwDestLen))
1073 WideCharToMultiByte(CP_ACP, 0, buff, -1, lpszDest, dwDestLen, NULL, NULL);
1074 return TRUE;
1076 return FALSE;
1079 /*************************************************************************
1080 * SHLWAPI_161 [SHLWAPI.161]
1082 * Unicode version of SHLWAPI_160.
1084 BOOL WINAPI SHLWAPI_161(LPWSTR lpszDest, DWORD dwDestLen)
1086 static const WCHAR szIEKey[] = { 'S','O','F','T','W','A','R','E','\\',
1087 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
1088 ' ','E','x','p','l','o','r','e','r','\0' };
1089 static const WCHAR szWinNtKey[] = { 'S','O','F','T','W','A','R','E','\\',
1090 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s',' ',
1091 'N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
1092 static const WCHAR szWinKey[] = { 'S','O','F','T','W','A','R','E','\\',
1093 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
1094 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0' };
1095 static const WCHAR szRegKey[] = { 'S','O','F','T','W','A','R','E','\\',
1096 'M','i','c','r','o','s','o','f','t','\\','I','n','t','e','r','n','e','t',
1097 ' ','E','x','p','l','o','r','e','r','\\',
1098 'R','e','g','i','s','t','r','a','t','i','o','n','\0' };
1099 static const WCHAR szVersion[] = { 'V','e','r','s','i','o','n','\0' };
1100 static const WCHAR szCustomized[] = { 'C','u','s','t','o','m','i','z','e','d',
1101 'V','e','r','s','i','o','n','\0' };
1102 static const WCHAR szOwner[] = { 'R','e','g','i','s','t','e','r','e','d',
1103 'O','w','n','e','r','\0' };
1104 static const WCHAR szOrg[] = { 'R','e','g','i','s','t','e','r','e','d',
1105 'O','r','g','a','n','i','z','a','t','i','o','n','\0' };
1106 static const WCHAR szProduct[] = { 'P','r','o','d','u','c','t','I','d','\0' };
1107 static const WCHAR szUpdate[] = { 'I','E','A','K',
1108 'U','p','d','a','t','e','U','r','l','\0' };
1109 static const WCHAR szHelp[] = { 'I','E','A','K',
1110 'H','e','l','p','S','t','r','i','n','g','\0' };
1111 WCHAR buff[2084];
1112 HKEY hReg;
1113 DWORD dwType, dwLen;
1115 TRACE("(%p,%ld)", lpszDest, dwDestLen);
1117 if (!lpszDest)
1118 return FALSE;
1120 *lpszDest = '\0';
1122 /* Try the NT key first, followed by 95/98 key */
1123 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinNtKey, 0, KEY_READ, &hReg) &&
1124 RegOpenKeyExW(HKEY_LOCAL_MACHINE, szWinKey, 0, KEY_READ, &hReg))
1125 return FALSE;
1127 /* OS Version */
1128 buff[0] = '\0';
1129 dwLen = 30;
1130 if (!SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey, szVersion, &dwType, buff, &dwLen))
1132 DWORD dwStrLen = strlenW(buff);
1133 dwLen = 30 - dwStrLen;
1134 SHGetValueW(HKEY_LOCAL_MACHINE, szIEKey,
1135 szCustomized, &dwType, buff+dwStrLen, &dwLen);
1137 StrCatBuffW(lpszDest, buff, dwDestLen);
1139 /* ~Registered Owner */
1140 buff[0] = '~';
1141 dwLen = 256;
1142 if (SHGetValueW(hReg, szOwner, 0, &dwType, buff+1, &dwLen))
1143 buff[1] = '\0';
1144 StrCatBuffW(lpszDest, buff, dwDestLen);
1146 /* ~Registered Organization */
1147 dwLen = 256;
1148 if (SHGetValueW(hReg, szOrg, 0, &dwType, buff+1, &dwLen))
1149 buff[1] = '\0';
1150 StrCatBuffW(lpszDest, buff, dwDestLen);
1152 /* FIXME: Not sure where this number comes from */
1153 buff[0] = '~';
1154 buff[1] = '0';
1155 buff[2] = '\0';
1156 StrCatBuffW(lpszDest, buff, dwDestLen);
1158 /* ~Product Id */
1159 dwLen = 256;
1160 if (SHGetValueW(HKEY_LOCAL_MACHINE, szRegKey, szProduct, &dwType, buff+1, &dwLen))
1161 buff[1] = '\0';
1162 StrCatBuffW(lpszDest, buff, dwDestLen);
1164 /* ~IE Update Url */
1165 dwLen = 2048;
1166 if(SHGetValueW(HKEY_LOCAL_MACHINE, szWinKey, szUpdate, &dwType, buff+1, &dwLen))
1167 buff[1] = '\0';
1168 StrCatBuffW(lpszDest, buff, dwDestLen);
1170 /* ~IE Help String */
1171 dwLen = 256;
1172 if(SHGetValueW(hReg, szHelp, 0, &dwType, buff+1, &dwLen))
1173 buff[1] = '\0';
1174 StrCatBuffW(lpszDest, buff, dwDestLen);
1176 RegCloseKey(hReg);
1177 return TRUE;
1180 /*************************************************************************
1181 * @ [SHLWAPI.162]
1183 * Remove a hanging lead byte from the end of a string, if present.
1185 * PARAMS
1186 * lpStr [I] String to check for a hanging lead byte
1187 * size [I] Length of lpStr
1189 * RETURNS
1190 * Success: The new length of the string. Any hanging lead bytes are removed.
1191 * Failure: 0, if any parameters are invalid.
1193 DWORD WINAPI SHLWAPI_162(LPSTR lpStr, DWORD size)
1195 if (lpStr && size)
1197 LPSTR lastByte = lpStr + size - 1;
1199 while(lpStr < lastByte)
1200 lpStr += IsDBCSLeadByte(*lpStr) ? 2 : 1;
1202 if(lpStr == lastByte && IsDBCSLeadByte(*lpStr))
1204 *lpStr = '\0';
1205 size--;
1207 return size;
1209 return 0;
1212 /*************************************************************************
1213 * @ [SHLWAPI.163]
1215 * Call IOleCommandTarget_QueryStatus() on an object.
1217 * PARAMS
1218 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1219 * pguidCmdGroup [I] GUID for the command group
1220 * cCmds [I]
1221 * prgCmds [O] Commands
1222 * pCmdText [O] Command text
1224 * RETURNS
1225 * Success: S_OK.
1226 * Failure: E_FAIL, if lpUnknown is NULL.
1227 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1228 * Otherwise, an error code from IOleCommandTarget_QueryStatus().
1230 HRESULT WINAPI SHLWAPI_163(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
1231 ULONG cCmds, OLECMD *prgCmds, OLECMDTEXT* pCmdText)
1233 HRESULT hRet = E_FAIL;
1235 TRACE("(%p,%p,%ld,%p,%p)\n",lpUnknown, pguidCmdGroup, cCmds, prgCmds, pCmdText);
1237 if (lpUnknown)
1239 IOleCommandTarget* lpOle;
1241 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
1242 (void**)&lpOle);
1244 if (SUCCEEDED(hRet) && lpOle)
1246 hRet = IOleCommandTarget_QueryStatus(lpOle, pguidCmdGroup, cCmds,
1247 prgCmds, pCmdText);
1248 IOleCommandTarget_Release(lpOle);
1251 return hRet;
1254 /*************************************************************************
1255 * @ [SHLWAPI.164]
1257 * Call IOleCommandTarget_Exec() on an object.
1259 * PARAMS
1260 * lpUnknown [I] Object supporting the IOleCommandTarget interface
1261 * pguidCmdGroup [I] GUID for the command group
1263 * RETURNS
1264 * Success: S_OK.
1265 * Failure: E_FAIL, if lpUnknown is NULL.
1266 * E_NOINTERFACE, if lpUnknown does not support IOleCommandTarget.
1267 * Otherwise, an error code from IOleCommandTarget_Exec().
1269 HRESULT WINAPI SHLWAPI_164(IUnknown* lpUnknown, REFGUID pguidCmdGroup,
1270 DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
1271 VARIANT* pvaOut)
1273 HRESULT hRet = E_FAIL;
1275 TRACE("(%p,%p,%ld,%ld,%p,%p)\n",lpUnknown, pguidCmdGroup, nCmdID,
1276 nCmdexecopt, pvaIn, pvaOut);
1278 if (lpUnknown)
1280 IOleCommandTarget* lpOle;
1282 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleCommandTarget,
1283 (void**)&lpOle);
1284 if (SUCCEEDED(hRet) && lpOle)
1286 hRet = IOleCommandTarget_Exec(lpOle, pguidCmdGroup, nCmdID,
1287 nCmdexecopt, pvaIn, pvaOut);
1288 IOleCommandTarget_Release(lpOle);
1291 return hRet;
1294 /*************************************************************************
1295 * @ [SHLWAPI.165]
1297 * Retrieve, modify, and re-set a value from a window.
1299 * PARAMS
1300 * hWnd [I] Window to get value from
1301 * offset [I] Offset of value
1302 * wMask [I] Mask for uiFlags
1303 * wFlags [I] Bits to set in window value
1305 * RETURNS
1306 * The new value as it was set, or 0 if any parameter is invalid.
1308 * NOTES
1309 * Any bits set in uiMask are cleared from the value, then any bits set in
1310 * uiFlags are set in the value.
1312 LONG WINAPI SHLWAPI_165(HWND hwnd, INT offset, UINT wMask, UINT wFlags)
1314 LONG ret = GetWindowLongA(hwnd, offset);
1315 LONG newFlags = (wFlags & wMask) | (ret & ~wFlags);
1317 if (newFlags != ret)
1318 ret = SetWindowLongA(hwnd, offset, newFlags);
1319 return ret;
1322 /*************************************************************************
1323 * @ [SHLWAPI.167]
1325 * Change a window's parent.
1327 * PARAMS
1328 * hWnd [I] Window to change parent of
1329 * hWndParent [I] New parent window
1331 * RETURNS
1332 * The old parent of hWnd.
1334 * NOTES
1335 * If hWndParent is NULL (desktop), the window style is changed to WS_POPUP.
1336 * If hWndParent is NOT NULL then we set the WS_CHILD style.
1338 HWND WINAPI SHLWAPI_167(HWND hWnd, HWND hWndParent)
1340 TRACE("%p, %p\n", hWnd, hWndParent);
1342 if(GetParent(hWnd) == hWndParent)
1343 return 0;
1345 if(hWndParent)
1346 SHLWAPI_165(hWnd, GWL_STYLE, WS_CHILD, WS_CHILD);
1347 else
1348 SHLWAPI_165(hWnd, GWL_STYLE, WS_POPUP, WS_POPUP);
1350 return SetParent(hWnd, hWndParent);
1353 /*************************************************************************
1354 * @ [SHLWAPI.168]
1356 * Locate and advise a connection point in an IConnectionPointContainer object.
1358 * PARAMS
1359 * lpUnkSink [I] Sink for the connection point advise call
1360 * riid [I] REFIID of connection point to advise
1361 * bAdviseOnly [I] TRUE = Advise only, FALSE = Unadvise first
1362 * lpUnknown [I] Object supporting the IConnectionPointContainer interface
1363 * lpCookie [O] Pointer to connection point cookie
1364 * lppCP [O] Destination for the IConnectionPoint found
1366 * RETURNS
1367 * Success: S_OK. If lppCP is non-NULL, it is filled with the IConnectionPoint
1368 * that was advised. The caller is responsable for releasing it.
1369 * Failure: E_FAIL, if any arguments are invalid.
1370 * E_NOINTERFACE, if lpUnknown isn't an IConnectionPointContainer,
1371 * Or an HRESULT error code if any call fails.
1373 HRESULT WINAPI SHLWAPI_168(IUnknown* lpUnkSink, REFIID riid, BOOL bAdviseOnly,
1374 IUnknown* lpUnknown, LPDWORD lpCookie,
1375 IConnectionPoint **lppCP)
1377 HRESULT hRet;
1378 IConnectionPointContainer* lpContainer;
1379 IConnectionPoint *lpCP;
1381 if(!lpUnknown || (bAdviseOnly && !lpUnkSink))
1382 return E_FAIL;
1384 if(lppCP)
1385 *lppCP = NULL;
1387 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer,
1388 (void**)&lpContainer);
1389 if (SUCCEEDED(hRet))
1391 hRet = IConnectionPointContainer_FindConnectionPoint(lpContainer, riid, &lpCP);
1393 if (SUCCEEDED(hRet))
1395 if(!bAdviseOnly)
1396 hRet = IConnectionPoint_Unadvise(lpCP, *lpCookie);
1397 hRet = IConnectionPoint_Advise(lpCP, lpUnkSink, lpCookie);
1399 if (FAILED(hRet))
1400 *lpCookie = 0;
1402 if (lppCP && SUCCEEDED(hRet))
1403 *lppCP = lpCP; /* Caller keeps the interface */
1404 else
1405 IConnectionPoint_Release(lpCP); /* Release it */
1408 IUnknown_Release(lpContainer);
1410 return hRet;
1413 /*************************************************************************
1414 * @ [SHLWAPI.169]
1416 * Release an interface.
1418 * PARAMS
1419 * lpUnknown [I] Object to release
1421 * RETURNS
1422 * Nothing.
1424 DWORD WINAPI SHLWAPI_169 (IUnknown ** lpUnknown)
1426 IUnknown *temp;
1428 TRACE("(%p)\n",lpUnknown);
1429 if(!lpUnknown || !*((LPDWORD)lpUnknown)) return 0;
1430 temp = *lpUnknown;
1431 *lpUnknown = NULL;
1432 TRACE("doing Release\n");
1433 return IUnknown_Release(temp);
1436 /*************************************************************************
1437 * @ [SHLWAPI.170]
1439 * Skip '//' if present in a string.
1441 * PARAMS
1442 * lpszSrc [I] String to check for '//'
1444 * RETURNS
1445 * Success: The next character after the '//' or the string if not present
1446 * Failure: NULL, if lpszStr is NULL.
1448 LPCSTR WINAPI SHLWAPI_170(LPCSTR lpszSrc)
1450 if (lpszSrc && lpszSrc[0] == '/' && lpszSrc[1] == '/')
1451 lpszSrc += 2;
1452 return lpszSrc;
1455 /*************************************************************************
1456 * @ [SHLWAPI.171]
1458 * Check if two interfaces come from the same object.
1460 * PARAMS
1461 * lpInt1 [I] Interface to check against lpInt2.
1462 * lpInt2 [I] Interface to check against lpInt1.
1464 * RETURNS
1465 * TRUE, If the interfaces come from the same object.
1466 * FALSE Otherwise.
1468 BOOL WINAPI SHLWAPI_171(IUnknown* lpInt1, IUnknown* lpInt2)
1470 LPVOID lpUnknown1, lpUnknown2;
1472 TRACE("%p %p\n", lpInt1, lpInt2);
1474 if (!lpInt1 || !lpInt2)
1475 return FALSE;
1477 if (lpInt1 == lpInt2)
1478 return TRUE;
1480 if (!SUCCEEDED(IUnknown_QueryInterface(lpInt1, &IID_IUnknown,
1481 (LPVOID *)&lpUnknown1)))
1482 return FALSE;
1484 if (!SUCCEEDED(IUnknown_QueryInterface(lpInt2, &IID_IUnknown,
1485 (LPVOID *)&lpUnknown2)))
1486 return FALSE;
1488 if (lpUnknown1 == lpUnknown2)
1489 return TRUE;
1491 return FALSE;
1494 /*************************************************************************
1495 * @ [SHLWAPI.172]
1497 * Get the window handle of an object.
1499 * PARAMS
1500 * lpUnknown [I] Object to get the window handle of
1501 * lphWnd [O] Destination for window handle
1503 * RETURNS
1504 * Success: S_OK. lphWnd contains the objects window handle.
1505 * Failure: An HRESULT error code.
1507 * NOTES
1508 * lpUnknown is expected to support one of the following interfaces:
1509 * IOleWindow(), IInternetSecurityMgrSite(), or IShellView().
1511 HRESULT WINAPI SHLWAPI_172(IUnknown *lpUnknown, HWND *lphWnd)
1513 /* FIXME: Wine has no header for this object */
1514 static const GUID IID_IInternetSecurityMgrSite = { 0x79eac9ed,
1515 0xbaf9, 0x11ce, { 0x8c, 0x82, 0x00, 0xaa, 0x00, 0x4b, 0xa9, 0x0b }};
1516 IUnknown *lpOle;
1517 HRESULT hRet = E_FAIL;
1519 TRACE("(%p,%p)\n", lpUnknown, lphWnd);
1521 if (!lpUnknown)
1522 return hRet;
1524 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleWindow, (void**)&lpOle);
1526 if (FAILED(hRet))
1528 hRet = IUnknown_QueryInterface(lpUnknown,&IID_IShellView, (void**)&lpOle);
1530 if (FAILED(hRet))
1532 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IInternetSecurityMgrSite,
1533 (void**)&lpOle);
1537 if (SUCCEEDED(hRet))
1539 /* Lazyness here - Since GetWindow() is the first method for the above 3
1540 * interfaces, we use the same call for them all.
1542 hRet = IOleWindow_GetWindow((IOleWindow*)lpOle, lphWnd);
1543 IUnknown_Release(lpOle);
1544 if (lphWnd)
1545 TRACE("Returning HWND=%p\n", *lphWnd);
1548 return hRet;
1551 /*************************************************************************
1552 * @ [SHLWAPI.173]
1554 * Call a method on as as yet unidentified object.
1556 * PARAMS
1557 * pUnk [I] Object supporting the unidentified interface,
1558 * arg [I] Argument for the call on the object.
1560 * RETURNS
1561 * S_OK.
1563 HRESULT WINAPI SHLWAPI_173(IUnknown *pUnk, ULONG arg)
1565 static const GUID guid_173 = {
1566 0x5836fb00, 0x8187, 0x11cf, { 0xa1,0x2b,0x00,0xaa,0x00,0x4a,0xe8,0x37 }
1568 IMalloc *pUnk2;
1570 TRACE("(%p,%ld)\n", pUnk, arg);
1572 /* Note: arg may not be a ULONG and pUnk2 is for sure not an IMalloc -
1573 * We use this interface as its vtable entry is compatible with the
1574 * object in question.
1575 * FIXME: Find out what this object is and where it should be defined.
1577 if (pUnk &&
1578 SUCCEEDED(IUnknown_QueryInterface(pUnk, &guid_173, (void**)&pUnk2)))
1580 IMalloc_Alloc(pUnk2, arg); /* Faked call!! */
1581 IMalloc_Release(pUnk2);
1583 return S_OK;
1586 /*************************************************************************
1587 * @ [SHLWAPI.174]
1589 * Call either IObjectWithSite_SetSite() or IPersistMoniker_GetClassID() on
1590 * an interface.
1592 * RETURNS
1593 * Success: S_OK.
1594 * Failure: E_FAIL, if p1 is NULL.
1595 * E_NOINTERFACE If p1 does not support the IPersist interface,
1596 * Or an HRESULT error code.
1598 DWORD WINAPI SHLWAPI_174(
1599 IUnknown *p1, /* [in] OLE object */
1600 LPVOID *p2) /* [out] ptr for call results */
1602 DWORD ret, aa;
1604 if (!p1) return E_FAIL;
1606 /* see if SetSite interface exists for IObjectWithSite object */
1607 ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id1, (LPVOID *)&p1);
1608 TRACE("first IU_QI ret=%08lx, p1=%p\n", ret, p1);
1609 if (ret) {
1611 /* see if GetClassId interface exists for IPersistMoniker object */
1612 ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id2, (LPVOID *)&aa);
1613 TRACE("second IU_QI ret=%08lx, aa=%08lx\n", ret, aa);
1614 if (ret) return ret;
1616 /* fake a GetClassId call */
1617 ret = IOleWindow_GetWindow((IOleWindow *)aa, (HWND*)p2);
1618 TRACE("second IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1619 *(LPDWORD)p2);
1620 IUnknown_Release((IUnknown *)aa);
1622 else {
1623 /* fake a SetSite call */
1624 ret = IOleWindow_GetWindow((IOleWindow *)p1, (HWND*)p2);
1625 TRACE("first IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1626 *(LPDWORD)p2);
1627 IUnknown_Release((IUnknown *)p1);
1629 return ret;
1632 /*************************************************************************
1633 * @ [SHLWAPI.175]
1635 * Call IPersist_GetClassID() on an object.
1637 * PARAMS
1638 * lpUnknown [I] Object supporting the IPersist interface
1639 * lpClassId [O] Destination for Class Id
1641 * RETURNS
1642 * Success: S_OK. lpClassId contains the Class Id requested.
1643 * Failure: E_FAIL, If lpUnknown is NULL,
1644 * E_NOINTERFACE If lpUnknown does not support IPersist,
1645 * Or an HRESULT error code.
1647 HRESULT WINAPI SHLWAPI_175 (IUnknown *lpUnknown, CLSID* lpClassId)
1649 IPersist* lpPersist;
1650 HRESULT hRet = E_FAIL;
1652 TRACE("(%p,%p)\n", lpUnknown, debugstr_guid(lpClassId));
1654 if (lpUnknown)
1656 hRet = IUnknown_QueryInterface(lpUnknown,&IID_IPersist,(void**)&lpPersist);
1657 if (SUCCEEDED(hRet))
1659 IPersist_GetClassID(lpPersist, lpClassId);
1660 IPersist_Release(lpPersist);
1663 return hRet;
1666 /*************************************************************************
1667 * @ [SHLWAPI.176]
1669 * Retrieve a Service Interface from an object.
1671 * PARAMS
1672 * lpUnknown [I] Object to get an IServiceProvider interface from
1673 * sid [I] Service ID for IServiceProvider_QueryService() call
1674 * riid [I] Function requested for QueryService call
1675 * lppOut [O] Destination for the service interface pointer
1677 * RETURNS
1678 * Success: S_OK. lppOut contains an object providing the requested service
1679 * Failure: An HRESULT error code
1681 * NOTES
1682 * lpUnknown is expected to support the IServiceProvider interface.
1684 HRESULT WINAPI SHLWAPI_176(IUnknown* lpUnknown, REFGUID sid, REFIID riid,
1685 LPVOID *lppOut)
1687 IServiceProvider* pService = NULL;
1688 HRESULT hRet;
1690 if (!lppOut)
1691 return E_FAIL;
1693 *lppOut = NULL;
1695 if (!lpUnknown)
1696 return E_FAIL;
1698 /* Get an IServiceProvider interface from the object */
1699 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IServiceProvider,
1700 (LPVOID*)&pService);
1702 if (!hRet && pService)
1704 TRACE("QueryInterface returned (IServiceProvider*)%p\n", pService);
1706 /* Get a Service interface from the object */
1707 hRet = IServiceProvider_QueryService(pService, sid, riid, lppOut);
1709 TRACE("(IServiceProvider*)%p returned (IUnknown*)%p\n", pService, *lppOut);
1711 /* Release the IServiceProvider interface */
1712 IUnknown_Release(pService);
1714 return hRet;
1717 /*************************************************************************
1718 * @ [SHLWAPI.177]
1720 * Destroy a menu.
1722 * PARAMS
1723 * hInst [I] Instance handle
1724 * szName [I] Menu name
1726 * RETURNS
1727 * Success: TRUE.
1728 * Failure: FALSE.
1730 BOOL WINAPI SHLWAPI_177(HINSTANCE hInst, LPCWSTR szName)
1732 HMENU hMenu, hSubMenu;
1734 if ((hMenu = LoadMenuW(hInst, szName)))
1736 if ((hSubMenu = GetSubMenu(hMenu, 0)))
1737 RemoveMenu(hMenu, 0, MF_BYPOSITION);
1739 DestroyMenu(hMenu); /* FIXME: Should be: SHLWAPI_426(hMenu); */
1740 return TRUE;
1742 return FALSE;
1745 typedef struct _enumWndData
1747 UINT uiMsgId;
1748 WPARAM wParam;
1749 LPARAM lParam;
1750 LRESULT (WINAPI *pfnPost)(HWND,UINT,WPARAM,LPARAM);
1751 } enumWndData;
1753 /* Callback for SHLWAPI_178 */
1754 static BOOL CALLBACK SHLWAPI_EnumChildProc(HWND hWnd, LPARAM lParam)
1756 enumWndData *data = (enumWndData *)lParam;
1758 TRACE("(%p,%p)\n", hWnd, data);
1759 data->pfnPost(hWnd, data->uiMsgId, data->wParam, data->lParam);
1760 return TRUE;
1763 /*************************************************************************
1764 * @ [SHLWAPI.178]
1766 * Send or post a message to every child of a window.
1768 * PARAMS
1769 * hWnd [I] Window whose children will get the messages
1770 * uiMsgId [I] Message Id
1771 * wParam [I] WPARAM of message
1772 * lParam [I] LPARAM of message
1773 * bSend [I] TRUE = Use SendMessageA(), FALSE = Use PostMessageA()
1775 * RETURNS
1776 * Nothing.
1778 * NOTES
1779 * The appropriate ASCII or Unicode function is called for the window.
1781 void WINAPI SHLWAPI_178(HWND hWnd, UINT uiMsgId, WPARAM wParam, LPARAM lParam, BOOL bSend)
1783 enumWndData data;
1785 TRACE("(%p,%u,%d,%ld,%d)\n", hWnd, uiMsgId, wParam, lParam, bSend);
1787 if(hWnd)
1789 data.uiMsgId = uiMsgId;
1790 data.wParam = wParam;
1791 data.lParam = lParam;
1793 if (bSend)
1794 data.pfnPost = IsWindowUnicode(hWnd) ? (void*)SendMessageW : (void*)SendMessageA;
1795 else
1796 data.pfnPost = IsWindowUnicode(hWnd) ? (void*)PostMessageW : (void*)PostMessageA;
1798 EnumChildWindows(hWnd, SHLWAPI_EnumChildProc, (LPARAM)&data);
1802 /*************************************************************************
1803 * @ [SHLWAPI.180]
1805 * Remove all sub-menus from a menu.
1807 * PARAMS
1808 * hMenu [I] Menu to remove sub-menus from
1810 * RETURNS
1811 * Success: 0. All sub-menus under hMenu are removed
1812 * Failure: -1, if any parameter is invalid
1814 DWORD WINAPI SHLWAPI_180(HMENU hMenu)
1816 int iItemCount = GetMenuItemCount(hMenu) - 1;
1817 while (iItemCount >= 0)
1819 HMENU hSubMenu = GetSubMenu(hMenu, iItemCount);
1820 if (hSubMenu)
1821 RemoveMenu(hMenu, iItemCount, MF_BYPOSITION);
1822 iItemCount--;
1824 return iItemCount;
1827 /*************************************************************************
1828 * @ [SHLWAPI.181]
1830 * Enable or disable a menu item.
1832 * PARAMS
1833 * hMenu [I] Menu holding menu item
1834 * uID [I] ID of menu item to enable/disable
1835 * bEnable [I] Whether to enable (TRUE) or disable (FALSE) the item.
1837 * RETURNS
1838 * The return code from EnableMenuItem.
1840 UINT WINAPI SHLWAPI_181(HMENU hMenu, UINT wItemID, BOOL bEnable)
1842 return EnableMenuItem(hMenu, wItemID, bEnable ? MF_ENABLED : MF_GRAYED);
1845 /*************************************************************************
1846 * @ [SHLWAPI.182]
1848 * Check or uncheck a menu item.
1850 * PARAMS
1851 * hMenu [I] Menu holding menu item
1852 * uID [I] ID of menu item to check/uncheck
1853 * bCheck [I] Whether to check (TRUE) or uncheck (FALSE) the item.
1855 * RETURNS
1856 * The return code from CheckMenuItem.
1858 DWORD WINAPI SHLWAPI_182(HMENU hMenu, UINT uID, BOOL bCheck)
1860 return CheckMenuItem(hMenu, uID, bCheck ? MF_CHECKED : MF_UNCHECKED);
1863 /*************************************************************************
1864 * @ [SHLWAPI.183]
1866 * Register a window class if it isn't already.
1868 * PARAMS
1869 * lpWndClass [I] Window class to register
1871 * RETURNS
1872 * The result of the RegisterClassA call.
1874 DWORD WINAPI SHLWAPI_183(WNDCLASSA *wndclass)
1876 WNDCLASSA wca;
1877 if (GetClassInfoA(wndclass->hInstance, wndclass->lpszClassName, &wca))
1878 return TRUE;
1879 return (DWORD)RegisterClassA(wndclass);
1882 /*************************************************************************
1883 * @ [SHLWAPI.187]
1885 * Call IPersistPropertyBag_Load() on an object.
1887 * PARAMS
1888 * lpUnknown [I] Object supporting the IPersistPropertyBag interface
1889 * lpPropBag [O] Destination for loaded IPropertyBag
1891 * RETURNS
1892 * Success: S_OK.
1893 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1895 DWORD WINAPI SHLWAPI_187(IUnknown *lpUnknown, IPropertyBag* lpPropBag)
1897 IPersistPropertyBag* lpPPBag;
1898 HRESULT hRet = E_FAIL;
1900 TRACE("(%p,%p)\n", lpUnknown, lpPropBag);
1902 if (lpUnknown)
1904 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IPersistPropertyBag,
1905 (void**)&lpPPBag);
1906 if (SUCCEEDED(hRet) && lpPPBag)
1908 hRet = IPersistPropertyBag_Load(lpPPBag, lpPropBag, NULL);
1909 IPersistPropertyBag_Release(lpPPBag);
1912 return hRet;
1915 /*************************************************************************
1916 * @ [SHLWAPI.189]
1918 * Call IOleControlSite_GetExtendedControl() on an object.
1920 * PARAMS
1921 * lpUnknown [I] Object supporting the IOleControlSite interface
1922 * lppDisp [O] Destination for resulting IDispatch.
1924 * RETURNS
1925 * Success: S_OK.
1926 * Failure: An HRESULT error code, or E_FAIL if lpUnknown is NULL.
1928 DWORD WINAPI SHLWAPI_189(IUnknown *lpUnknown, IDispatch** lppDisp)
1930 IOleControlSite* lpCSite;
1931 HRESULT hRet = E_FAIL;
1933 TRACE("(%p,%p)\n", lpUnknown, lppDisp);
1934 if (lpUnknown)
1936 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IOleControlSite,
1937 (void**)&lpCSite);
1938 if (SUCCEEDED(hRet) && lpCSite)
1940 hRet = IOleControlSite_GetExtendedControl(lpCSite, lppDisp);
1941 IOleControlSite_Release(lpCSite);
1944 return hRet;
1947 static const WCHAR szDontShowKey[] = { 'S','o','f','t','w','a','r','e','\\',
1948 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
1949 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
1950 'E','x','p','l','o','r','e','r','\\','D','o','n','t','S','h','o','w',
1951 'M','e','T','h','i','s','D','i','a','l','o','g','A','g','a','i','n','\0'
1954 /*************************************************************************
1955 * @ [SHLWAPI.191]
1957 * Pop up a 'Don't show this message again' error dialog box.
1959 * PARAMS
1960 * hWnd [I] Window to own the dialog box
1961 * arg2 [I] Unknown
1962 * arg3 [I] Unknown
1963 * arg4 [I] Unknown
1964 * arg5 [I] Unknown
1965 * lpszValue [I] Registry value holding boolean show/don't show.
1967 * RETURNS
1968 * Nothing.
1970 void WINAPI SHLWAPI_191(HWND hWnd, PVOID arg2, PVOID arg3, PVOID arg4, PVOID arg5, LPCWSTR lpszValue)
1972 FIXME("(%p,%p,%p,%p,%p,%s) - stub!\n", hWnd, arg2, arg3, arg4, arg5, debugstr_w(lpszValue));
1974 if (SHRegGetBoolUSValueW(szDontShowKey, lpszValue, FALSE, TRUE))
1976 /* FIXME: Should use DialogBoxParamW to load a dialog box; its dlgproc
1977 * should accept clicks on 'Don't show' and set the reg value appropriately.
1982 /*************************************************************************
1983 * @ [SHLWAPI.192]
1985 * Get a sub-menu from a menu item.
1987 * PARAMS
1988 * hMenu [I] Menu to get sub-menu from
1989 * uID [I] ID of menu item containing sub-menu
1991 * RETURNS
1992 * The sub-menu of the item, or a NULL handle if any parameters are invalid.
1994 HMENU WINAPI SHLWAPI_192(HMENU hMenu, UINT uID)
1996 MENUITEMINFOA mi;
1998 TRACE("(%p,%uld)\n", hMenu, uID);
2000 mi.cbSize = sizeof(MENUITEMINFOA);
2001 mi.fMask = MIIM_SUBMENU;
2003 if (!GetMenuItemInfoA(hMenu, uID, 0, &mi))
2004 return (HMENU)NULL;
2006 return mi.hSubMenu;
2009 /*************************************************************************
2010 * @ [SHLWAPI.193]
2012 * Get the color depth of the primary display.
2014 * PARAMS
2015 * None.
2017 * RETURNS
2018 * The color depth of the primary display.
2020 DWORD WINAPI SHLWAPI_193 ()
2022 HDC hdc;
2023 DWORD ret;
2025 TRACE("()\n");
2027 hdc = GetDC(0);
2028 ret = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
2029 ReleaseDC(0, hdc);
2030 return ret;
2033 /*************************************************************************
2034 * @ [SHLWAPI.197]
2036 * Blank out a region of text by drawing the background only.
2038 * PARAMS
2039 * hDC [I] Device context to draw in
2040 * pRect [I] Area to draw in
2041 * cRef [I] Color to draw in
2043 * RETURNS
2044 * Nothing.
2046 DWORD WINAPI SHLWAPI_197(HDC hDC, LPCRECT pRect, COLORREF cRef)
2048 COLORREF cOldColor = SetBkColor(hDC, cRef);
2049 ExtTextOutA(hDC, 0, 0, ETO_OPAQUE, pRect, 0, 0, 0);
2050 SetBkColor(hDC, cOldColor);
2051 return 0;
2054 /*************************************************************************
2055 * @ [SHLWAPI.199]
2057 * Copy an interface pointer
2059 * PARAMS
2060 * lppDest [O] Destination for copy
2061 * lpUnknown [I] Source for copy
2063 * RETURNS
2064 * Nothing.
2066 VOID WINAPI SHLWAPI_199(IUnknown **lppDest, IUnknown *lpUnknown)
2068 TRACE("(%p,%p)\n", lppDest, lpUnknown);
2070 if (lppDest)
2071 SHLWAPI_169(lppDest); /* Release existing interface */
2073 if (lpUnknown)
2075 /* Copy */
2076 IUnknown_AddRef(lpUnknown);
2077 *lppDest = lpUnknown;
2081 /*************************************************************************
2082 * @ [SHLWAPI.201]
2085 HRESULT WINAPI SHLWAPI_201(IUnknown* lpUnknown, INT iUnk, REFGUID pguidCmdGroup,
2086 DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn,
2087 VARIANT* pvaOut)
2089 FIXME("(%p,%d,%p,%ld,%ld,%p,%p) - stub!\n", lpUnknown, iUnk, pguidCmdGroup,
2090 nCmdID, nCmdexecopt, pvaIn, pvaOut);
2091 return DRAGDROP_E_NOTREGISTERED;
2094 /*************************************************************************
2095 * @ [SHLWAPI.202]
2098 HRESULT WINAPI SHLWAPI_202(REFGUID pguidCmdGroup,ULONG cCmds, OLECMD *prgCmds)
2100 FIXME("(%p,%ld,%p) - stub!\n", pguidCmdGroup, cCmds, prgCmds);
2101 return DRAGDROP_E_NOTREGISTERED;
2104 /*************************************************************************
2105 * @ [SHLWAPI.204]
2107 * Determine if a window is not a child of another window.
2109 * PARAMS
2110 * hParent [I] Suspected parent window
2111 * hChild [I] Suspected child window
2113 * RETURNS
2114 * TRUE: If hChild is a child window of hParent
2115 * FALSE: If hChild is not a child window of hParent, or they are equal
2117 BOOL WINAPI SHLWAPI_204(HWND hParent, HWND hChild)
2119 TRACE("(%p,%p)\n", hParent, hChild);
2121 if (!hParent || !hChild)
2122 return TRUE;
2123 else if(hParent == hChild)
2124 return FALSE;
2125 return !IsChild(hParent, hChild);
2128 /*************************************************************************
2129 * @ [SHLWAPI.208]
2131 * Some sort of memory management process - associated with _210
2133 DWORD WINAPI SHLWAPI_208 (
2134 DWORD a,
2135 DWORD b,
2136 LPVOID c,
2137 LPVOID d,
2138 DWORD e)
2140 FIXME("(0x%08lx 0x%08lx %p %p 0x%08lx) stub\n",
2141 a, b, c, d, e);
2142 return 1;
2145 /*************************************************************************
2146 * @ [SHLWAPI.209]
2148 * Some sort of memory management process - associated with _208
2150 DWORD WINAPI SHLWAPI_209 (
2151 LPVOID a)
2153 FIXME("(%p) stub\n",
2155 return 1;
2158 /*************************************************************************
2159 * @ [SHLWAPI.210]
2161 * Some sort of memory management process - associated with _208
2163 DWORD WINAPI SHLWAPI_210 (
2164 LPVOID a,
2165 DWORD b,
2166 LPVOID c)
2168 FIXME("(%p 0x%08lx %p) stub\n",
2169 a, b, c);
2170 return 0;
2173 /*************************************************************************
2174 * @ [SHLWAPI.211]
2176 DWORD WINAPI SHLWAPI_211 (
2177 LPVOID a,
2178 DWORD b)
2180 FIXME("(%p 0x%08lx) stub\n",
2181 a, b);
2182 return 1;
2185 /*************************************************************************
2186 * @ [SHLWAPI.215]
2188 * NOTES
2189 * check me!
2191 DWORD WINAPI SHLWAPI_215 (
2192 LPCSTR lpStrSrc,
2193 LPWSTR lpwStrDest,
2194 int len)
2196 INT len_a, ret;
2198 len_a = lstrlenA(lpStrSrc);
2199 ret = MultiByteToWideChar(0, 0, lpStrSrc, len_a, lpwStrDest, len);
2200 TRACE("%s %s %d, ret=%d\n",
2201 debugstr_a(lpStrSrc), debugstr_w(lpwStrDest), len, ret);
2202 return ret;
2205 /*************************************************************************
2206 * @ [SHLWAPI.218]
2208 * WideCharToMultiByte with support for multiple codepages.
2210 * PARAMS
2211 * CodePage [I] Code page to use for the conversion
2212 * lpSrcStr [I] Source Unicode string to convert
2213 * lpDstStr [O] Destination for converted Ascii string
2214 * lpnMultiCharCount [O] Input length of lpDstStr/destination for length of lpDstStr
2216 * RETURNS
2217 * Success: The number of characters that result from the conversion.
2218 * Failure: 0.
2220 INT WINAPI SHLWAPI_218(UINT CodePage, LPCWSTR lpSrcStr, LPSTR lpDstStr,
2221 LPINT lpnMultiCharCount)
2223 WCHAR emptyW[] = { '\0' };
2224 int len , reqLen;
2225 LPSTR mem;
2227 if (!lpDstStr || !lpnMultiCharCount)
2228 return 0;
2230 if (!lpSrcStr)
2231 lpSrcStr = emptyW;
2233 *lpDstStr = '\0';
2235 len = strlenW(lpSrcStr) + 1;
2237 switch (CodePage)
2239 case CP_WINUNICODE:
2240 CodePage = CP_UTF8; /* Fall through... */
2241 case 0x0000C350: /* FIXME: CP_ #define */
2242 case CP_UTF7:
2243 case CP_UTF8:
2245 DWORD dwMode = 0;
2246 INT nWideCharCount = len - 1;
2248 GET_FUNC(pConvertINetUnicodeToMultiByte, mlang, "ConvertINetUnicodeToMultiByte", 0);
2249 if (!pConvertINetUnicodeToMultiByte(&dwMode, CodePage, lpSrcStr, &nWideCharCount, lpDstStr,
2250 lpnMultiCharCount))
2251 return 0;
2253 if (nWideCharCount < len - 1)
2255 mem = (LPSTR)HeapAlloc(GetProcessHeap(), 0, *lpnMultiCharCount);
2256 if (!mem)
2257 return 0;
2259 *lpnMultiCharCount = 0;
2261 if (pConvertINetUnicodeToMultiByte(&dwMode, CodePage, lpSrcStr, &len, mem, lpnMultiCharCount))
2263 SHLWAPI_162 (mem, *lpnMultiCharCount);
2264 lstrcpynA(lpDstStr, mem, *lpnMultiCharCount + 1);
2265 return *lpnMultiCharCount + 1;
2267 HeapFree(GetProcessHeap(), 0, mem);
2268 return *lpnMultiCharCount;
2270 lpDstStr[*lpnMultiCharCount] = '\0';
2271 return *lpnMultiCharCount;
2273 break;
2274 default:
2275 break;
2278 reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, lpDstStr,
2279 *lpnMultiCharCount, NULL, NULL);
2281 if (!reqLen && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
2283 reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, NULL, 0, NULL, NULL);
2284 if (reqLen)
2286 mem = (LPSTR)HeapAlloc(GetProcessHeap(), 0, reqLen);
2287 if (mem)
2289 reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, mem,
2290 reqLen, NULL, NULL);
2292 reqLen = SHLWAPI_162(mem, *lpnMultiCharCount);
2293 reqLen++;
2295 lstrcpynA(lpDstStr, mem, *lpnMultiCharCount);
2297 HeapFree(GetProcessHeap(), 0, mem);
2301 return reqLen;
2304 /*************************************************************************
2305 * @ [SHLWAPI.217]
2307 * WideCharToMultiByte with support for multiple codepages.
2309 * PARAMS
2310 * lpSrcStr [I] Source Unicode string to convert
2311 * lpDstStr [O] Destination for converted Ascii string
2312 * lpnMultiCharCount [O] Input length of lpDstStr/destination for length of lpDstStr
2314 * RETURNS
2315 * See SHLWAPI_218.
2317 * NOTES
2318 * This function simply calls SHLWAPI_218() with CodePage = CP_ACP.
2320 INT WINAPI SHLWAPI_217(LPCWSTR lpSrcStr, LPSTR lpDstStr, INT MultiCharCount)
2322 INT myint = MultiCharCount;
2324 return SHLWAPI_218(CP_ACP, lpSrcStr, lpDstStr, &myint);
2327 typedef struct {
2328 REFIID refid;
2329 DWORD indx;
2330 } IFACE_INDEX_TBL;
2332 /*************************************************************************
2333 * @ [SHLWAPI.219]
2335 * Call IUnknown_QueryInterface() on a table of objects.
2337 * RETURNS
2338 * Success: S_OK.
2339 * Failure: E_POINTER or E_NOINTERFACE.
2341 HRESULT WINAPI SHLWAPI_219 (
2342 LPVOID w, /* [in] Table of interfaces */
2343 IFACE_INDEX_TBL *x, /* [in] Array of REFIIDs and indexes into the table */
2344 REFIID riid, /* [in] REFIID to get interface for */
2345 LPVOID *ppv) /* [out] Destination for interface pointer */
2347 HRESULT ret;
2348 IUnknown *a_vtbl;
2349 IFACE_INDEX_TBL *xmove;
2351 TRACE("(%p %p %s %p)\n", w,x,debugstr_guid(riid),ppv);
2352 if (ppv) {
2353 xmove = x;
2354 while (xmove->refid) {
2355 TRACE("trying (indx %ld) %s\n", xmove->indx, debugstr_guid(xmove->refid));
2356 if (IsEqualIID(riid, xmove->refid)) {
2357 a_vtbl = (IUnknown*)(xmove->indx + (LPBYTE)w);
2358 TRACE("matched, returning (%p)\n", a_vtbl);
2359 *ppv = (LPVOID)a_vtbl;
2360 IUnknown_AddRef(a_vtbl);
2361 return S_OK;
2363 xmove++;
2366 if (IsEqualIID(riid, &IID_IUnknown)) {
2367 a_vtbl = (IUnknown*)(x->indx + (LPBYTE)w);
2368 TRACE("returning first for IUnknown (%p)\n", a_vtbl);
2369 *ppv = (LPVOID)a_vtbl;
2370 IUnknown_AddRef(a_vtbl);
2371 return S_OK;
2373 *ppv = 0;
2374 ret = E_NOINTERFACE;
2375 } else
2376 ret = E_POINTER;
2378 TRACE("-- 0x%08lx\n", ret);
2379 return ret;
2382 /*************************************************************************
2383 * @ [SHLWAPI.221]
2385 * Remove the "PropDlgFont" property from a window.
2387 * PARAMS
2388 * hWnd [I] Window to remove the property from
2390 * RETURNS
2391 * A handle to the removed property, or NULL if it did not exist.
2393 HANDLE WINAPI SHLWAPI_221(HWND hWnd)
2395 HANDLE hProp;
2397 TRACE("(%p)\n", hWnd);
2399 hProp = GetPropA(hWnd, "PropDlgFont");
2401 if(hProp)
2403 DeleteObject(hProp);
2404 hProp = RemovePropA(hWnd, "PropDlgFont");
2406 return hProp;
2409 /*************************************************************************
2410 * @ [SHLWAPI.236]
2412 * Load the in-process server of a given GUID.
2414 * PARAMS
2415 * refiid [I] GUID of the server to load.
2417 * RETURNS
2418 * Success: A handle to the loaded server dll.
2419 * Failure: A NULL handle.
2421 HMODULE WINAPI SHLWAPI_236(REFIID refiid)
2423 HKEY newkey;
2424 DWORD type, count;
2425 CHAR value[MAX_PATH], string[MAX_PATH];
2427 strcpy(string, "CLSID\\");
2428 SHLWAPI_23(refiid, string + 6, sizeof(string)/sizeof(char) - 6);
2429 strcat(string, "\\InProcServer32");
2431 count = MAX_PATH;
2432 RegOpenKeyExA(HKEY_CLASSES_ROOT, string, 0, 1, &newkey);
2433 RegQueryValueExA(newkey, 0, 0, &type, (PBYTE)value, &count);
2434 RegCloseKey(newkey);
2435 return LoadLibraryExA(value, 0, 0);
2438 /*************************************************************************
2439 * @ [SHLWAPI.237]
2441 * Unicode version of SHLWAPI_183.
2443 DWORD WINAPI SHLWAPI_237 (WNDCLASSW * lpWndClass)
2445 WNDCLASSW WndClass;
2447 TRACE("(%p %s)\n",lpWndClass->hInstance, debugstr_w(lpWndClass->lpszClassName));
2449 if (GetClassInfoW(lpWndClass->hInstance, lpWndClass->lpszClassName, &WndClass))
2450 return TRUE;
2451 return RegisterClassW(lpWndClass);
2454 /*************************************************************************
2455 * SHLWAPI_238 [SHLWAPI.238]
2457 * Unregister a list of classes.
2459 * PARAMS
2460 * hInst [I] Application instance that registered the classes
2461 * lppClasses [I] List of class names
2462 * iCount [I] Number of names in lppClasses
2464 * RETURNS
2465 * Nothing.
2467 void WINAPI SHLWAPI_238(HINSTANCE hInst, LPCSTR *lppClasses, INT iCount)
2469 WNDCLASSA WndClass;
2471 TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);
2473 while (iCount > 0)
2475 if (GetClassInfoA(hInst, *lppClasses, &WndClass))
2476 UnregisterClassA(*lppClasses, hInst);
2477 lppClasses++;
2478 iCount--;
2482 /*************************************************************************
2483 * SHLWAPI_239 [SHLWAPI.239]
2485 * Unicode version of SHLWAPI_238.
2487 void WINAPI SHLWAPI_239(HINSTANCE hInst, LPCWSTR *lppClasses, INT iCount)
2489 WNDCLASSW WndClass;
2491 TRACE("(%p,%p,%d)\n", hInst, lppClasses, iCount);
2493 while (iCount > 0)
2495 if (GetClassInfoW(hInst, *lppClasses, &WndClass))
2496 UnregisterClassW(*lppClasses, hInst);
2497 lppClasses++;
2498 iCount--;
2502 /*************************************************************************
2503 * @ [SHLWAPI.240]
2505 * Call The correct (Ascii/Unicode) default window procedure for a window.
2507 * PARAMS
2508 * hWnd [I] Window to call the default procedure for
2509 * uMessage [I] Message ID
2510 * wParam [I] WPARAM of message
2511 * lParam [I] LPARAM of message
2513 * RETURNS
2514 * The result of calling DefWindowProcA() or DefWindowProcW().
2516 LRESULT CALLBACK SHLWAPI_240(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
2518 if (IsWindowUnicode(hWnd))
2519 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
2520 return DefWindowProcA(hWnd, uMessage, wParam, lParam);
2523 /*************************************************************************
2524 * @ [SHLWAPI.241]
2527 DWORD WINAPI SHLWAPI_241 ()
2529 FIXME("()stub\n");
2530 return /* 0xabba1243 */ 0;
2533 /*************************************************************************
2534 * @ [SHLWAPI.257]
2536 * Create a worker window using CreateWindowExA().
2538 * PARAMS
2539 * wndProc [I] Window procedure
2540 * hWndParent [I] Parent window
2541 * dwExStyle [I] Extra style flags
2542 * dwStyle [I] Style flags
2543 * hMenu [I] Window menu
2544 * z [I] Unknown
2546 * RETURNS
2547 * Success: The window handle of the newly created window.
2548 * Failure: 0.
2550 HWND WINAPI SHLWAPI_257(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
2551 DWORD dwStyle, HMENU hMenu, LONG z)
2553 static const char* szClass = "WorkerA";
2554 WNDCLASSA wc;
2555 HWND hWnd;
2557 TRACE("(0x%08lx,%p,0x%08lx,0x%08lx,%p,0x%08lx)\n",
2558 wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2560 /* Create Window class */
2561 wc.style = 0;
2562 wc.lpfnWndProc = DefWindowProcA;
2563 wc.cbClsExtra = 0;
2564 wc.cbWndExtra = 4;
2565 wc.hInstance = shlwapi_hInstance;
2566 wc.hIcon = (HICON)0;
2567 wc.hCursor = LoadCursorA((HINSTANCE)0, IDC_ARROWA);
2568 wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
2569 wc.lpszMenuName = NULL;
2570 wc.lpszClassName = szClass;
2572 SHLWAPI_183(&wc); /* Register class */
2574 /* FIXME: Set extra bits in dwExStyle */
2576 hWnd = CreateWindowExA(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
2577 hWndParent, hMenu, shlwapi_hInstance, 0);
2578 if (hWnd)
2580 SetWindowLongA(hWnd, DWL_MSGRESULT, z);
2582 if (wndProc)
2583 SetWindowLongA(hWnd, GWL_WNDPROC, wndProc);
2585 return hWnd;
2588 typedef struct tagPOLICYDATA
2590 DWORD policy; /* flags value passed to SHRestricted */
2591 LPCWSTR appstr; /* application str such as "Explorer" */
2592 LPCWSTR keystr; /* name of the actual registry key / policy */
2593 } POLICYDATA, *LPPOLICYDATA;
2595 #define SHELL_NO_POLICY 0xffffffff
2597 /* default shell policy registry key */
2598 static WCHAR strRegistryPolicyW[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o',
2599 's','o','f','t','\\','W','i','n','d','o','w','s','\\',
2600 'C','u','r','r','e','n','t','V','e','r','s','i','o','n',
2601 '\\','P','o','l','i','c','i','e','s',0};
2603 /*************************************************************************
2604 * @ [SHLWAPI.271]
2606 * Retrieve a policy value from the registry.
2608 * PARAMS
2609 * lpSubKey [I] registry key name
2610 * lpSubName [I] subname of registry key
2611 * lpValue [I] value name of registry value
2613 * RETURNS
2614 * the value associated with the registry key or 0 if not found
2616 DWORD WINAPI SHLWAPI_271(LPCWSTR lpSubKey, LPCWSTR lpSubName, LPCWSTR lpValue)
2618 DWORD retval, datsize = 4;
2619 HKEY hKey;
2621 if (!lpSubKey)
2622 lpSubKey = (LPCWSTR)strRegistryPolicyW;
2624 retval = RegOpenKeyW(HKEY_LOCAL_MACHINE, lpSubKey, &hKey);
2625 if (retval != ERROR_SUCCESS)
2626 retval = RegOpenKeyW(HKEY_CURRENT_USER, lpSubKey, &hKey);
2627 if (retval != ERROR_SUCCESS)
2628 return 0;
2630 SHGetValueW(hKey, lpSubName, lpValue, NULL, (LPBYTE)&retval, &datsize);
2631 RegCloseKey(hKey);
2632 return retval;
2635 /*************************************************************************
2636 * @ [SHLWAPI.266]
2638 * Helper function to retrieve the possibly cached value for a specific policy
2640 * PARAMS
2641 * policy [I] The policy to look for
2642 * initial [I] Main registry key to open, if NULL use default
2643 * polTable [I] Table of known policies, 0 terminated
2644 * polArr [I] Cache array of policy values
2646 * RETURNS
2647 * The retrieved policy value or 0 if not successful
2649 * NOTES
2650 * This function is used by the native SHRestricted function to search for the
2651 * policy and cache it once retrieved. The current Wine implementation uses a
2652 * different POLICYDATA structure and implements a similar algorithme adapted to
2653 * that structure.
2655 DWORD WINAPI SHLWAPI_266 (
2656 DWORD policy,
2657 LPCWSTR initial,
2658 LPPOLICYDATA polTable,
2659 LPDWORD polArr)
2661 TRACE("(0x%08lx %s %p %p)\n", policy, debugstr_w(initial), polTable, polArr);
2663 if (!polTable || !polArr)
2664 return 0;
2666 for (;polTable->policy; polTable++, polArr++)
2668 if (policy == polTable->policy)
2670 /* we have a known policy */
2672 /* check if this policy has been cached */
2673 if (*polArr == SHELL_NO_POLICY)
2674 *polArr = SHLWAPI_271(initial, polTable->appstr, polTable->keystr);
2675 return *polArr;
2678 /* we don't know this policy, return 0 */
2679 TRACE("unknown policy: (%08lx)\n", policy);
2680 return 0;
2683 /*************************************************************************
2684 * @ [SHLWAPI.267]
2686 * Get an interface from an object.
2688 * RETURNS
2689 * Success: S_OK. ppv contains the requested interface.
2690 * Failure: An HRESULT error code.
2692 * NOTES
2693 * This QueryInterface asks the inner object for a interface. In case
2694 * of aggregation this request would be forwarded by the inner to the
2695 * outer object. This function asks the inner object directly for the
2696 * interface circumventing the forwarding to the outer object.
2698 HRESULT WINAPI SHLWAPI_267 (
2699 IUnknown * pUnk, /* [in] Outer object */
2700 IUnknown * pInner, /* [in] Inner object */
2701 IID * riid, /* [in] Interface GUID to query for */
2702 LPVOID* ppv) /* [out] Destination for queried interface */
2704 HRESULT hret = E_NOINTERFACE;
2705 TRACE("(pUnk=%p pInner=%p\n\tIID: %s %p)\n",pUnk,pInner,debugstr_guid(riid), ppv);
2707 *ppv = NULL;
2708 if(pUnk && pInner) {
2709 hret = IUnknown_QueryInterface(pInner, riid, (LPVOID*)ppv);
2710 if (SUCCEEDED(hret)) IUnknown_Release(pUnk);
2712 TRACE("-- 0x%08lx\n", hret);
2713 return hret;
2716 /*************************************************************************
2717 * @ [SHLWAPI.268]
2719 * Move a reference from one interface to another.
2721 * PARAMS
2722 * lpDest [O] Destination to receive the reference
2723 * lppUnknown [O] Source to give up the reference to lpDest
2725 * RETURNS
2726 * Nothing.
2728 VOID WINAPI SHLWAPI_268(IUnknown *lpDest, IUnknown **lppUnknown)
2730 TRACE("(%p,%p)\n", lpDest, lppUnknown);
2732 if (*lppUnknown)
2734 /* Copy Reference*/
2735 IUnknown_AddRef(lpDest);
2736 SHLWAPI_169(lppUnknown); /* Release existing interface */
2740 /*************************************************************************
2741 * @ [SHLWAPI.269]
2743 * Convert an ASCII string of a CLSID into a CLSID.
2745 * PARAMS
2746 * idstr [I] String representing a CLSID in registry format
2747 * id [O] Destination for the converted CLSID
2749 * RETURNS
2750 * Success: TRUE. id contains the converted CLSID.
2751 * Failure: FALSE.
2753 BOOL WINAPI SHLWAPI_269(LPCSTR idstr, CLSID *id)
2755 WCHAR wClsid[40];
2756 MultiByteToWideChar(CP_ACP, 0, idstr, -1, wClsid, sizeof(wClsid)/sizeof(WCHAR));
2757 return SUCCEEDED(SHLWAPI_436(wClsid, id));
2760 /*************************************************************************
2761 * @ [SHLWAPI.270]
2763 * Unicode version of SHLWAPI_269.
2765 BOOL WINAPI SHLWAPI_270(LPCWSTR idstr, CLSID *id)
2767 return SUCCEEDED(SHLWAPI_436(idstr, id));
2770 /*************************************************************************
2771 * @ [SHLWAPI.276]
2773 * Determine if the browser is integrated into the shell, and set a registry
2774 * key accordingly.
2776 * PARAMS
2777 * None.
2779 * RETURNS
2780 * 1, If the browser is not integrated.
2781 * 2, If the browser is integrated.
2783 * NOTES
2784 * The key "HKLM\Software\Microsoft\Internet Explorer\IntegratedBrowser" is
2785 * either set to TRUE, or removed depending on whether the browser is deemed
2786 * to be integrated.
2788 DWORD WINAPI SHLWAPI_276()
2790 static LPCSTR szIntegratedBrowser = "IntegratedBrowser";
2791 static DWORD dwState = 0;
2792 HKEY hKey;
2793 DWORD dwRet, dwData, dwSize;
2795 if (dwState)
2796 return dwState;
2798 /* If shell32 exports DllGetVersion(), the browser is integrated */
2799 GET_FUNC(pDllGetVersion, shell32, "DllGetVersion", 1);
2800 dwState = pDllGetVersion ? 2 : 1;
2802 /* Set or delete the key accordinly */
2803 dwRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
2804 "Software\\Microsoft\\Internet Explorer", 0,
2805 KEY_ALL_ACCESS, &hKey);
2806 if (!dwRet)
2808 dwRet = RegQueryValueExA(hKey, szIntegratedBrowser, 0, 0,
2809 (LPBYTE)&dwData, &dwSize);
2811 if (!dwRet && dwState == 1)
2813 /* Value exists but browser is not integrated */
2814 RegDeleteValueA(hKey, szIntegratedBrowser);
2816 else if (dwRet && dwState == 2)
2818 /* Browser is integrated but value does not exist */
2819 dwData = TRUE;
2820 RegSetValueExA(hKey, szIntegratedBrowser, 0, REG_DWORD,
2821 (LPBYTE)&dwData, sizeof(dwData));
2823 RegCloseKey(hKey);
2825 return dwState;
2828 /*************************************************************************
2829 * @ [SHLWAPI.278]
2831 * Unicode version of SHLWAPI_257.
2833 HWND WINAPI SHLWAPI_278(LONG wndProc, HWND hWndParent, DWORD dwExStyle,
2834 DWORD dwStyle, HMENU hMenu, LONG z)
2836 static const WCHAR szClass[] = { 'W', 'o', 'r', 'k', 'e', 'r', 'W', '\0' };
2837 WNDCLASSW wc;
2838 HWND hWnd;
2840 TRACE("(0x%08lx,%p,0x%08lx,0x%08lx,%p,0x%08lx)\n",
2841 wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2843 /* If our OS is natively ASCII, use the ASCII version */
2844 if (!(GetVersion() & 0x80000000)) /* NT */
2845 return SHLWAPI_257(wndProc, hWndParent, dwExStyle, dwStyle, hMenu, z);
2847 /* Create Window class */
2848 wc.style = 0;
2849 wc.lpfnWndProc = DefWindowProcW;
2850 wc.cbClsExtra = 0;
2851 wc.cbWndExtra = 4;
2852 wc.hInstance = shlwapi_hInstance;
2853 wc.hIcon = (HICON)0;
2854 wc.hCursor = LoadCursorA((HINSTANCE)0, IDC_ARROWA);
2855 wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
2856 wc.lpszMenuName = NULL;
2857 wc.lpszClassName = szClass;
2859 SHLWAPI_237(&wc); /* Register class */
2861 /* FIXME: Set extra bits in dwExStyle */
2863 hWnd = CreateWindowExW(dwExStyle, szClass, 0, dwStyle, 0, 0, 0, 0,
2864 hWndParent, hMenu, shlwapi_hInstance, 0);
2865 if (hWnd)
2867 SetWindowLongA(hWnd, DWL_MSGRESULT, z);
2869 if (wndProc)
2870 SetWindowLongA(hWnd, GWL_WNDPROC, wndProc);
2872 return hWnd;
2875 /*************************************************************************
2876 * @ [SHLWAPI.279]
2878 * Get and show a context menu from a shell folder.
2880 * PARAMS
2881 * hWnd [I] Window displaying the shell folder
2882 * lpFolder [I] IShellFolder interface
2883 * lpApidl [I] Id for the particular folder desired
2885 * RETURNS
2886 * Success: S_OK.
2887 * Failure: An HRESULT error code indicating the error.
2889 HRESULT WINAPI SHLWAPI_279(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl)
2891 return SHLWAPI_363(hWnd, lpFolder, lpApidl, FALSE);
2894 /*************************************************************************
2895 * @ [SHLWAPI.281]
2897 * _SHPackDispParamsV
2899 HRESULT WINAPI SHLWAPI_281(LPVOID w, LPVOID x, LPVOID y, LPVOID z)
2901 FIXME("%p %p %p %p\n",w,x,y,z);
2902 return E_FAIL;
2905 /*************************************************************************
2906 * @ [SHLWAPI.282]
2908 * This function seems to be a forward to SHLWAPI.281 (whatever THAT
2909 * function does...).
2911 HRESULT WINAPI SHLWAPI_282(LPVOID w, LPVOID x, LPVOID y, LPVOID z)
2913 FIXME("%p %p %p %p\n", w, x, y, z);
2914 return E_FAIL;
2917 /*************************************************************************
2918 * @ [SHLWAPI.284]
2920 * _IConnectionPoint_SimpleInvoke
2922 DWORD WINAPI SHLWAPI_284 (
2923 LPVOID x,
2924 LPVOID y,
2925 LPVOID z)
2927 TRACE("(%p %p %p) stub\n",x,y,z);
2928 return 0;
2931 /*************************************************************************
2932 * SHLWAPI_285 [SHLWAPI.285]
2934 * Notify an IConnectionPoint object of changes.
2936 * PARAMS
2937 * lpCP [I] Object to notify
2938 * dispID [I]
2940 * RETURNS
2941 * Success: S_OK.
2942 * Failure: E_NOINTERFACE, if lpCP is NULL or does not support the
2943 * IConnectionPoint interface.
2945 HRESULT WINAPI SHLWAPI_285(IConnectionPoint* lpCP, DISPID dispID)
2947 IEnumConnections *lpEnum;
2948 HRESULT hRet = E_NOINTERFACE;
2950 TRACE("(%p,0x%8lX)\n", lpCP, dispID);
2952 /* Get an enumerator for the connections */
2953 if (lpCP)
2954 hRet = IConnectionPoint_EnumConnections(lpCP, &lpEnum);
2956 if (SUCCEEDED(hRet))
2958 IPropertyNotifySink *lpSink;
2959 CONNECTDATA connData;
2960 ULONG ulFetched;
2962 /* Call OnChanged() for every notify sink in the connection point */
2963 while (IEnumConnections_Next(lpEnum, 1, &connData, &ulFetched) == S_OK)
2965 if (SUCCEEDED(IUnknown_QueryInterface(connData.pUnk, &IID_IPropertyNotifySink, (void**)&lpSink)) &&
2966 lpSink)
2968 IPropertyNotifySink_OnChanged(lpSink, dispID);
2969 IPropertyNotifySink_Release(lpSink);
2971 IUnknown_Release(connData.pUnk);
2974 IEnumConnections_Release(lpEnum);
2976 return hRet;
2979 /*************************************************************************
2980 * SHLWAPI_287 [SHLWAPI.287]
2982 * Notify an IConnectionPointContainer object of changes.
2984 * PARAMS
2985 * lpUnknown [I] Object to notify
2986 * dispID [I]
2988 * RETURNS
2989 * Success: S_OK.
2990 * Failure: E_NOINTERFACE, if lpUnknown is NULL or does not support the
2991 * IConnectionPointContainer interface.
2993 HRESULT WINAPI SHLWAPI_287(IUnknown *lpUnknown, DISPID dispID)
2995 IConnectionPointContainer* lpCPC = NULL;
2996 HRESULT hRet = E_NOINTERFACE;
2998 TRACE("(%p,0x%8lX)\n", lpUnknown, dispID);
3000 if (lpUnknown)
3001 hRet = IUnknown_QueryInterface(lpUnknown, &IID_IConnectionPointContainer, (void**)&lpCPC);
3003 if (SUCCEEDED(hRet))
3005 IConnectionPoint* lpCP;
3007 hRet = IConnectionPointContainer_FindConnectionPoint(lpCPC, &IID_IPropertyNotifySink, &lpCP);
3008 IConnectionPointContainer_Release(lpCPC);
3010 hRet = SHLWAPI_285(lpCP, dispID);
3011 IConnectionPoint_Release(lpCP);
3013 return hRet;
3016 /*************************************************************************
3017 * @ [SHLWAPI.289]
3019 * See PlaySoundW.
3021 BOOL WINAPI SHLWAPI_289(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
3023 GET_FUNC(pPlaySoundW, winmm, "PlaySoundW", FALSE);
3024 return pPlaySoundW(pszSound, hmod, fdwSound);
3027 /*************************************************************************
3028 * @ [SHLWAPI.294]
3030 BOOL WINAPI SHLWAPI_294(LPSTR str1, LPSTR str2, LPSTR pStr, DWORD some_len, LPCSTR lpStr2)
3033 * str1: "I" "I" pushl esp+0x20
3034 * str2: "U" "I" pushl 0x77c93810
3035 * (is "I" and "U" "integer" and "unsigned" ??)
3037 * pStr: "" "" pushl eax
3038 * some_len: 0x824 0x104 pushl 0x824
3039 * lpStr2: "%l" "%l" pushl esp+0xc
3041 * shlwapi. StrCpyNW(lpStr2, irrelevant_var, 0x104);
3042 * LocalAlloc(0x00, some_len) -> irrelevant_var
3043 * LocalAlloc(0x40, irrelevant_len) -> pStr
3044 * shlwapi.294(str1, str2, pStr, some_len, lpStr2);
3045 * shlwapi.PathRemoveBlanksW(pStr);
3047 FIXME("('%s', '%s', '%s', %08lx, '%s'): stub!\n", str1, str2, pStr, some_len, lpStr2);
3048 return TRUE;
3051 /*************************************************************************
3052 * @ [SHLWAPI.295]
3054 * Called by ICQ2000b install via SHDOCVW:
3055 * str1: "InternetShortcut"
3056 * x: some unknown pointer
3057 * str2: "http://free.aol.com/tryaolfree/index.adp?139269"
3058 * str3: "C:\\WINDOWS\\Desktop.new2\\Free AOL & Unlimited Internet.url"
3060 * In short: this one maybe creates a desktop link :-)
3062 BOOL WINAPI SHLWAPI_295(LPWSTR str1, LPVOID x, LPWSTR str2, LPWSTR str3)
3064 FIXME("('%s', %p, '%s', '%s'), stub.\n", debugstr_w(str1), x, debugstr_w(str2), debugstr_w(str3));
3065 return TRUE;
3068 /*************************************************************************
3069 * @ [SHLWAPI.299]
3071 * See COMCTL32_417.
3073 BOOL WINAPI SHLWAPI_299(HDC hdc, INT x, INT y, UINT flags, const RECT *lprect,
3074 LPCWSTR str, UINT count, const INT *lpDx)
3076 GET_FUNC(pCOMCTL32_417, comctl32, (LPCSTR)417, FALSE);
3077 return pCOMCTL32_417(hdc, x, y, flags, lprect, str, count, lpDx);
3080 /*************************************************************************
3081 * @ [SHLWAPI.313]
3083 * See SHGetFileInfoW.
3085 DWORD WINAPI SHLWAPI_313(LPCWSTR path, DWORD dwFileAttributes,
3086 SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
3088 GET_FUNC(pSHGetFileInfoW, shell32, "SHGetFileInfoW", 0);
3089 return pSHGetFileInfoW(path, dwFileAttributes, psfi, sizeofpsfi, flags);
3092 /*************************************************************************
3093 * @ [SHLWAPI.318]
3095 * See DragQueryFileW.
3097 UINT WINAPI SHLWAPI_318(HDROP hDrop, UINT lFile, LPWSTR lpszFile, UINT lLength)
3099 GET_FUNC(pDragQueryFileW, shell32, "DragQueryFileW", 0);
3100 return pDragQueryFileW(hDrop, lFile, lpszFile, lLength);
3103 /*************************************************************************
3104 * @ [SHLWAPI.333]
3106 * See SHBrowseForFolderW.
3108 LPITEMIDLIST WINAPI SHLWAPI_333(LPBROWSEINFOW lpBi)
3110 GET_FUNC(pSHBrowseForFolderW, shell32, "SHBrowseForFolderW", NULL);
3111 return pSHBrowseForFolderW(lpBi);
3114 /*************************************************************************
3115 * @ [SHLWAPI.334]
3117 * See SHGetPathFromIDListW.
3119 BOOL WINAPI SHLWAPI_334(LPCITEMIDLIST pidl,LPWSTR pszPath)
3121 GET_FUNC(pSHGetPathFromIDListW, shell32, "SHGetPathFromIDListW", 0);
3122 return pSHGetPathFromIDListW(pidl, pszPath);
3125 /*************************************************************************
3126 * @ [SHLWAPI.335]
3128 * See ShellExecuteExW.
3130 BOOL WINAPI SHLWAPI_335(LPSHELLEXECUTEINFOW lpExecInfo)
3132 GET_FUNC(pShellExecuteExW, shell32, "ShellExecuteExW", FALSE);
3133 return pShellExecuteExW(lpExecInfo);
3136 /*************************************************************************
3137 * @ [SHLWAPI.336]
3139 * See SHFileOperationW.
3141 HICON WINAPI SHLWAPI_336(LPSHFILEOPSTRUCTW lpFileOp)
3143 GET_FUNC(pSHFileOperationW, shell32, "SHFileOperationW", 0);
3144 return pSHFileOperationW(lpFileOp);
3147 /*************************************************************************
3148 * @ [SHLWAPI.337]
3150 * See ExtractIconExW.
3152 UINT WINAPI SHLWAPI_337(LPCWSTR lpszFile, INT nIconIndex, HICON *phiconLarge,
3153 HICON *phiconSmall, UINT nIcons)
3155 GET_FUNC(pExtractIconExW, shell32, "ExtractIconExW", 0);
3156 return pExtractIconExW(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
3159 /*************************************************************************
3160 * @ [SHLWAPI.342]
3163 LONG WINAPI SHInterlockedCompareExchange( PLONG dest, LONG xchg, LONG compare)
3165 return InterlockedCompareExchange(dest, xchg, compare);
3168 /*************************************************************************
3169 * @ [SHLWAPI.346]
3171 DWORD WINAPI SHLWAPI_346 (
3172 LPCWSTR src,
3173 LPWSTR dest,
3174 int len)
3176 FIXME("(%s %p 0x%08x)stub\n",debugstr_w(src),dest,len);
3177 lstrcpynW(dest, src, len);
3178 return lstrlenW(dest)+1;
3181 /*************************************************************************
3182 * @ [SHLWAPI.350]
3184 * See GetFileVersionInfoSizeW.
3186 DWORD WINAPI SHLWAPI_350 (
3187 LPWSTR x,
3188 LPVOID y)
3190 DWORD ret;
3192 GET_FUNC(pGetFileVersionInfoSizeW, version, "GetFileVersionInfoSizeW", 0);
3193 ret = pGetFileVersionInfoSizeW(x, y);
3194 return 0x208 + ret;
3197 /*************************************************************************
3198 * @ [SHLWAPI.351]
3200 * See GetFileVersionInfoW.
3202 BOOL WINAPI SHLWAPI_351 (
3203 LPWSTR w, /* [in] path to dll */
3204 DWORD x, /* [in] parm 2 to GetFileVersionInfoA */
3205 DWORD y, /* [in] return value from SHLWAPI_350() - assume length */
3206 LPVOID z) /* [in/out] buffer (+0x208 sent to GetFileVersionInfoA()) */
3208 GET_FUNC(pGetFileVersionInfoW, version, "GetFileVersionInfoW", 0);
3209 return pGetFileVersionInfoW(w, x, y-0x208, (char*)z+0x208);
3212 /*************************************************************************
3213 * @ [SHLWAPI.352]
3215 * See VerQueryValueW.
3217 WORD WINAPI SHLWAPI_352 (
3218 LPVOID w, /* [in] Buffer from SHLWAPI_351() */
3219 LPWSTR x, /* [in] Value to retrieve - converted and passed to VerQueryValueA() as #2 */
3220 LPVOID y, /* [out] Ver buffer - passed to VerQueryValueA as #3 */
3221 UINT* z) /* [in] Ver length - passed to VerQueryValueA as #4 */
3223 GET_FUNC(pVerQueryValueW, version, "VerQueryValueW", 0);
3224 return pVerQueryValueW((char*)w+0x208, x, y, z);
3227 #define IsIface(type) SUCCEEDED((hRet = IUnknown_QueryInterface(lpUnknown, &IID_##type, (void**)&lpObj)))
3228 #define IShellBrowser_EnableModeless IShellBrowser_EnableModelessSB
3229 #define EnableModeless(type) type##_EnableModeless((type*)lpObj, bModeless)
3231 /*************************************************************************
3232 * SHLWAPI_355 [SHLWAPI.355]
3234 * Change the modality of a shell object.
3236 * PARAMS
3237 * lpUnknown [I] Object to make modeless
3238 * bModeless [I] TRUE=Make modeless, FALSE=Make modal
3240 * RETURNS
3241 * Success: S_OK. The modality lpUnknown is changed.
3242 * Failure: An HRESULT error code indicating the error.
3244 * NOTES
3245 * lpUnknown must support the IOleInPlaceFrame interface, the
3246 * IInternetSecurityMgrSite interface, the IShellBrowser interface
3247 * or the IDocHostUIHandler interface, or this call fails.
3249 HRESULT WINAPI SHLWAPI_355(IUnknown *lpUnknown, BOOL bModeless)
3251 IUnknown *lpObj;
3252 HRESULT hRet;
3254 TRACE("(%p,%d)\n", lpUnknown, bModeless);
3256 if (!lpUnknown)
3257 return E_FAIL;
3259 if (IsIface(IOleInPlaceFrame))
3260 EnableModeless(IOleInPlaceFrame);
3261 else if (IsIface(IShellBrowser))
3262 EnableModeless(IShellBrowser);
3263 #if 0
3264 /* FIXME: Wine has no headers for these objects yet */
3265 else if (IsIface(IInternetSecurityMgrSite))
3266 EnableModeless(IInternetSecurityMgrSite);
3267 else if (IsIface(IDocHostUIHandler))
3268 EnableModeless(IDocHostUIHandler);
3269 #endif
3270 else
3271 return hRet;
3273 IUnknown_Release(lpObj);
3274 return S_OK;
3277 /*************************************************************************
3278 * @ [SHLWAPI.357]
3280 * See SHGetNewLinkInfoW.
3282 BOOL WINAPI SHLWAPI_357(LPCWSTR pszLinkTo, LPCWSTR pszDir, LPWSTR pszName,
3283 BOOL *pfMustCopy, UINT uFlags)
3285 GET_FUNC(pSHGetNewLinkInfoW, shell32, "SHGetNewLinkInfoW", FALSE);
3286 return pSHGetNewLinkInfoW(pszLinkTo, pszDir, pszName, pfMustCopy, uFlags);
3289 /*************************************************************************
3290 * @ [SHLWAPI.358]
3292 * See SHDefExtractIconW.
3294 UINT WINAPI SHLWAPI_358(LPCWSTR pszIconFile, int iIndex, UINT uFlags, HICON* phiconLarge,
3295 HICON* phiconSmall, UINT nIconSize)
3297 GET_FUNC(pSHDefExtractIconW, shell32, "SHDefExtractIconW", 0);
3298 return pSHDefExtractIconW(pszIconFile, iIndex, uFlags, phiconLarge, phiconSmall, nIconSize);
3301 /*************************************************************************
3302 * @ [SHLWAPI.363]
3304 * Get and show a context menu from a shell folder.
3306 * PARAMS
3307 * hWnd [I] Window displaying the shell folder
3308 * lpFolder [I] IShellFolder interface
3309 * lpApidl [I] Id for the particular folder desired
3310 * bInvokeDefault [I] Whether to invoke the default menu item
3312 * RETURNS
3313 * Success: S_OK. If bInvokeDefault is TRUE, the default menu action was
3314 * executed.
3315 * Failure: An HRESULT error code indicating the error.
3317 HRESULT WINAPI SHLWAPI_363(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl, BOOL bInvokeDefault)
3319 IContextMenu *iContext;
3320 HRESULT hRet = E_FAIL;
3322 TRACE("(%p,%p,%p,%d)\n", hWnd, lpFolder, lpApidl, bInvokeDefault);
3324 if (!lpFolder)
3325 return hRet;
3327 /* Get the context menu from the shell folder */
3328 hRet = IShellFolder_GetUIObjectOf(lpFolder, hWnd, 1, &lpApidl,
3329 &IID_IContextMenu, 0, (void**)&iContext);
3330 if (SUCCEEDED(hRet))
3332 HMENU hMenu;
3333 if ((hMenu = CreatePopupMenu()))
3335 HRESULT hQuery;
3336 DWORD dwDefaultId = 0;
3338 /* Add the context menu entries to the popup */
3339 hQuery = IContextMenu_QueryContextMenu(iContext, hMenu, 0, 1, 0x7FFF,
3340 bInvokeDefault ? CMF_NORMAL : CMF_DEFAULTONLY);
3342 if (SUCCEEDED(hQuery))
3344 if (bInvokeDefault &&
3345 (dwDefaultId = GetMenuDefaultItem(hMenu, 0, 0)) != 0xFFFFFFFF)
3347 CMINVOKECOMMANDINFO cmIci;
3348 /* Invoke the default item */
3349 memset(&cmIci,0,sizeof(cmIci));
3350 cmIci.cbSize = sizeof(cmIci);
3351 cmIci.fMask = CMIC_MASK_ASYNCOK;
3352 cmIci.hwnd = hWnd;
3353 cmIci.lpVerb = MAKEINTRESOURCEA(dwDefaultId);
3354 cmIci.nShow = SW_SCROLLCHILDREN;
3356 hRet = IContextMenu_InvokeCommand(iContext, &cmIci);
3359 DestroyMenu(hMenu);
3361 IContextMenu_Release(iContext);
3363 return hRet;
3366 /*************************************************************************
3367 * @ [SHLWAPI.364]
3369 * Copy one string to another, up to a given length.
3371 * PARAMS
3372 * lpszSrc [I] Source string to copy
3373 * lpszDst [O] Destination for copied string
3374 * iLen [I] Number of characters to copy
3376 * RETURNS
3377 * TRUE.
3379 DWORD WINAPI SHLWAPI_364(LPCSTR lpszSrc, LPSTR lpszDst, INT iLen)
3381 lstrcpynA(lpszDst, lpszSrc, iLen);
3382 return TRUE;
3385 /*************************************************************************
3386 * @ [SHLWAPI.370]
3388 * See ExtractIconW.
3390 HICON WINAPI SHLWAPI_370(HINSTANCE hInstance, LPCWSTR lpszExeFileName,
3391 UINT nIconIndex)
3393 GET_FUNC(pExtractIconW, shell32, "ExtractIconW", NULL);
3394 return pExtractIconW(hInstance, lpszExeFileName, nIconIndex);
3397 /*************************************************************************
3398 * @ [SHLWAPI.376]
3400 LANGID WINAPI SHLWAPI_376 ()
3402 FIXME("() stub\n");
3403 /* FIXME: This should be a forward in the .spec file to the win2k function
3404 * kernel32.GetUserDefaultUILanguage, however that function isn't there yet.
3406 return GetUserDefaultLangID();
3409 /*************************************************************************
3410 * @ [SHLWAPI.377]
3412 * Load a library from the directory of a particular process.
3414 * PARAMS
3415 * new_mod [I] Library name
3416 * inst_hwnd [I] Module whose directory is to be used
3417 * dwFlags [I] Flags controlling the load
3419 * RETURNS
3420 * Success: A handle to the loaded module
3421 * Failure: A NULL handle.
3423 HMODULE WINAPI SHLWAPI_377 (LPCSTR new_mod, HMODULE inst_hwnd, DWORD dwFlags)
3425 /* FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for
3426 * each call here.
3427 * FIXME: Native shows calls to:
3428 * SHRegGetUSValue for "Software\Microsoft\Internet Explorer\International"
3429 * CheckVersion
3430 * RegOpenKeyExA for "HKLM\Software\Microsoft\Internet Explorer"
3431 * RegQueryValueExA for "LPKInstalled"
3432 * RegCloseKey
3433 * RegOpenKeyExA for "HKCU\Software\Microsoft\Internet Explorer\International"
3434 * RegQueryValueExA for "ResourceLocale"
3435 * RegCloseKey
3436 * RegOpenKeyExA for "HKLM\Software\Microsoft\Active Setup\Installed Components\{guid}"
3437 * RegQueryValueExA for "Locale"
3438 * RegCloseKey
3439 * and then tests the Locale ("en" for me).
3440 * code below
3441 * after the code then a DPA_Create (first time) and DPA_InsertPtr are done.
3443 CHAR mod_path[2*MAX_PATH];
3444 LPSTR ptr;
3446 FIXME("(%s,%p,0x%08lx) semi-stub!\n", debugstr_a(new_mod), inst_hwnd, dwFlags);
3447 GetModuleFileNameA(inst_hwnd, mod_path, 2*MAX_PATH);
3448 ptr = strrchr(mod_path, '\\');
3449 if (ptr) {
3450 strcpy(ptr+1, new_mod);
3451 TRACE("loading %s\n", debugstr_a(mod_path));
3452 return LoadLibraryA(mod_path);
3454 return NULL;
3457 /*************************************************************************
3458 * @ [SHLWAPI.378]
3460 * Unicode version of SHLWAPI_377
3462 DWORD WINAPI SHLWAPI_378 (LPCWSTR new_mod, HMODULE inst_hwnd, DWORD dwFlags)
3464 WCHAR mod_path[2*MAX_PATH];
3465 LPWSTR ptr;
3467 FIXME("(%s,%p,0x%08lx) semi-stub!\n", debugstr_w(new_mod), inst_hwnd, dwFlags);
3468 GetModuleFileNameW(inst_hwnd, mod_path, 2*MAX_PATH);
3469 ptr = strrchrW(mod_path, '\\');
3470 if (ptr) {
3471 strcpyW(ptr+1, new_mod);
3472 TRACE("loading %s\n", debugstr_w(mod_path));
3473 return (DWORD)LoadLibraryW(mod_path);
3475 return 0;
3478 /*************************************************************************
3479 * ColorAdjustLuma [SHLWAPI.387]
3481 * Adjust the luminosity of a color
3483 * PARAMS
3484 * cRGB [I] RGB value to convert
3485 * dwLuma [I] Luma adjustment
3486 * bUnknown [I] Unknown
3488 * RETURNS
3489 * The adjusted RGB color.
3491 COLORREF WINAPI ColorAdjustLuma(COLORREF cRGB, int dwLuma, BOOL bUnknown)
3493 TRACE("(0x%8lx,%d,%d)\n", cRGB, dwLuma, bUnknown);
3495 if (dwLuma)
3497 WORD wH, wL, wS;
3499 ColorRGBToHLS(cRGB, &wH, &wL, &wS);
3501 FIXME("Ignoring luma adjustment\n");
3503 /* FIXME: The ajdustment is not linear */
3505 cRGB = ColorHLSToRGB(wH, wL, wS);
3507 return cRGB;
3510 /*************************************************************************
3511 * @ [SHLWAPI.389]
3513 * See GetSaveFileNameW.
3515 BOOL WINAPI SHLWAPI_389(LPOPENFILENAMEW ofn)
3517 GET_FUNC(pGetSaveFileNameW, comdlg32, "GetSaveFileNameW", FALSE);
3518 return pGetSaveFileNameW(ofn);
3521 /*************************************************************************
3522 * @ [SHLWAPI.390]
3524 * See WNetRestoreConnectionW.
3526 DWORD WINAPI SHLWAPI_390(HWND hwndOwner, LPWSTR lpszDevice)
3528 GET_FUNC(pWNetRestoreConnectionW, mpr, "WNetRestoreConnectionW", 0);
3529 return pWNetRestoreConnectionW(hwndOwner, lpszDevice);
3532 /*************************************************************************
3533 * @ [SHLWAPI.391]
3535 * See WNetGetLastErrorW.
3537 DWORD WINAPI SHLWAPI_391(LPDWORD lpError, LPWSTR lpErrorBuf, DWORD nErrorBufSize,
3538 LPWSTR lpNameBuf, DWORD nNameBufSize)
3540 GET_FUNC(pWNetGetLastErrorW, mpr, "WNetGetLastErrorW", 0);
3541 return pWNetGetLastErrorW(lpError, lpErrorBuf, nErrorBufSize, lpNameBuf, nNameBufSize);
3544 /*************************************************************************
3545 * @ [SHLWAPI.401]
3547 * See PageSetupDlgW.
3549 BOOL WINAPI SHLWAPI_401(LPPAGESETUPDLGW pagedlg)
3551 GET_FUNC(pPageSetupDlgW, comdlg32, "PageSetupDlgW", FALSE);
3552 return pPageSetupDlgW(pagedlg);
3555 /*************************************************************************
3556 * @ [SHLWAPI.402]
3558 * See PrintDlgW.
3560 BOOL WINAPI SHLWAPI_402(LPPRINTDLGW printdlg)
3562 GET_FUNC(pPrintDlgW, comdlg32, "PrintDlgW", FALSE);
3563 return pPrintDlgW(printdlg);
3566 /*************************************************************************
3567 * @ [SHLWAPI.403]
3569 * See GetOpenFileNameW.
3571 BOOL WINAPI SHLWAPI_403(LPOPENFILENAMEW ofn)
3573 GET_FUNC(pGetOpenFileNameW, comdlg32, "GetOpenFileNameW", FALSE);
3574 return pGetOpenFileNameW(ofn);
3577 /* INTERNAL: Map from HLS color space to RGB */
3578 static WORD WINAPI ConvertHue(int wHue, WORD wMid1, WORD wMid2)
3580 wHue = wHue > 240 ? wHue - 240 : wHue < 0 ? wHue + 240 : wHue;
3582 if (wHue > 160)
3583 return wMid1;
3584 else if (wHue > 120)
3585 wHue = 160 - wHue;
3586 else if (wHue > 40)
3587 return wMid2;
3589 return ((wHue * (wMid2 - wMid1) + 20) / 40) + wMid1;
3592 /* Convert to RGB and scale into RGB range (0..255) */
3593 #define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240
3595 /*************************************************************************
3596 * ColorHLSToRGB [SHLWAPI.404]
3598 * Convert from hls color space into an rgb COLORREF.
3600 * PARAMS
3601 * wHue [I] Hue amount
3602 * wLuminosity [I] Luminosity amount
3603 * wSaturation [I] Saturation amount
3605 * RETURNS
3606 * A COLORREF representing the converted color.
3608 * NOTES
3609 * Input hls values are constrained to the range (0..240).
3611 COLORREF WINAPI ColorHLSToRGB(WORD wHue, WORD wLuminosity, WORD wSaturation)
3613 WORD wRed;
3615 if (wSaturation)
3617 WORD wGreen, wBlue, wMid1, wMid2;
3619 if (wLuminosity > 120)
3620 wMid2 = wSaturation + wLuminosity - (wSaturation * wLuminosity + 120) / 240;
3621 else
3622 wMid2 = ((wSaturation + 240) * wLuminosity + 120) / 240;
3624 wMid1 = wLuminosity * 2 - wMid2;
3626 wRed = GET_RGB(wHue + 80);
3627 wGreen = GET_RGB(wHue);
3628 wBlue = GET_RGB(wHue - 80);
3630 return RGB(wRed, wGreen, wBlue);
3633 wRed = wLuminosity * 255 / 240;
3634 return RGB(wRed, wRed, wRed);
3637 /*************************************************************************
3638 * @ [SHLWAPI.406]
3640 DWORD WINAPI SHLWAPI_406(LPVOID u, LPVOID v, LPVOID w, LPVOID x, LPVOID y, LPVOID z)
3642 FIXME("%p %p %p %p %p %p\n", u, v, w, x, y, z);
3643 return 0;
3646 /*************************************************************************
3647 * @ [SHLWAPI.413]
3649 * Get the current docking status of the system.
3651 * PARAMS
3652 * dwFlags [I] DOCKINFO_ flags from "winbase.h", unused
3654 * RETURNS
3655 * One of DOCKINFO_UNDOCKED, DOCKINFO_UNDOCKED, or 0 if the system is not
3656 * a notebook.
3658 DWORD WINAPI SHLWAPI_413(DWORD dwFlags)
3660 HW_PROFILE_INFOA hwInfo;
3662 TRACE("(0x%08lx)\n", dwFlags);
3664 GetCurrentHwProfileA(&hwInfo);
3665 switch (hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED))
3667 case DOCKINFO_DOCKED:
3668 case DOCKINFO_UNDOCKED:
3669 return hwInfo.dwDockInfo & (DOCKINFO_DOCKED|DOCKINFO_UNDOCKED);
3670 default:
3671 return 0;
3675 /*************************************************************************
3676 * @ [SHLWAPI.418]
3678 * Function seems to do FreeLibrary plus other things.
3680 * FIXME native shows the following calls:
3681 * RtlEnterCriticalSection
3682 * LocalFree
3683 * GetProcAddress(Comctl32??, 150L)
3684 * DPA_DeletePtr
3685 * RtlLeaveCriticalSection
3686 * followed by the FreeLibrary.
3687 * The above code may be related to .377 above.
3689 BOOL WINAPI SHLWAPI_418(HMODULE hModule)
3691 FIXME("(%p) semi-stub\n", hModule);
3692 return FreeLibrary(hModule);
3695 /*************************************************************************
3696 * @ [SHLWAPI.430]
3698 DWORD WINAPI SHLWAPI_430(HINSTANCE hInst, HANDLE hHeap)
3700 FIXME("(%p,%p) stub\n", hInst, hHeap);
3701 return E_FAIL; /* This is what is used if shlwapi not loaded */
3704 /*************************************************************************
3705 * @ [SHLWAPI.431]
3707 DWORD WINAPI SHLWAPI_431 (DWORD x)
3709 FIXME("(0x%08lx)stub\n", x);
3710 return 0xabba1247;
3713 /*************************************************************************
3714 * @ [SHLWAPI.436]
3716 * Convert an Unicode string CLSID into a CLSID.
3718 * PARAMS
3719 * idstr [I] string containing a CLSID in text form
3720 * id [O] CLSID extracted from the string
3722 * RETURNS
3723 * S_OK on success or E_INVALIDARG on failure
3725 * NOTES
3726 * This is really CLSIDFromString() which is exported by ole32.dll,
3727 * however the native shlwapi.dll does *not* import ole32. Nor does
3728 * ole32.dll import this ordinal from shlwapi. Therefore we must conclude
3729 * that MS duplicated the code for CLSIDFromString(), and yes they did, only
3730 * it returns an E_INVALIDARG error code on failure.
3731 * This is a duplicate (with changes for Unicode) of CLSIDFromString16()
3732 * in "dlls/ole32/compobj.c".
3734 HRESULT WINAPI SHLWAPI_436(LPCWSTR idstr, CLSID *id)
3736 LPCWSTR s = idstr;
3737 BYTE *p;
3738 INT i;
3739 WCHAR table[256];
3741 if (!s) {
3742 memset(id, 0, sizeof(CLSID));
3743 return S_OK;
3745 else { /* validate the CLSID string */
3747 if (strlenW(s) != 38)
3748 return E_INVALIDARG;
3750 if ((s[0]!=L'{') || (s[9]!=L'-') || (s[14]!=L'-') || (s[19]!=L'-') || (s[24]!=L'-') || (s[37]!=L'}'))
3751 return E_INVALIDARG;
3753 for (i=1; i<37; i++)
3755 if ((i == 9)||(i == 14)||(i == 19)||(i == 24))
3756 continue;
3757 if (!(((s[i] >= L'0') && (s[i] <= L'9')) ||
3758 ((s[i] >= L'a') && (s[i] <= L'f')) ||
3759 ((s[i] >= L'A') && (s[i] <= L'F')))
3761 return E_INVALIDARG;
3765 TRACE("%s -> %p\n", debugstr_w(s), id);
3767 /* quick lookup table */
3768 memset(table, 0, 256*sizeof(WCHAR));
3770 for (i = 0; i < 10; i++) {
3771 table['0' + i] = i;
3773 for (i = 0; i < 6; i++) {
3774 table['A' + i] = i+10;
3775 table['a' + i] = i+10;
3778 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
3780 p = (BYTE *) id;
3782 s++; /* skip leading brace */
3783 for (i = 0; i < 4; i++) {
3784 p[3 - i] = table[*s]<<4 | table[*(s+1)];
3785 s += 2;
3787 p += 4;
3788 s++; /* skip - */
3790 for (i = 0; i < 2; i++) {
3791 p[1-i] = table[*s]<<4 | table[*(s+1)];
3792 s += 2;
3794 p += 2;
3795 s++; /* skip - */
3797 for (i = 0; i < 2; i++) {
3798 p[1-i] = table[*s]<<4 | table[*(s+1)];
3799 s += 2;
3801 p += 2;
3802 s++; /* skip - */
3804 /* these are just sequential bytes */
3805 for (i = 0; i < 2; i++) {
3806 *p++ = table[*s]<<4 | table[*(s+1)];
3807 s += 2;
3809 s++; /* skip - */
3811 for (i = 0; i < 6; i++) {
3812 *p++ = table[*s]<<4 | table[*(s+1)];
3813 s += 2;
3816 return S_OK;
3819 /*************************************************************************
3820 * @ [SHLWAPI.437]
3822 * Determine if the OS supports a given feature.
3824 * PARAMS
3825 * dwFeature [I] Feature requested (undocumented)
3827 * RETURNS
3828 * TRUE If the feature is available.
3829 * FALSE If the feature is not available.
3831 DWORD WINAPI SHLWAPI_437 (DWORD feature)
3833 FIXME("(0x%08lx) stub\n", feature);
3834 return FALSE;
3837 /*************************************************************************
3838 * ColorRGBToHLS [SHLWAPI.445]
3840 * Convert an rgb COLORREF into the hls color space.
3842 * PARAMS
3843 * cRGB [I] Source rgb value
3844 * pwHue [O] Destination for converted hue
3845 * pwLuminance [O] Destination for converted luminance
3846 * pwSaturation [O] Destination for converted saturation
3848 * RETURNS
3849 * Nothing. pwHue, pwLuminance and pwSaturation are set to the converted
3850 * values.
3852 * NOTES
3853 * Output HLS values are constrained to the range (0..240).
3854 * For Achromatic conversions, Hue is set to 160.
3856 VOID WINAPI ColorRGBToHLS(COLORREF cRGB, LPWORD pwHue,
3857 LPWORD pwLuminance, LPWORD pwSaturation)
3859 int wR, wG, wB, wMax, wMin, wHue, wLuminosity, wSaturation;
3861 TRACE("(%08lx,%p,%p,%p)\n", cRGB, pwHue, pwLuminance, pwSaturation);
3863 wR = GetRValue(cRGB);
3864 wG = GetGValue(cRGB);
3865 wB = GetBValue(cRGB);
3867 wMax = max(wR, max(wG, wB));
3868 wMin = min(wR, min(wG, wB));
3870 /* Luminosity */
3871 wLuminosity = ((wMax + wMin) * 240 + 255) / 510;
3873 if (wMax == wMin)
3875 /* Achromatic case */
3876 wSaturation = 0;
3877 /* Hue is now unrepresentable, but this is what native returns... */
3878 wHue = 160;
3880 else
3882 /* Chromatic case */
3883 int wDelta = wMax - wMin, wRNorm, wGNorm, wBNorm;
3885 /* Saturation */
3886 if (wLuminosity <= 120)
3887 wSaturation = ((wMax + wMin)/2 + wDelta * 240) / (wMax + wMin);
3888 else
3889 wSaturation = ((510 - wMax - wMin)/2 + wDelta * 240) / (510 - wMax - wMin);
3891 /* Hue */
3892 wRNorm = (wDelta/2 + wMax * 40 - wR * 40) / wDelta;
3893 wGNorm = (wDelta/2 + wMax * 40 - wG * 40) / wDelta;
3894 wBNorm = (wDelta/2 + wMax * 40 - wB * 40) / wDelta;
3896 if (wR == wMax)
3897 wHue = wBNorm - wGNorm;
3898 else if (wG == wMax)
3899 wHue = 80 + wRNorm - wBNorm;
3900 else
3901 wHue = 160 + wGNorm - wRNorm;
3902 if (wHue < 0)
3903 wHue += 240;
3904 else if (wHue > 240)
3905 wHue -= 240;
3907 if (pwHue)
3908 *pwHue = wHue;
3909 if (pwLuminance)
3910 *pwLuminance = wLuminosity;
3911 if (pwSaturation)
3912 *pwSaturation = wSaturation;
3915 /*************************************************************************
3916 * SHCreateShellPalette [SHLWAPI.@]
3918 HPALETTE WINAPI SHCreateShellPalette(HDC hdc)
3920 FIXME("stub\n");
3921 return CreateHalftonePalette(hdc);
3924 /*************************************************************************
3925 * SHGetInverseCMAP (SHLWAPI.@)
3927 * Get an inverse color map table.
3929 * PARAMS
3930 * lpCmap [O] Destination for color map
3931 * dwSize [I] Size of memory pointed to by lpCmap
3933 * RETURNS
3934 * Success: S_OK.
3935 * Failure: E_POINTER, If lpCmap is invalid.
3936 * E_INVALIDARG, If dwFlags is invalid
3937 * E_OUTOFMEMORY, If there is no memory available
3939 * NOTES
3940 * dwSize may only be CMAP_PTR_SIZE (4) or CMAP_SIZE (8192).
3941 * If dwSize = CMAP_PTR_SIZE, *lpCmap is set to the address of this DLL's
3942 * internal CMap.
3943 * If dwSize = CMAP_SIZE, lpCmap is filled with a copy of the data from
3944 * this DLL's internal CMap.
3946 HRESULT WINAPI SHGetInverseCMAP(LPDWORD dest, DWORD dwSize)
3948 if (dwSize == 4) {
3949 FIXME(" - returning bogus address for SHGetInverseCMAP\n");
3950 *dest = (DWORD)0xabba1249;
3951 return 0;
3953 FIXME("(%p, %#lx) stub\n", dest, dwSize);
3954 return 0;
3957 /*************************************************************************
3958 * SHIsLowMemoryMachine [SHLWAPI.@]
3960 * Determine if the current computer has low memory.
3962 * PARAMS
3963 * x [I] FIXME
3965 * RETURNS
3966 * TRUE if the users machine has 16 Megabytes of memory or less,
3967 * FALSE otherwise.
3969 BOOL WINAPI SHIsLowMemoryMachine (DWORD x)
3971 FIXME("(0x%08lx) stub\n", x);
3972 return FALSE;
3975 /*************************************************************************
3976 * GetMenuPosFromID [SHLWAPI.@]
3978 INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID)
3980 MENUITEMINFOA mi;
3981 INT nCount = GetMenuItemCount(hMenu), nIter = 0;
3983 while (nIter < nCount)
3985 mi.wID = 0;
3986 if (!GetMenuItemInfoA(hMenu, nIter, TRUE, &mi) && mi.wID == wID)
3987 return nIter;
3988 nIter++;
3990 return -1;
3993 /*************************************************************************
3994 * SHSkipJunction [SHLWAPI.@]
3996 * Determine if a bind context can be bound to an object
3998 * PARAMS
3999 * pbc [I] Bind context to check
4000 * pclsid [I] CLSID of object to be bound to
4002 * RETURNS
4003 * TRUE: If it is safe to bind
4004 * FALSE: If pbc is invalid or binding would not be safe
4007 BOOL WINAPI SHSkipJunction(IBindCtx *pbc, const CLSID *pclsid)
4009 static WCHAR szSkipBinding[] = { 'S','k','i','p',' ',
4010 'B','i','n','d','i','n','g',' ','C','L','S','I','D','\0' };
4011 BOOL bRet = FALSE;
4013 if (pbc)
4015 IUnknown* lpUnk;
4017 if (SUCCEEDED(IBindCtx_GetObjectParam(pbc, szSkipBinding, &lpUnk)))
4019 CLSID clsid;
4021 if (SUCCEEDED(SHLWAPI_175(lpUnk, &clsid)) &&
4022 IsEqualGUID(pclsid, &clsid))
4023 bRet = TRUE;
4025 IUnknown_Release(lpUnk);
4028 return bRet;