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

Last change on this file since 8706 was 8584, checked in by sandervl, 23 years ago

resynced with latest Wine

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