Reimplemented SHRegGetPathA/W, SHGetValueA/W, SHRegGetPathA/W.
[wine/multimedia.git] / dlls / shlwapi / ordinal.c
blobc107aae084c8f65afe44408ff0e212d768b0dcbc
1 /*
2 * SHLWAPI ordinal functions
4 * Copyright 1997 Marcus Meissner
5 * 1998 Jürgen Schmied
6 * 2001 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 #include <stdio.h>
24 #include <string.h>
26 #include "windef.h"
27 #include "winnls.h"
28 #include "winbase.h"
29 #include "ddeml.h"
30 #include "shlobj.h"
31 #include "shellapi.h"
32 #include "commdlg.h"
33 #include "wine/unicode.h"
34 #include "wine/obj_base.h"
35 #include "wine/obj_inplace.h"
36 #include "wine/obj_serviceprovider.h"
37 #include "wingdi.h"
38 #include "winreg.h"
39 #include "winuser.h"
40 #include "wine/debug.h"
41 #include "ordinal.h"
42 #include "shlwapi.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(shell);
46 extern HINSTANCE shlwapi_hInstance;
47 extern HMODULE SHLWAPI_hshell32;
48 extern HMODULE SHLWAPI_hwinmm;
49 extern HMODULE SHLWAPI_hcomdlg32;
50 extern HMODULE SHLWAPI_hmpr;
51 extern HMODULE SHLWAPI_hmlang;
52 extern HMODULE SHLWAPI_hversion;
54 extern DWORD SHLWAPI_ThreadRef_index;
56 typedef HANDLE HSHARED; /* Shared memory */
58 /* following is GUID for IObjectWithSite::SetSite -- see _174 */
59 static DWORD id1[4] = {0xfc4801a3, 0x11cf2ba9, 0xaa0029a2, 0x52733d00};
60 /* following is GUID for IPersistMoniker::GetClassID -- see _174 */
61 static DWORD id2[4] = {0x79eac9ee, 0x11cebaf9, 0xaa00828c, 0x0ba94b00};
63 /* The following schemes were identified in the native version of
64 * SHLWAPI.DLL version 5.50
66 typedef enum {
67 URL_SCHEME_INVALID = -1,
68 URL_SCHEME_UNKNOWN = 0,
69 URL_SCHEME_FTP,
70 URL_SCHEME_HTTP,
71 URL_SCHEME_GOPHER,
72 URL_SCHEME_MAILTO,
73 URL_SCHEME_NEWS,
74 URL_SCHEME_NNTP,
75 URL_SCHEME_TELNET,
76 URL_SCHEME_WAIS,
77 URL_SCHEME_FILE,
78 URL_SCHEME_MK,
79 URL_SCHEME_HTTPS,
80 URL_SCHEME_SHELL,
81 URL_SCHEME_SNEWS,
82 URL_SCHEME_LOCAL,
83 URL_SCHEME_JAVASCRIPT,
84 URL_SCHEME_VBSCRIPT,
85 URL_SCHEME_ABOUT,
86 URL_SCHEME_RES,
87 URL_SCHEME_MAXVALUE
88 } URL_SCHEME;
90 typedef struct {
91 URL_SCHEME scheme_number;
92 LPCSTR scheme_name;
93 } SHL_2_inet_scheme;
95 static const SHL_2_inet_scheme shlwapi_schemes[] = {
96 {URL_SCHEME_FTP, "ftp"},
97 {URL_SCHEME_HTTP, "http"},
98 {URL_SCHEME_GOPHER, "gopher"},
99 {URL_SCHEME_MAILTO, "mailto"},
100 {URL_SCHEME_NEWS, "news"},
101 {URL_SCHEME_NNTP, "nntp"},
102 {URL_SCHEME_TELNET, "telnet"},
103 {URL_SCHEME_WAIS, "wais"},
104 {URL_SCHEME_FILE, "file"},
105 {URL_SCHEME_MK, "mk"},
106 {URL_SCHEME_HTTPS, "https"},
107 {URL_SCHEME_SHELL, "shell"},
108 {URL_SCHEME_SNEWS, "snews"},
109 {URL_SCHEME_LOCAL, "local"},
110 {URL_SCHEME_JAVASCRIPT, "javascript"},
111 {URL_SCHEME_VBSCRIPT, "vbscript"},
112 {URL_SCHEME_ABOUT, "about"},
113 {URL_SCHEME_RES, "res"},
114 {0, 0}
117 /* function pointers for GET_FUNC macro; these need to be global because of gcc bug */
118 static LPITEMIDLIST (WINAPI *pSHBrowseForFolderW)(LPBROWSEINFOW);
119 static HRESULT (WINAPI *pConvertINetUnicodeToMultiByte)(LPDWORD,DWORD,LPCWSTR,LPINT,LPSTR,LPINT);
120 static BOOL (WINAPI *pPlaySoundW)(LPCWSTR, HMODULE, DWORD);
121 static DWORD (WINAPI *pSHGetFileInfoW)(LPCWSTR,DWORD,SHFILEINFOW*,UINT,UINT);
122 static UINT (WINAPI *pDragQueryFileW)(HDROP, UINT, LPWSTR, UINT);
123 static BOOL (WINAPI *pSHGetPathFromIDListW)(LPCITEMIDLIST, LPWSTR);
124 static BOOL (WINAPI *pShellExecuteExW)(LPSHELLEXECUTEINFOW);
125 static HICON (WINAPI *pSHFileOperationW)(LPSHFILEOPSTRUCTW);
126 static HICON (WINAPI *pExtractIconExW)(LPCWSTR, INT,HICON *,HICON *, UINT);
127 static BOOL (WINAPI *pSHGetNewLinkInfoW)(LPCWSTR, LPCWSTR, LPCWSTR, BOOL*, UINT);
128 static DWORD (WINAPI *pSHDefExtractIconW)(LPVOID, LPVOID, LPVOID, LPVOID, LPVOID, LPVOID); /* FIXME: Correct args */
129 static HICON (WINAPI *pExtractIconW)(HINSTANCE, LPCWSTR, UINT);
130 static BOOL (WINAPI *pGetSaveFileNameW)(LPOPENFILENAMEW);
131 static DWORD (WINAPI *pWNetRestoreConnectionW)(LPVOID, LPVOID); /* FIXME: Correct args */
132 static DWORD (WINAPI *pWNetGetLastErrorW)(LPVOID, LPVOID, LPVOID, LPVOID, LPVOID); /* FIXME: Correct args */
133 static BOOL (WINAPI *pPageSetupDlgW)(LPPAGESETUPDLGW);
134 static BOOL (WINAPI *pPrintDlgW)(LPPRINTDLGW);
135 static BOOL (WINAPI *pGetOpenFileNameW)(LPOPENFILENAMEW);
136 static HRESULT (WINAPI *pSHGetInstanceExplorer)(LPUNKNOWN *);
137 static DWORD (WINAPI *pGetFileVersionInfoSizeW)(LPCWSTR,LPDWORD);
138 static BOOL (WINAPI *pGetFileVersionInfoW)(LPCWSTR,DWORD,DWORD,LPVOID);
139 static WORD (WINAPI *pVerQueryValueW)(LPVOID,LPCWSTR,LPVOID*,UINT*);
142 NOTES: Most functions exported by ordinal seem to be superflous.
143 The reason for these functions to be there is to provide a wraper
144 for unicode functions to provide these functions on systems without
145 unicode functions eg. win95/win98. Since we have such functions we just
146 call these. If running Wine with native DLL's, some late bound calls may
147 fail. However, its better to implement the functions in the forward DLL
148 and recommend the builtin rather than reimplementing the calls here!
151 /*************************************************************************
152 * @ [SHLWAPI.1]
154 * Identifies the Internet "scheme" in the passed string. ASCII based.
155 * Also determines start and length of item after the ':'
157 DWORD WINAPI SHLWAPI_1 (LPCSTR x, UNKNOWN_SHLWAPI_1 *y)
159 DWORD cnt;
160 const SHL_2_inet_scheme *inet_pro;
162 if (y->size != 0x18) return E_INVALIDARG;
163 /* FIXME: leading white space generates error of 0x80041001 which
164 * is undefined
166 if (*x <= ' ') return 0x80041001;
167 cnt = 0;
168 y->sizep1 = 0;
169 y->ap1 = x;
170 while (*x) {
171 if (*x == ':') {
172 y->sizep1 = cnt;
173 cnt = -1;
174 y->ap2 = x+1;
175 break;
177 x++;
178 cnt++;
181 /* check for no scheme in string start */
182 /* (apparently schemes *must* be larger than a single character) */
183 if ((*x == '\0') || (y->sizep1 <= 1)) {
184 y->ap1 = 0;
185 return 0x80041001;
188 /* found scheme, set length of remainder */
189 y->sizep2 = lstrlenA(y->ap2);
191 /* see if known scheme and return indicator number */
192 y->fcncde = URL_SCHEME_UNKNOWN;
193 inet_pro = shlwapi_schemes;
194 while (inet_pro->scheme_name) {
195 if (!strncasecmp(inet_pro->scheme_name, y->ap1,
196 min(y->sizep1, lstrlenA(inet_pro->scheme_name)))) {
197 y->fcncde = inet_pro->scheme_number;
198 break;
200 inet_pro++;
202 return S_OK;
205 /*************************************************************************
206 * @ [SHLWAPI.2]
208 * Identifies the Internet "scheme" in the passed string. UNICODE based.
209 * Also determines start and length of item after the ':'
211 DWORD WINAPI SHLWAPI_2 (LPCWSTR x, UNKNOWN_SHLWAPI_2 *y)
213 DWORD cnt;
214 const SHL_2_inet_scheme *inet_pro;
215 LPSTR cmpstr;
216 INT len;
218 if (y->size != 0x18) return E_INVALIDARG;
219 /* FIXME: leading white space generates error of 0x80041001 which
220 * is undefined
222 if (*x <= L' ') return 0x80041001;
223 cnt = 0;
224 y->sizep1 = 0;
225 y->ap1 = x;
226 while (*x) {
227 if (*x == L':') {
228 y->sizep1 = cnt;
229 cnt = -1;
230 y->ap2 = x+1;
231 break;
233 x++;
234 cnt++;
237 /* check for no scheme in string start */
238 /* (apparently schemes *must* be larger than a single character) */
239 if ((*x == L'\0') || (y->sizep1 <= 1)) {
240 y->ap1 = 0;
241 return 0x80041001;
244 /* found scheme, set length of remainder */
245 y->sizep2 = lstrlenW(y->ap2);
247 /* see if known scheme and return indicator number */
248 len = WideCharToMultiByte(0, 0, y->ap1, y->sizep1, 0, 0, 0, 0);
249 cmpstr = (LPSTR)HeapAlloc(GetProcessHeap(), 0, len+1);
250 WideCharToMultiByte(0, 0, y->ap1, y->sizep1, cmpstr, len+1, 0, 0);
251 y->fcncde = URL_SCHEME_UNKNOWN;
252 inet_pro = shlwapi_schemes;
253 while (inet_pro->scheme_name) {
254 if (!strncasecmp(inet_pro->scheme_name, cmpstr,
255 min(len, lstrlenA(inet_pro->scheme_name)))) {
256 y->fcncde = inet_pro->scheme_number;
257 break;
259 inet_pro++;
261 HeapFree(GetProcessHeap(), 0, cmpstr);
262 return S_OK;
265 /*************************************************************************
266 * @ [SHLWAPI.3]
268 * Determine if a file exists locally and is of an executable type.
270 * PARAMS
271 * lpszFile [O] File to search for
272 * dwWhich [I] Type of executable to search for
274 * RETURNS
275 * TRUE If the file was found. lpszFile contains the file name.
276 * FALSE Otherwise.
278 * NOTES
279 * lpszPath is modified in place and must be at least MAX_PATH in length.
280 * If the function returns FALSE, the path is modified to its orginal state.
281 * If the given path contains an extension or dwWhich is 0, executable
282 * extensions are not checked.
284 * Ordinals 3-6 are a classic case of MS exposing limited functionality to
285 * users (here through PathFindOnPath) and keeping advanced functionality for
286 * their own developers exclusive use. Monopoly, anyone?
288 BOOL WINAPI SHLWAPI_3(LPSTR lpszFile,DWORD dwWhich)
290 return SHLWAPI_PathFindLocalExeA(lpszFile,dwWhich);
293 /*************************************************************************
294 * @ [SHLWAPI.4]
296 * Unicode version of SHLWAPI_3.
298 BOOL WINAPI SHLWAPI_4(LPWSTR lpszFile,DWORD dwWhich)
300 return SHLWAPI_PathFindLocalExeW(lpszFile,dwWhich);
303 /*************************************************************************
304 * @ [SHLWAPI.5]
306 * Search a range of paths for a specific type of executable.
308 * PARAMS
309 * lpszFile [O] File to search for
310 * lppszOtherDirs [I] Other directories to look in
311 * dwWhich [I] Type of executable to search for
313 * RETURNS
314 * Success: TRUE. The path to the executable is stored in sFile.
315 * Failure: FALSE. The path to the executable is unchanged.
317 BOOL WINAPI SHLWAPI_5(LPSTR lpszFile,LPCSTR *lppszOtherDirs,DWORD dwWhich)
319 return SHLWAPI_PathFindOnPathExA(lpszFile,lppszOtherDirs,dwWhich);
322 /*************************************************************************
323 * @ [SHLWAPI.6]
325 * Unicode version of SHLWAPI_5.
327 BOOL WINAPI SHLWAPI_6(LPWSTR lpszFile,LPCWSTR *lppszOtherDirs,DWORD dwWhich)
329 return SHLWAPI_PathFindOnPathExW(lpszFile,lppszOtherDirs,dwWhich);
332 /*************************************************************************
333 * SHLWAPI_DupSharedHandle
335 * Internal implemetation of SHLWAPI_11.
337 static
338 HSHARED WINAPI SHLWAPI_DupSharedHandle(HSHARED hShared, DWORD dwDstProcId,
339 DWORD dwSrcProcId, DWORD dwAccess,
340 DWORD dwOptions)
342 HANDLE hDst, hSrc;
343 DWORD dwMyProcId = GetCurrentProcessId();
344 HSHARED hRet = (HSHARED)NULL;
346 TRACE("(%p,%ld,%ld,%08lx,%08lx)\n", (PVOID)hShared, dwDstProcId, dwSrcProcId,
347 dwAccess, dwOptions);
349 /* Get dest process handle */
350 if (dwDstProcId == dwMyProcId)
351 hDst = GetCurrentProcess();
352 else
353 hDst = OpenProcess(PROCESS_DUP_HANDLE, 0, dwDstProcId);
355 if (hDst)
357 /* Get src process handle */
358 if (dwSrcProcId == dwMyProcId)
359 hSrc = GetCurrentProcess();
360 else
361 hSrc = OpenProcess(PROCESS_DUP_HANDLE, 0, dwSrcProcId);
363 if (hSrc)
365 /* Make handle available to dest process */
366 if (!DuplicateHandle(hDst, (HANDLE)hShared, hSrc, &hRet,
367 dwAccess, 0, dwOptions | DUPLICATE_SAME_ACCESS))
368 hRet = (HSHARED)NULL;
370 if (dwSrcProcId != dwMyProcId)
371 CloseHandle(hSrc);
374 if (dwDstProcId != dwMyProcId)
375 CloseHandle(hDst);
378 TRACE("Returning handle %p\n", (PVOID)hRet);
379 return hRet;
382 /*************************************************************************
383 * @ [SHLWAPI.7]
385 * Create a block of sharable memory and initialise it with data.
387 * PARAMS
388 * dwProcId [I] ID of process owning data
389 * lpvData [I] Pointer to data to write
390 * dwSize [I] Size of data
392 * RETURNS
393 * Success: A shared memory handle
394 * Failure: NULL
396 * NOTES
397 * Ordinals 7-11 provide a set of calls to create shared memory between a
398 * group of processes. The shared memory is treated opaquely in that its size
399 * is not exposed to clients who map it. This is accomplished by storing
400 * the size of the map as the first DWORD of mapped data, and then offsetting
401 * the view pointer returned by this size.
403 * SHLWAPI_7/SHLWAPI_10 - Create/Destroy the shared memory handle
404 * SHLWAPI_8/SHLWAPI_9 - Get/Release a pointer to the shared data
405 * SHLWAPI_11 - Helper function; Duplicate cross-process handles
407 HSHARED WINAPI SHLWAPI_7 (DWORD dwProcId, DWORD dwSize, LPCVOID lpvData)
409 HANDLE hMap;
410 LPVOID pMapped;
411 HSHARED hRet = (HSHARED)NULL;
413 TRACE("(%ld,%p,%ld)\n", dwProcId, lpvData, dwSize);
415 /* Create file mapping of the correct length */
416 hMap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, FILE_MAP_READ, 0,
417 dwSize + sizeof(dwSize), NULL);
418 if (!hMap)
419 return hRet;
421 /* Get a view in our process address space */
422 pMapped = MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
424 if (pMapped)
426 /* Write size of data, followed by the data, to the view */
427 *((DWORD*)pMapped) = dwSize;
428 if (dwSize)
429 memcpy((char *) pMapped + sizeof(dwSize), lpvData, dwSize);
431 /* Release view. All further views mapped will be opaque */
432 UnmapViewOfFile(pMapped);
433 hRet = SHLWAPI_DupSharedHandle((HSHARED)hMap, dwProcId,
434 GetCurrentProcessId(), FILE_MAP_ALL_ACCESS,
435 DUPLICATE_SAME_ACCESS);
438 CloseHandle(hMap);
439 return hRet;
442 /*************************************************************************
443 * @ [SHLWAPI.8]
445 * Get a pointer to a block of shared memory from a shared memory handle.
447 * PARAMS
448 * hShared [I] Shared memory handle
449 * dwProcId [I] ID of process owning hShared
451 * RETURNS
452 * Success: A pointer to the shared memory
453 * Failure: NULL
455 * NOTES
456 * See SHLWAPI_7.
458 PVOID WINAPI SHLWAPI_8 (HSHARED hShared, DWORD dwProcId)
460 HSHARED hDup;
461 LPVOID pMapped;
463 TRACE("(%p %ld)\n", (PVOID)hShared, dwProcId);
465 /* Get handle to shared memory for current process */
466 hDup = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
467 FILE_MAP_ALL_ACCESS, 0);
468 /* Get View */
469 pMapped = MapViewOfFile((HANDLE)hDup, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
470 CloseHandle(hDup);
472 if (pMapped)
473 return (char *) pMapped + sizeof(DWORD); /* Hide size */
474 return NULL;
477 /*************************************************************************
478 * @ [SHLWAPI.9]
480 * Release a pointer to a block of shared memory.
482 * PARAMS
483 * lpView [I] Shared memory pointer
485 * RETURNS
486 * Success: TRUE
487 * Failure: FALSE
489 * NOTES
490 * See SHLWAPI_7.
492 BOOL WINAPI SHLWAPI_9 (LPVOID lpView)
494 TRACE("(%p)\n", lpView);
495 return UnmapViewOfFile((char *) lpView - sizeof(DWORD)); /* Include size */
498 /*************************************************************************
499 * @ [SHLWAPI.10]
501 * Destroy a block of sharable memory.
503 * PARAMS
504 * hShared [I] Shared memory handle
505 * dwProcId [I] ID of process owning hShared
507 * RETURNS
508 * Success: TRUE
509 * Failure: FALSE
511 * NOTES
512 * See SHLWAPI_7.
514 BOOL WINAPI SHLWAPI_10 (HSHARED hShared, DWORD dwProcId)
516 HSHARED hClose;
518 TRACE("(%p %ld)\n", (PVOID)hShared, dwProcId);
520 /* Get a copy of the handle for our process, closing the source handle */
521 hClose = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
522 FILE_MAP_ALL_ACCESS,DUPLICATE_CLOSE_SOURCE);
523 /* Close local copy */
524 return CloseHandle((HANDLE)hClose);
527 /*************************************************************************
528 * @ [SHLWAPI.11]
530 * Copy a sharable memory handle from one process to another.
532 * PARAMS
533 * hShared [I] Shared memory handle to duplicate
534 * dwDstProcId [I] ID of the process wanting the duplicated handle
535 * dwSrcProcId [I] ID of the process owning hShared
536 * dwAccess [I] Desired DuplicateHandle access
537 * dwOptions [I] Desired DuplicateHandle options
539 * RETURNS
540 * Success: A handle suitable for use by the dwDstProcId process.
541 * Failure: A NULL handle.
543 * NOTES
544 * See SHLWAPI_7.
546 HSHARED WINAPI SHLWAPI_11(HSHARED hShared, DWORD dwDstProcId, DWORD dwSrcProcId,
547 DWORD dwAccess, DWORD dwOptions)
549 HSHARED hRet;
551 hRet = SHLWAPI_DupSharedHandle(hShared, dwDstProcId, dwSrcProcId,
552 dwAccess, dwOptions);
553 return hRet;
556 /*************************************************************************
557 * @ [SHLWAPI.13]
558 * (Used by IE4 during startup)
560 HRESULT WINAPI SHLWAPI_13 (
561 LPVOID w,
562 LPVOID x)
564 FIXME("(%p %p)stub\n",w,x);
565 return 1;
566 #if 0
567 /* pseudo code extracted from relay trace */
568 RegOpenKeyA(HKLM, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Aceepted Documents", &newkey);
569 ret = 0;
570 i = 0;
571 size = 0;
572 while(!ret) {
573 ret = RegEnumValueA(newkey, i, a1, a2, 0, a3, 0, 0);
574 size += ???;
575 i++;
577 b1 = LocalAlloc(0x40, size);
578 ret = 0;
579 i = 0;
580 while(!ret) {
581 ret = RegEnumValueA(newkey, i, a1, a2, 0, a3, a4, a5);
582 RegisterClipBoardFormatA(a4);
583 i++;
585 hwnd1 = GetModuleHandleA("URLMON.DLL");
586 proc = GetProcAddress(hwnd1, "CreateFormatEnumerator");
587 HeapAlloc(??, 0, 0x14);
588 HeapAlloc(??, 0, 0x50);
589 LocalAlloc(0x40, 0x78);
590 /* FIXME: bad string below */
591 lstrlenW(L"{D0FCA420-D3F5-11CF-B211-00AA004AE837}");
592 StrCpyW(a6, L"{D0FCA420-D3F5-11CF-B211-00AA004AE837}");
594 GetTickCount();
595 IsBadReadPtr(c1 = 0x403fd210,4);
596 InterlockedIncrement(c1+4);
597 LocalFree(b1);
598 RegCloseKey(newkey);
599 IsBadReadPtr(c1 = 0x403fd210,4);
600 InterlockedIncrement(c1+4);
602 HeapAlloc(40350000,00000000,00000014) retval=403fd0a8;
603 HeapAlloc(40350000,00000000,00000050) retval=403feb44;
604 hwnd1 = GetModuleHandleA("URLMON.DLL");
605 proc = GetProcAddress(hwnd1, "RegisterFormatEnumerator");
606 /* 0x1a40c88c is in URLMON.DLL just before above proc
607 * content is L"_EnumFORMATETC_"
608 * label is d1
610 IsBadReadPtr(d1 = 0x1a40c88c,00000002);
611 lstrlenW(d1);
612 lstrlenW(d1);
613 HeapAlloc(40350000,00000000,0000001e) retval=403fed44;
614 IsBadReadPtr(d2 = 0x403fd0a8,00000004);
615 InterlockedIncrement(d2+4);
616 IsBadReadPtr(d2 = 0x403fd0a8,00000004);
617 InterlockedDecrement(d2+4);
618 IsBadReadPtr(c1,00000004);
619 InterlockedDecrement(c1+4);
620 IsBadReadPtr(c1,00000004);
621 InterlockedDecrement(c1+4);
623 #endif
626 /*************************************************************************
627 * @ [SHLWAPI.14]
629 * Function:
630 * Retrieves IE "AcceptLanguage" value from registry. ASCII mode.
633 HRESULT WINAPI SHLWAPI_14 (
634 LPSTR langbuf,
635 LPDWORD buflen)
637 CHAR *mystr;
638 DWORD mystrlen, mytype;
639 HKEY mykey;
640 LCID mylcid;
642 mystrlen = (*buflen > 6) ? *buflen : 6;
643 mystr = (CHAR*)HeapAlloc(GetProcessHeap(),
644 HEAP_ZERO_MEMORY, mystrlen);
645 RegOpenKeyA(HKEY_CURRENT_USER,
646 "Software\\Microsoft\\Internet Explorer\\International",
647 &mykey);
648 if (RegQueryValueExA(mykey, "AcceptLanguage",
649 0, &mytype, mystr, &mystrlen)) {
650 /* Did not find value */
651 mylcid = GetUserDefaultLCID();
652 /* somehow the mylcid translates into "en-us"
653 * this is similar to "LOCALE_SABBREVLANGNAME"
654 * which could be gotten via GetLocaleInfo.
655 * The only problem is LOCALE_SABBREVLANGUAGE" is
656 * a 3 char string (first 2 are country code and third is
657 * letter for "sublanguage", which does not come close to
658 * "en-us"
660 lstrcpyA(mystr, "en-us");
661 mystrlen = lstrlenA(mystr);
663 else {
664 /* handle returned string */
665 FIXME("missing code\n");
667 if (mystrlen > *buflen)
668 lstrcpynA(langbuf, mystr, *buflen);
669 else {
670 lstrcpyA(langbuf, mystr);
671 *buflen = lstrlenA(langbuf);
673 RegCloseKey(mykey);
674 HeapFree(GetProcessHeap(), 0, mystr);
675 TRACE("language is %s\n", debugstr_a(langbuf));
676 return 0;
679 /*************************************************************************
680 * @ [SHLWAPI.15]
682 * Function:
683 * Retrieves IE "AcceptLanguage" value from registry. UNICODE mode.
686 HRESULT WINAPI SHLWAPI_15 (
687 LPWSTR langbuf,
688 LPDWORD buflen)
690 CHAR *mystr;
691 DWORD mystrlen, mytype;
692 HKEY mykey;
693 LCID mylcid;
695 mystrlen = (*buflen > 6) ? *buflen : 6;
696 mystr = (CHAR*)HeapAlloc(GetProcessHeap(),
697 HEAP_ZERO_MEMORY, mystrlen);
698 RegOpenKeyA(HKEY_CURRENT_USER,
699 "Software\\Microsoft\\Internet Explorer\\International",
700 &mykey);
701 if (RegQueryValueExA(mykey, "AcceptLanguage",
702 0, &mytype, mystr, &mystrlen)) {
703 /* Did not find value */
704 mylcid = GetUserDefaultLCID();
705 /* somehow the mylcid translates into "en-us"
706 * this is similar to "LOCALE_SABBREVLANGNAME"
707 * which could be gotten via GetLocaleInfo.
708 * The only problem is LOCALE_SABBREVLANGUAGE" is
709 * a 3 char string (first 2 are country code and third is
710 * letter for "sublanguage", which does not come close to
711 * "en-us"
713 lstrcpyA(mystr, "en-us");
714 mystrlen = lstrlenA(mystr);
716 else {
717 /* handle returned string */
718 FIXME("missing code\n");
720 RegCloseKey(mykey);
721 *buflen = MultiByteToWideChar(0, 0, mystr, -1, langbuf, (*buflen)-1);
722 HeapFree(GetProcessHeap(), 0, mystr);
723 TRACE("language is %s\n", debugstr_w(langbuf));
724 return 0;
727 /*************************************************************************
728 * @ [SHLWAPI.16]
730 HRESULT WINAPI SHLWAPI_16 (
731 LPVOID w,
732 LPVOID x,
733 LPVOID y,
734 LPWSTR z)
736 FIXME("(%p %p %p %p)stub\n",w,x,y,z);
737 return 0xabba1252;
740 /*************************************************************************
741 * @ [SHLWAPI.18]
743 * w is pointer to address of callback routine
744 * x is pointer to LPVOID to receive address of locally allocated
745 * space size 0x14
746 * return is 0 (unless out of memory???)
748 * related to _19, _21 and _22 below
749 * only seen invoked by SHDOCVW
751 LONG WINAPI SHLWAPI_18 (
752 LPVOID *w,
753 LPVOID x)
755 FIXME("(%p %p)stub\n",w,x);
756 *((LPDWORD)x) = 0;
757 return 0;
760 /*************************************************************************
761 * @ [SHLWAPI.19]
763 * w is address of allocated memory from _21
764 * return is 0 (unless out of memory???)
766 * related to _18, _21 and _22 below
767 * only seen invoked by SHDOCVW
769 LONG WINAPI SHLWAPI_19 (
770 LPVOID w)
772 FIXME("(%p) stub\n",w);
773 return 0;
776 /*************************************************************************
777 * @ [SHLWAPI.21]
779 * w points to space allocated via .18 above
780 * LocalSize is done on it (retrieves 18)
781 * LocalReAlloc is done on it to size 8 with LMEM_MOVEABLE & LMEM_ZEROINIT
782 * x values seen 0xa0000005
783 * returns 1
785 * relates to _18, _19 and _22 above and below
786 * only seen invoked by SHDOCVW
788 LONG WINAPI SHLWAPI_21 (
789 LPVOID w,
790 DWORD x)
792 FIXME("(%p %lx)stub\n",w,x);
793 return 1;
796 /*************************************************************************
797 * @ [SHLWAPI.22]
799 * return is 'w' value seen in x is 0xa0000005
801 * relates to _18, _19 and _21 above
802 * only seen invoked by SHDOCVW
804 LPVOID WINAPI SHLWAPI_22 (
805 LPVOID w,
806 DWORD x)
808 FIXME("(%p %lx)stub\n",w,x);
809 return w;
812 /*************************************************************************
813 * @ [SHLWAPI.23]
815 * NOTES
816 * converts a guid to a string
817 * returns strlen(str)
819 DWORD WINAPI SHLWAPI_23 (
820 REFGUID guid, /* [in] clsid */
821 LPSTR str, /* [out] buffer */
822 INT cmax) /* [in] size of buffer */
824 char xguid[40];
826 sprintf( xguid, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
827 guid->Data1, guid->Data2, guid->Data3,
828 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
829 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
830 TRACE("(%s %p 0x%08x)stub\n", xguid, str, cmax);
831 if (strlen(xguid)>=cmax) return 0;
832 strcpy(str,xguid);
833 return strlen(xguid) + 1;
836 /*************************************************************************
837 * @ [SHLWAPI.24]
839 * NOTES
840 * converts a guid to a string
841 * returns strlen(str)
843 DWORD WINAPI SHLWAPI_24 (
844 REFGUID guid, /* [in] clsid */
845 LPWSTR str, /* [out] buffer */
846 INT cmax) /* [in] size of buffer */
848 char xguid[40];
850 sprintf( xguid, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
851 guid->Data1, guid->Data2, guid->Data3,
852 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
853 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
854 return MultiByteToWideChar( CP_ACP, 0, xguid, -1, str, cmax );
857 /*************************************************************************
858 * @ [SHLWAPI.25]
860 * Seems to be iswalpha
862 BOOL WINAPI SHLWAPI_25(WCHAR wc)
864 return (get_char_typeW(wc) & C1_ALPHA) != 0;
867 /*************************************************************************
868 * @ [SHLWAPI.26]
870 * Seems to be iswupper
872 BOOL WINAPI SHLWAPI_26(WCHAR wc)
874 return (get_char_typeW(wc) & C1_UPPER) != 0;
877 /*************************************************************************
878 * @ [SHLWAPI.27]
880 * Seems to be iswlower
882 BOOL WINAPI SHLWAPI_27(WCHAR wc)
884 return (get_char_typeW(wc) & C1_LOWER) != 0;
887 /*************************************************************************
888 * @ [SHLWAPI.28]
890 * Seems to be iswalnum
892 BOOL WINAPI SHLWAPI_28(WCHAR wc)
894 return (get_char_typeW(wc) & (C1_ALPHA|C1_DIGIT)) != 0;
897 /*************************************************************************
898 * @ [SHLWAPI.29]
900 * Seems to be iswspace
902 BOOL WINAPI SHLWAPI_29(WCHAR wc)
904 return (get_char_typeW(wc) & C1_SPACE) != 0;
907 /*************************************************************************
908 * @ [SHLWAPI.30]
910 * Seems to be iswblank
912 BOOL WINAPI SHLWAPI_30(WCHAR wc)
914 return (get_char_typeW(wc) & C1_BLANK) != 0;
917 /*************************************************************************
918 * @ [SHLWAPI.31]
920 * Seems to be iswpunct
922 BOOL WINAPI SHLWAPI_31(WCHAR wc)
924 return (get_char_typeW(wc) & C1_PUNCT) != 0;
927 /*************************************************************************
928 * @ [SHLWAPI.32]
930 * Seems to be iswcntrl
932 BOOL WINAPI SHLWAPI_32(WCHAR wc)
934 return (get_char_typeW(wc) & C1_CNTRL) != 0;
937 /*************************************************************************
938 * @ [SHLWAPI.33]
940 * Seems to be iswdigit
942 BOOL WINAPI SHLWAPI_33(WCHAR wc)
944 return (get_char_typeW(wc) & C1_DIGIT) != 0;
947 /*************************************************************************
948 * @ [SHLWAPI.34]
950 * Seems to be iswxdigit
952 BOOL WINAPI SHLWAPI_34(WCHAR wc)
954 return (get_char_typeW(wc) & C1_XDIGIT) != 0;
957 /*************************************************************************
958 * @ [SHLWAPI.35]
961 BOOL WINAPI SHLWAPI_35(LPVOID p1, DWORD dw2, LPVOID p3)
963 FIXME("(%p, 0x%08lx, %p): stub\n", p1, dw2, p3);
964 return TRUE;
967 /*************************************************************************
968 * @ [SHLWAPI.36]
971 BOOL WINAPI SHLWAPI_36(HMENU h1, UINT ui2, UINT h3, LPCWSTR p4)
973 TRACE("(0x%08x, 0x%08x, 0x%08x, %s): stub\n",
974 h1, ui2, h3, debugstr_w(p4));
975 return AppendMenuW(h1, ui2, h3, p4);
978 /*************************************************************************
979 * @ [SHLWAPI.74]
981 * Get the text from a given dialog item.
983 INT WINAPI SHLWAPI_74(HWND hWnd, INT nItem, LPWSTR lpsDest,INT nDestLen)
985 HWND hItem = GetDlgItem(hWnd, nItem);
987 if (hItem)
988 return GetWindowTextW(hItem, lpsDest, nDestLen);
989 if (nDestLen)
990 *lpsDest = (WCHAR)'\0';
991 return 0;
994 /*************************************************************************
995 * @ [SHLWAPI.151]
996 * Function: Compare two ASCII strings for "len" bytes.
997 * Returns: *str1-*str2 (case sensitive)
999 DWORD WINAPI SHLWAPI_151(LPSTR str1, LPSTR str2, INT len)
1001 return strncmp( str1, str2, len );
1004 /*************************************************************************
1005 * @ [SHLWAPI.152]
1007 * Function: Compare two WIDE strings for "len" bytes.
1008 * Returns: *str1-*str2 (case sensitive)
1010 DWORD WINAPI SHLWAPI_152(LPWSTR str1, LPWSTR str2, INT len)
1012 return strncmpW( str1, str2, len );
1015 /*************************************************************************
1016 * @ [SHLWAPI.153]
1017 * Function: Compare two ASCII strings for "len" bytes via caseless compare.
1018 * Returns: *str1-*str2 (case insensitive)
1020 DWORD WINAPI SHLWAPI_153(LPSTR str1, LPSTR str2, DWORD len)
1022 return strncasecmp( str1, str2, len );
1025 /*************************************************************************
1026 * @ [SHLWAPI.154]
1028 * Function: Compare two WIDE strings for "len" bytes via caseless compare.
1029 * Returns: *str1-*str2 (case insensitive)
1031 DWORD WINAPI SHLWAPI_154(LPWSTR str1, LPWSTR str2, DWORD len)
1033 return strncmpiW( str1, str2, len );
1036 /*************************************************************************
1037 * @ [SHLWAPI.155]
1039 * Case sensitive string compare (ASCII). Does not SetLastError().
1041 DWORD WINAPI SHLWAPI_155 ( LPSTR str1, LPSTR str2)
1043 return strcmp(str1, str2);
1046 /*************************************************************************
1047 * @ [SHLWAPI.156]
1049 * Case sensitive string compare. Does not SetLastError().
1051 DWORD WINAPI SHLWAPI_156 ( LPWSTR str1, LPWSTR str2)
1053 return strcmpW( str1, str2 );
1056 /*************************************************************************
1057 * @ [SHLWAPI.158]
1059 * Case insensitive string compare. Does not SetLastError(). ??
1061 DWORD WINAPI SHLWAPI_158 ( LPWSTR str1, LPWSTR str2)
1063 return strcmpiW( str1, str2 );
1066 /*************************************************************************
1067 * @ [SHLWAPI.162]
1069 * Ensure a multibyte character string doesn't end in a hanging lead byte.
1071 DWORD WINAPI SHLWAPI_162(LPSTR lpStr, DWORD size)
1073 if (lpStr && size)
1075 LPSTR lastByte = lpStr + size - 1;
1077 while(lpStr < lastByte)
1078 lpStr += IsDBCSLeadByte(*lpStr) ? 2 : 1;
1080 if(lpStr == lastByte && IsDBCSLeadByte(*lpStr))
1082 *lpStr = '\0';
1083 size--;
1085 return size;
1087 return 0;
1090 /*************************************************************************
1091 * @ [SHLWAPI.164]
1093 DWORD WINAPI SHLWAPI_164 (
1094 LPVOID u,
1095 LPVOID v,
1096 LPVOID w,
1097 LPVOID x,
1098 LPVOID y,
1099 LPVOID z)
1101 TRACE("(%p %p %p %p %p %p) stub\n",u,v,w,x,y,z);
1102 return 0x80004002; /* E_NOINTERFACE */
1105 /*************************************************************************
1106 * @ [SHLWAPI.165]
1108 * SetWindowLongA with mask.
1110 LONG WINAPI SHLWAPI_165(HWND hwnd, INT offset, UINT wFlags, UINT wMask)
1112 LONG ret = GetWindowLongA(hwnd, offset);
1113 UINT newFlags = (wFlags & wMask) | (ret & ~wFlags);
1115 if (newFlags != ret)
1116 ret = SetWindowLongA(hwnd, offset, newFlags);
1117 return ret;
1120 /*************************************************************************
1121 * @ [SHLWAPI.169]
1123 * Do IUnknown::Release on passed object.
1125 DWORD WINAPI SHLWAPI_169 (IUnknown ** lpUnknown)
1127 IUnknown *temp;
1129 TRACE("(%p)\n",lpUnknown);
1130 if(!lpUnknown || !*((LPDWORD)lpUnknown)) return 0;
1131 temp = *lpUnknown;
1132 *lpUnknown = NULL;
1133 TRACE("doing Release\n");
1134 return IUnknown_Release(temp);
1137 /*************************************************************************
1138 * @ [SHLWAPI.170]
1140 * Skip URL '//' sequence.
1142 LPCSTR WINAPI SHLWAPI_170(LPCSTR lpszSrc)
1144 if (lpszSrc && lpszSrc[0] == '/' && lpszSrc[1] == '/')
1145 lpszSrc += 2;
1146 return lpszSrc;
1149 /*************************************************************************
1150 * @ [SHLWAPI.172]
1151 * Get window handle of OLE object
1153 DWORD WINAPI SHLWAPI_172 (
1154 IUnknown *y, /* [in] OLE object interface */
1155 LPHWND z) /* [out] location to put window handle */
1157 DWORD ret;
1158 IUnknown *pv;
1160 TRACE("(%p %p)\n",y,z);
1161 if (!y) return E_FAIL;
1163 if ((ret = IUnknown_QueryInterface(y, &IID_IOleWindow,(LPVOID *)&pv)) < 0) {
1164 /* error */
1165 return ret;
1167 ret = IOleWindow_GetWindow((IOleWindow *)pv, z);
1168 IUnknown_Release(pv);
1169 TRACE("result hwnd=%08x\n", *z);
1170 return ret;
1173 /*************************************************************************
1174 * @ [SHLWAPI.174]
1176 * Seems to do call either IObjectWithSite::SetSite or
1177 * IPersistMoniker::GetClassID. But since we do not implement either
1178 * of those classes in our headers, we will fake it out.
1180 DWORD WINAPI SHLWAPI_174(
1181 IUnknown *p1, /* [in] OLE object */
1182 LPVOID *p2) /* [out] ptr to result of either GetClassID
1183 or SetSite call. */
1185 DWORD ret, aa;
1187 if (!p1) return E_FAIL;
1189 /* see if SetSite interface exists for IObjectWithSite object */
1190 ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id1, (LPVOID *)&p1);
1191 TRACE("first IU_QI ret=%08lx, p1=%p\n", ret, p1);
1192 if (ret) {
1194 /* see if GetClassId interface exists for IPersistMoniker object */
1195 ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id2, (LPVOID *)&aa);
1196 TRACE("second IU_QI ret=%08lx, aa=%08lx\n", ret, aa);
1197 if (ret) return ret;
1199 /* fake a GetClassId call */
1200 ret = IOleWindow_GetWindow((IOleWindow *)aa, (HWND*)p2);
1201 TRACE("second IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1202 *(LPDWORD)p2);
1203 IUnknown_Release((IUnknown *)aa);
1205 else {
1206 /* fake a SetSite call */
1207 ret = IOleWindow_GetWindow((IOleWindow *)p1, (HWND*)p2);
1208 TRACE("first IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1209 *(LPDWORD)p2);
1210 IUnknown_Release((IUnknown *)p1);
1212 return ret;
1215 /*************************************************************************
1216 * @ [SHLWAPI.175]
1218 * NOTE:
1219 * Param1 can be an IShellFolder Object
1221 HRESULT WINAPI SHLWAPI_175 (LPVOID x, LPVOID y)
1223 FIXME("(%p %p) stub\n", x,y);
1224 return E_FAIL;
1226 /*************************************************************************
1227 * @ [SHLWAPI.176]
1229 * Function appears to be interface to IServiceProvider::QueryService
1231 * NOTE:
1232 * returns E_NOINTERFACE
1233 * E_FAIL if w == 0
1234 * S_OK if _219 called successfully
1236 DWORD WINAPI SHLWAPI_176 (
1237 IUnknown* unk, /* [in] object to give Service Provider */
1238 REFGUID sid, /* [in] Service ID */
1239 REFIID riid, /* [in] Function requested */
1240 LPVOID *z) /* [out] place to save interface pointer */
1242 DWORD ret;
1243 LPVOID aa;
1244 *z = 0;
1245 if (!unk) return E_FAIL;
1246 ret = IUnknown_QueryInterface(unk, &IID_IServiceProvider, &aa);
1247 TRACE("did IU_QI retval=%08lx, aa=%p\n", ret, aa);
1248 if (ret) return ret;
1249 ret = IServiceProvider_QueryService((IServiceProvider *)aa, sid, riid,
1250 (void **)z);
1251 TRACE("did ISP_QS retval=%08lx, *z=%p\n", ret, (LPVOID)*z);
1252 IUnknown_Release((IUnknown*)aa);
1253 return ret;
1256 /*************************************************************************
1257 * @ [SHLWAPI.181]
1259 * Enable or disable a menu item.
1261 UINT WINAPI SHLWAPI_181(HMENU hMenu, UINT wItemID, BOOL bEnable)
1263 return EnableMenuItem(hMenu, wItemID, bEnable ? MF_ENABLED : MF_GRAYED);
1266 /*************************************************************************
1267 * @ [SHLWAPI.183]
1269 * Register a window class if it isn't already.
1271 DWORD WINAPI SHLWAPI_183(WNDCLASSA *wndclass)
1273 WNDCLASSA wca;
1274 if (GetClassInfoA(wndclass->hInstance, wndclass->lpszClassName, &wca))
1275 return TRUE;
1276 return (DWORD)RegisterClassA(wndclass);
1279 /*************************************************************************
1280 * @ [SHLWAPI.193]
1282 DWORD WINAPI SHLWAPI_193 ()
1284 HDC hdc;
1285 DWORD ret;
1287 TRACE("()\n");
1289 hdc = GetDC(0);
1290 ret = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
1291 ReleaseDC(0, hdc);
1292 return ret;
1295 /*************************************************************************
1296 * @ [SHLWAPI.199]
1298 * Copy interface pointer
1300 DWORD WINAPI SHLWAPI_199 (
1301 IUnknown **dest, /* [out] pointer to copy of interface ptr */
1302 IUnknown *src) /* [in] interface pointer */
1304 TRACE("(%p %p)\n",dest,src);
1305 if (*dest != src) {
1306 if (*dest)
1307 IUnknown_Release(*dest);
1308 if (src) {
1309 IUnknown_AddRef(src);
1310 *dest = src;
1313 return 4;
1316 /*************************************************************************
1317 * @ [SHLWAPI.208]
1319 * Some sort of memory management process - associated with _210
1321 DWORD WINAPI SHLWAPI_208 (
1322 DWORD a,
1323 DWORD b,
1324 LPVOID c,
1325 LPVOID d,
1326 DWORD e)
1328 FIXME("(0x%08lx 0x%08lx %p %p 0x%08lx) stub\n",
1329 a, b, c, d, e);
1330 return 1;
1333 /*************************************************************************
1334 * @ [SHLWAPI.209]
1336 * Some sort of memory management process - associated with _208
1338 DWORD WINAPI SHLWAPI_209 (
1339 LPVOID a)
1341 FIXME("(%p) stub\n",
1343 return 1;
1346 /*************************************************************************
1347 * @ [SHLWAPI.210]
1349 * Some sort of memory management process - associated with _208
1351 DWORD WINAPI SHLWAPI_210 (
1352 LPVOID a,
1353 DWORD b,
1354 LPVOID c)
1356 FIXME("(%p 0x%08lx %p) stub\n",
1357 a, b, c);
1358 return 0;
1361 /*************************************************************************
1362 * @ [SHLWAPI.211]
1364 DWORD WINAPI SHLWAPI_211 (
1365 LPVOID a,
1366 DWORD b)
1368 FIXME("(%p 0x%08lx) stub\n",
1369 a, b);
1370 return 1;
1373 /*************************************************************************
1374 * @ [SHLWAPI.215]
1376 * NOTES
1377 * check me!
1379 DWORD WINAPI SHLWAPI_215 (
1380 LPCSTR lpStrSrc,
1381 LPWSTR lpwStrDest,
1382 int len)
1384 INT len_a, ret;
1386 len_a = lstrlenA(lpStrSrc);
1387 ret = MultiByteToWideChar(0, 0, lpStrSrc, len_a, lpwStrDest, len);
1388 TRACE("%s %s %d, ret=%d\n",
1389 debugstr_a(lpStrSrc), debugstr_w(lpwStrDest), len, ret);
1390 return ret;
1393 /*************************************************************************
1394 * @ [SHLWAPI.218]
1396 * WideCharToMultiByte with multi language support.
1398 INT WINAPI SHLWAPI_218(UINT CodePage, LPCWSTR lpSrcStr, LPSTR lpDstStr,
1399 LPINT lpnMultiCharCount)
1401 WCHAR emptyW[] = { '\0' };
1402 int len , reqLen;
1403 LPSTR mem;
1405 if (!lpDstStr || !lpnMultiCharCount)
1406 return 0;
1408 if (!lpSrcStr)
1409 lpSrcStr = emptyW;
1411 *lpDstStr = '\0';
1413 len = strlenW(lpSrcStr) + 1;
1415 switch (CodePage)
1417 case CP_WINUNICODE:
1418 CodePage = CP_UTF8; /* Fall through... */
1419 case 0x0000C350: /* FIXME: CP_ #define */
1420 case CP_UTF7:
1421 case CP_UTF8:
1423 DWORD dwMode = 0;
1424 INT nWideCharCount = len - 1;
1426 GET_FUNC(pConvertINetUnicodeToMultiByte, mlang, "ConvertINetUnicodeToMultiByte", 0);
1427 if (!pConvertINetUnicodeToMultiByte(&dwMode, CodePage, lpSrcStr, &nWideCharCount, lpDstStr,
1428 lpnMultiCharCount))
1429 return 0;
1431 if (nWideCharCount < len - 1)
1433 mem = (LPSTR)HeapAlloc(GetProcessHeap(), 0, *lpnMultiCharCount);
1434 if (!mem)
1435 return 0;
1437 *lpnMultiCharCount = 0;
1439 if (pConvertINetUnicodeToMultiByte(&dwMode, CodePage, lpSrcStr, &len, mem, lpnMultiCharCount))
1441 SHLWAPI_162 (mem, *lpnMultiCharCount);
1442 lstrcpynA(lpDstStr, mem, *lpnMultiCharCount + 1);
1443 return *lpnMultiCharCount + 1;
1445 HeapFree(GetProcessHeap(), 0, mem);
1446 return *lpnMultiCharCount;
1448 lpDstStr[*lpnMultiCharCount] = '\0';
1449 return *lpnMultiCharCount;
1451 break;
1452 default:
1453 break;
1456 reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, lpDstStr,
1457 *lpnMultiCharCount, NULL, NULL);
1459 if (!reqLen && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1461 reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, NULL, 0, NULL, NULL);
1462 if (reqLen)
1464 mem = (LPSTR)HeapAlloc(GetProcessHeap(), 0, reqLen);
1465 if (mem)
1467 reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, mem,
1468 reqLen, NULL, NULL);
1470 reqLen = SHLWAPI_162(mem, *lpnMultiCharCount);
1471 reqLen++;
1473 lstrcpynA(lpDstStr, mem, *lpnMultiCharCount);
1475 HeapFree(GetProcessHeap(), 0, mem);
1479 return reqLen;
1482 /*************************************************************************
1483 * @ [SHLWAPI.217]
1485 * Hmm, some program used lpnMultiCharCount == 0x3 (and lpSrcStr was "C")
1486 * --> Crash. Something wrong here.
1488 * It seems from OE v5 that the third param is the count. (GA 11/2001)
1490 INT WINAPI SHLWAPI_217(LPCWSTR lpSrcStr, LPSTR lpDstStr, INT MultiCharCount)
1492 INT myint = MultiCharCount;
1494 return SHLWAPI_218(CP_ACP, lpSrcStr, lpDstStr, &myint);
1497 /*************************************************************************
1498 * @ [SHLWAPI.219]
1500 * Seems to be "super" QueryInterface. Supplied with at table of interfaces
1501 * and an array of IIDs and offsets into the table.
1503 * NOTES
1504 * error codes: E_POINTER, E_NOINTERFACE
1506 typedef struct {
1507 REFIID refid;
1508 DWORD indx;
1509 } IFACE_INDEX_TBL;
1511 HRESULT WINAPI SHLWAPI_219 (
1512 LPVOID w, /* [in] table of interfaces */
1513 IFACE_INDEX_TBL *x, /* [in] array of REFIIDs and indexes to above */
1514 REFIID riid, /* [in] REFIID to get interface for */
1515 LPVOID *z) /* [out] location to get interface pointer */
1517 HRESULT ret;
1518 IUnknown *a_vtbl;
1519 IFACE_INDEX_TBL *xmove;
1521 TRACE("(%p %p %s %p)\n",
1522 w,x,debugstr_guid(riid),z);
1523 if (z) {
1524 xmove = x;
1525 while (xmove->refid) {
1526 TRACE("trying (indx %ld) %s\n", xmove->indx,
1527 debugstr_guid(xmove->refid));
1528 if (IsEqualIID(riid, xmove->refid)) {
1529 a_vtbl = (IUnknown*)(xmove->indx + (LPBYTE)w);
1530 TRACE("matched, returning (%p)\n", a_vtbl);
1531 *z = (LPVOID)a_vtbl;
1532 IUnknown_AddRef(a_vtbl);
1533 return S_OK;
1535 xmove++;
1538 if (IsEqualIID(riid, &IID_IUnknown)) {
1539 a_vtbl = (IUnknown*)(x->indx + (LPBYTE)w);
1540 TRACE("returning first for IUnknown (%p)\n", a_vtbl);
1541 *z = (LPVOID)a_vtbl;
1542 IUnknown_AddRef(a_vtbl);
1543 return S_OK;
1545 *z = 0;
1546 ret = E_NOINTERFACE;
1547 } else
1548 ret = E_POINTER;
1549 return ret;
1552 /*************************************************************************
1553 * @ [SHLWAPI.222]
1555 * NOTES
1556 * securityattributes missing
1558 HANDLE WINAPI SHLWAPI_222 (LPCLSID guid)
1560 char lpstrName[80];
1562 sprintf( lpstrName, "shell.{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
1563 guid->Data1, guid->Data2, guid->Data3,
1564 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
1565 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
1566 FIXME("(%s) stub\n", lpstrName);
1567 return CreateSemaphoreA(NULL,0, 0x7fffffff, lpstrName);
1570 /*************************************************************************
1571 * @ [SHLWAPI.223]
1573 * NOTES
1574 * get the count of the semaphore
1576 DWORD WINAPI SHLWAPI_223 (HANDLE handle)
1578 DWORD oldCount;
1580 FIXME("(0x%08x) stub\n",handle);
1582 ReleaseSemaphore( handle, 1, &oldCount); /* +1 */
1583 WaitForSingleObject( handle, 0 ); /* -1 */
1584 return oldCount;
1587 /*************************************************************************
1588 * @ [SHLWAPI.236]
1590 HMODULE WINAPI SHLWAPI_236 (REFIID lpUnknown)
1592 HKEY newkey;
1593 DWORD type, count;
1594 CHAR value[MAX_PATH], string[MAX_PATH];
1596 strcpy(string, "CLSID\\");
1597 strcat(string, debugstr_guid(lpUnknown));
1598 strcat(string, "\\InProcServer32");
1600 count = MAX_PATH;
1601 RegOpenKeyExA(HKEY_CLASSES_ROOT, string, 0, 1, &newkey);
1602 RegQueryValueExA(newkey, 0, 0, &type, value, &count);
1603 RegCloseKey(newkey);
1604 return LoadLibraryExA(value, 0, 0);
1607 /*************************************************************************
1608 * @ [SHLWAPI.237]
1610 * Unicode version of SHLWAPI_183.
1612 DWORD WINAPI SHLWAPI_237 (WNDCLASSW * lpWndClass)
1614 WNDCLASSW WndClass;
1616 TRACE("(0x%08x %s)\n",lpWndClass->hInstance, debugstr_w(lpWndClass->lpszClassName));
1618 if (GetClassInfoW(lpWndClass->hInstance, lpWndClass->lpszClassName, &WndClass))
1619 return TRUE;
1620 return RegisterClassW(lpWndClass);
1623 /*************************************************************************
1624 * @ [SHLWAPI.239]
1626 DWORD WINAPI SHLWAPI_239(HINSTANCE hInstance, LPVOID p2, DWORD dw3)
1628 FIXME("(0x%08x %p 0x%08lx) stub\n",
1629 hInstance, p2, dw3);
1630 return 0;
1631 #if 0
1632 /* pseudo code from relay trace */
1633 WideCharToMultiByte(0, 0, L"Shell DocObject View", -1, &aa, 0x0207, 0, 0);
1634 GetClassInfoA(70fe0000,405868ec "Shell DocObject View",40586b14);
1635 /* above pair repeated for:
1636 TridentThicketUrlDlClass
1637 Shell Embedding
1638 CIESplashScreen
1639 Inet Notify_Hidden
1640 OCHost
1642 #endif
1645 /*************************************************************************
1646 * @ [SHLWAPI.240]
1648 * Calls ASCII or Unicode WindowProc for the given window.
1650 LRESULT CALLBACK SHLWAPI_240(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
1652 if (IsWindowUnicode(hWnd))
1653 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
1654 return DefWindowProcA(hWnd, uMessage, wParam, lParam);
1657 /*************************************************************************
1658 * @ [SHLWAPI.241]
1661 DWORD WINAPI SHLWAPI_241 ()
1663 FIXME("()stub\n");
1664 return /* 0xabba1243 */ 0;
1667 /*************************************************************************
1668 * @ [SHLWAPI.266]
1670 * native does at least approximately:
1671 * strcpyW(newstr, x);
1672 * strcatW(newstr, "\\Restrictions");
1673 * if (RegOpenKeyExA(80000001, newstr, 00000000,00000001,40520b78))
1674 * return 0;
1675 * *unknown*
1677 DWORD WINAPI SHLWAPI_266 (
1678 LPVOID w,
1679 LPVOID x, /* [in] partial registry key */
1680 LPVOID y,
1681 LPVOID z)
1683 FIXME("(%p %p %p %p)stub\n",w,x,y,z);
1684 return /* 0xabba1248 */ 0;
1687 /*************************************************************************
1688 * @ [SHLWAPI.267]
1690 HRESULT WINAPI SHLWAPI_267 (
1691 LPVOID w,
1692 LPVOID x,
1693 LPVOID y, /* [???] NOTE: same as 3rd parameter of SHLWAPI_219 */
1694 LPVOID z) /* [???] NOTE: same as 4th parameter of SHLWAPI_219 */
1696 FIXME("(%p %p %p %p)stub\n",w,x,y,z);
1698 /* native seems to do:
1699 * SHLWAPI_219 ((LPVOID)(((LPSTR)x)-4), ???, (REFIID) y, (LPVOID*) z);
1702 *((LPDWORD)z) = 0xabba1200;
1703 return /* 0xabba1254 */ 0;
1706 /*************************************************************************
1707 * @ [SHLWAPI.268]
1709 DWORD WINAPI SHLWAPI_268 (
1710 LPVOID w,
1711 LPVOID x)
1713 FIXME("(%p %p)\n",w,x);
1714 return 0xabba1251; /* 0 = failure */
1717 /*************************************************************************
1718 * @ [SHLWAPI.276]
1720 * on first call process does following: other calls just returns 2
1721 * instance = LoadLibraryA("SHELL32.DLL");
1722 * func = GetProcAddress(instance, "DllGetVersion");
1723 * ret = RegOpenKeyExA(80000002, "Software\\Microsoft\\Internet Explorer",00000000,0002001f, newkey);
1724 * ret = RegQueryValueExA(newkey, "IntegratedBrowser",00000000,00000000,4052588c,40525890);
1725 * RegCloseKey(newkey);
1726 * FreeLibrary(instance);
1727 * return 2;
1729 DWORD WINAPI SHLWAPI_276 ()
1731 FIXME("()stub\n");
1732 return /* 0xabba1244 */ 2;
1735 /*************************************************************************
1736 * @ [SHLWAPI.278]
1739 HWND WINAPI SHLWAPI_278 (
1740 LONG wndProc,
1741 HWND hWndParent,
1742 DWORD dwExStyle,
1743 DWORD dwStyle,
1744 HMENU hMenu,
1745 LONG z)
1747 WNDCLASSA wndclass;
1748 HWND hwnd;
1749 HCURSOR hCursor;
1750 char * clsname = "WorkerA";
1752 FIXME("(0x%08lx 0x%08x 0x%08lx 0x%08lx 0x%08x 0x%08lx) partial stub\n",
1753 wndProc,hWndParent,dwExStyle,dwStyle,hMenu,z);
1755 hCursor = LoadCursorA(0x00000000,IDC_ARROWA);
1757 if(!GetClassInfoA(shlwapi_hInstance, clsname, &wndclass))
1759 RtlZeroMemory(&wndclass, sizeof(WNDCLASSA));
1760 wndclass.lpfnWndProc = DefWindowProcW;
1761 wndclass.cbWndExtra = 4;
1762 wndclass.hInstance = shlwapi_hInstance;
1763 wndclass.hCursor = hCursor;
1764 wndclass.hbrBackground = COLOR_BTNSHADOW;
1765 wndclass.lpszMenuName = NULL;
1766 wndclass.lpszClassName = clsname;
1767 RegisterClassA (&wndclass);
1769 hwnd = CreateWindowExA(dwExStyle, clsname, 0,dwStyle,0,0,0,0,hWndParent,
1770 hMenu,shlwapi_hInstance,0);
1771 SetWindowLongA(hwnd, 0, z);
1772 SetWindowLongA(hwnd, GWL_WNDPROC, wndProc);
1773 return hwnd;
1776 /*************************************************************************
1777 * @ [SHLWAPI.289]
1779 * Late bound call to winmm.PlaySoundW
1781 BOOL WINAPI SHLWAPI_289(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
1783 GET_FUNC(pPlaySoundW, winmm, "PlaySoundW", FALSE);
1784 return pPlaySoundW(pszSound, hmod, fdwSound);
1787 /*************************************************************************
1788 * @ [SHLWAPI.294]
1790 BOOL WINAPI SHLWAPI_294(LPSTR str1, LPSTR str2, LPSTR pStr, DWORD some_len, LPCSTR lpStr2)
1793 * str1: "I" "I" pushl esp+0x20
1794 * str2: "U" "I" pushl 0x77c93810
1795 * (is "I" and "U" "integer" and "unsigned" ??)
1797 * pStr: "" "" pushl eax
1798 * some_len: 0x824 0x104 pushl 0x824
1799 * lpStr2: "%l" "%l" pushl esp+0xc
1801 * shlwapi. StrCpyNW(lpStr2, irrelevant_var, 0x104);
1802 * LocalAlloc(0x00, some_len) -> irrelevant_var
1803 * LocalAlloc(0x40, irrelevant_len) -> pStr
1804 * shlwapi.294(str1, str2, pStr, some_len, lpStr2);
1805 * shlwapi.PathRemoveBlanksW(pStr);
1807 ERR("('%s', '%s', '%s', %08lx, '%s'): stub!\n", str1, str2, pStr, some_len, lpStr2);
1808 return TRUE;
1811 /*************************************************************************
1812 * @ [SHLWAPI.313]
1814 * Late bound call to shell32.SHGetFileInfoW
1816 DWORD WINAPI SHLWAPI_313(LPCWSTR path, DWORD dwFileAttributes,
1817 SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
1819 GET_FUNC(pSHGetFileInfoW, shell32, "SHGetFileInfoW", 0);
1820 return pSHGetFileInfoW(path, dwFileAttributes, psfi, sizeofpsfi, flags);
1823 /*************************************************************************
1824 * @ [SHLWAPI.318]
1826 * Late bound call to shell32.DragQueryFileW
1828 UINT WINAPI SHLWAPI_318(HDROP hDrop, UINT lFile, LPWSTR lpszFile, UINT lLength)
1830 GET_FUNC(pDragQueryFileW, shell32, "DragQueryFileW", 0);
1831 return pDragQueryFileW(hDrop, lFile, lpszFile, lLength);
1834 /*************************************************************************
1835 * @ [SHLWAPI.333]
1837 * Late bound call to shell32.SHBrowseForFolderW
1839 LPITEMIDLIST WINAPI SHLWAPI_333(LPBROWSEINFOW lpBi)
1841 GET_FUNC(pSHBrowseForFolderW, shell32, "SHBrowseForFolderW", NULL);
1842 return pSHBrowseForFolderW(lpBi);
1845 /*************************************************************************
1846 * @ [SHLWAPI.334]
1848 * Late bound call to shell32.SHGetPathFromIDListW
1850 BOOL WINAPI SHLWAPI_334(LPCITEMIDLIST pidl,LPWSTR pszPath)
1852 GET_FUNC(pSHGetPathFromIDListW, shell32, "SHGetPathFromIDListW", 0);
1853 return pSHGetPathFromIDListW(pidl, pszPath);
1856 /*************************************************************************
1857 * @ [SHLWAPI.335]
1859 * Late bound call to shell32.ShellExecuteExW
1861 BOOL WINAPI SHLWAPI_335(LPSHELLEXECUTEINFOW lpExecInfo)
1863 GET_FUNC(pShellExecuteExW, shell32, "ShellExecuteExW", FALSE);
1864 return pShellExecuteExW(lpExecInfo);
1867 /*************************************************************************
1868 * @ [SHLWAPI.336]
1870 * Late bound call to shell32.SHFileOperationW.
1872 DWORD WINAPI SHLWAPI_336(LPSHFILEOPSTRUCTW lpFileOp)
1874 GET_FUNC(pSHFileOperationW, shell32, "SHFileOperationW", 0);
1875 return pSHFileOperationW(lpFileOp);
1878 /*************************************************************************
1879 * @ [SHLWAPI.337]
1881 * Late bound call to shell32.ExtractIconExW.
1883 HICON WINAPI SHLWAPI_337(LPCWSTR lpszFile, INT nIconIndex, HICON *phiconLarge,
1884 HICON *phiconSmall, UINT nIcons)
1886 GET_FUNC(pExtractIconExW, shell32, "ExtractIconExW", (HICON)0);
1887 return pExtractIconExW(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
1890 /*************************************************************************
1891 * @ [SHLWAPI.342]
1894 LONG WINAPI SHInterlockedCompareExchange( PLONG dest, LONG xchg, LONG compare)
1896 return InterlockedCompareExchange(dest, xchg, compare);
1899 /*************************************************************************
1900 * @ [SHLWAPI.346]
1902 DWORD WINAPI SHLWAPI_346 (
1903 LPCWSTR src,
1904 LPWSTR dest,
1905 int len)
1907 FIXME("(%s %p 0x%08x)stub\n",debugstr_w(src),dest,len);
1908 lstrcpynW(dest, src, len);
1909 return lstrlenW(dest)+1;
1912 /*************************************************************************
1913 * @ [SHLWAPI.350]
1915 * seems to be late bound call to GetFileVersionInfoSizeW
1917 DWORD WINAPI SHLWAPI_350 (
1918 LPWSTR x,
1919 LPVOID y)
1921 DWORD ret;
1923 GET_FUNC(pGetFileVersionInfoSizeW, version, "GetFileVersionInfoSizeW", 0);
1924 ret = pGetFileVersionInfoSizeW(x, y);
1925 return 0x208 + ret;
1928 /*************************************************************************
1929 * @ [SHLWAPI.351]
1931 * seems to be late bound call to GetFileVersionInfoW
1933 BOOL WINAPI SHLWAPI_351 (
1934 LPWSTR w, /* [in] path to dll */
1935 DWORD x, /* [in] parm 2 to GetFileVersionInfoA */
1936 DWORD y, /* [in] return value from .350 - assume length */
1937 LPVOID z) /* [in/out] buffer (+0x208 sent to GetFileVersionInfoA) */
1939 GET_FUNC(pGetFileVersionInfoW, version, "GetFileVersionInfoW", 0);
1940 return pGetFileVersionInfoW(w, x, y-0x208, z+0x208);
1943 /*************************************************************************
1944 * @ [SHLWAPI.352]
1946 * seems to be late bound call to VerQueryValueW
1948 WORD WINAPI SHLWAPI_352 (
1949 LPVOID w, /* [in] buffer from _351 */
1950 LPWSTR x, /* [in] value to retrieve -
1951 converted and passed to VerQueryValueA as #2 */
1952 LPVOID y, /* [out] ver buffer - passed to VerQueryValueA as #3 */
1953 UINT* z) /* [in] ver length - passed to VerQueryValueA as #4 */
1955 GET_FUNC(pVerQueryValueW, version, "VerQueryValueW", 0);
1956 return pVerQueryValueW(w+0x208, x, y, z);
1959 /**************************************************************************
1960 * @ [SHLWAPI.356]
1962 * mbc - this function is undocumented, The parameters are correct and
1963 * the calls to InitializeSecurityDescriptor and
1964 * SetSecurityDescriptorDacl are correct, but apparently some
1965 * apps call this function with all zero parameters.
1968 DWORD WINAPI SHLWAPI_356(PACL pDacl, PSECURITY_DESCRIPTOR pSD, LPCSTR *str)
1970 if(str != 0){
1971 *str = 0;
1974 if(!pDacl){
1975 return 0;
1978 if (!InitializeSecurityDescriptor(pSD, 1)) return 0;
1979 return SetSecurityDescriptorDacl(pSD, 1, pDacl, 0);
1983 /*************************************************************************
1984 * @ [SHLWAPI.357]
1986 * Late bound call to shell32.SHGetNewLinkInfoW
1988 BOOL WINAPI SHLWAPI_357(LPCWSTR pszLinkTo, LPCWSTR pszDir, LPWSTR pszName,
1989 BOOL *pfMustCopy, UINT uFlags)
1991 GET_FUNC(pSHGetNewLinkInfoW, shell32, "SHGetNewLinkInfoW", FALSE);
1992 return pSHGetNewLinkInfoW(pszLinkTo, pszDir, pszName, pfMustCopy, uFlags);
1995 /*************************************************************************
1996 * @ [SHLWAPI.358]
1998 * Late bound call to shell32.SHDefExtractIconW
2000 DWORD WINAPI SHLWAPI_358(LPVOID arg1, LPVOID arg2, LPVOID arg3, LPVOID arg4,
2001 LPVOID arg5, LPVOID arg6)
2003 GET_FUNC(pSHDefExtractIconW, shell32, "SHDefExtractIconW", 0);
2004 return pSHDefExtractIconW(arg1, arg2, arg3, arg4, arg5, arg6);
2007 /*************************************************************************
2008 * @ [SHLWAPI.364]
2010 * Wrapper for lstrcpynA with src and dst swapped.
2012 DWORD WINAPI SHLWAPI_364(LPCSTR src, LPSTR dst, INT n)
2014 lstrcpynA(dst, src, n);
2015 return TRUE;
2018 /*************************************************************************
2019 * @ [SHLWAPI.370]
2021 * Late bound call to shell32.ExtractIconW
2023 HICON WINAPI SHLWAPI_370(HINSTANCE hInstance, LPCWSTR lpszExeFileName,
2024 UINT nIconIndex)
2026 GET_FUNC(pExtractIconW, shell32, "ExtractIconW", (HICON)0);
2027 return pExtractIconW(hInstance, lpszExeFileName, nIconIndex);
2030 /*************************************************************************
2031 * @ [SHLWAPI.376]
2033 LANGID WINAPI SHLWAPI_376 ()
2035 FIXME("() stub\n");
2036 /* FIXME: This should be a forward in the .spec file to the win2k function
2037 * kernel32.GetUserDefaultUILanguage, however that function isn't there yet.
2039 return GetUserDefaultLangID();
2042 /*************************************************************************
2043 * @ [SHLWAPI.377]
2045 * FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for
2046 * each call here.
2047 * FIXME: Native shows calls to:
2048 * SHRegGetUSValue for "Software\Microsoft\Internet Explorer\International"
2049 * CheckVersion
2050 * RegOpenKeyExA for "HKLM\Software\Microsoft\Internet Explorer"
2051 * RegQueryValueExA for "LPKInstalled"
2052 * RegCloseKey
2053 * RegOpenKeyExA for "HKCU\Software\Microsoft\Internet Explorer\International"
2054 * RegQueryValueExA for "ResourceLocale"
2055 * RegCloseKey
2056 * RegOpenKeyExA for "HKLM\Software\Microsoft\Active Setup\Installed Components\{guid}"
2057 * RegQueryValueExA for "Locale"
2058 * RegCloseKey
2059 * and then tests the Locale ("en" for me).
2060 * code below
2061 * after the code then a DPA_Create (first time) and DPA_InsertPtr are done.
2063 DWORD WINAPI SHLWAPI_377 (LPCSTR new_mod, HMODULE inst_hwnd, LPVOID z)
2065 CHAR mod_path[2*MAX_PATH];
2066 LPSTR ptr;
2068 GetModuleFileNameA(inst_hwnd, mod_path, 2*MAX_PATH);
2069 ptr = strrchr(mod_path, '\\');
2070 if (ptr) {
2071 strcpy(ptr+1, new_mod);
2072 TRACE("loading %s\n", debugstr_a(mod_path));
2073 return (DWORD)LoadLibraryA(mod_path);
2075 return 0;
2078 /*************************************************************************
2079 * @ [SHLWAPI.378]
2081 * This is Unicode version of .377
2083 DWORD WINAPI SHLWAPI_378 (
2084 LPCWSTR new_mod, /* [in] new module name */
2085 HMODULE inst_hwnd, /* [in] calling module handle */
2086 LPVOID z) /* [???] 4 */
2088 WCHAR mod_path[2*MAX_PATH];
2089 LPWSTR ptr;
2091 GetModuleFileNameW(inst_hwnd, mod_path, 2*MAX_PATH);
2092 ptr = strrchrW(mod_path, '\\');
2093 if (ptr) {
2094 strcpyW(ptr+1, new_mod);
2095 TRACE("loading %s\n", debugstr_w(mod_path));
2096 return (DWORD)LoadLibraryW(mod_path);
2098 return 0;
2101 /*************************************************************************
2102 * @ [SHLWAPI.389]
2104 * Late bound call to comdlg32.GetSaveFileNameW
2106 BOOL WINAPI SHLWAPI_389(LPOPENFILENAMEW ofn)
2108 GET_FUNC(pGetSaveFileNameW, comdlg32, "GetSaveFileNameW", FALSE);
2109 return pGetSaveFileNameW(ofn);
2112 /*************************************************************************
2113 * @ [SHLWAPI.390]
2115 * Late bound call to mpr.WNetRestoreConnectionW
2117 DWORD WINAPI SHLWAPI_390(LPVOID arg1, LPVOID arg2)
2119 GET_FUNC(pWNetRestoreConnectionW, mpr, "WNetRestoreConnectionW", 0);
2120 return pWNetRestoreConnectionW(arg1, arg2);
2123 /*************************************************************************
2124 * @ [SHLWAPI.391]
2126 * Late bound call to mpr.WNetGetLastErrorW
2128 DWORD WINAPI SHLWAPI_391(LPVOID arg1, LPVOID arg2, LPVOID arg3, LPVOID arg4,
2129 LPVOID arg5)
2131 GET_FUNC(pWNetGetLastErrorW, mpr, "WNetGetLastErrorW", 0);
2132 return pWNetGetLastErrorW(arg1, arg2, arg3, arg4, arg5);
2135 /*************************************************************************
2136 * @ [SHLWAPI.401]
2138 * Late bound call to comdlg32.PageSetupDlgW
2140 BOOL WINAPI SHLWAPI_401(LPPAGESETUPDLGW pagedlg)
2142 GET_FUNC(pPageSetupDlgW, comdlg32, "PageSetupDlgW", FALSE);
2143 return pPageSetupDlgW(pagedlg);
2146 /*************************************************************************
2147 * @ [SHLWAPI.402]
2149 * Late bound call to comdlg32.PrintDlgW
2151 BOOL WINAPI SHLWAPI_402(LPPRINTDLGW printdlg)
2153 GET_FUNC(pPrintDlgW, comdlg32, "PrintDlgW", FALSE);
2154 return pPrintDlgW(printdlg);
2157 /*************************************************************************
2158 * @ [SHLWAPI.403]
2160 * Late bound call to comdlg32.GetOpenFileNameW
2162 BOOL WINAPI SHLWAPI_403(LPOPENFILENAMEW ofn)
2164 GET_FUNC(pGetOpenFileNameW, comdlg32, "GetOpenFileNameW", FALSE);
2165 return pGetOpenFileNameW(ofn);
2168 /* INTERNAL: Map from HLS color space to RGB */
2169 static WORD ConvertHue(int wHue, WORD wMid1, WORD wMid2)
2171 wHue = wHue > 240 ? wHue - 240 : wHue < 0 ? wHue + 240 : wHue;
2173 if (wHue > 160)
2174 return wMid1;
2175 else if (wHue > 120)
2176 wHue = 160 - wHue;
2177 else if (wHue > 40)
2178 return wMid2;
2180 return ((wHue * (wMid2 - wMid1) + 20) / 40) + wMid1;
2183 /* Convert to RGB and scale into RGB range (0..255) */
2184 #define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240
2186 /*************************************************************************
2187 * ColorHLSToRGB [SHLWAPI.404]
2189 * Convert from HLS color space into an RGB COLORREF.
2191 * NOTES
2192 * Input HLS values are constrained to the range (0..240).
2194 COLORREF WINAPI ColorHLSToRGB(WORD wHue, WORD wLuminosity, WORD wSaturation)
2196 WORD wRed;
2198 if (wSaturation)
2200 WORD wGreen, wBlue, wMid1, wMid2;
2202 if (wLuminosity > 120)
2203 wMid2 = wSaturation + wLuminosity - (wSaturation * wLuminosity + 120) / 240;
2204 else
2205 wMid2 = ((wSaturation + 240) * wLuminosity + 120) / 240;
2207 wMid1 = wLuminosity * 2 - wMid2;
2209 wRed = GET_RGB(wHue + 80);
2210 wGreen = GET_RGB(wHue);
2211 wBlue = GET_RGB(wHue - 80);
2213 return RGB(wRed, wGreen, wBlue);
2216 wRed = wLuminosity * 255 / 240;
2217 return RGB(wRed, wRed, wRed);
2220 /*************************************************************************
2221 * @ [SHLWAPI.413]
2223 * Function unknown seems to always to return 0
2225 DWORD WINAPI SHLWAPI_413 (DWORD x)
2227 FIXME("(0x%08lx)stub\n", x);
2228 return 0;
2231 /*************************************************************************
2232 * @ [SHLWAPI.418]
2234 * Function seems to do FreeLibrary plus other things.
2236 * FIXME native shows the following calls:
2237 * RtlEnterCriticalSection
2238 * LocalFree
2239 * GetProcAddress(Comctl32??, 150L)
2240 * DPA_DeletePtr
2241 * RtlLeaveCriticalSection
2242 * followed by the FreeLibrary.
2243 * The above code may be related to .377 above.
2245 BOOL WINAPI SHLWAPI_418 (HMODULE x)
2247 FIXME("(0x%08lx) partial stub\n", (LONG)x);
2248 return FreeLibrary(x);
2251 /*************************************************************************
2252 * @ [SHLWAPI.431]
2254 DWORD WINAPI SHLWAPI_431 (DWORD x)
2256 FIXME("(0x%08lx)stub\n", x);
2257 return 0xabba1247;
2260 /*************************************************************************
2261 * @ [SHLWAPI.436]
2263 * This is really CLSIDFromString which is exported by ole32.dll,
2264 * however the native shlwapi.dll does *not* import ole32. Nor does
2265 * ole32.dll import this ordinal from shlwapi. Therefore we must conclude
2266 * that MS duplicated the code for CLSIDFromString.
2268 * This is a duplicate (with changes for UNICODE) of CLSIDFromString16
2269 * in dlls/ole32/compobj.c
2271 DWORD WINAPI SHLWAPI_436 (LPWSTR idstr, CLSID *id)
2273 LPWSTR s = idstr;
2274 BYTE *p;
2275 INT i;
2276 WCHAR table[256];
2278 if (!s) {
2279 memset(s, 0, sizeof(CLSID));
2280 return S_OK;
2282 else { /* validate the CLSID string */
2284 if (strlenW(s) != 38)
2285 return CO_E_CLASSSTRING;
2287 if ((s[0]!=L'{') || (s[9]!=L'-') || (s[14]!=L'-') || (s[19]!=L'-') || (s[24]!=L'-') || (s[37]!=L'}'))
2288 return CO_E_CLASSSTRING;
2290 for (i=1; i<37; i++)
2292 if ((i == 9)||(i == 14)||(i == 19)||(i == 24)) continue;
2293 if (!(((s[i] >= L'0') && (s[i] <= L'9')) ||
2294 ((s[i] >= L'a') && (s[i] <= L'f')) ||
2295 ((s[i] >= L'A') && (s[i] <= L'F')))
2297 return CO_E_CLASSSTRING;
2301 TRACE("%s -> %p\n", debugstr_w(s), id);
2303 /* quick lookup table */
2304 memset(table, 0, 256*sizeof(WCHAR));
2306 for (i = 0; i < 10; i++) {
2307 table['0' + i] = i;
2309 for (i = 0; i < 6; i++) {
2310 table['A' + i] = i+10;
2311 table['a' + i] = i+10;
2314 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
2316 p = (BYTE *) id;
2318 s++; /* skip leading brace */
2319 for (i = 0; i < 4; i++) {
2320 p[3 - i] = table[*s]<<4 | table[*(s+1)];
2321 s += 2;
2323 p += 4;
2324 s++; /* skip - */
2326 for (i = 0; i < 2; i++) {
2327 p[1-i] = table[*s]<<4 | table[*(s+1)];
2328 s += 2;
2330 p += 2;
2331 s++; /* skip - */
2333 for (i = 0; i < 2; i++) {
2334 p[1-i] = table[*s]<<4 | table[*(s+1)];
2335 s += 2;
2337 p += 2;
2338 s++; /* skip - */
2340 /* these are just sequential bytes */
2341 for (i = 0; i < 2; i++) {
2342 *p++ = table[*s]<<4 | table[*(s+1)];
2343 s += 2;
2345 s++; /* skip - */
2347 for (i = 0; i < 6; i++) {
2348 *p++ = table[*s]<<4 | table[*(s+1)];
2349 s += 2;
2352 return S_OK;
2355 /*************************************************************************
2356 * @ [SHLWAPI.437]
2358 * NOTES
2359 * In the real shlwapi, One time initialisation calls GetVersionEx and reads
2360 * the registry to determine what O/S & Service Pack level is running, and
2361 * therefore which functions are available. Currently we always run as NT,
2362 * since this means that we don't need extra code to emulate Unicode calls,
2363 * they are forwarded directly to the appropriate API call instead.
2364 * Since the flags for whether to call or emulate Unicode are internal to
2365 * the dll, this function does not need a full implementation.
2367 DWORD WINAPI SHLWAPI_437 (DWORD functionToCall)
2369 FIXME("(0x%08lx)stub\n", functionToCall);
2370 return /* 0xabba1247 */ 0;
2373 /*************************************************************************
2374 * ColorRGBToHLS [SHLWAPI.445]
2376 * Convert from RGB COLORREF into the HLS color space.
2378 * NOTES
2379 * Input HLS values are constrained to the range (0..240).
2381 VOID WINAPI ColorRGBToHLS(COLORREF drRGB, LPWORD pwHue,
2382 LPWORD wLuminance, LPWORD pwSaturation)
2384 FIXME("stub\n");
2385 return;
2388 /*************************************************************************
2389 * SHCreateShellPalette [SHLWAPI.@]
2391 HPALETTE WINAPI SHCreateShellPalette(HDC hdc)
2393 FIXME("stub\n");
2394 return CreateHalftonePalette(hdc);
2397 /*************************************************************************
2398 * SHGetInverseCMAP (SHLWAPI.@)
2400 DWORD WINAPI SHGetInverseCMAP (LPDWORD* x, DWORD why)
2402 if (why == 4) {
2403 FIXME(" - returning bogus address for SHGetInverseCMAP\n");
2404 *x = (LPDWORD)0xabba1249;
2405 return 0;
2407 FIXME("(%p, %#lx)stub\n", x, why);
2408 return 0;
2411 /*************************************************************************
2412 * SHIsLowMemoryMachine [SHLWAPI.@]
2414 DWORD WINAPI SHIsLowMemoryMachine (DWORD x)
2416 FIXME("0x%08lx\n", x);
2417 return 0;
2420 /*************************************************************************
2421 * GetMenuPosFromID [SHLWAPI.@]
2423 INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID)
2425 MENUITEMINFOA mi;
2426 INT nCount = GetMenuItemCount(hMenu), nIter = 0;
2428 while (nIter < nCount)
2430 mi.wID = 0;
2431 if (!GetMenuItemInfoA(hMenu, nIter, TRUE, &mi) && mi.wID == wID)
2432 return nIter;
2433 nIter++;
2435 return -1;
2438 /*************************************************************************
2439 * _SHGetInstanceExplorer@4 [SHLWAPI.@]
2441 * Late bound call to shell32.SHGetInstanceExplorer.
2443 HRESULT WINAPI _SHGetInstanceExplorer (LPUNKNOWN *lpUnknown)
2445 GET_FUNC(pSHGetInstanceExplorer, shell32, "SHGetInstanceExplorer", E_FAIL);
2446 return pSHGetInstanceExplorer(lpUnknown);
2449 /*************************************************************************
2450 * SHGetThreadRef [SHLWAPI.@]
2452 * Retrieves the per-thread object reference set by SHSetThreadRef
2453 * "punk" - Address of a pointer to the IUnknown interface. Returns S_OK if
2454 * successful or E_NOINTERFACE otherwise.
2456 HRESULT WINAPI SHGetThreadRef (IUnknown ** ppunk)
2458 if (SHLWAPI_ThreadRef_index < 0) return E_NOINTERFACE;
2459 *ppunk = (IUnknown *)TlsGetValue(SHLWAPI_ThreadRef_index);
2460 return S_OK;
2463 /*************************************************************************
2464 * SHSetThreadRef [SHLWAPI.@]
2466 * Stores a per-thread reference to a COM object
2467 * "punk" - Pointer to the IUnknown interface of the object to
2468 * which you want to store a reference. Returns S_OK if successful
2469 * or an OLE error value.
2471 HRESULT WINAPI SHSetThreadRef (IUnknown * punk)
2473 if (SHLWAPI_ThreadRef_index < 0) return E_NOINTERFACE;
2474 TlsSetValue(SHLWAPI_ThreadRef_index, (LPVOID) punk);
2475 return S_OK;