source: trunk/src/shlwapi/ordinal.c@ 10367

Last change on this file since 10367 was 10053, checked in by sandervl, 22 years ago

DT: Fixed PathIsUrlA/W

File size: 69.4 KB
Line 
1/*
2 * SHLWAPI ordinal functions
3 *
4 * Copyright 1997 Marcus Meissner
5 * 1998 Jürgen Schmied
6 * 2001 Jon Griffiths
7 *
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.
12 *
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.
17 *
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
21 */
22
23#include <stdio.h>
24#include <string.h>
25
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"
43
44WINE_DEFAULT_DEBUG_CHANNEL(shell);
45
46extern HINSTANCE shlwapi_hInstance;
47extern HMODULE SHLWAPI_hshell32;
48extern HMODULE SHLWAPI_hwinmm;
49extern HMODULE SHLWAPI_hcomdlg32;
50extern HMODULE SHLWAPI_hmpr;
51extern HMODULE SHLWAPI_hmlang;
52extern HMODULE SHLWAPI_hversion;
53
54extern DWORD SHLWAPI_ThreadRef_index;
55
56typedef HANDLE HSHARED; /* Shared memory */
57
58/* following is GUID for IObjectWithSite::SetSite -- see _174 */
59static DWORD id1[4] = {0xfc4801a3, 0x11cf2ba9, 0xaa0029a2, 0x52733d00};
60/* following is GUID for IPersistMoniker::GetClassID -- see _174 */
61static DWORD id2[4] = {0x79eac9ee, 0x11cebaf9, 0xaa00828c, 0x0ba94b00};
62
63/* The following schemes were identified in the native version of
64 * SHLWAPI.DLL version 5.50
65 */
66typedef 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;
89
90typedef struct {
91 URL_SCHEME scheme_number;
92 LPCSTR scheme_name;
93} SHL_2_inet_scheme;
94
95static 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}
115};
116
117/* function pointers for GET_FUNC macro; these need to be global because of gcc bug */
118#ifdef __WIN32OS2__
119static LPITEMIDLIST (* WINAPI pSHBrowseForFolderW)(LPBROWSEINFOW);
120static HRESULT (* WINAPI pConvertINetUnicodeToMultiByte)(LPDWORD,DWORD,LPCWSTR,LPINT,LPSTR,LPINT);
121static BOOL (* WINAPI pPlaySoundW)(LPCWSTR, HMODULE, DWORD);
122static DWORD (* WINAPI pSHGetFileInfoW)(LPCWSTR,DWORD,SHFILEINFOW*,UINT,UINT);
123static UINT (* WINAPI pDragQueryFileW)(HDROP, UINT, LPWSTR, UINT);
124static BOOL (* WINAPI pSHGetPathFromIDListW)(LPCITEMIDLIST, LPWSTR);
125static BOOL (* WINAPI pShellExecuteExW)(LPSHELLEXECUTEINFOW);
126static HICON (* WINAPI pSHFileOperationW)(LPSHFILEOPSTRUCTW);
127static HICON (* WINAPI pExtractIconExW)(LPCWSTR, INT,HICON *,HICON *, UINT);
128static BOOL (* WINAPI pSHGetNewLinkInfoW)(LPCWSTR, LPCWSTR, LPCWSTR, BOOL*, UINT);
129static DWORD (* WINAPI pSHDefExtractIconW)(LPVOID, LPVOID, LPVOID, LPVOID, LPVOID, LPVOID); /* FIXME: Correct args */
130static HICON (* WINAPI pExtractIconW)(HINSTANCE, LPCWSTR, UINT);
131static BOOL (* WINAPI pGetSaveFileNameW)(LPOPENFILENAMEW);
132static DWORD (* WINAPI pWNetRestoreConnectionW)(LPVOID, LPVOID); /* FIXME: Correct args */
133static DWORD (* WINAPI pWNetGetLastErrorW)(LPVOID, LPVOID, LPVOID, LPVOID, LPVOID); /* FIXME: Correct args */
134static BOOL (* WINAPI pPageSetupDlgW)(LPPAGESETUPDLGW);
135static BOOL (* WINAPI pPrintDlgW)(LPPRINTDLGW);
136static BOOL (* WINAPI pGetOpenFileNameW)(LPOPENFILENAMEW);
137static HRESULT (* WINAPI pSHGetInstanceExplorer)(LPUNKNOWN *);
138static DWORD (* WINAPI pGetFileVersionInfoSizeW)(LPCWSTR,LPDWORD);
139static BOOL (* WINAPI pGetFileVersionInfoW)(LPCWSTR,DWORD,DWORD,LPVOID);
140static WORD (* WINAPI pVerQueryValueW)(LPVOID,LPCWSTR,LPVOID*,UINT*);
141#else
142static LPITEMIDLIST (WINAPI *pSHBrowseForFolderW)(LPBROWSEINFOW);
143static HRESULT (WINAPI *pConvertINetUnicodeToMultiByte)(LPDWORD,DWORD,LPCWSTR,LPINT,LPSTR,LPINT);
144static BOOL (WINAPI *pPlaySoundW)(LPCWSTR, HMODULE, DWORD);
145static DWORD (WINAPI *pSHGetFileInfoW)(LPCWSTR,DWORD,SHFILEINFOW*,UINT,UINT);
146static UINT (WINAPI *pDragQueryFileW)(HDROP, UINT, LPWSTR, UINT);
147static BOOL (WINAPI *pSHGetPathFromIDListW)(LPCITEMIDLIST, LPWSTR);
148static BOOL (WINAPI *pShellExecuteExW)(LPSHELLEXECUTEINFOW);
149static HICON (WINAPI *pSHFileOperationW)(LPSHFILEOPSTRUCTW);
150static HICON (WINAPI *pExtractIconExW)(LPCWSTR, INT,HICON *,HICON *, UINT);
151static BOOL (WINAPI *pSHGetNewLinkInfoW)(LPCWSTR, LPCWSTR, LPCWSTR, BOOL*, UINT);
152static DWORD (WINAPI *pSHDefExtractIconW)(LPVOID, LPVOID, LPVOID, LPVOID, LPVOID, LPVOID); /* FIXME: Correct args */
153static HICON (WINAPI *pExtractIconW)(HINSTANCE, LPCWSTR, UINT);
154static BOOL (WINAPI *pGetSaveFileNameW)(LPOPENFILENAMEW);
155static DWORD (WINAPI *pWNetRestoreConnectionW)(LPVOID, LPVOID); /* FIXME: Correct args */
156static DWORD (WINAPI *pWNetGetLastErrorW)(LPVOID, LPVOID, LPVOID, LPVOID, LPVOID); /* FIXME: Correct args */
157static BOOL (WINAPI *pPageSetupDlgW)(LPPAGESETUPDLGW);
158static BOOL (WINAPI *pPrintDlgW)(LPPRINTDLGW);
159static BOOL (WINAPI *pGetOpenFileNameW)(LPOPENFILENAMEW);
160static HRESULT (WINAPI *pSHGetInstanceExplorer)(LPUNKNOWN *);
161static DWORD (WINAPI *pGetFileVersionInfoSizeW)(LPCWSTR,LPDWORD);
162static BOOL (WINAPI *pGetFileVersionInfoW)(LPCWSTR,DWORD,DWORD,LPVOID);
163static WORD (WINAPI *pVerQueryValueW)(LPVOID,LPCWSTR,LPVOID*,UINT*);
164#endif
165
166/*
167 NOTES: Most functions exported by ordinal seem to be superflous.
168 The reason for these functions to be there is to provide a wraper
169 for unicode functions to provide these functions on systems without
170 unicode functions eg. win95/win98. Since we have such functions we just
171 call these. If running Wine with native DLL's, some late bound calls may
172 fail. However, its better to implement the functions in the forward DLL
173 and recommend the builtin rather than reimplementing the calls here!
174*/
175
176/*************************************************************************
177 * @ [SHLWAPI.1]
178 *
179 * Identifies the Internet "scheme" in the passed string. ASCII based.
180 * Also determines start and length of item after the ':'
181 */
182DWORD WINAPI SHLWAPI_1 (LPCSTR x, UNKNOWN_SHLWAPI_1 *y)
183{
184 DWORD cnt;
185 const SHL_2_inet_scheme *inet_pro;
186
187 y->fcncde = URL_SCHEME_INVALID;
188 if (y->size != 0x18) return E_INVALIDARG;
189 /* FIXME: leading white space generates error of 0x80041001 which
190 * is undefined
191 */
192 if (*x <= ' ') return 0x80041001;
193 cnt = 0;
194 y->sizep1 = 0;
195 y->ap1 = x;
196 while (*x) {
197 if (*x == ':') {
198 y->sizep1 = cnt;
199 cnt = -1;
200 y->ap2 = x+1;
201 break;
202 }
203 x++;
204 cnt++;
205 }
206
207 /* check for no scheme in string start */
208 /* (apparently schemes *must* be larger than a single character) */
209 if ((*x == '\0') || (y->sizep1 <= 1)) {
210 y->ap1 = 0;
211 return 0x80041001;
212 }
213
214 /* found scheme, set length of remainder */
215 y->sizep2 = lstrlenA(y->ap2);
216
217 /* see if known scheme and return indicator number */
218 y->fcncde = URL_SCHEME_UNKNOWN;
219 inet_pro = shlwapi_schemes;
220 while (inet_pro->scheme_name) {
221 if (!strncasecmp(inet_pro->scheme_name, y->ap1,
222 min(y->sizep1, lstrlenA(inet_pro->scheme_name)))) {
223 y->fcncde = inet_pro->scheme_number;
224 break;
225 }
226 inet_pro++;
227 }
228 return S_OK;
229}
230
231/*************************************************************************
232 * @ [SHLWAPI.2]
233 *
234 * Identifies the Internet "scheme" in the passed string. UNICODE based.
235 * Also determines start and length of item after the ':'
236 */
237DWORD WINAPI SHLWAPI_2 (LPCWSTR x, UNKNOWN_SHLWAPI_2 *y)
238{
239 DWORD cnt;
240 const SHL_2_inet_scheme *inet_pro;
241 LPSTR cmpstr;
242 INT len;
243
244 y->fcncde = URL_SCHEME_INVALID;
245 if (y->size != 0x18) return E_INVALIDARG;
246 /* FIXME: leading white space generates error of 0x80041001 which
247 * is undefined
248 */
249 if (*x <= L' ') return 0x80041001;
250 cnt = 0;
251 y->sizep1 = 0;
252 y->ap1 = x;
253 while (*x) {
254 if (*x == L':') {
255 y->sizep1 = cnt;
256 cnt = -1;
257 y->ap2 = x+1;
258 break;
259 }
260 x++;
261 cnt++;
262 }
263
264 /* check for no scheme in string start */
265 /* (apparently schemes *must* be larger than a single character) */
266 if ((*x == L'\0') || (y->sizep1 <= 1)) {
267 y->ap1 = 0;
268 return 0x80041001;
269 }
270
271 /* found scheme, set length of remainder */
272 y->sizep2 = lstrlenW(y->ap2);
273
274 /* see if known scheme and return indicator number */
275 len = WideCharToMultiByte(0, 0, y->ap1, y->sizep1, 0, 0, 0, 0);
276 cmpstr = (LPSTR)HeapAlloc(GetProcessHeap(), 0, len+1);
277 WideCharToMultiByte(0, 0, y->ap1, y->sizep1, cmpstr, len+1, 0, 0);
278 y->fcncde = URL_SCHEME_UNKNOWN;
279 inet_pro = shlwapi_schemes;
280 while (inet_pro->scheme_name) {
281 if (!strncasecmp(inet_pro->scheme_name, cmpstr,
282 min(len, lstrlenA(inet_pro->scheme_name)))) {
283 y->fcncde = inet_pro->scheme_number;
284 break;
285 }
286 inet_pro++;
287 }
288 HeapFree(GetProcessHeap(), 0, cmpstr);
289 return S_OK;
290}
291
292/*************************************************************************
293 * @ [SHLWAPI.3]
294 *
295 * Determine if a file exists locally and is of an executable type.
296 *
297 * PARAMS
298 * lpszFile [O] File to search for
299 * dwWhich [I] Type of executable to search for
300 *
301 * RETURNS
302 * TRUE If the file was found. lpszFile contains the file name.
303 * FALSE Otherwise.
304 *
305 * NOTES
306 * lpszPath is modified in place and must be at least MAX_PATH in length.
307 * If the function returns FALSE, the path is modified to its orginal state.
308 * If the given path contains an extension or dwWhich is 0, executable
309 * extensions are not checked.
310 *
311 * Ordinals 3-6 are a classic case of MS exposing limited functionality to
312 * users (here through PathFindOnPath) and keeping advanced functionality for
313 * their own developers exclusive use. Monopoly, anyone?
314 */
315BOOL WINAPI SHLWAPI_3(LPSTR lpszFile,DWORD dwWhich)
316{
317 return SHLWAPI_PathFindLocalExeA(lpszFile,dwWhich);
318}
319
320/*************************************************************************
321 * @ [SHLWAPI.4]
322 *
323 * Unicode version of SHLWAPI_3.
324 */
325BOOL WINAPI SHLWAPI_4(LPWSTR lpszFile,DWORD dwWhich)
326{
327 return SHLWAPI_PathFindLocalExeW(lpszFile,dwWhich);
328}
329
330/*************************************************************************
331 * @ [SHLWAPI.5]
332 *
333 * Search a range of paths for a specific type of executable.
334 *
335 * PARAMS
336 * lpszFile [O] File to search for
337 * lppszOtherDirs [I] Other directories to look in
338 * dwWhich [I] Type of executable to search for
339 *
340 * RETURNS
341 * Success: TRUE. The path to the executable is stored in sFile.
342 * Failure: FALSE. The path to the executable is unchanged.
343 */
344BOOL WINAPI SHLWAPI_5(LPSTR lpszFile,LPCSTR *lppszOtherDirs,DWORD dwWhich)
345{
346 return SHLWAPI_PathFindOnPathExA(lpszFile,lppszOtherDirs,dwWhich);
347}
348
349/*************************************************************************
350 * @ [SHLWAPI.6]
351 *
352 * Unicode version of SHLWAPI_5.
353 */
354BOOL WINAPI SHLWAPI_6(LPWSTR lpszFile,LPCWSTR *lppszOtherDirs,DWORD dwWhich)
355{
356 return SHLWAPI_PathFindOnPathExW(lpszFile,lppszOtherDirs,dwWhich);
357}
358
359/*************************************************************************
360 * SHLWAPI_DupSharedHandle
361 *
362 * Internal implemetation of SHLWAPI_11.
363 */
364static
365HSHARED WINAPI SHLWAPI_DupSharedHandle(HSHARED hShared, DWORD dwDstProcId,
366 DWORD dwSrcProcId, DWORD dwAccess,
367 DWORD dwOptions)
368{
369 HANDLE hDst, hSrc;
370 DWORD dwMyProcId = GetCurrentProcessId();
371 HSHARED hRet = (HSHARED)NULL;
372
373 TRACE("(%p,%ld,%ld,%08lx,%08lx)\n", (PVOID)hShared, dwDstProcId, dwSrcProcId,
374 dwAccess, dwOptions);
375
376 /* Get dest process handle */
377 if (dwDstProcId == dwMyProcId)
378 hDst = GetCurrentProcess();
379 else
380 hDst = OpenProcess(PROCESS_DUP_HANDLE, 0, dwDstProcId);
381
382 if (hDst)
383 {
384 /* Get src process handle */
385 if (dwSrcProcId == dwMyProcId)
386 hSrc = GetCurrentProcess();
387 else
388 hSrc = OpenProcess(PROCESS_DUP_HANDLE, 0, dwSrcProcId);
389
390 if (hSrc)
391 {
392 /* Make handle available to dest process */
393 if (!DuplicateHandle(hDst, (HANDLE)hShared, hSrc, &hRet,
394 dwAccess, 0, dwOptions | DUPLICATE_SAME_ACCESS))
395 hRet = (HSHARED)NULL;
396
397 if (dwSrcProcId != dwMyProcId)
398 CloseHandle(hSrc);
399 }
400
401 if (dwDstProcId != dwMyProcId)
402 CloseHandle(hDst);
403 }
404
405 TRACE("Returning handle %p\n", (PVOID)hRet);
406 return hRet;
407}
408
409/*************************************************************************
410 * @ [SHLWAPI.7]
411 *
412 * Create a block of sharable memory and initialise it with data.
413 *
414 * PARAMS
415 * dwProcId [I] ID of process owning data
416 * lpvData [I] Pointer to data to write
417 * dwSize [I] Size of data
418 *
419 * RETURNS
420 * Success: A shared memory handle
421 * Failure: NULL
422 *
423 * NOTES
424 * Ordinals 7-11 provide a set of calls to create shared memory between a
425 * group of processes. The shared memory is treated opaquely in that its size
426 * is not exposed to clients who map it. This is accomplished by storing
427 * the size of the map as the first DWORD of mapped data, and then offsetting
428 * the view pointer returned by this size.
429 *
430 * SHLWAPI_7/SHLWAPI_10 - Create/Destroy the shared memory handle
431 * SHLWAPI_8/SHLWAPI_9 - Get/Release a pointer to the shared data
432 * SHLWAPI_11 - Helper function; Duplicate cross-process handles
433 */
434HSHARED WINAPI SHLWAPI_7 (DWORD dwProcId, DWORD dwSize, LPCVOID lpvData)
435{
436 HANDLE hMap;
437 LPVOID pMapped;
438 HSHARED hRet = (HSHARED)NULL;
439
440 TRACE("(%ld,%p,%ld)\n", dwProcId, lpvData, dwSize);
441
442 /* Create file mapping of the correct length */
443 hMap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, FILE_MAP_READ, 0,
444 dwSize + sizeof(dwSize), NULL);
445 if (!hMap)
446 return hRet;
447
448 /* Get a view in our process address space */
449 pMapped = MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
450
451 if (pMapped)
452 {
453 /* Write size of data, followed by the data, to the view */
454 *((DWORD*)pMapped) = dwSize;
455 if (dwSize)
456 memcpy((char *) pMapped + sizeof(dwSize), lpvData, dwSize);
457
458 /* Release view. All further views mapped will be opaque */
459 UnmapViewOfFile(pMapped);
460 hRet = SHLWAPI_DupSharedHandle((HSHARED)hMap, dwProcId,
461 GetCurrentProcessId(), FILE_MAP_ALL_ACCESS,
462 DUPLICATE_SAME_ACCESS);
463 }
464
465 CloseHandle(hMap);
466 return hRet;
467}
468
469/*************************************************************************
470 * @ [SHLWAPI.8]
471 *
472 * Get a pointer to a block of shared memory from a shared memory handle.
473 *
474 * PARAMS
475 * hShared [I] Shared memory handle
476 * dwProcId [I] ID of process owning hShared
477 *
478 * RETURNS
479 * Success: A pointer to the shared memory
480 * Failure: NULL
481 *
482 * NOTES
483 * See SHLWAPI_7.
484 */
485PVOID WINAPI SHLWAPI_8 (HSHARED hShared, DWORD dwProcId)
486 {
487 HSHARED hDup;
488 LPVOID pMapped;
489
490 TRACE("(%p %ld)\n", (PVOID)hShared, dwProcId);
491
492 /* Get handle to shared memory for current process */
493 hDup = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
494 FILE_MAP_ALL_ACCESS, 0);
495 /* Get View */
496 pMapped = MapViewOfFile((HANDLE)hDup, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
497 CloseHandle(hDup);
498
499 if (pMapped)
500 return (char *) pMapped + sizeof(DWORD); /* Hide size */
501 return NULL;
502}
503
504/*************************************************************************
505 * @ [SHLWAPI.9]
506 *
507 * Release a pointer to a block of shared memory.
508 *
509 * PARAMS
510 * lpView [I] Shared memory pointer
511 *
512 * RETURNS
513 * Success: TRUE
514 * Failure: FALSE
515 *
516 * NOTES
517 * See SHLWAPI_7.
518 */
519BOOL WINAPI SHLWAPI_9 (LPVOID lpView)
520{
521 TRACE("(%p)\n", lpView);
522 return UnmapViewOfFile((char *) lpView - sizeof(DWORD)); /* Include size */
523}
524
525/*************************************************************************
526 * @ [SHLWAPI.10]
527 *
528 * Destroy a block of sharable memory.
529 *
530 * PARAMS
531 * hShared [I] Shared memory handle
532 * dwProcId [I] ID of process owning hShared
533 *
534 * RETURNS
535 * Success: TRUE
536 * Failure: FALSE
537 *
538 * NOTES
539 * See SHLWAPI_7.
540 */
541BOOL WINAPI SHLWAPI_10 (HSHARED hShared, DWORD dwProcId)
542{
543 HSHARED hClose;
544
545 TRACE("(%p %ld)\n", (PVOID)hShared, dwProcId);
546
547 /* Get a copy of the handle for our process, closing the source handle */
548 hClose = SHLWAPI_DupSharedHandle(hShared, dwProcId, GetCurrentProcessId(),
549 FILE_MAP_ALL_ACCESS,DUPLICATE_CLOSE_SOURCE);
550 /* Close local copy */
551 return CloseHandle((HANDLE)hClose);
552}
553
554/*************************************************************************
555 * @ [SHLWAPI.11]
556 *
557 * Copy a sharable memory handle from one process to another.
558 *
559 * PARAMS
560 * hShared [I] Shared memory handle to duplicate
561 * dwDstProcId [I] ID of the process wanting the duplicated handle
562 * dwSrcProcId [I] ID of the process owning hShared
563 * dwAccess [I] Desired DuplicateHandle access
564 * dwOptions [I] Desired DuplicateHandle options
565 *
566 * RETURNS
567 * Success: A handle suitable for use by the dwDstProcId process.
568 * Failure: A NULL handle.
569 *
570 * NOTES
571 * See SHLWAPI_7.
572 */
573HSHARED WINAPI SHLWAPI_11(HSHARED hShared, DWORD dwDstProcId, DWORD dwSrcProcId,
574 DWORD dwAccess, DWORD dwOptions)
575{
576 HSHARED hRet;
577
578 hRet = SHLWAPI_DupSharedHandle(hShared, dwDstProcId, dwSrcProcId,
579 dwAccess, dwOptions);
580 return hRet;
581}
582
583/*************************************************************************
584 * @ [SHLWAPI.13]
585 * (Used by IE4 during startup)
586 */
587HRESULT WINAPI SHLWAPI_13 (
588 LPVOID w,
589 LPVOID x)
590{
591 FIXME("(%p %p)stub\n",w,x);
592 return 1;
593#if 0
594 /* pseudo code extracted from relay trace */
595 RegOpenKeyA(HKLM, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Aceepted Documents", &newkey);
596 ret = 0;
597 i = 0;
598 size = 0;
599 while(!ret) {
600 ret = RegEnumValueA(newkey, i, a1, a2, 0, a3, 0, 0);
601 size += ???;
602 i++;
603 }
604 b1 = LocalAlloc(0x40, size);
605 ret = 0;
606 i = 0;
607 while(!ret) {
608 ret = RegEnumValueA(newkey, i, a1, a2, 0, a3, a4, a5);
609 RegisterClipBoardFormatA(a4);
610 i++;
611 }
612 hwnd1 = GetModuleHandleA("URLMON.DLL");
613 proc = GetProcAddress(hwnd1, "CreateFormatEnumerator");
614 HeapAlloc(??, 0, 0x14);
615 HeapAlloc(??, 0, 0x50);
616 LocalAlloc(0x40, 0x78);
617 /* FIXME: bad string below */
618 lstrlenW(L"{D0FCA420-D3F5-11CF-B211-00AA004AE837}");
619 StrCpyW(a6, L"{D0FCA420-D3F5-11CF-B211-00AA004AE837}");
620
621 GetTickCount();
622 IsBadReadPtr(c1 = 0x403fd210,4);
623 InterlockedIncrement(c1+4);
624 LocalFree(b1);
625 RegCloseKey(newkey);
626 IsBadReadPtr(c1 = 0x403fd210,4);
627 InterlockedIncrement(c1+4);
628
629 HeapAlloc(40350000,00000000,00000014) retval=403fd0a8;
630 HeapAlloc(40350000,00000000,00000050) retval=403feb44;
631 hwnd1 = GetModuleHandleA("URLMON.DLL");
632 proc = GetProcAddress(hwnd1, "RegisterFormatEnumerator");
633 /* 0x1a40c88c is in URLMON.DLL just before above proc
634 * content is L"_EnumFORMATETC_"
635 * label is d1
636 */
637 IsBadReadPtr(d1 = 0x1a40c88c,00000002);
638 lstrlenW(d1);
639 lstrlenW(d1);
640 HeapAlloc(40350000,00000000,0000001e) retval=403fed44;
641 IsBadReadPtr(d2 = 0x403fd0a8,00000004);
642 InterlockedIncrement(d2+4);
643 IsBadReadPtr(d2 = 0x403fd0a8,00000004);
644 InterlockedDecrement(d2+4);
645 IsBadReadPtr(c1,00000004);
646 InterlockedDecrement(c1+4);
647 IsBadReadPtr(c1,00000004);
648 InterlockedDecrement(c1+4);
649
650#endif
651}
652
653/*************************************************************************
654 * @ [SHLWAPI.14]
655 *
656 * Function:
657 * Retrieves IE "AcceptLanguage" value from registry. ASCII mode.
658 *
659 */
660HRESULT WINAPI SHLWAPI_14 (
661 LPSTR langbuf,
662 LPDWORD buflen)
663{
664 CHAR *mystr;
665 DWORD mystrlen, mytype;
666 HKEY mykey;
667 LCID mylcid;
668
669 mystrlen = (*buflen > 6) ? *buflen : 6;
670 mystr = (CHAR*)HeapAlloc(GetProcessHeap(),
671 HEAP_ZERO_MEMORY, mystrlen);
672 RegOpenKeyA(HKEY_CURRENT_USER,
673 "Software\\Microsoft\\Internet Explorer\\International",
674 &mykey);
675 if (RegQueryValueExA(mykey, "AcceptLanguage",
676 0, &mytype, mystr, &mystrlen)) {
677 /* Did not find value */
678 mylcid = GetUserDefaultLCID();
679 /* somehow the mylcid translates into "en-us"
680 * this is similar to "LOCALE_SABBREVLANGNAME"
681 * which could be gotten via GetLocaleInfo.
682 * The only problem is LOCALE_SABBREVLANGUAGE" is
683 * a 3 char string (first 2 are country code and third is
684 * letter for "sublanguage", which does not come close to
685 * "en-us"
686 */
687 lstrcpyA(mystr, "en-us");
688 mystrlen = lstrlenA(mystr);
689 }
690 else {
691 /* handle returned string */
692 FIXME("missing code\n");
693 }
694 if (mystrlen > *buflen)
695 lstrcpynA(langbuf, mystr, *buflen);
696 else {
697 lstrcpyA(langbuf, mystr);
698 *buflen = lstrlenA(langbuf);
699 }
700 RegCloseKey(mykey);
701 HeapFree(GetProcessHeap(), 0, mystr);
702 TRACE("language is %s\n", debugstr_a(langbuf));
703 return 0;
704}
705
706/*************************************************************************
707 * @ [SHLWAPI.15]
708 *
709 * Function:
710 * Retrieves IE "AcceptLanguage" value from registry. UNICODE mode.
711 *
712 */
713HRESULT WINAPI SHLWAPI_15 (
714 LPWSTR langbuf,
715 LPDWORD buflen)
716{
717 CHAR *mystr;
718 DWORD mystrlen, mytype;
719 HKEY mykey;
720 LCID mylcid;
721
722 mystrlen = (*buflen > 6) ? *buflen : 6;
723 mystr = (CHAR*)HeapAlloc(GetProcessHeap(),
724 HEAP_ZERO_MEMORY, mystrlen);
725 RegOpenKeyA(HKEY_CURRENT_USER,
726 "Software\\Microsoft\\Internet Explorer\\International",
727 &mykey);
728 if (RegQueryValueExA(mykey, "AcceptLanguage",
729 0, &mytype, mystr, &mystrlen)) {
730 /* Did not find value */
731 mylcid = GetUserDefaultLCID();
732 /* somehow the mylcid translates into "en-us"
733 * this is similar to "LOCALE_SABBREVLANGNAME"
734 * which could be gotten via GetLocaleInfo.
735 * The only problem is LOCALE_SABBREVLANGUAGE" is
736 * a 3 char string (first 2 are country code and third is
737 * letter for "sublanguage", which does not come close to
738 * "en-us"
739 */
740 lstrcpyA(mystr, "en-us");
741 mystrlen = lstrlenA(mystr);
742 }
743 else {
744 /* handle returned string */
745 FIXME("missing code\n");
746 }
747 RegCloseKey(mykey);
748 *buflen = MultiByteToWideChar(0, 0, mystr, -1, langbuf, (*buflen)-1);
749 HeapFree(GetProcessHeap(), 0, mystr);
750 TRACE("language is %s\n", debugstr_w(langbuf));
751 return 0;
752}
753
754/*************************************************************************
755 * @ [SHLWAPI.16]
756 */
757HRESULT WINAPI SHLWAPI_16 (
758 LPVOID w,
759 LPVOID x,
760 LPVOID y,
761 LPWSTR z)
762{
763 FIXME("(%p %p %p %p)stub\n",w,x,y,z);
764 return 0xabba1252;
765}
766
767/*************************************************************************
768 * @ [SHLWAPI.18]
769 *
770 * w is pointer to address of callback routine
771 * x is pointer to LPVOID to receive address of locally allocated
772 * space size 0x14
773 * return is 0 (unless out of memory???)
774 *
775 * related to _19, _21 and _22 below
776 * only seen invoked by SHDOCVW
777 */
778LONG WINAPI SHLWAPI_18 (
779 LPVOID *w,
780 LPVOID x)
781{
782 FIXME("(%p %p)stub\n",w,x);
783 *((LPDWORD)x) = 0;
784 return 0;
785}
786
787/*************************************************************************
788 * @ [SHLWAPI.19]
789 *
790 * w is address of allocated memory from _21
791 * return is 0 (unless out of memory???)
792 *
793 * related to _18, _21 and _22 below
794 * only seen invoked by SHDOCVW
795 */
796LONG WINAPI SHLWAPI_19 (
797 LPVOID w)
798{
799 FIXME("(%p) stub\n",w);
800 return 0;
801}
802
803/*************************************************************************
804 * @ [SHLWAPI.21]
805 *
806 * w points to space allocated via .18 above
807 * LocalSize is done on it (retrieves 18)
808 * LocalReAlloc is done on it to size 8 with LMEM_MOVEABLE & LMEM_ZEROINIT
809 * x values seen 0xa0000005
810 * returns 1
811 *
812 * relates to _18, _19 and _22 above and below
813 * only seen invoked by SHDOCVW
814 */
815LONG WINAPI SHLWAPI_21 (
816 LPVOID w,
817 DWORD x)
818{
819 FIXME("(%p %lx)stub\n",w,x);
820 return 1;
821}
822
823/*************************************************************************
824 * @ [SHLWAPI.22]
825 *
826 * return is 'w' value seen in x is 0xa0000005
827 *
828 * relates to _18, _19 and _21 above
829 * only seen invoked by SHDOCVW
830 */
831LPVOID WINAPI SHLWAPI_22 (
832 LPVOID w,
833 DWORD x)
834{
835 FIXME("(%p %lx)stub\n",w,x);
836 return w;
837}
838
839/*************************************************************************
840 * @ [SHLWAPI.23]
841 *
842 * NOTES
843 * converts a guid to a string
844 * returns strlen(str)
845 */
846DWORD WINAPI SHLWAPI_23 (
847 REFGUID guid, /* [in] clsid */
848 LPSTR str, /* [out] buffer */
849 INT cmax) /* [in] size of buffer */
850{
851 char xguid[40];
852
853 sprintf( xguid, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
854 guid->Data1, guid->Data2, guid->Data3,
855 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
856 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
857 TRACE("(%s %p 0x%08x)stub\n", xguid, str, cmax);
858 if (strlen(xguid)>=cmax) return 0;
859 strcpy(str,xguid);
860 return strlen(xguid) + 1;
861}
862
863/*************************************************************************
864 * @ [SHLWAPI.24]
865 *
866 * NOTES
867 * converts a guid to a string
868 * returns strlen(str)
869 */
870DWORD WINAPI SHLWAPI_24 (
871 REFGUID guid, /* [in] clsid */
872 LPWSTR str, /* [out] buffer */
873 INT cmax) /* [in] size of buffer */
874{
875 char xguid[40];
876
877 sprintf( xguid, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
878 guid->Data1, guid->Data2, guid->Data3,
879 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
880 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
881 return MultiByteToWideChar( CP_ACP, 0, xguid, -1, str, cmax );
882}
883
884/*************************************************************************
885 * @ [SHLWAPI.25]
886 *
887 * Seems to be iswalpha
888 */
889BOOL WINAPI SHLWAPI_25(WCHAR wc)
890{
891 return (get_char_typeW(wc) & C1_ALPHA) != 0;
892}
893
894/*************************************************************************
895 * @ [SHLWAPI.26]
896 *
897 * Seems to be iswupper
898 */
899BOOL WINAPI SHLWAPI_26(WCHAR wc)
900{
901 return (get_char_typeW(wc) & C1_UPPER) != 0;
902}
903
904/*************************************************************************
905 * @ [SHLWAPI.27]
906 *
907 * Seems to be iswlower
908 */
909BOOL WINAPI SHLWAPI_27(WCHAR wc)
910{
911 return (get_char_typeW(wc) & C1_LOWER) != 0;
912}
913
914/*************************************************************************
915 * @ [SHLWAPI.28]
916 *
917 * Seems to be iswalnum
918 */
919BOOL WINAPI SHLWAPI_28(WCHAR wc)
920{
921 return (get_char_typeW(wc) & (C1_ALPHA|C1_DIGIT)) != 0;
922}
923
924/*************************************************************************
925 * @ [SHLWAPI.29]
926 *
927 * Seems to be iswspace
928 */
929BOOL WINAPI SHLWAPI_29(WCHAR wc)
930{
931 return (get_char_typeW(wc) & C1_SPACE) != 0;
932}
933
934/*************************************************************************
935 * @ [SHLWAPI.30]
936 *
937 * Seems to be iswblank
938 */
939BOOL WINAPI SHLWAPI_30(WCHAR wc)
940{
941 return (get_char_typeW(wc) & C1_BLANK) != 0;
942}
943
944/*************************************************************************
945 * @ [SHLWAPI.31]
946 *
947 * Seems to be iswpunct
948 */
949BOOL WINAPI SHLWAPI_31(WCHAR wc)
950{
951 return (get_char_typeW(wc) & C1_PUNCT) != 0;
952}
953
954/*************************************************************************
955 * @ [SHLWAPI.32]
956 *
957 * Seems to be iswcntrl
958 */
959BOOL WINAPI SHLWAPI_32(WCHAR wc)
960{
961 return (get_char_typeW(wc) & C1_CNTRL) != 0;
962}
963
964/*************************************************************************
965 * @ [SHLWAPI.33]
966 *
967 * Seems to be iswdigit
968 */
969BOOL WINAPI SHLWAPI_33(WCHAR wc)
970{
971 return (get_char_typeW(wc) & C1_DIGIT) != 0;
972}
973
974/*************************************************************************
975 * @ [SHLWAPI.34]
976 *
977 * Seems to be iswxdigit
978 */
979BOOL WINAPI SHLWAPI_34(WCHAR wc)
980{
981 return (get_char_typeW(wc) & C1_XDIGIT) != 0;
982}
983
984/*************************************************************************
985 * @ [SHLWAPI.35]
986 *
987 */
988BOOL WINAPI SHLWAPI_35(LPVOID p1, DWORD dw2, LPVOID p3)
989{
990 FIXME("(%p, 0x%08lx, %p): stub\n", p1, dw2, p3);
991 return TRUE;
992}
993
994/*************************************************************************
995 * @ [SHLWAPI.36]
996 *
997 */
998BOOL WINAPI SHLWAPI_36(HMENU h1, UINT ui2, UINT h3, LPCWSTR p4)
999{
1000 TRACE("(0x%08x, 0x%08x, 0x%08x, %s): stub\n",
1001 h1, ui2, h3, debugstr_w(p4));
1002 return AppendMenuW(h1, ui2, h3, p4);
1003}
1004
1005/*************************************************************************
1006 * @ [SHLWAPI.74]
1007 *
1008 * Get the text from a given dialog item.
1009 */
1010INT WINAPI SHLWAPI_74(HWND hWnd, INT nItem, LPWSTR lpsDest,INT nDestLen)
1011{
1012 HWND hItem = GetDlgItem(hWnd, nItem);
1013
1014 if (hItem)
1015 return GetWindowTextW(hItem, lpsDest, nDestLen);
1016 if (nDestLen)
1017 *lpsDest = (WCHAR)'\0';
1018 return 0;
1019}
1020
1021/*************************************************************************
1022 * @ [SHLWAPI.151]
1023 * Function: Compare two ASCII strings for "len" bytes.
1024 * Returns: *str1-*str2 (case sensitive)
1025 */
1026DWORD WINAPI SHLWAPI_151(LPSTR str1, LPSTR str2, INT len)
1027{
1028 return strncmp( str1, str2, len );
1029}
1030
1031/*************************************************************************
1032 * @ [SHLWAPI.152]
1033 *
1034 * Function: Compare two WIDE strings for "len" bytes.
1035 * Returns: *str1-*str2 (case sensitive)
1036 */
1037DWORD WINAPI SHLWAPI_152(LPWSTR str1, LPWSTR str2, INT len)
1038{
1039 return strncmpW( str1, str2, len );
1040}
1041
1042/*************************************************************************
1043 * @ [SHLWAPI.153]
1044 * Function: Compare two ASCII strings for "len" bytes via caseless compare.
1045 * Returns: *str1-*str2 (case insensitive)
1046 */
1047DWORD WINAPI SHLWAPI_153(LPSTR str1, LPSTR str2, DWORD len)
1048{
1049 return strncasecmp( str1, str2, len );
1050}
1051
1052/*************************************************************************
1053 * @ [SHLWAPI.154]
1054 *
1055 * Function: Compare two WIDE strings for "len" bytes via caseless compare.
1056 * Returns: *str1-*str2 (case insensitive)
1057 */
1058DWORD WINAPI SHLWAPI_154(LPWSTR str1, LPWSTR str2, DWORD len)
1059{
1060 return strncmpiW( str1, str2, len );
1061}
1062
1063/*************************************************************************
1064 * @ [SHLWAPI.155]
1065 *
1066 * Case sensitive string compare (ASCII). Does not SetLastError().
1067 */
1068DWORD WINAPI SHLWAPI_155 ( LPSTR str1, LPSTR str2)
1069{
1070 return strcmp(str1, str2);
1071}
1072
1073/*************************************************************************
1074 * @ [SHLWAPI.156]
1075 *
1076 * Case sensitive string compare. Does not SetLastError().
1077 */
1078DWORD WINAPI SHLWAPI_156 ( LPWSTR str1, LPWSTR str2)
1079{
1080 return strcmpW( str1, str2 );
1081}
1082
1083/*************************************************************************
1084 * @ [SHLWAPI.158]
1085 *
1086 * Case insensitive string compare. Does not SetLastError(). ??
1087 */
1088DWORD WINAPI SHLWAPI_158 ( LPWSTR str1, LPWSTR str2)
1089{
1090 return strcmpiW( str1, str2 );
1091}
1092
1093/*************************************************************************
1094 * @ [SHLWAPI.162]
1095 *
1096 * Ensure a multibyte character string doesn't end in a hanging lead byte.
1097 */
1098DWORD WINAPI SHLWAPI_162(LPSTR lpStr, DWORD size)
1099{
1100 if (lpStr && size)
1101 {
1102 LPSTR lastByte = lpStr + size - 1;
1103
1104 while(lpStr < lastByte)
1105 lpStr += IsDBCSLeadByte(*lpStr) ? 2 : 1;
1106
1107 if(lpStr == lastByte && IsDBCSLeadByte(*lpStr))
1108 {
1109 *lpStr = '\0';
1110 size--;
1111 }
1112 return size;
1113 }
1114 return 0;
1115}
1116
1117/*************************************************************************
1118 * @ [SHLWAPI.164]
1119 */
1120DWORD WINAPI SHLWAPI_164 (
1121 LPVOID u,
1122 LPVOID v,
1123 LPVOID w,
1124 LPVOID x,
1125 LPVOID y,
1126 LPVOID z)
1127{
1128 TRACE("(%p %p %p %p %p %p) stub\n",u,v,w,x,y,z);
1129 return 0x80004002; /* E_NOINTERFACE */
1130}
1131
1132/*************************************************************************
1133 * @ [SHLWAPI.165]
1134 *
1135 * SetWindowLongA with mask.
1136 */
1137LONG WINAPI SHLWAPI_165(HWND hwnd, INT offset, UINT wFlags, UINT wMask)
1138{
1139 LONG ret = GetWindowLongA(hwnd, offset);
1140 UINT newFlags = (wFlags & wMask) | (ret & ~wFlags);
1141
1142 if (newFlags != ret)
1143 ret = SetWindowLongA(hwnd, offset, newFlags);
1144 return ret;
1145}
1146
1147/*************************************************************************
1148 * @ [SHLWAPI.169]
1149 *
1150 * Do IUnknown::Release on passed object.
1151 */
1152DWORD WINAPI SHLWAPI_169 (IUnknown ** lpUnknown)
1153{
1154 IUnknown *temp;
1155
1156 TRACE("(%p)\n",lpUnknown);
1157 if(!lpUnknown || !*((LPDWORD)lpUnknown)) return 0;
1158 temp = *lpUnknown;
1159 *lpUnknown = NULL;
1160 TRACE("doing Release\n");
1161 return IUnknown_Release(temp);
1162}
1163
1164/*************************************************************************
1165 * @ [SHLWAPI.170]
1166 *
1167 * Skip URL '//' sequence.
1168 */
1169LPCSTR WINAPI SHLWAPI_170(LPCSTR lpszSrc)
1170{
1171 if (lpszSrc && lpszSrc[0] == '/' && lpszSrc[1] == '/')
1172 lpszSrc += 2;
1173 return lpszSrc;
1174}
1175
1176/*************************************************************************
1177 * @ [SHLWAPI.172]
1178 * Get window handle of OLE object
1179 */
1180DWORD WINAPI SHLWAPI_172 (
1181 IUnknown *y, /* [in] OLE object interface */
1182 LPHWND z) /* [out] location to put window handle */
1183{
1184 DWORD ret;
1185 IUnknown *pv;
1186
1187 TRACE("(%p %p)\n",y,z);
1188 if (!y) return E_FAIL;
1189
1190 if ((ret = IUnknown_QueryInterface(y, &IID_IOleWindow,(LPVOID *)&pv)) < 0) {
1191 /* error */
1192 return ret;
1193 }
1194 ret = IOleWindow_GetWindow((IOleWindow *)pv, z);
1195 IUnknown_Release(pv);
1196 TRACE("result hwnd=%08x\n", *z);
1197 return ret;
1198}
1199
1200/*************************************************************************
1201 * @ [SHLWAPI.174]
1202 *
1203 * Seems to do call either IObjectWithSite::SetSite or
1204 * IPersistMoniker::GetClassID. But since we do not implement either
1205 * of those classes in our headers, we will fake it out.
1206 */
1207DWORD WINAPI SHLWAPI_174(
1208 IUnknown *p1, /* [in] OLE object */
1209 LPVOID *p2) /* [out] ptr to result of either GetClassID
1210 or SetSite call. */
1211{
1212 DWORD ret, aa;
1213
1214 if (!p1) return E_FAIL;
1215
1216 /* see if SetSite interface exists for IObjectWithSite object */
1217 ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id1, (LPVOID *)&p1);
1218 TRACE("first IU_QI ret=%08lx, p1=%p\n", ret, p1);
1219 if (ret) {
1220
1221 /* see if GetClassId interface exists for IPersistMoniker object */
1222 ret = IUnknown_QueryInterface((IUnknown *)p1, (REFIID)id2, (LPVOID *)&aa);
1223 TRACE("second IU_QI ret=%08lx, aa=%08lx\n", ret, aa);
1224 if (ret) return ret;
1225
1226 /* fake a GetClassId call */
1227 ret = IOleWindow_GetWindow((IOleWindow *)aa, (HWND*)p2);
1228 TRACE("second IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1229 *(LPDWORD)p2);
1230 IUnknown_Release((IUnknown *)aa);
1231 }
1232 else {
1233 /* fake a SetSite call */
1234 ret = IOleWindow_GetWindow((IOleWindow *)p1, (HWND*)p2);
1235 TRACE("first IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret,
1236 *(LPDWORD)p2);
1237 IUnknown_Release((IUnknown *)p1);
1238 }
1239 return ret;
1240}
1241
1242/*************************************************************************
1243 * @ [SHLWAPI.175]
1244 *
1245 * NOTE:
1246 * Param1 can be an IShellFolder Object
1247 */
1248HRESULT WINAPI SHLWAPI_175 (LPVOID x, LPVOID y)
1249{
1250 FIXME("(%p %p) stub\n", x,y);
1251 return E_FAIL;
1252}
1253/*************************************************************************
1254 * @ [SHLWAPI.176]
1255 *
1256 * Function appears to be interface to IServiceProvider::QueryService
1257 *
1258 * NOTE:
1259 * returns E_NOINTERFACE
1260 * E_FAIL if w == 0
1261 * S_OK if _219 called successfully
1262 */
1263DWORD WINAPI SHLWAPI_176 (
1264 IUnknown* unk, /* [in] object to give Service Provider */
1265 REFGUID sid, /* [in] Service ID */
1266 REFIID riid, /* [in] Function requested */
1267 LPVOID *z) /* [out] place to save interface pointer */
1268{
1269 DWORD ret;
1270 LPVOID aa;
1271 *z = 0;
1272 if (!unk) return E_FAIL;
1273 ret = IUnknown_QueryInterface(unk, &IID_IServiceProvider, &aa);
1274 TRACE("did IU_QI retval=%08lx, aa=%p\n", ret, aa);
1275 if (ret) return ret;
1276 ret = IServiceProvider_QueryService((IServiceProvider *)aa, sid, riid,
1277 (void **)z);
1278 TRACE("did ISP_QS retval=%08lx, *z=%p\n", ret, (LPVOID)*z);
1279 IUnknown_Release((IUnknown*)aa);
1280 return ret;
1281}
1282
1283/*************************************************************************
1284 * @ [SHLWAPI.181]
1285 *
1286 * Enable or disable a menu item.
1287 */
1288UINT WINAPI SHLWAPI_181(HMENU hMenu, UINT wItemID, BOOL bEnable)
1289{
1290 return EnableMenuItem(hMenu, wItemID, bEnable ? MF_ENABLED : MF_GRAYED);
1291}
1292
1293/*************************************************************************
1294 * @ [SHLWAPI.183]
1295 *
1296 * Register a window class if it isn't already.
1297 */
1298DWORD WINAPI SHLWAPI_183(WNDCLASSA *wndclass)
1299{
1300 WNDCLASSA wca;
1301 if (GetClassInfoA(wndclass->hInstance, wndclass->lpszClassName, &wca))
1302 return TRUE;
1303 return (DWORD)RegisterClassA(wndclass);
1304}
1305
1306/*************************************************************************
1307 * @ [SHLWAPI.193]
1308 */
1309DWORD WINAPI SHLWAPI_193 ()
1310{
1311 HDC hdc;
1312 DWORD ret;
1313
1314 TRACE("()\n");
1315
1316 hdc = GetDC(0);
1317 ret = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
1318 ReleaseDC(0, hdc);
1319 return ret;
1320}
1321
1322/*************************************************************************
1323 * @ [SHLWAPI.199]
1324 *
1325 * Copy interface pointer
1326 */
1327DWORD WINAPI SHLWAPI_199 (
1328 IUnknown **dest, /* [out] pointer to copy of interface ptr */
1329 IUnknown *src) /* [in] interface pointer */
1330{
1331 TRACE("(%p %p)\n",dest,src);
1332 if (*dest != src) {
1333 if (*dest)
1334 IUnknown_Release(*dest);
1335 if (src) {
1336 IUnknown_AddRef(src);
1337 *dest = src;
1338 }
1339 }
1340 return 4;
1341}
1342
1343/*************************************************************************
1344 * @ [SHLWAPI.208]
1345 *
1346 * Some sort of memory management process - associated with _210
1347 */
1348DWORD WINAPI SHLWAPI_208 (
1349 DWORD a,
1350 DWORD b,
1351 LPVOID c,
1352 LPVOID d,
1353 DWORD e)
1354{
1355 FIXME("(0x%08lx 0x%08lx %p %p 0x%08lx) stub\n",
1356 a, b, c, d, e);
1357 return 1;
1358}
1359
1360/*************************************************************************
1361 * @ [SHLWAPI.209]
1362 *
1363 * Some sort of memory management process - associated with _208
1364 */
1365DWORD WINAPI SHLWAPI_209 (
1366 LPVOID a)
1367{
1368 FIXME("(%p) stub\n",
1369 a);
1370 return 1;
1371}
1372
1373/*************************************************************************
1374 * @ [SHLWAPI.210]
1375 *
1376 * Some sort of memory management process - associated with _208
1377 */
1378DWORD WINAPI SHLWAPI_210 (
1379 LPVOID a,
1380 DWORD b,
1381 LPVOID c)
1382{
1383 FIXME("(%p 0x%08lx %p) stub\n",
1384 a, b, c);
1385 return 0;
1386}
1387
1388/*************************************************************************
1389 * @ [SHLWAPI.211]
1390 */
1391DWORD WINAPI SHLWAPI_211 (
1392 LPVOID a,
1393 DWORD b)
1394{
1395 FIXME("(%p 0x%08lx) stub\n",
1396 a, b);
1397 return 1;
1398}
1399
1400/*************************************************************************
1401 * @ [SHLWAPI.215]
1402 *
1403 * NOTES
1404 * check me!
1405 */
1406DWORD WINAPI SHLWAPI_215 (
1407 LPCSTR lpStrSrc,
1408 LPWSTR lpwStrDest,
1409 int len)
1410{
1411 INT len_a, ret;
1412
1413 len_a = lstrlenA(lpStrSrc);
1414 ret = MultiByteToWideChar(0, 0, lpStrSrc, len_a, lpwStrDest, len);
1415 TRACE("%s %s %d, ret=%d\n",
1416 debugstr_a(lpStrSrc), debugstr_w(lpwStrDest), len, ret);
1417 return ret;
1418}
1419
1420/*************************************************************************
1421 * @ [SHLWAPI.218]
1422 *
1423 * WideCharToMultiByte with multi language support.
1424 */
1425INT WINAPI SHLWAPI_218(UINT CodePage, LPCWSTR lpSrcStr, LPSTR lpDstStr,
1426 LPINT lpnMultiCharCount)
1427{
1428 WCHAR emptyW[] = { '\0' };
1429 int len , reqLen;
1430 LPSTR mem;
1431
1432 if (!lpDstStr || !lpnMultiCharCount)
1433 return 0;
1434
1435 if (!lpSrcStr)
1436 lpSrcStr = emptyW;
1437
1438 *lpDstStr = '\0';
1439
1440 len = strlenW(lpSrcStr) + 1;
1441
1442 switch (CodePage)
1443 {
1444 case CP_WINUNICODE:
1445 CodePage = CP_UTF8; /* Fall through... */
1446 case 0x0000C350: /* FIXME: CP_ #define */
1447 case CP_UTF7:
1448 case CP_UTF8:
1449 {
1450 DWORD dwMode = 0;
1451 INT nWideCharCount = len - 1;
1452
1453 GET_FUNC(pConvertINetUnicodeToMultiByte, mlang, "ConvertINetUnicodeToMultiByte", 0);
1454 if (!pConvertINetUnicodeToMultiByte(&dwMode, CodePage, lpSrcStr, &nWideCharCount, lpDstStr,
1455 lpnMultiCharCount))
1456 return 0;
1457
1458 if (nWideCharCount < len - 1)
1459 {
1460 mem = (LPSTR)HeapAlloc(GetProcessHeap(), 0, *lpnMultiCharCount);
1461 if (!mem)
1462 return 0;
1463
1464 *lpnMultiCharCount = 0;
1465
1466 if (pConvertINetUnicodeToMultiByte(&dwMode, CodePage, lpSrcStr, &len, mem, lpnMultiCharCount))
1467 {
1468 SHLWAPI_162 (mem, *lpnMultiCharCount);
1469 lstrcpynA(lpDstStr, mem, *lpnMultiCharCount + 1);
1470 return *lpnMultiCharCount + 1;
1471 }
1472 HeapFree(GetProcessHeap(), 0, mem);
1473 return *lpnMultiCharCount;
1474 }
1475 lpDstStr[*lpnMultiCharCount] = '\0';
1476 return *lpnMultiCharCount;
1477 }
1478 break;
1479 default:
1480 break;
1481 }
1482
1483 reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, lpDstStr,
1484 *lpnMultiCharCount, NULL, NULL);
1485
1486 if (!reqLen && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1487 {
1488 reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, NULL, 0, NULL, NULL);
1489 if (reqLen)
1490 {
1491 mem = (LPSTR)HeapAlloc(GetProcessHeap(), 0, reqLen);
1492 if (mem)
1493 {
1494 reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, mem,
1495 reqLen, NULL, NULL);
1496
1497 reqLen = SHLWAPI_162(mem, *lpnMultiCharCount);
1498 reqLen++;
1499
1500 lstrcpynA(lpDstStr, mem, *lpnMultiCharCount);
1501
1502 HeapFree(GetProcessHeap(), 0, mem);
1503 }
1504 }
1505 }
1506 return reqLen;
1507}
1508
1509/*************************************************************************
1510 * @ [SHLWAPI.217]
1511 *
1512 * Hmm, some program used lpnMultiCharCount == 0x3 (and lpSrcStr was "C")
1513 * --> Crash. Something wrong here.
1514 *
1515 * It seems from OE v5 that the third param is the count. (GA 11/2001)
1516 */
1517INT WINAPI SHLWAPI_217(LPCWSTR lpSrcStr, LPSTR lpDstStr, INT MultiCharCount)
1518{
1519 INT myint = MultiCharCount;
1520
1521 return SHLWAPI_218(CP_ACP, lpSrcStr, lpDstStr, &myint);
1522}
1523
1524/*************************************************************************
1525 * @ [SHLWAPI.219]
1526 *
1527 * Seems to be "super" QueryInterface. Supplied with at table of interfaces
1528 * and an array of IIDs and offsets into the table.
1529 *
1530 * NOTES
1531 * error codes: E_POINTER, E_NOINTERFACE
1532 */
1533typedef struct {
1534 REFIID refid;
1535 DWORD indx;
1536} IFACE_INDEX_TBL;
1537
1538HRESULT WINAPI SHLWAPI_219 (
1539 LPVOID w, /* [in] table of interfaces */
1540 IFACE_INDEX_TBL *x, /* [in] array of REFIIDs and indexes to above */
1541 REFIID riid, /* [in] REFIID to get interface for */
1542 LPVOID *z) /* [out] location to get interface pointer */
1543{
1544 HRESULT ret;
1545 IUnknown *a_vtbl;
1546 IFACE_INDEX_TBL *xmove;
1547
1548 TRACE("(%p %p %s %p)\n",
1549 w,x,debugstr_guid(riid),z);
1550 if (z) {
1551 xmove = x;
1552 while (xmove->refid) {
1553 TRACE("trying (indx %ld) %s\n", xmove->indx,
1554 debugstr_guid(xmove->refid));
1555 if (IsEqualIID(riid, xmove->refid)) {
1556 a_vtbl = (IUnknown*)(xmove->indx + (LPBYTE)w);
1557 TRACE("matched, returning (%p)\n", a_vtbl);
1558 *z = (LPVOID)a_vtbl;
1559 IUnknown_AddRef(a_vtbl);
1560 return S_OK;
1561 }
1562 xmove++;
1563 }
1564
1565 if (IsEqualIID(riid, &IID_IUnknown)) {
1566 a_vtbl = (IUnknown*)(x->indx + (LPBYTE)w);
1567 TRACE("returning first for IUnknown (%p)\n", a_vtbl);
1568 *z = (LPVOID)a_vtbl;
1569 IUnknown_AddRef(a_vtbl);
1570 return S_OK;
1571 }
1572 *z = 0;
1573 ret = E_NOINTERFACE;
1574 } else
1575 ret = E_POINTER;
1576 return ret;
1577}
1578
1579/*************************************************************************
1580 * @ [SHLWAPI.222]
1581 *
1582 * NOTES
1583 * securityattributes missing
1584 */
1585HANDLE WINAPI SHLWAPI_222 (LPCLSID guid)
1586{
1587 char lpstrName[80];
1588
1589 sprintf( lpstrName, "shell.{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
1590 guid->Data1, guid->Data2, guid->Data3,
1591 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
1592 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
1593 FIXME("(%s) stub\n", lpstrName);
1594 return CreateSemaphoreA(NULL,0, 0x7fffffff, lpstrName);
1595}
1596
1597/*************************************************************************
1598 * @ [SHLWAPI.223]
1599 *
1600 * NOTES
1601 * get the count of the semaphore
1602 */
1603DWORD WINAPI SHLWAPI_223 (HANDLE handle)
1604{
1605 DWORD oldCount;
1606
1607 FIXME("(0x%08x) stub\n",handle);
1608
1609 ReleaseSemaphore( handle, 1, &oldCount); /* +1 */
1610 WaitForSingleObject( handle, 0 ); /* -1 */
1611 return oldCount;
1612}
1613
1614/*************************************************************************
1615 * @ [SHLWAPI.236]
1616 */
1617HMODULE WINAPI SHLWAPI_236 (REFIID lpUnknown)
1618{
1619 HKEY newkey;
1620 DWORD type, count;
1621 CHAR value[MAX_PATH], string[MAX_PATH];
1622
1623 strcpy(string, "CLSID\\");
1624 strcat(string, debugstr_guid(lpUnknown));
1625 strcat(string, "\\InProcServer32");
1626
1627 count = MAX_PATH;
1628 RegOpenKeyExA(HKEY_CLASSES_ROOT, string, 0, 1, &newkey);
1629 RegQueryValueExA(newkey, 0, 0, &type, value, &count);
1630 RegCloseKey(newkey);
1631 return LoadLibraryExA(value, 0, 0);
1632}
1633
1634/*************************************************************************
1635 * @ [SHLWAPI.237]
1636 *
1637 * Unicode version of SHLWAPI_183.
1638 */
1639DWORD WINAPI SHLWAPI_237 (WNDCLASSW * lpWndClass)
1640{
1641 WNDCLASSW WndClass;
1642
1643 TRACE("(0x%08x %s)\n",lpWndClass->hInstance, debugstr_w(lpWndClass->lpszClassName));
1644
1645 if (GetClassInfoW(lpWndClass->hInstance, lpWndClass->lpszClassName, &WndClass))
1646 return TRUE;
1647 return RegisterClassW(lpWndClass);
1648}
1649
1650/*************************************************************************
1651 * @ [SHLWAPI.239]
1652 */
1653DWORD WINAPI SHLWAPI_239(HINSTANCE hInstance, LPVOID p2, DWORD dw3)
1654{
1655 FIXME("(0x%08x %p 0x%08lx) stub\n",
1656 hInstance, p2, dw3);
1657 return 0;
1658#if 0
1659 /* pseudo code from relay trace */
1660 WideCharToMultiByte(0, 0, L"Shell DocObject View", -1, &aa, 0x0207, 0, 0);
1661 GetClassInfoA(70fe0000,405868ec "Shell DocObject View",40586b14);
1662 /* above pair repeated for:
1663 TridentThicketUrlDlClass
1664 Shell Embedding
1665 CIESplashScreen
1666 Inet Notify_Hidden
1667 OCHost
1668 */
1669#endif
1670}
1671
1672/*************************************************************************
1673 * @ [SHLWAPI.240]
1674 *
1675 * Calls ASCII or Unicode WindowProc for the given window.
1676 */
1677LRESULT CALLBACK SHLWAPI_240(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
1678{
1679 if (IsWindowUnicode(hWnd))
1680 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
1681 return DefWindowProcA(hWnd, uMessage, wParam, lParam);
1682}
1683
1684/*************************************************************************
1685 * @ [SHLWAPI.241]
1686 *
1687 */
1688DWORD WINAPI SHLWAPI_241 ()
1689{
1690 FIXME("()stub\n");
1691 return /* 0xabba1243 */ 0;
1692}
1693
1694/*************************************************************************
1695 * @ [SHLWAPI.266]
1696 *
1697 * native does at least approximately:
1698 * strcpyW(newstr, x);
1699 * strcatW(newstr, "\\Restrictions");
1700 * if (RegOpenKeyExA(80000001, newstr, 00000000,00000001,40520b78))
1701 * return 0;
1702 * *unknown*
1703 */
1704DWORD WINAPI SHLWAPI_266 (
1705 LPVOID w,
1706 LPVOID x, /* [in] partial registry key */
1707 LPVOID y,
1708 LPVOID z)
1709{
1710 FIXME("(%p %p %p %p)stub\n",w,x,y,z);
1711 return /* 0xabba1248 */ 0;
1712}
1713
1714/*************************************************************************
1715 * @ [SHLWAPI.267]
1716 */
1717HRESULT WINAPI SHLWAPI_267 (
1718 LPVOID w,
1719 LPVOID x,
1720 LPVOID y, /* [???] NOTE: same as 3rd parameter of SHLWAPI_219 */
1721 LPVOID z) /* [???] NOTE: same as 4th parameter of SHLWAPI_219 */
1722{
1723 FIXME("(%p %p %p %p)stub\n",w,x,y,z);
1724
1725 /* native seems to do:
1726 * SHLWAPI_219 ((LPVOID)(((LPSTR)x)-4), ???, (REFIID) y, (LPVOID*) z);
1727 */
1728
1729 *((LPDWORD)z) = 0xabba1200;
1730 return /* 0xabba1254 */ 0;
1731}
1732
1733/*************************************************************************
1734 * @ [SHLWAPI.268]
1735 */
1736DWORD WINAPI SHLWAPI_268 (
1737 LPVOID w,
1738 LPVOID x)
1739{
1740 FIXME("(%p %p)\n",w,x);
1741 return 0xabba1251; /* 0 = failure */
1742}
1743
1744/*************************************************************************
1745 * @ [SHLWAPI.276]
1746 *
1747 * on first call process does following: other calls just returns 2
1748 * instance = LoadLibraryA("SHELL32.DLL");
1749 * func = GetProcAddress(instance, "DllGetVersion");
1750 * ret = RegOpenKeyExA(80000002, "Software\\Microsoft\\Internet Explorer",00000000,0002001f, newkey);
1751 * ret = RegQueryValueExA(newkey, "IntegratedBrowser",00000000,00000000,4052588c,40525890);
1752 * RegCloseKey(newkey);
1753 * FreeLibrary(instance);
1754 * return 2;
1755 */
1756DWORD WINAPI SHLWAPI_276 ()
1757{
1758 FIXME("()stub\n");
1759 return /* 0xabba1244 */ 2;
1760}
1761
1762/*************************************************************************
1763 * @ [SHLWAPI.278]
1764 *
1765 */
1766HWND WINAPI SHLWAPI_278 (
1767 LONG wndProc,
1768 HWND hWndParent,
1769 DWORD dwExStyle,
1770 DWORD dwStyle,
1771 HMENU hMenu,
1772 LONG z)
1773{
1774 WNDCLASSA wndclass;
1775 HWND hwnd;
1776 HCURSOR hCursor;
1777 char * clsname = "WorkerA";
1778
1779 FIXME("(0x%08lx 0x%08x 0x%08lx 0x%08lx 0x%08x 0x%08lx) partial stub\n",
1780 wndProc,hWndParent,dwExStyle,dwStyle,hMenu,z);
1781
1782 hCursor = LoadCursorA(0x00000000,IDC_ARROWA);
1783
1784 if(!GetClassInfoA(shlwapi_hInstance, clsname, &wndclass))
1785 {
1786 RtlZeroMemory(&wndclass, sizeof(WNDCLASSA));
1787 wndclass.lpfnWndProc = DefWindowProcW;
1788 wndclass.cbWndExtra = 4;
1789 wndclass.hInstance = shlwapi_hInstance;
1790 wndclass.hCursor = hCursor;
1791 wndclass.hbrBackground = COLOR_BTNSHADOW;
1792 wndclass.lpszMenuName = NULL;
1793 wndclass.lpszClassName = clsname;
1794 RegisterClassA (&wndclass);
1795 }
1796 hwnd = CreateWindowExA(dwExStyle, clsname, 0,dwStyle,0,0,0,0,hWndParent,
1797 hMenu,shlwapi_hInstance,0);
1798 SetWindowLongA(hwnd, 0, z);
1799 SetWindowLongA(hwnd, GWL_WNDPROC, wndProc);
1800 return hwnd;
1801}
1802
1803/*************************************************************************
1804 * @ [SHLWAPI.289]
1805 *
1806 * Late bound call to winmm.PlaySoundW
1807 */
1808BOOL WINAPI SHLWAPI_289(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
1809{
1810 GET_FUNC(pPlaySoundW, winmm, "PlaySoundW", FALSE);
1811 return pPlaySoundW(pszSound, hmod, fdwSound);
1812}
1813
1814/*************************************************************************
1815 * @ [SHLWAPI.294]
1816 */
1817BOOL WINAPI SHLWAPI_294(LPSTR str1, LPSTR str2, LPSTR pStr, DWORD some_len, LPCSTR lpStr2)
1818{
1819 /*
1820 * str1: "I" "I" pushl esp+0x20
1821 * str2: "U" "I" pushl 0x77c93810
1822 * (is "I" and "U" "integer" and "unsigned" ??)
1823 *
1824 * pStr: "" "" pushl eax
1825 * some_len: 0x824 0x104 pushl 0x824
1826 * lpStr2: "%l" "%l" pushl esp+0xc
1827 *
1828 * shlwapi. StrCpyNW(lpStr2, irrelevant_var, 0x104);
1829 * LocalAlloc(0x00, some_len) -> irrelevant_var
1830 * LocalAlloc(0x40, irrelevant_len) -> pStr
1831 * shlwapi.294(str1, str2, pStr, some_len, lpStr2);
1832 * shlwapi.PathRemoveBlanksW(pStr);
1833 */
1834 ERR("('%s', '%s', '%s', %08lx, '%s'): stub!\n", str1, str2, pStr, some_len, lpStr2);
1835 return TRUE;
1836}
1837
1838/*************************************************************************
1839 * @ [SHLWAPI.313]
1840 *
1841 * Late bound call to shell32.SHGetFileInfoW
1842 */
1843DWORD WINAPI SHLWAPI_313(LPCWSTR path, DWORD dwFileAttributes,
1844 SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
1845{
1846 GET_FUNC(pSHGetFileInfoW, shell32, "SHGetFileInfoW", 0);
1847 return pSHGetFileInfoW(path, dwFileAttributes, psfi, sizeofpsfi, flags);
1848}
1849
1850/*************************************************************************
1851 * @ [SHLWAPI.318]
1852 *
1853 * Late bound call to shell32.DragQueryFileW
1854 */
1855UINT WINAPI SHLWAPI_318(HDROP hDrop, UINT lFile, LPWSTR lpszFile, UINT lLength)
1856{
1857 GET_FUNC(pDragQueryFileW, shell32, "DragQueryFileW", 0);
1858 return pDragQueryFileW(hDrop, lFile, lpszFile, lLength);
1859}
1860
1861/*************************************************************************
1862 * @ [SHLWAPI.333]
1863 *
1864 * Late bound call to shell32.SHBrowseForFolderW
1865 */
1866LPITEMIDLIST WINAPI SHLWAPI_333(LPBROWSEINFOW lpBi)
1867{
1868 GET_FUNC(pSHBrowseForFolderW, shell32, "SHBrowseForFolderW", NULL);
1869 return pSHBrowseForFolderW(lpBi);
1870}
1871
1872/*************************************************************************
1873 * @ [SHLWAPI.334]
1874 *
1875 * Late bound call to shell32.SHGetPathFromIDListW
1876 */
1877BOOL WINAPI SHLWAPI_334(LPCITEMIDLIST pidl,LPWSTR pszPath)
1878{
1879 GET_FUNC(pSHGetPathFromIDListW, shell32, "SHGetPathFromIDListW", 0);
1880 return pSHGetPathFromIDListW(pidl, pszPath);
1881}
1882
1883/*************************************************************************
1884 * @ [SHLWAPI.335]
1885 *
1886 * Late bound call to shell32.ShellExecuteExW
1887 */
1888BOOL WINAPI SHLWAPI_335(LPSHELLEXECUTEINFOW lpExecInfo)
1889{
1890 GET_FUNC(pShellExecuteExW, shell32, "ShellExecuteExW", FALSE);
1891 return pShellExecuteExW(lpExecInfo);
1892}
1893
1894/*************************************************************************
1895 * @ [SHLWAPI.336]
1896 *
1897 * Late bound call to shell32.SHFileOperationW.
1898 */
1899DWORD WINAPI SHLWAPI_336(LPSHFILEOPSTRUCTW lpFileOp)
1900{
1901 GET_FUNC(pSHFileOperationW, shell32, "SHFileOperationW", 0);
1902 return pSHFileOperationW(lpFileOp);
1903}
1904
1905/*************************************************************************
1906 * @ [SHLWAPI.337]
1907 *
1908 * Late bound call to shell32.ExtractIconExW.
1909 */
1910HICON WINAPI SHLWAPI_337(LPCWSTR lpszFile, INT nIconIndex, HICON *phiconLarge,
1911 HICON *phiconSmall, UINT nIcons)
1912{
1913 GET_FUNC(pExtractIconExW, shell32, "ExtractIconExW", (HICON)0);
1914 return pExtractIconExW(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
1915}
1916
1917/*************************************************************************
1918 * @ [SHLWAPI.342]
1919 *
1920 */
1921LONG WINAPI SHInterlockedCompareExchange( PLONG dest, LONG xchg, LONG compare)
1922{
1923 return InterlockedCompareExchange(dest, xchg, compare);
1924}
1925
1926/*************************************************************************
1927 * @ [SHLWAPI.346]
1928 */
1929DWORD WINAPI SHLWAPI_346 (
1930 LPCWSTR src,
1931 LPWSTR dest,
1932 int len)
1933{
1934 FIXME("(%s %p 0x%08x)stub\n",debugstr_w(src),dest,len);
1935 lstrcpynW(dest, src, len);
1936 return lstrlenW(dest)+1;
1937}
1938
1939/*************************************************************************
1940 * @ [SHLWAPI.350]
1941 *
1942 * seems to be late bound call to GetFileVersionInfoSizeW
1943 */
1944DWORD WINAPI SHLWAPI_350 (
1945 LPWSTR x,
1946 LPVOID y)
1947{
1948 DWORD ret;
1949
1950 GET_FUNC(pGetFileVersionInfoSizeW, version, "GetFileVersionInfoSizeW", 0);
1951 ret = pGetFileVersionInfoSizeW(x, y);
1952 return 0x208 + ret;
1953}
1954
1955/*************************************************************************
1956 * @ [SHLWAPI.351]
1957 *
1958 * seems to be late bound call to GetFileVersionInfoW
1959 */
1960BOOL WINAPI SHLWAPI_351 (
1961 LPWSTR w, /* [in] path to dll */
1962 DWORD x, /* [in] parm 2 to GetFileVersionInfoA */
1963 DWORD y, /* [in] return value from .350 - assume length */
1964 LPVOID z) /* [in/out] buffer (+0x208 sent to GetFileVersionInfoA) */
1965{
1966 GET_FUNC(pGetFileVersionInfoW, version, "GetFileVersionInfoW", 0);
1967#ifdef __WIN32OS2__
1968 return pGetFileVersionInfoW(w, x, y-0x208, (LPSTR)z+0x208);
1969#else
1970 return pGetFileVersionInfoW(w, x, y-0x208, z+0x208);
1971#endif
1972}
1973
1974/*************************************************************************
1975 * @ [SHLWAPI.352]
1976 *
1977 * seems to be late bound call to VerQueryValueW
1978 */
1979WORD WINAPI SHLWAPI_352 (
1980 LPVOID w, /* [in] buffer from _351 */
1981 LPWSTR x, /* [in] value to retrieve -
1982 converted and passed to VerQueryValueA as #2 */
1983 LPVOID y, /* [out] ver buffer - passed to VerQueryValueA as #3 */
1984 UINT* z) /* [in] ver length - passed to VerQueryValueA as #4 */
1985{
1986 GET_FUNC(pVerQueryValueW, version, "VerQueryValueW", 0);
1987#ifdef __WIN32OS2__
1988 return pVerQueryValueW((LPSTR)w+0x208, x, y, z);
1989#else
1990 return pVerQueryValueW(w+0x208, x, y, z);
1991#endif
1992}
1993
1994/**************************************************************************
1995 * @ [SHLWAPI.356]
1996 *
1997 * mbc - this function is undocumented, The parameters are correct and
1998 * the calls to InitializeSecurityDescriptor and
1999 * SetSecurityDescriptorDacl are correct, but apparently some
2000 * apps call this function with all zero parameters.
2001 */
2002
2003DWORD WINAPI SHLWAPI_356(PACL pDacl, PSECURITY_DESCRIPTOR pSD, LPCSTR *str)
2004{
2005 if(str != 0){
2006 *str = 0;
2007 }
2008
2009 if(!pDacl){
2010 return 0;
2011 }
2012
2013 if (!InitializeSecurityDescriptor(pSD, 1)) return 0;
2014 return SetSecurityDescriptorDacl(pSD, 1, pDacl, 0);
2015}
2016
2017
2018/*************************************************************************
2019 * @ [SHLWAPI.357]
2020 *
2021 * Late bound call to shell32.SHGetNewLinkInfoW
2022 */
2023BOOL WINAPI SHLWAPI_357(LPCWSTR pszLinkTo, LPCWSTR pszDir, LPWSTR pszName,
2024 BOOL *pfMustCopy, UINT uFlags)
2025{
2026 GET_FUNC(pSHGetNewLinkInfoW, shell32, "SHGetNewLinkInfoW", FALSE);
2027 return pSHGetNewLinkInfoW(pszLinkTo, pszDir, pszName, pfMustCopy, uFlags);
2028}
2029
2030/*************************************************************************
2031 * @ [SHLWAPI.358]
2032 *
2033 * Late bound call to shell32.SHDefExtractIconW
2034 */
2035DWORD WINAPI SHLWAPI_358(LPVOID arg1, LPVOID arg2, LPVOID arg3, LPVOID arg4,
2036 LPVOID arg5, LPVOID arg6)
2037{
2038 GET_FUNC(pSHDefExtractIconW, shell32, "SHDefExtractIconW", 0);
2039 return pSHDefExtractIconW(arg1, arg2, arg3, arg4, arg5, arg6);
2040}
2041
2042/*************************************************************************
2043 * @ [SHLWAPI.364]
2044 *
2045 * Wrapper for lstrcpynA with src and dst swapped.
2046 */
2047DWORD WINAPI SHLWAPI_364(LPCSTR src, LPSTR dst, INT n)
2048{
2049 lstrcpynA(dst, src, n);
2050 return TRUE;
2051}
2052
2053/*************************************************************************
2054 * @ [SHLWAPI.370]
2055 *
2056 * Late bound call to shell32.ExtractIconW
2057 */
2058HICON WINAPI SHLWAPI_370(HINSTANCE hInstance, LPCWSTR lpszExeFileName,
2059 UINT nIconIndex)
2060{
2061 GET_FUNC(pExtractIconW, shell32, "ExtractIconW", (HICON)0);
2062 return pExtractIconW(hInstance, lpszExeFileName, nIconIndex);
2063}
2064
2065/*************************************************************************
2066 * @ [SHLWAPI.376]
2067 */
2068LANGID WINAPI SHLWAPI_376 ()
2069{
2070 FIXME("() stub\n");
2071 /* FIXME: This should be a forward in the .spec file to the win2k function
2072 * kernel32.GetUserDefaultUILanguage, however that function isn't there yet.
2073 */
2074 return GetUserDefaultLangID();
2075}
2076
2077/*************************************************************************
2078 * @ [SHLWAPI.377]
2079 *
2080 * FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for
2081 * each call here.
2082 * FIXME: Native shows calls to:
2083 * SHRegGetUSValue for "Software\Microsoft\Internet Explorer\International"
2084 * CheckVersion
2085 * RegOpenKeyExA for "HKLM\Software\Microsoft\Internet Explorer"
2086 * RegQueryValueExA for "LPKInstalled"
2087 * RegCloseKey
2088 * RegOpenKeyExA for "HKCU\Software\Microsoft\Internet Explorer\International"
2089 * RegQueryValueExA for "ResourceLocale"
2090 * RegCloseKey
2091 * RegOpenKeyExA for "HKLM\Software\Microsoft\Active Setup\Installed Components\{guid}"
2092 * RegQueryValueExA for "Locale"
2093 * RegCloseKey
2094 * and then tests the Locale ("en" for me).
2095 * code below
2096 * after the code then a DPA_Create (first time) and DPA_InsertPtr are done.
2097 */
2098DWORD WINAPI SHLWAPI_377 (LPCSTR new_mod, HMODULE inst_hwnd, LPVOID z)
2099{
2100 CHAR mod_path[2*MAX_PATH];
2101 LPSTR ptr;
2102
2103 GetModuleFileNameA(inst_hwnd, mod_path, 2*MAX_PATH);
2104 ptr = strrchr(mod_path, '\\');
2105 if (ptr) {
2106 strcpy(ptr+1, new_mod);
2107 TRACE("loading %s\n", debugstr_a(mod_path));
2108 return (DWORD)LoadLibraryA(mod_path);
2109 }
2110 return 0;
2111}
2112
2113/*************************************************************************
2114 * @ [SHLWAPI.378]
2115 *
2116 * This is Unicode version of .377
2117 */
2118DWORD WINAPI SHLWAPI_378 (
2119 LPCWSTR new_mod, /* [in] new module name */
2120 HMODULE inst_hwnd, /* [in] calling module handle */
2121 LPVOID z) /* [???] 4 */
2122{
2123 WCHAR mod_path[2*MAX_PATH];
2124 LPWSTR ptr;
2125
2126 GetModuleFileNameW(inst_hwnd, mod_path, 2*MAX_PATH);
2127 ptr = strrchrW(mod_path, '\\');
2128 if (ptr) {
2129 strcpyW(ptr+1, new_mod);
2130 TRACE("loading %s\n", debugstr_w(mod_path));
2131 return (DWORD)LoadLibraryW(mod_path);
2132 }
2133 return 0;
2134}
2135
2136/*************************************************************************
2137 * @ [SHLWAPI.389]
2138 *
2139 * Late bound call to comdlg32.GetSaveFileNameW
2140 */
2141BOOL WINAPI SHLWAPI_389(LPOPENFILENAMEW ofn)
2142{
2143 GET_FUNC(pGetSaveFileNameW, comdlg32, "GetSaveFileNameW", FALSE);
2144 return pGetSaveFileNameW(ofn);
2145}
2146
2147/*************************************************************************
2148 * @ [SHLWAPI.390]
2149 *
2150 * Late bound call to mpr.WNetRestoreConnectionW
2151 */
2152DWORD WINAPI SHLWAPI_390(LPVOID arg1, LPVOID arg2)
2153{
2154 GET_FUNC(pWNetRestoreConnectionW, mpr, "WNetRestoreConnectionW", 0);
2155 return pWNetRestoreConnectionW(arg1, arg2);
2156}
2157
2158/*************************************************************************
2159 * @ [SHLWAPI.391]
2160 *
2161 * Late bound call to mpr.WNetGetLastErrorW
2162 */
2163DWORD WINAPI SHLWAPI_391(LPVOID arg1, LPVOID arg2, LPVOID arg3, LPVOID arg4,
2164 LPVOID arg5)
2165{
2166 GET_FUNC(pWNetGetLastErrorW, mpr, "WNetGetLastErrorW", 0);
2167 return pWNetGetLastErrorW(arg1, arg2, arg3, arg4, arg5);
2168}
2169
2170/*************************************************************************
2171 * @ [SHLWAPI.401]
2172 *
2173 * Late bound call to comdlg32.PageSetupDlgW
2174 */
2175BOOL WINAPI SHLWAPI_401(LPPAGESETUPDLGW pagedlg)
2176{
2177 GET_FUNC(pPageSetupDlgW, comdlg32, "PageSetupDlgW", FALSE);
2178 return pPageSetupDlgW(pagedlg);
2179}
2180
2181/*************************************************************************
2182 * @ [SHLWAPI.402]
2183 *
2184 * Late bound call to comdlg32.PrintDlgW
2185 */
2186BOOL WINAPI SHLWAPI_402(LPPRINTDLGW printdlg)
2187{
2188 GET_FUNC(pPrintDlgW, comdlg32, "PrintDlgW", FALSE);
2189 return pPrintDlgW(printdlg);
2190}
2191
2192/*************************************************************************
2193 * @ [SHLWAPI.403]
2194 *
2195 * Late bound call to comdlg32.GetOpenFileNameW
2196 */
2197BOOL WINAPI SHLWAPI_403(LPOPENFILENAMEW ofn)
2198{
2199 GET_FUNC(pGetOpenFileNameW, comdlg32, "GetOpenFileNameW", FALSE);
2200 return pGetOpenFileNameW(ofn);
2201}
2202
2203/* INTERNAL: Map from HLS color space to RGB */
2204static WORD ConvertHue(int wHue, WORD wMid1, WORD wMid2)
2205{
2206 wHue = wHue > 240 ? wHue - 240 : wHue < 0 ? wHue + 240 : wHue;
2207
2208 if (wHue > 160)
2209 return wMid1;
2210 else if (wHue > 120)
2211 wHue = 160 - wHue;
2212 else if (wHue > 40)
2213 return wMid2;
2214
2215 return ((wHue * (wMid2 - wMid1) + 20) / 40) + wMid1;
2216}
2217
2218/* Convert to RGB and scale into RGB range (0..255) */
2219#define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240
2220
2221/*************************************************************************
2222 * ColorHLSToRGB [SHLWAPI.404]
2223 *
2224 * Convert from HLS color space into an RGB COLORREF.
2225 *
2226 * NOTES
2227 * Input HLS values are constrained to the range (0..240).
2228 */
2229COLORREF WINAPI ColorHLSToRGB(WORD wHue, WORD wLuminosity, WORD wSaturation)
2230{
2231 WORD wRed;
2232
2233 if (wSaturation)
2234 {
2235 WORD wGreen, wBlue, wMid1, wMid2;
2236
2237 if (wLuminosity > 120)
2238 wMid2 = wSaturation + wLuminosity - (wSaturation * wLuminosity + 120) / 240;
2239 else
2240 wMid2 = ((wSaturation + 240) * wLuminosity + 120) / 240;
2241
2242 wMid1 = wLuminosity * 2 - wMid2;
2243
2244 wRed = GET_RGB(wHue + 80);
2245 wGreen = GET_RGB(wHue);
2246 wBlue = GET_RGB(wHue - 80);
2247
2248 return RGB(wRed, wGreen, wBlue);
2249 }
2250
2251 wRed = wLuminosity * 255 / 240;
2252 return RGB(wRed, wRed, wRed);
2253}
2254
2255/*************************************************************************
2256 * @ [SHLWAPI.413]
2257 *
2258 * Function unknown seems to always to return 0
2259 */
2260DWORD WINAPI SHLWAPI_413 (DWORD x)
2261{
2262 FIXME("(0x%08lx)stub\n", x);
2263 return 0;
2264}
2265
2266/*************************************************************************
2267 * @ [SHLWAPI.418]
2268 *
2269 * Function seems to do FreeLibrary plus other things.
2270 *
2271 * FIXME native shows the following calls:
2272 * RtlEnterCriticalSection
2273 * LocalFree
2274 * GetProcAddress(Comctl32??, 150L)
2275 * DPA_DeletePtr
2276 * RtlLeaveCriticalSection
2277 * followed by the FreeLibrary.
2278 * The above code may be related to .377 above.
2279 */
2280BOOL WINAPI SHLWAPI_418 (HMODULE x)
2281{
2282 FIXME("(0x%08lx) partial stub\n", (LONG)x);
2283 return FreeLibrary(x);
2284}
2285
2286/*************************************************************************
2287 * @ [SHLWAPI.431]
2288 */
2289DWORD WINAPI SHLWAPI_431 (DWORD x)
2290{
2291 FIXME("(0x%08lx)stub\n", x);
2292 return 0xabba1247;
2293}
2294
2295/*************************************************************************
2296 * @ [SHLWAPI.436]
2297 *
2298 * This is really CLSIDFromString which is exported by ole32.dll,
2299 * however the native shlwapi.dll does *not* import ole32. Nor does
2300 * ole32.dll import this ordinal from shlwapi. Therefore we must conclude
2301 * that MS duplicated the code for CLSIDFromString.
2302 *
2303 * This is a duplicate (with changes for UNICODE) of CLSIDFromString16
2304 * in dlls/ole32/compobj.c
2305 */
2306DWORD WINAPI SHLWAPI_436 (LPWSTR idstr, CLSID *id)
2307{
2308 LPWSTR s = idstr;
2309 BYTE *p;
2310 INT i;
2311 WCHAR table[256];
2312
2313 if (!s) {
2314 memset(s, 0, sizeof(CLSID));
2315 return S_OK;
2316 }
2317 else { /* validate the CLSID string */
2318
2319 if (strlenW(s) != 38)
2320 return CO_E_CLASSSTRING;
2321
2322 if ((s[0]!=L'{') || (s[9]!=L'-') || (s[14]!=L'-') || (s[19]!=L'-') || (s[24]!=L'-') || (s[37]!=L'}'))
2323 return CO_E_CLASSSTRING;
2324
2325 for (i=1; i<37; i++)
2326 {
2327 if ((i == 9)||(i == 14)||(i == 19)||(i == 24)) continue;
2328 if (!(((s[i] >= L'0') && (s[i] <= L'9')) ||
2329 ((s[i] >= L'a') && (s[i] <= L'f')) ||
2330 ((s[i] >= L'A') && (s[i] <= L'F')))
2331 )
2332 return CO_E_CLASSSTRING;
2333 }
2334 }
2335
2336 TRACE("%s -> %p\n", debugstr_w(s), id);
2337
2338 /* quick lookup table */
2339 memset(table, 0, 256*sizeof(WCHAR));
2340
2341 for (i = 0; i < 10; i++) {
2342 table['0' + i] = i;
2343 }
2344 for (i = 0; i < 6; i++) {
2345 table['A' + i] = i+10;
2346 table['a' + i] = i+10;
2347 }
2348
2349 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
2350
2351 p = (BYTE *) id;
2352
2353 s++; /* skip leading brace */
2354 for (i = 0; i < 4; i++) {
2355 p[3 - i] = table[*s]<<4 | table[*(s+1)];
2356 s += 2;
2357 }
2358 p += 4;
2359 s++; /* skip - */
2360
2361 for (i = 0; i < 2; i++) {
2362 p[1-i] = table[*s]<<4 | table[*(s+1)];
2363 s += 2;
2364 }
2365 p += 2;
2366 s++; /* skip - */
2367
2368 for (i = 0; i < 2; i++) {
2369 p[1-i] = table[*s]<<4 | table[*(s+1)];
2370 s += 2;
2371 }
2372 p += 2;
2373 s++; /* skip - */
2374
2375 /* these are just sequential bytes */
2376 for (i = 0; i < 2; i++) {
2377 *p++ = table[*s]<<4 | table[*(s+1)];
2378 s += 2;
2379 }
2380 s++; /* skip - */
2381
2382 for (i = 0; i < 6; i++) {
2383 *p++ = table[*s]<<4 | table[*(s+1)];
2384 s += 2;
2385 }
2386
2387 return S_OK;
2388}
2389#ifndef __WIN32OS2__
2390/*************************************************************************
2391 * @ [SHLWAPI.437]
2392 *
2393 * NOTES
2394 * In the real shlwapi, One time initialisation calls GetVersionEx and reads
2395 * the registry to determine what O/S & Service Pack level is running, and
2396 * therefore which functions are available. Currently we always run as NT,
2397 * since this means that we don't need extra code to emulate Unicode calls,
2398 * they are forwarded directly to the appropriate API call instead.
2399 * Since the flags for whether to call or emulate Unicode are internal to
2400 * the dll, this function does not need a full implementation.
2401 */
2402DWORD WINAPI SHLWAPI_437 (DWORD functionToCall)
2403{
2404 FIXME("(0x%08lx)stub\n", functionToCall);
2405 return /* 0xabba1247 */ 0;
2406}
2407#endif
2408/*************************************************************************
2409 * ColorRGBToHLS [SHLWAPI.445]
2410 *
2411 * Convert from RGB COLORREF into the HLS color space.
2412 *
2413 * NOTES
2414 * Input HLS values are constrained to the range (0..240).
2415 */
2416VOID WINAPI ColorRGBToHLS(COLORREF drRGB, LPWORD pwHue,
2417 LPWORD wLuminance, LPWORD pwSaturation)
2418{
2419 FIXME("stub\n");
2420 return;
2421}
2422
2423/*************************************************************************
2424 * SHCreateShellPalette [SHLWAPI.@]
2425 */
2426HPALETTE WINAPI SHCreateShellPalette(HDC hdc)
2427{
2428 FIXME("stub\n");
2429 return CreateHalftonePalette(hdc);
2430}
2431
2432/*************************************************************************
2433 * SHGetInverseCMAP (SHLWAPI.@)
2434 */
2435DWORD WINAPI SHGetInverseCMAP (LPDWORD* x, DWORD why)
2436{
2437 if (why == 4) {
2438 FIXME(" - returning bogus address for SHGetInverseCMAP\n");
2439 *x = (LPDWORD)0xabba1249;
2440 return 0;
2441 }
2442 FIXME("(%p, %#lx)stub\n", x, why);
2443 return 0;
2444}
2445
2446/*************************************************************************
2447 * SHIsLowMemoryMachine [SHLWAPI.@]
2448 */
2449DWORD WINAPI SHIsLowMemoryMachine (DWORD x)
2450{
2451 FIXME("0x%08lx\n", x);
2452 return 0;
2453}
2454
2455/*************************************************************************
2456 * GetMenuPosFromID [SHLWAPI.@]
2457 */
2458INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID)
2459{
2460 MENUITEMINFOA mi;
2461 INT nCount = GetMenuItemCount(hMenu), nIter = 0;
2462
2463 while (nIter < nCount)
2464 {
2465 mi.wID = 0;
2466 if (!GetMenuItemInfoA(hMenu, nIter, TRUE, &mi) && mi.wID == wID)
2467 return nIter;
2468 nIter++;
2469 }
2470 return -1;
2471}
2472
2473/*************************************************************************
2474 * _SHGetInstanceExplorer@4 [SHLWAPI.@]
2475 *
2476 * Late bound call to shell32.SHGetInstanceExplorer.
2477 */
2478HRESULT WINAPI _SHGetInstanceExplorer (LPUNKNOWN *lpUnknown)
2479{
2480 GET_FUNC(pSHGetInstanceExplorer, shell32, "SHGetInstanceExplorer", E_FAIL);
2481 return pSHGetInstanceExplorer(lpUnknown);
2482}
2483
2484/*************************************************************************
2485 * SHGetThreadRef [SHLWAPI.@]
2486 *
2487 * Retrieves the per-thread object reference set by SHSetThreadRef
2488 * "punk" - Address of a pointer to the IUnknown interface. Returns S_OK if
2489 * successful or E_NOINTERFACE otherwise.
2490 */
2491HRESULT WINAPI SHGetThreadRef (IUnknown ** ppunk)
2492{
2493 if (SHLWAPI_ThreadRef_index < 0) return E_NOINTERFACE;
2494 *ppunk = (IUnknown *)TlsGetValue(SHLWAPI_ThreadRef_index);
2495 return S_OK;
2496}
2497
2498/*************************************************************************
2499 * SHSetThreadRef [SHLWAPI.@]
2500 *
2501 * Stores a per-thread reference to a COM object
2502 * "punk" - Pointer to the IUnknown interface of the object to
2503 * which you want to store a reference. Returns S_OK if successful
2504 * or an OLE error value.
2505 */
2506HRESULT WINAPI SHSetThreadRef (IUnknown * punk)
2507{
2508 if (SHLWAPI_ThreadRef_index < 0) return E_NOINTERFACE;
2509 TlsSetValue(SHLWAPI_ThreadRef_index, (LPVOID) punk);
2510 return S_OK;
2511}
Note: See TracBrowser for help on using the repository browser.