2 * SHLWAPI ordinal functions
4 * Copyright 1997 Marcus Meissner
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33 #include "wine/unicode.h"
34 #include "wine/obj_base.h"
35 #include "wine/obj_inplace.h"
36 #include "wine/obj_serviceprovider.h"
40 #include "wine/debug.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
46 extern HINSTANCE shlwapi_hInstance
;
47 extern HMODULE SHLWAPI_hshell32
;
48 extern HMODULE SHLWAPI_hwinmm
;
49 extern HMODULE SHLWAPI_hcomdlg32
;
50 extern HMODULE SHLWAPI_hmpr
;
51 extern HMODULE SHLWAPI_hmlang
;
52 extern HMODULE SHLWAPI_hversion
;
54 extern DWORD SHLWAPI_ThreadRef_index
;
56 typedef HANDLE HSHARED
; /* Shared memory */
58 /* following is GUID for IObjectWithSite::SetSite -- see _174 */
59 static DWORD id1
[4] = {0xfc4801a3, 0x11cf2ba9, 0xaa0029a2, 0x52733d00};
60 /* following is GUID for IPersistMoniker::GetClassID -- see _174 */
61 static DWORD id2
[4] = {0x79eac9ee, 0x11cebaf9, 0xaa00828c, 0x0ba94b00};
63 /* The following schemes were identified in the native version of
64 * SHLWAPI.DLL version 5.50
67 URL_SCHEME_INVALID
= -1,
68 URL_SCHEME_UNKNOWN
= 0,
83 URL_SCHEME_JAVASCRIPT
,
91 URL_SCHEME scheme_number
;
95 static const SHL_2_inet_scheme shlwapi_schemes
[] = {
96 {URL_SCHEME_FTP
, "ftp"},
97 {URL_SCHEME_HTTP
, "http"},
98 {URL_SCHEME_GOPHER
, "gopher"},
99 {URL_SCHEME_MAILTO
, "mailto"},
100 {URL_SCHEME_NEWS
, "news"},
101 {URL_SCHEME_NNTP
, "nntp"},
102 {URL_SCHEME_TELNET
, "telnet"},
103 {URL_SCHEME_WAIS
, "wais"},
104 {URL_SCHEME_FILE
, "file"},
105 {URL_SCHEME_MK
, "mk"},
106 {URL_SCHEME_HTTPS
, "https"},
107 {URL_SCHEME_SHELL
, "shell"},
108 {URL_SCHEME_SNEWS
, "snews"},
109 {URL_SCHEME_LOCAL
, "local"},
110 {URL_SCHEME_JAVASCRIPT
, "javascript"},
111 {URL_SCHEME_VBSCRIPT
, "vbscript"},
112 {URL_SCHEME_ABOUT
, "about"},
113 {URL_SCHEME_RES
, "res"},
117 /* function pointers for GET_FUNC macro; these need to be global because of gcc bug */
118 static LPITEMIDLIST (WINAPI
*pSHBrowseForFolderW
)(LPBROWSEINFOW
);
119 static HRESULT (WINAPI
*pConvertINetUnicodeToMultiByte
)(LPDWORD
,DWORD
,LPCWSTR
,LPINT
,LPSTR
,LPINT
);
120 static BOOL (WINAPI
*pPlaySoundW
)(LPCWSTR
, HMODULE
, DWORD
);
121 static DWORD (WINAPI
*pSHGetFileInfoW
)(LPCWSTR
,DWORD
,SHFILEINFOW
*,UINT
,UINT
);
122 static UINT (WINAPI
*pDragQueryFileW
)(HDROP
, UINT
, LPWSTR
, UINT
);
123 static BOOL (WINAPI
*pSHGetPathFromIDListW
)(LPCITEMIDLIST
, LPWSTR
);
124 static BOOL (WINAPI
*pShellExecuteExW
)(LPSHELLEXECUTEINFOW
);
125 static HICON (WINAPI
*pSHFileOperationW
)(LPSHFILEOPSTRUCTW
);
126 static HICON (WINAPI
*pExtractIconExW
)(LPCWSTR
, INT
,HICON
*,HICON
*, UINT
);
127 static BOOL (WINAPI
*pSHGetNewLinkInfoW
)(LPCWSTR
, LPCWSTR
, LPCWSTR
, BOOL
*, UINT
);
128 static DWORD (WINAPI
*pSHDefExtractIconW
)(LPVOID
, LPVOID
, LPVOID
, LPVOID
, LPVOID
, LPVOID
); /* FIXME: Correct args */
129 static HICON (WINAPI
*pExtractIconW
)(HINSTANCE
, LPCWSTR
, UINT
);
130 static BOOL (WINAPI
*pGetSaveFileNameW
)(LPOPENFILENAMEW
);
131 static DWORD (WINAPI
*pWNetRestoreConnectionW
)(LPVOID
, LPVOID
); /* FIXME: Correct args */
132 static DWORD (WINAPI
*pWNetGetLastErrorW
)(LPVOID
, LPVOID
, LPVOID
, LPVOID
, LPVOID
); /* FIXME: Correct args */
133 static BOOL (WINAPI
*pPageSetupDlgW
)(LPPAGESETUPDLGW
);
134 static BOOL (WINAPI
*pPrintDlgW
)(LPPRINTDLGW
);
135 static BOOL (WINAPI
*pGetOpenFileNameW
)(LPOPENFILENAMEW
);
136 static DWORD (WINAPI
*pGetFileVersionInfoSizeW
)(LPCWSTR
,LPDWORD
);
137 static BOOL (WINAPI
*pGetFileVersionInfoW
)(LPCWSTR
,DWORD
,DWORD
,LPVOID
);
138 static WORD (WINAPI
*pVerQueryValueW
)(LPVOID
,LPCWSTR
,LPVOID
*,UINT
*);
141 NOTES: Most functions exported by ordinal seem to be superflous.
142 The reason for these functions to be there is to provide a wrapper
143 for unicode functions to provide these functions on systems without
144 unicode functions eg. win95/win98. Since we have such functions we just
145 call these. If running Wine with native DLL's, some late bound calls may
146 fail. However, its better to implement the functions in the forward DLL
147 and recommend the builtin rather than reimplementing the calls here!
150 /*************************************************************************
153 * Identifies the Internet "scheme" in the passed string. ASCII based.
154 * Also determines start and length of item after the ':'
156 DWORD WINAPI
SHLWAPI_1 (LPCSTR x
, UNKNOWN_SHLWAPI_1
*y
)
159 const SHL_2_inet_scheme
*inet_pro
;
161 if (y
->size
!= 0x18) return E_INVALIDARG
;
162 /* FIXME: leading white space generates error of 0x80041001 which
165 if (*x
<= ' ') return 0x80041001;
180 /* check for no scheme in string start */
181 /* (apparently schemes *must* be larger than a single character) */
182 if ((*x
== '\0') || (y
->sizep1
<= 1)) {
187 /* found scheme, set length of remainder */
188 y
->sizep2
= lstrlenA(y
->ap2
);
190 /* see if known scheme and return indicator number */
191 y
->fcncde
= URL_SCHEME_UNKNOWN
;
192 inet_pro
= shlwapi_schemes
;
193 while (inet_pro
->scheme_name
) {
194 if (!strncasecmp(inet_pro
->scheme_name
, y
->ap1
,
195 min(y
->sizep1
, lstrlenA(inet_pro
->scheme_name
)))) {
196 y
->fcncde
= inet_pro
->scheme_number
;
204 /*************************************************************************
207 * Identifies the Internet "scheme" in the passed string. UNICODE based.
208 * Also determines start and length of item after the ':'
210 DWORD WINAPI
SHLWAPI_2 (LPCWSTR x
, UNKNOWN_SHLWAPI_2
*y
)
213 const SHL_2_inet_scheme
*inet_pro
;
217 if (y
->size
!= 0x18) return E_INVALIDARG
;
218 /* FIXME: leading white space generates error of 0x80041001 which
221 if (*x
<= L
' ') return 0x80041001;
236 /* check for no scheme in string start */
237 /* (apparently schemes *must* be larger than a single character) */
238 if ((*x
== L
'\0') || (y
->sizep1
<= 1)) {
243 /* found scheme, set length of remainder */
244 y
->sizep2
= lstrlenW(y
->ap2
);
246 /* see if known scheme and return indicator number */
247 len
= WideCharToMultiByte(0, 0, y
->ap1
, y
->sizep1
, 0, 0, 0, 0);
248 cmpstr
= (LPSTR
)HeapAlloc(GetProcessHeap(), 0, len
+1);
249 WideCharToMultiByte(0, 0, y
->ap1
, y
->sizep1
, cmpstr
, len
+1, 0, 0);
250 y
->fcncde
= URL_SCHEME_UNKNOWN
;
251 inet_pro
= shlwapi_schemes
;
252 while (inet_pro
->scheme_name
) {
253 if (!strncasecmp(inet_pro
->scheme_name
, cmpstr
,
254 min(len
, lstrlenA(inet_pro
->scheme_name
)))) {
255 y
->fcncde
= inet_pro
->scheme_number
;
260 HeapFree(GetProcessHeap(), 0, cmpstr
);
264 /*************************************************************************
267 * Determine if a file exists locally and is of an executable type.
270 * lpszFile [O] File to search for
271 * dwWhich [I] Type of executable to search for
274 * TRUE If the file was found. lpszFile contains the file name.
278 * lpszPath is modified in place and must be at least MAX_PATH in length.
279 * If the function returns FALSE, the path is modified to its orginal state.
280 * If the given path contains an extension or dwWhich is 0, executable
281 * extensions are not checked.
283 * Ordinals 3-6 are a classic case of MS exposing limited functionality to
284 * users (here through PathFindOnPath) and keeping advanced functionality for
285 * their own developers exclusive use. Monopoly, anyone?
287 BOOL WINAPI
SHLWAPI_3(LPSTR lpszFile
,DWORD dwWhich
)
289 return SHLWAPI_PathFindLocalExeA(lpszFile
,dwWhich
);
292 /*************************************************************************
295 * Unicode version of SHLWAPI_3.
297 BOOL WINAPI
SHLWAPI_4(LPWSTR lpszFile
,DWORD dwWhich
)
299 return SHLWAPI_PathFindLocalExeW(lpszFile
,dwWhich
);
302 /*************************************************************************
305 * Search a range of paths for a specific type of executable.
308 * lpszFile [O] File to search for
309 * lppszOtherDirs [I] Other directories to look in
310 * dwWhich [I] Type of executable to search for
313 * Success: TRUE. The path to the executable is stored in sFile.
314 * Failure: FALSE. The path to the executable is unchanged.
316 BOOL WINAPI
SHLWAPI_5(LPSTR lpszFile
,LPCSTR
*lppszOtherDirs
,DWORD dwWhich
)
318 return SHLWAPI_PathFindOnPathExA(lpszFile
,lppszOtherDirs
,dwWhich
);
321 /*************************************************************************
324 * Unicode version of SHLWAPI_5.
326 BOOL WINAPI
SHLWAPI_6(LPWSTR lpszFile
,LPCWSTR
*lppszOtherDirs
,DWORD dwWhich
)
328 return SHLWAPI_PathFindOnPathExW(lpszFile
,lppszOtherDirs
,dwWhich
);
331 /*************************************************************************
332 * SHLWAPI_DupSharedHandle
334 * Internal implemetation of SHLWAPI_11.
337 HSHARED WINAPI
SHLWAPI_DupSharedHandle(HSHARED hShared
, DWORD dwDstProcId
,
338 DWORD dwSrcProcId
, DWORD dwAccess
,
342 DWORD dwMyProcId
= GetCurrentProcessId();
343 HSHARED hRet
= (HSHARED
)NULL
;
345 TRACE("(%p,%ld,%ld,%08lx,%08lx)\n", (PVOID
)hShared
, dwDstProcId
, dwSrcProcId
,
346 dwAccess
, dwOptions
);
348 /* Get dest process handle */
349 if (dwDstProcId
== dwMyProcId
)
350 hDst
= GetCurrentProcess();
352 hDst
= OpenProcess(PROCESS_DUP_HANDLE
, 0, dwDstProcId
);
356 /* Get src process handle */
357 if (dwSrcProcId
== dwMyProcId
)
358 hSrc
= GetCurrentProcess();
360 hSrc
= OpenProcess(PROCESS_DUP_HANDLE
, 0, dwSrcProcId
);
364 /* Make handle available to dest process */
365 if (!DuplicateHandle(hDst
, (HANDLE
)hShared
, hSrc
, &hRet
,
366 dwAccess
, 0, dwOptions
| DUPLICATE_SAME_ACCESS
))
367 hRet
= (HSHARED
)NULL
;
369 if (dwSrcProcId
!= dwMyProcId
)
373 if (dwDstProcId
!= dwMyProcId
)
377 TRACE("Returning handle %p\n", (PVOID
)hRet
);
381 /*************************************************************************
384 * Create a block of sharable memory and initialise it with data.
387 * dwProcId [I] ID of process owning data
388 * lpvData [I] Pointer to data to write
389 * dwSize [I] Size of data
392 * Success: A shared memory handle
396 * Ordinals 7-11 provide a set of calls to create shared memory between a
397 * group of processes. The shared memory is treated opaquely in that its size
398 * is not exposed to clients who map it. This is accomplished by storing
399 * the size of the map as the first DWORD of mapped data, and then offsetting
400 * the view pointer returned by this size.
402 * SHLWAPI_7/SHLWAPI_10 - Create/Destroy the shared memory handle
403 * SHLWAPI_8/SHLWAPI_9 - Get/Release a pointer to the shared data
404 * SHLWAPI_11 - Helper function; Duplicate cross-process handles
406 HSHARED WINAPI
SHLWAPI_7 (DWORD dwProcId
, DWORD dwSize
, LPCVOID lpvData
)
410 HSHARED hRet
= (HSHARED
)NULL
;
412 TRACE("(%ld,%p,%ld)\n", dwProcId
, lpvData
, dwSize
);
414 /* Create file mapping of the correct length */
415 hMap
= CreateFileMappingA(INVALID_HANDLE_VALUE
, NULL
, FILE_MAP_READ
, 0,
416 dwSize
+ sizeof(dwSize
), NULL
);
420 /* Get a view in our process address space */
421 pMapped
= MapViewOfFile(hMap
, FILE_MAP_READ
| FILE_MAP_WRITE
, 0, 0, 0);
425 /* Write size of data, followed by the data, to the view */
426 *((DWORD
*)pMapped
) = dwSize
;
428 memcpy((char *) pMapped
+ sizeof(dwSize
), lpvData
, dwSize
);
430 /* Release view. All further views mapped will be opaque */
431 UnmapViewOfFile(pMapped
);
432 hRet
= SHLWAPI_DupSharedHandle((HSHARED
)hMap
, dwProcId
,
433 GetCurrentProcessId(), FILE_MAP_ALL_ACCESS
,
434 DUPLICATE_SAME_ACCESS
);
441 /*************************************************************************
444 * Get a pointer to a block of shared memory from a shared memory handle.
447 * hShared [I] Shared memory handle
448 * dwProcId [I] ID of process owning hShared
451 * Success: A pointer to the shared memory
457 PVOID WINAPI
SHLWAPI_8 (HSHARED hShared
, DWORD dwProcId
)
462 TRACE("(%p %ld)\n", (PVOID
)hShared
, dwProcId
);
464 /* Get handle to shared memory for current process */
465 hDup
= SHLWAPI_DupSharedHandle(hShared
, dwProcId
, GetCurrentProcessId(),
466 FILE_MAP_ALL_ACCESS
, 0);
468 pMapped
= MapViewOfFile((HANDLE
)hDup
, FILE_MAP_READ
| FILE_MAP_WRITE
, 0, 0, 0);
472 return (char *) pMapped
+ sizeof(DWORD
); /* Hide size */
476 /*************************************************************************
479 * Release a pointer to a block of shared memory.
482 * lpView [I] Shared memory pointer
491 BOOL WINAPI
SHLWAPI_9 (LPVOID lpView
)
493 TRACE("(%p)\n", lpView
);
494 return UnmapViewOfFile((char *) lpView
- sizeof(DWORD
)); /* Include size */
497 /*************************************************************************
500 * Destroy a block of sharable memory.
503 * hShared [I] Shared memory handle
504 * dwProcId [I] ID of process owning hShared
513 BOOL WINAPI
SHLWAPI_10 (HSHARED hShared
, DWORD dwProcId
)
517 TRACE("(%p %ld)\n", (PVOID
)hShared
, dwProcId
);
519 /* Get a copy of the handle for our process, closing the source handle */
520 hClose
= SHLWAPI_DupSharedHandle(hShared
, dwProcId
, GetCurrentProcessId(),
521 FILE_MAP_ALL_ACCESS
,DUPLICATE_CLOSE_SOURCE
);
522 /* Close local copy */
523 return CloseHandle((HANDLE
)hClose
);
526 /*************************************************************************
529 * Copy a sharable memory handle from one process to another.
532 * hShared [I] Shared memory handle to duplicate
533 * dwDstProcId [I] ID of the process wanting the duplicated handle
534 * dwSrcProcId [I] ID of the process owning hShared
535 * dwAccess [I] Desired DuplicateHandle access
536 * dwOptions [I] Desired DuplicateHandle options
539 * Success: A handle suitable for use by the dwDstProcId process.
540 * Failure: A NULL handle.
545 HSHARED WINAPI
SHLWAPI_11(HSHARED hShared
, DWORD dwDstProcId
, DWORD dwSrcProcId
,
546 DWORD dwAccess
, DWORD dwOptions
)
550 hRet
= SHLWAPI_DupSharedHandle(hShared
, dwDstProcId
, dwSrcProcId
,
551 dwAccess
, dwOptions
);
555 /*************************************************************************
557 * (Used by IE4 during startup)
559 HRESULT WINAPI
SHLWAPI_13 (
563 FIXME("(%p %p)stub\n",w
,x
);
566 /* pseudo code extracted from relay trace */
567 RegOpenKeyA(HKLM
, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Accepted Documents", &newkey
);
572 ret
= RegEnumValueA(newkey
, i
, a1
, a2
, 0, a3
, 0, 0);
576 b1
= LocalAlloc(0x40, size
);
580 ret
= RegEnumValueA(newkey
, i
, a1
, a2
, 0, a3
, a4
, a5
);
581 RegisterClipBoardFormatA(a4
);
584 hmod1
= GetModuleHandleA("URLMON.DLL");
585 proc
= GetProcAddress(hmod1
, "CreateFormatEnumerator");
586 HeapAlloc(??, 0, 0x14);
587 HeapAlloc(??, 0, 0x50);
588 LocalAlloc(0x40, 0x78);
589 /* FIXME: bad string below */
590 lstrlenW(L
"{D0FCA420-D3F5-11CF-B211-00AA004AE837}");
591 StrCpyW(a6
, L
"{D0FCA420-D3F5-11CF-B211-00AA004AE837}");
594 IsBadReadPtr(c1
= 0x403fd210,4);
595 InterlockedIncrement(c1
+4);
598 IsBadReadPtr(c1
= 0x403fd210,4);
599 InterlockedIncrement(c1
+4);
601 HeapAlloc(40350000,00000000,00000014) retval
=403fd0a8
;
602 HeapAlloc(40350000,00000000,00000050) retval
=403feb44
;
603 hmod1
= GetModuleHandleA("URLMON.DLL");
604 proc
= GetProcAddress(hmod1
, "RegisterFormatEnumerator");
605 /* 0x1a40c88c is in URLMON.DLL just before above proc
606 * content is L"_EnumFORMATETC_"
609 IsBadReadPtr(d1
= 0x1a40c88c,00000002);
612 HeapAlloc(40350000,00000000,0000001e
) retval
=403fed44
;
613 IsBadReadPtr(d2
= 0x403fd0a8,00000004);
614 InterlockedIncrement(d2
+4);
615 IsBadReadPtr(d2
= 0x403fd0a8,00000004);
616 InterlockedDecrement(d2
+4);
617 IsBadReadPtr(c1
,00000004);
618 InterlockedDecrement(c1
+4);
619 IsBadReadPtr(c1
,00000004);
620 InterlockedDecrement(c1
+4);
625 /*************************************************************************
629 * Retrieves IE "AcceptLanguage" value from registry. ASCII mode.
632 HRESULT WINAPI
SHLWAPI_14 (
637 DWORD mystrlen
, mytype
;
641 mystrlen
= (*buflen
> 6) ? *buflen
: 6;
642 mystr
= (CHAR
*)HeapAlloc(GetProcessHeap(),
643 HEAP_ZERO_MEMORY
, mystrlen
);
644 RegOpenKeyA(HKEY_CURRENT_USER
,
645 "Software\\Microsoft\\Internet Explorer\\International",
647 if (RegQueryValueExA(mykey
, "AcceptLanguage",
648 0, &mytype
, mystr
, &mystrlen
)) {
649 /* Did not find value */
650 mylcid
= GetUserDefaultLCID();
651 /* somehow the mylcid translates into "en-us"
652 * this is similar to "LOCALE_SABBREVLANGNAME"
653 * which could be gotten via GetLocaleInfo.
654 * The only problem is LOCALE_SABBREVLANGUAGE" is
655 * a 3 char string (first 2 are country code and third is
656 * letter for "sublanguage", which does not come close to
659 lstrcpyA(mystr
, "en-us");
660 mystrlen
= lstrlenA(mystr
);
663 /* handle returned string */
664 FIXME("missing code\n");
666 if (mystrlen
> *buflen
)
667 lstrcpynA(langbuf
, mystr
, *buflen
);
669 lstrcpyA(langbuf
, mystr
);
670 *buflen
= lstrlenA(langbuf
);
673 HeapFree(GetProcessHeap(), 0, mystr
);
674 TRACE("language is %s\n", debugstr_a(langbuf
));
678 /*************************************************************************
682 * Retrieves IE "AcceptLanguage" value from registry. UNICODE mode.
685 HRESULT WINAPI
SHLWAPI_15 (
690 DWORD mystrlen
, mytype
;
694 mystrlen
= (*buflen
> 6) ? *buflen
: 6;
695 mystr
= (CHAR
*)HeapAlloc(GetProcessHeap(),
696 HEAP_ZERO_MEMORY
, mystrlen
);
697 RegOpenKeyA(HKEY_CURRENT_USER
,
698 "Software\\Microsoft\\Internet Explorer\\International",
700 if (RegQueryValueExA(mykey
, "AcceptLanguage",
701 0, &mytype
, mystr
, &mystrlen
)) {
702 /* Did not find value */
703 mylcid
= GetUserDefaultLCID();
704 /* somehow the mylcid translates into "en-us"
705 * this is similar to "LOCALE_SABBREVLANGNAME"
706 * which could be gotten via GetLocaleInfo.
707 * The only problem is LOCALE_SABBREVLANGUAGE" is
708 * a 3 char string (first 2 are country code and third is
709 * letter for "sublanguage", which does not come close to
712 lstrcpyA(mystr
, "en-us");
713 mystrlen
= lstrlenA(mystr
);
716 /* handle returned string */
717 FIXME("missing code\n");
720 *buflen
= MultiByteToWideChar(0, 0, mystr
, -1, langbuf
, (*buflen
)-1);
721 HeapFree(GetProcessHeap(), 0, mystr
);
722 TRACE("language is %s\n", debugstr_w(langbuf
));
726 /*************************************************************************
730 * converts a guid to a string
731 * returns strlen(str)
733 DWORD WINAPI
SHLWAPI_23 (
734 REFGUID guid
, /* [in] clsid */
735 LPSTR str
, /* [out] buffer */
736 INT cmax
) /* [in] size of buffer */
740 sprintf( xguid
, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
741 guid
->Data1
, guid
->Data2
, guid
->Data3
,
742 guid
->Data4
[0], guid
->Data4
[1], guid
->Data4
[2], guid
->Data4
[3],
743 guid
->Data4
[4], guid
->Data4
[5], guid
->Data4
[6], guid
->Data4
[7] );
744 TRACE("(%s %p 0x%08x)stub\n", xguid
, str
, cmax
);
745 if (strlen(xguid
)>=cmax
) return 0;
747 return strlen(xguid
) + 1;
750 /*************************************************************************
754 * converts a guid to a string
755 * returns strlen(str)
757 DWORD WINAPI
SHLWAPI_24 (
758 REFGUID guid
, /* [in] clsid */
759 LPWSTR str
, /* [out] buffer */
760 INT cmax
) /* [in] size of buffer */
764 sprintf( xguid
, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
765 guid
->Data1
, guid
->Data2
, guid
->Data3
,
766 guid
->Data4
[0], guid
->Data4
[1], guid
->Data4
[2], guid
->Data4
[3],
767 guid
->Data4
[4], guid
->Data4
[5], guid
->Data4
[6], guid
->Data4
[7] );
768 return MultiByteToWideChar( CP_ACP
, 0, xguid
, -1, str
, cmax
);
771 /*************************************************************************
774 * Seems to be iswalpha
776 BOOL WINAPI
SHLWAPI_25(WCHAR wc
)
778 return (get_char_typeW(wc
) & C1_ALPHA
) != 0;
781 /*************************************************************************
784 * Seems to be iswupper
786 BOOL WINAPI
SHLWAPI_26(WCHAR wc
)
788 return (get_char_typeW(wc
) & C1_UPPER
) != 0;
791 /*************************************************************************
794 * Seems to be iswlower
796 BOOL WINAPI
SHLWAPI_27(WCHAR wc
)
798 return (get_char_typeW(wc
) & C1_LOWER
) != 0;
801 /*************************************************************************
804 * Seems to be iswalnum
806 BOOL WINAPI
SHLWAPI_28(WCHAR wc
)
808 return (get_char_typeW(wc
) & (C1_ALPHA
|C1_DIGIT
)) != 0;
811 /*************************************************************************
814 * Seems to be iswspace
816 BOOL WINAPI
SHLWAPI_29(WCHAR wc
)
818 return (get_char_typeW(wc
) & C1_SPACE
) != 0;
821 /*************************************************************************
824 * Seems to be iswblank
826 BOOL WINAPI
SHLWAPI_30(WCHAR wc
)
828 return (get_char_typeW(wc
) & C1_BLANK
) != 0;
831 /*************************************************************************
834 * Seems to be iswpunct
836 BOOL WINAPI
SHLWAPI_31(WCHAR wc
)
838 return (get_char_typeW(wc
) & C1_PUNCT
) != 0;
841 /*************************************************************************
844 * Seems to be iswcntrl
846 BOOL WINAPI
SHLWAPI_32(WCHAR wc
)
848 return (get_char_typeW(wc
) & C1_CNTRL
) != 0;
851 /*************************************************************************
854 * Seems to be iswdigit
856 BOOL WINAPI
SHLWAPI_33(WCHAR wc
)
858 return (get_char_typeW(wc
) & C1_DIGIT
) != 0;
861 /*************************************************************************
864 * Seems to be iswxdigit
866 BOOL WINAPI
SHLWAPI_34(WCHAR wc
)
868 return (get_char_typeW(wc
) & C1_XDIGIT
) != 0;
871 /*************************************************************************
875 BOOL WINAPI
SHLWAPI_35(LPVOID p1
, DWORD dw2
, LPVOID p3
)
877 FIXME("(%p, 0x%08lx, %p): stub\n", p1
, dw2
, p3
);
881 /*************************************************************************
885 BOOL WINAPI
SHLWAPI_36(HMENU h1
, UINT ui2
, UINT h3
, LPCWSTR p4
)
887 TRACE("(0x%08x, 0x%08x, 0x%08x, %s): stub\n",
888 h1
, ui2
, h3
, debugstr_w(p4
));
889 return AppendMenuW(h1
, ui2
, h3
, p4
);
892 /*************************************************************************
895 * Get the text from a given dialog item.
897 INT WINAPI
SHLWAPI_74(HWND hWnd
, INT nItem
, LPWSTR lpsDest
,INT nDestLen
)
899 HWND hItem
= GetDlgItem(hWnd
, nItem
);
902 return GetWindowTextW(hItem
, lpsDest
, nDestLen
);
904 *lpsDest
= (WCHAR
)'\0';
908 /*************************************************************************
910 * Function: Compare two ASCII strings for "len" bytes.
911 * Returns: *str1-*str2 (case sensitive)
913 DWORD WINAPI
SHLWAPI_151(LPSTR str1
, LPSTR str2
, INT len
)
915 return strncmp( str1
, str2
, len
);
918 /*************************************************************************
921 * Function: Compare two WIDE strings for "len" bytes.
922 * Returns: *str1-*str2 (case sensitive)
924 DWORD WINAPI
SHLWAPI_152(LPWSTR str1
, LPWSTR str2
, INT len
)
926 return strncmpW( str1
, str2
, len
);
929 /*************************************************************************
931 * Function: Compare two ASCII strings for "len" bytes via caseless compare.
932 * Returns: *str1-*str2 (case insensitive)
934 DWORD WINAPI
SHLWAPI_153(LPSTR str1
, LPSTR str2
, DWORD len
)
936 return strncasecmp( str1
, str2
, len
);
939 /*************************************************************************
942 * Function: Compare two WIDE strings for "len" bytes via caseless compare.
943 * Returns: *str1-*str2 (case insensitive)
945 DWORD WINAPI
SHLWAPI_154(LPWSTR str1
, LPWSTR str2
, DWORD len
)
947 return strncmpiW( str1
, str2
, len
);
950 /*************************************************************************
953 * Case sensitive string compare (ASCII). Does not SetLastError().
955 DWORD WINAPI
SHLWAPI_155 ( LPSTR str1
, LPSTR str2
)
957 return strcmp(str1
, str2
);
960 /*************************************************************************
963 * Case sensitive string compare. Does not SetLastError().
965 DWORD WINAPI
SHLWAPI_156 ( LPWSTR str1
, LPWSTR str2
)
967 return strcmpW( str1
, str2
);
970 /*************************************************************************
973 * Case insensitive string compare. Does not SetLastError(). ??
975 DWORD WINAPI
SHLWAPI_158 ( LPWSTR str1
, LPWSTR str2
)
977 return strcmpiW( str1
, str2
);
980 /*************************************************************************
983 * Ensure a multibyte character string doesn't end in a hanging lead byte.
985 DWORD WINAPI
SHLWAPI_162(LPSTR lpStr
, DWORD size
)
989 LPSTR lastByte
= lpStr
+ size
- 1;
991 while(lpStr
< lastByte
)
992 lpStr
+= IsDBCSLeadByte(*lpStr
) ? 2 : 1;
994 if(lpStr
== lastByte
&& IsDBCSLeadByte(*lpStr
))
1004 /*************************************************************************
1007 * _IUnknown_QueryStatus
1009 DWORD WINAPI
SHLWAPI_163 (
1016 TRACE("(%p %p %p %p %p) stub\n", v
,w
,x
,y
,z
);
1021 /*************************************************************************
1026 DWORD WINAPI
SHLWAPI_164 (
1034 TRACE("(%p %p %p %p %p %p) stub\n",u
,v
,w
,x
,y
,z
);
1035 return 0x80004002; /* E_NOINTERFACE */
1038 /*************************************************************************
1041 * SetWindowLongA with mask.
1043 LONG WINAPI
SHLWAPI_165(HWND hwnd
, INT offset
, UINT wFlags
, UINT wMask
)
1045 LONG ret
= GetWindowLongA(hwnd
, offset
);
1046 UINT newFlags
= (wFlags
& wMask
) | (ret
& ~wFlags
);
1048 if (newFlags
!= ret
)
1049 ret
= SetWindowLongA(hwnd
, offset
, newFlags
);
1053 /*************************************************************************
1058 DWORD WINAPI
SHLWAPI_167(HWND hWnd
, LPVOID y
)
1060 FIXME("0x%08x %p\n", hWnd
,y
);
1064 /*************************************************************************
1067 * _IUnknown_AtomicRelease
1069 * Do IUnknown::Release on passed object.
1071 DWORD WINAPI
SHLWAPI_169 (IUnknown
** lpUnknown
)
1075 TRACE("(%p)\n",lpUnknown
);
1076 if(!lpUnknown
|| !*((LPDWORD
)lpUnknown
)) return 0;
1079 TRACE("doing Release\n");
1080 return IUnknown_Release(temp
);
1083 /*************************************************************************
1086 * Skip URL '//' sequence.
1088 LPCSTR WINAPI
SHLWAPI_170(LPCSTR lpszSrc
)
1090 if (lpszSrc
&& lpszSrc
[0] == '/' && lpszSrc
[1] == '/')
1095 /*************************************************************************
1100 BOOL WINAPI
SHLWAPI_171(LPVOID x
, LPVOID y
)
1102 FIXME("%p %p\n",x
,y
);
1106 /*************************************************************************
1109 * _IUnknown_GetWindow
1111 * Get window handle of OLE object
1113 DWORD WINAPI
SHLWAPI_172 (
1114 IUnknown
*pUnk
, /* [in] OLE object interface */
1115 LPHWND hWnd
) /* [out] location to put window handle */
1118 IOleWindow
*pOleWnd
;
1120 TRACE("(%p %p)\n",pUnk
,hWnd
);
1123 ret
= IUnknown_QueryInterface(pUnk
, &IID_IOleWindow
,(LPVOID
*)&pOleWnd
);
1124 if (SUCCEEDED(ret
)) {
1125 ret
= IOleWindow_GetWindow(pOleWnd
, hWnd
);
1126 IOleWindow_Release(pOleWnd
);
1127 TRACE("result hwnd=%08x\n", *hWnd
);
1134 /*************************************************************************
1137 * Seems to do call either IObjectWithSite::SetSite or
1138 * IPersistMoniker::GetClassID. But since we do not implement either
1139 * of those classes in our headers, we will fake it out.
1141 DWORD WINAPI
SHLWAPI_174(
1142 IUnknown
*p1
, /* [in] OLE object */
1143 LPVOID
*p2
) /* [out] ptr to result of either GetClassID
1148 if (!p1
) return E_FAIL
;
1150 /* see if SetSite interface exists for IObjectWithSite object */
1151 ret
= IUnknown_QueryInterface((IUnknown
*)p1
, (REFIID
)id1
, (LPVOID
*)&p1
);
1152 TRACE("first IU_QI ret=%08lx, p1=%p\n", ret
, p1
);
1155 /* see if GetClassId interface exists for IPersistMoniker object */
1156 ret
= IUnknown_QueryInterface((IUnknown
*)p1
, (REFIID
)id2
, (LPVOID
*)&aa
);
1157 TRACE("second IU_QI ret=%08lx, aa=%08lx\n", ret
, aa
);
1158 if (ret
) return ret
;
1160 /* fake a GetClassId call */
1161 ret
= IOleWindow_GetWindow((IOleWindow
*)aa
, (HWND
*)p2
);
1162 TRACE("second IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret
,
1164 IUnknown_Release((IUnknown
*)aa
);
1167 /* fake a SetSite call */
1168 ret
= IOleWindow_GetWindow((IOleWindow
*)p1
, (HWND
*)p2
);
1169 TRACE("first IU_QI doing 0x0c ret=%08lx, *p2=%08lx\n", ret
,
1171 IUnknown_Release((IUnknown
*)p1
);
1176 /*************************************************************************
1180 * Param1 can be an IShellFolder Object
1182 HRESULT WINAPI
SHLWAPI_175 (LPVOID x
, LPVOID y
)
1184 FIXME("(%p %p) stub\n", x
,y
);
1187 /*************************************************************************
1190 * _IUnknown_QueryService
1192 * Function appears to be interface to IServiceProvider::QueryService
1195 * returns E_NOINTERFACE
1197 * S_OK if _219 called successfully
1199 DWORD WINAPI
SHLWAPI_176 (
1200 IUnknown
* unk
, /* [in] object to give Service Provider */
1201 REFGUID sid
, /* [in] Service ID */
1202 REFIID riid
, /* [in] Function requested */
1203 LPVOID
*ppv
) /* [out] place to save interface pointer */
1205 HRESULT ret
= E_FAIL
;
1206 IServiceProvider
*pSP
;
1209 TRACE("%p, %s, %s, %p\n", unk
, debugstr_guid(sid
), debugstr_guid(riid
), ppv
);
1212 ret
= IUnknown_QueryInterface(unk
, &IID_IServiceProvider
,(LPVOID
*) &pSP
);
1213 TRACE("did IU_QI retval=%08lx, aa=%p\n", ret
, pSP
);
1214 if (SUCCEEDED(ret
)) {
1215 ret
= IServiceProvider_QueryService(pSP
, sid
, riid
, (LPVOID
*)ppv
);
1216 TRACE("did ISP_QS retval=%08lx, *z=%p\n", ret
, *ppv
);
1217 IServiceProvider_Release(pSP
);
1223 /*************************************************************************
1226 * Enable or disable a menu item.
1228 UINT WINAPI
SHLWAPI_181(HMENU hMenu
, UINT wItemID
, BOOL bEnable
)
1230 return EnableMenuItem(hMenu
, wItemID
, bEnable
? MF_ENABLED
: MF_GRAYED
);
1233 /*************************************************************************
1236 * Register a window class if it isn't already.
1238 DWORD WINAPI
SHLWAPI_183(WNDCLASSA
*wndclass
)
1241 if (GetClassInfoA(wndclass
->hInstance
, wndclass
->lpszClassName
, &wca
))
1243 return (DWORD
)RegisterClassA(wndclass
);
1246 /*************************************************************************
1249 * _IUnknown_OnFocusOCS
1251 DWORD WINAPI
SHLWAPI_189(LPVOID x
, LPVOID y
)
1253 FIXME("%p %p\n", x
, y
);
1257 /*************************************************************************
1260 DWORD WINAPI
SHLWAPI_193 ()
1268 ret
= GetDeviceCaps(hdc
, BITSPIXEL
) * GetDeviceCaps(hdc
, PLANES
);
1273 /*************************************************************************
1276 * Copy interface pointer
1278 DWORD WINAPI
SHLWAPI_199 (
1279 IUnknown
**dest
, /* [out] pointer to copy of interface ptr */
1280 IUnknown
*src
) /* [in] interface pointer */
1282 TRACE("(%p %p)\n",dest
,src
);
1285 IUnknown_Release(*dest
);
1287 IUnknown_AddRef(src
);
1294 /*************************************************************************
1297 * Some sort of memory management process - associated with _210
1299 DWORD WINAPI
SHLWAPI_208 (
1306 FIXME("(0x%08lx 0x%08lx %p %p 0x%08lx) stub\n",
1311 /*************************************************************************
1314 * Some sort of memory management process - associated with _208
1316 DWORD WINAPI
SHLWAPI_209 (
1319 FIXME("(%p) stub\n",
1324 /*************************************************************************
1327 * Some sort of memory management process - associated with _208
1329 DWORD WINAPI
SHLWAPI_210 (
1334 FIXME("(%p 0x%08lx %p) stub\n",
1339 /*************************************************************************
1342 DWORD WINAPI
SHLWAPI_211 (
1346 FIXME("(%p 0x%08lx) stub\n",
1351 /*************************************************************************
1357 DWORD WINAPI
SHLWAPI_215 (
1364 len_a
= lstrlenA(lpStrSrc
);
1365 ret
= MultiByteToWideChar(0, 0, lpStrSrc
, len_a
, lpwStrDest
, len
);
1366 TRACE("%s %s %d, ret=%d\n",
1367 debugstr_a(lpStrSrc
), debugstr_w(lpwStrDest
), len
, ret
);
1371 /*************************************************************************
1374 * WideCharToMultiByte with multi language support.
1376 INT WINAPI
SHLWAPI_218(UINT CodePage
, LPCWSTR lpSrcStr
, LPSTR lpDstStr
,
1377 LPINT lpnMultiCharCount
)
1379 WCHAR emptyW
[] = { '\0' };
1383 if (!lpDstStr
|| !lpnMultiCharCount
)
1391 len
= strlenW(lpSrcStr
) + 1;
1396 CodePage
= CP_UTF8
; /* Fall through... */
1397 case 0x0000C350: /* FIXME: CP_ #define */
1402 INT nWideCharCount
= len
- 1;
1404 GET_FUNC(pConvertINetUnicodeToMultiByte
, mlang
, "ConvertINetUnicodeToMultiByte", 0);
1405 if (!pConvertINetUnicodeToMultiByte(&dwMode
, CodePage
, lpSrcStr
, &nWideCharCount
, lpDstStr
,
1409 if (nWideCharCount
< len
- 1)
1411 mem
= (LPSTR
)HeapAlloc(GetProcessHeap(), 0, *lpnMultiCharCount
);
1415 *lpnMultiCharCount
= 0;
1417 if (pConvertINetUnicodeToMultiByte(&dwMode
, CodePage
, lpSrcStr
, &len
, mem
, lpnMultiCharCount
))
1419 SHLWAPI_162 (mem
, *lpnMultiCharCount
);
1420 lstrcpynA(lpDstStr
, mem
, *lpnMultiCharCount
+ 1);
1421 return *lpnMultiCharCount
+ 1;
1423 HeapFree(GetProcessHeap(), 0, mem
);
1424 return *lpnMultiCharCount
;
1426 lpDstStr
[*lpnMultiCharCount
] = '\0';
1427 return *lpnMultiCharCount
;
1434 reqLen
= WideCharToMultiByte(CodePage
, 0, lpSrcStr
, len
, lpDstStr
,
1435 *lpnMultiCharCount
, NULL
, NULL
);
1437 if (!reqLen
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
1439 reqLen
= WideCharToMultiByte(CodePage
, 0, lpSrcStr
, len
, NULL
, 0, NULL
, NULL
);
1442 mem
= (LPSTR
)HeapAlloc(GetProcessHeap(), 0, reqLen
);
1445 reqLen
= WideCharToMultiByte(CodePage
, 0, lpSrcStr
, len
, mem
,
1446 reqLen
, NULL
, NULL
);
1448 reqLen
= SHLWAPI_162(mem
, *lpnMultiCharCount
);
1451 lstrcpynA(lpDstStr
, mem
, *lpnMultiCharCount
);
1453 HeapFree(GetProcessHeap(), 0, mem
);
1460 /*************************************************************************
1463 * Hmm, some program used lpnMultiCharCount == 0x3 (and lpSrcStr was "C")
1464 * --> Crash. Something wrong here.
1466 * It seems from OE v5 that the third param is the count. (GA 11/2001)
1468 INT WINAPI
SHLWAPI_217(LPCWSTR lpSrcStr
, LPSTR lpDstStr
, INT MultiCharCount
)
1470 INT myint
= MultiCharCount
;
1472 return SHLWAPI_218(CP_ACP
, lpSrcStr
, lpDstStr
, &myint
);
1475 /*************************************************************************
1478 * Seems to be "super" QueryInterface. Supplied with a table of interfaces
1479 * and an array of IIDs and offsets into the table.
1482 * error codes: E_POINTER, E_NOINTERFACE
1489 HRESULT WINAPI
SHLWAPI_219 (
1490 LPVOID w
, /* [in] table of interfaces */
1491 IFACE_INDEX_TBL
*x
, /* [in] array of REFIIDs and indexes to above */
1492 REFIID riid
, /* [in] REFIID to get interface for */
1493 LPVOID
*ppv
) /* [out] location to get interface pointer */
1497 IFACE_INDEX_TBL
*xmove
;
1499 TRACE("(%p %p %s %p)\n", w
,x
,debugstr_guid(riid
),ppv
);
1502 while (xmove
->refid
) {
1503 TRACE("trying (indx %ld) %s\n", xmove
->indx
, debugstr_guid(xmove
->refid
));
1504 if (IsEqualIID(riid
, xmove
->refid
)) {
1505 a_vtbl
= (IUnknown
*)(xmove
->indx
+ (LPBYTE
)w
);
1506 TRACE("matched, returning (%p)\n", a_vtbl
);
1507 *ppv
= (LPVOID
)a_vtbl
;
1508 IUnknown_AddRef(a_vtbl
);
1514 if (IsEqualIID(riid
, &IID_IUnknown
)) {
1515 a_vtbl
= (IUnknown
*)(x
->indx
+ (LPBYTE
)w
);
1516 TRACE("returning first for IUnknown (%p)\n", a_vtbl
);
1517 *ppv
= (LPVOID
)a_vtbl
;
1518 IUnknown_AddRef(a_vtbl
);
1522 ret
= E_NOINTERFACE
;
1526 TRACE("-- 0x%08lx\n", ret
);
1530 /*************************************************************************
1533 HMODULE WINAPI
SHLWAPI_236 (REFIID lpUnknown
)
1537 CHAR value
[MAX_PATH
], string
[MAX_PATH
];
1539 strcpy(string
, "CLSID\\");
1540 strcat(string
, debugstr_guid(lpUnknown
));
1541 strcat(string
, "\\InProcServer32");
1544 RegOpenKeyExA(HKEY_CLASSES_ROOT
, string
, 0, 1, &newkey
);
1545 RegQueryValueExA(newkey
, 0, 0, &type
, value
, &count
);
1546 RegCloseKey(newkey
);
1547 return LoadLibraryExA(value
, 0, 0);
1550 /*************************************************************************
1553 * Unicode version of SHLWAPI_183.
1555 DWORD WINAPI
SHLWAPI_237 (WNDCLASSW
* lpWndClass
)
1559 TRACE("(0x%08x %s)\n",lpWndClass
->hInstance
, debugstr_w(lpWndClass
->lpszClassName
));
1561 if (GetClassInfoW(lpWndClass
->hInstance
, lpWndClass
->lpszClassName
, &WndClass
))
1563 return RegisterClassW(lpWndClass
);
1566 /*************************************************************************
1569 DWORD WINAPI
SHLWAPI_239(HINSTANCE hInstance
, LPVOID p2
, DWORD dw3
)
1571 FIXME("(0x%08x %p 0x%08lx) stub\n",
1572 hInstance
, p2
, dw3
);
1575 /* pseudo code from relay trace */
1576 WideCharToMultiByte(0, 0, L
"Shell DocObject View", -1, &aa
, 0x0207, 0, 0);
1577 GetClassInfoA(70fe0000
,405868ec
"Shell DocObject View",40586b14
);
1578 /* above pair repeated for:
1579 TridentThicketUrlDlClass
1588 /*************************************************************************
1591 * Calls ASCII or Unicode WindowProc for the given window.
1593 LRESULT CALLBACK
SHLWAPI_240(HWND hWnd
, UINT uMessage
, WPARAM wParam
, LPARAM lParam
)
1595 if (IsWindowUnicode(hWnd
))
1596 return DefWindowProcW(hWnd
, uMessage
, wParam
, lParam
);
1597 return DefWindowProcA(hWnd
, uMessage
, wParam
, lParam
);
1600 /*************************************************************************
1604 DWORD WINAPI
SHLWAPI_241 ()
1607 return /* 0xabba1243 */ 0;
1610 /*************************************************************************
1613 * native does at least approximately:
1614 * strcpyW(newstr, x);
1615 * strcatW(newstr, "\\Restrictions");
1616 * if (RegOpenKeyExA(80000001, newstr, 00000000,00000001,40520b78))
1620 DWORD WINAPI
SHLWAPI_266 (
1622 LPVOID x
, /* [in] partial registry key */
1626 FIXME("(%p %p %p %p)stub\n",w
,x
,y
,z
);
1627 return /* 0xabba1248 */ 0;
1630 /*************************************************************************
1634 * This QueryInterface asks the inner object for a interface. In case
1635 * of aggregation this request would be forwarded by the inner to the
1636 * outer object. This function asks the inner object directly for the
1637 * interface circumventing the forwarding to the outer object.
1639 HRESULT WINAPI
SHLWAPI_267 (
1640 IUnknown
* pUnk
, /* [in] outer object */
1641 IUnknown
* pInner
, /* [in] inner object */
1645 HRESULT hret
= E_NOINTERFACE
;
1646 TRACE("(pUnk=%p pInner=%p\n\tIID: %s %p)\n",pUnk
,pInner
,debugstr_guid(riid
), ppv
);
1649 if(pUnk
&& pInner
) {
1650 hret
= IUnknown_QueryInterface(pInner
, riid
, (LPVOID
*)ppv
);
1651 if (SUCCEEDED(hret
)) IUnknown_Release(pUnk
);
1653 TRACE("-- 0x%08lx\n", hret
);
1657 /*************************************************************************
1660 * pInner is returned by SHLWAPI_267 as ppv
1662 DWORD WINAPI
SHLWAPI_268 (
1668 TRACE("(pUnk=%p pInner=%p)\n",pUnk
,pInner
);
1670 IUnknown_AddRef(pUnk
);
1671 if (pInner
&& *pInner
) {
1672 ret
= IUnknown_Release(*pInner
);
1675 TRACE("-- count=%lu\n",ret
);
1679 /*************************************************************************
1682 * on first call process does following: other calls just returns 2
1683 * instance = LoadLibraryA("SHELL32.DLL");
1684 * func = GetProcAddress(instance, "DllGetVersion");
1685 * ret = RegOpenKeyExA(80000002, "Software\\Microsoft\\Internet Explorer",00000000,0002001f, newkey);
1686 * ret = RegQueryValueExA(newkey, "IntegratedBrowser",00000000,00000000,4052588c,40525890);
1687 * RegCloseKey(newkey);
1688 * FreeLibrary(instance);
1691 DWORD WINAPI
SHLWAPI_276 ()
1694 return /* 0xabba1244 */ 2;
1697 /*************************************************************************
1701 HWND WINAPI
SHLWAPI_278 (
1712 char * clsname
= "WorkerA";
1714 FIXME("(0x%08lx 0x%08x 0x%08lx 0x%08lx 0x%08x 0x%08lx) partial stub\n",
1715 wndProc
,hWndParent
,dwExStyle
,dwStyle
,hMenu
,z
);
1717 hCursor
= LoadCursorA(0x00000000,IDC_ARROWA
);
1719 if(!GetClassInfoA(shlwapi_hInstance
, clsname
, &wndclass
))
1721 RtlZeroMemory(&wndclass
, sizeof(WNDCLASSA
));
1722 wndclass
.lpfnWndProc
= DefWindowProcW
;
1723 wndclass
.cbWndExtra
= 4;
1724 wndclass
.hInstance
= shlwapi_hInstance
;
1725 wndclass
.hCursor
= hCursor
;
1726 wndclass
.hbrBackground
= COLOR_BTNSHADOW
;
1727 wndclass
.lpszMenuName
= NULL
;
1728 wndclass
.lpszClassName
= clsname
;
1729 RegisterClassA (&wndclass
);
1731 hwnd
= CreateWindowExA(dwExStyle
, clsname
, 0,dwStyle
,0,0,0,0,hWndParent
,
1732 hMenu
,shlwapi_hInstance
,0);
1733 SetWindowLongA(hwnd
, 0, z
);
1734 SetWindowLongA(hwnd
, GWL_WNDPROC
, wndProc
);
1738 /*************************************************************************
1741 * _SHPackDispParamsV
1743 HRESULT WINAPI
SHLWAPI_281(LPVOID w
, LPVOID x
, LPVOID y
, LPVOID z
)
1745 FIXME("%p %p %p %p\n",w
,x
,y
,z
);
1749 /*************************************************************************
1752 * _IConnectionPoint_SimpleInvoke
1754 DWORD WINAPI
SHLWAPI_284 (
1759 TRACE("(%p %p %p) stub\n",x
,y
,z
);
1763 /*************************************************************************
1766 * _IUnknown_CPContainerOnChanged
1768 HRESULT WINAPI
SHLWAPI_287(LPVOID x
, LPVOID y
)
1770 FIXME("%p %p\n", x
,y
);
1774 /*************************************************************************
1777 * Late bound call to winmm.PlaySoundW
1779 BOOL WINAPI
SHLWAPI_289(LPCWSTR pszSound
, HMODULE hmod
, DWORD fdwSound
)
1781 GET_FUNC(pPlaySoundW
, winmm
, "PlaySoundW", FALSE
);
1782 return pPlaySoundW(pszSound
, hmod
, fdwSound
);
1785 /*************************************************************************
1788 BOOL WINAPI
SHLWAPI_294(LPSTR str1
, LPSTR str2
, LPSTR pStr
, DWORD some_len
, LPCSTR lpStr2
)
1791 * str1: "I" "I" pushl esp+0x20
1792 * str2: "U" "I" pushl 0x77c93810
1793 * (is "I" and "U" "integer" and "unsigned" ??)
1795 * pStr: "" "" pushl eax
1796 * some_len: 0x824 0x104 pushl 0x824
1797 * lpStr2: "%l" "%l" pushl esp+0xc
1799 * shlwapi. StrCpyNW(lpStr2, irrelevant_var, 0x104);
1800 * LocalAlloc(0x00, some_len) -> irrelevant_var
1801 * LocalAlloc(0x40, irrelevant_len) -> pStr
1802 * shlwapi.294(str1, str2, pStr, some_len, lpStr2);
1803 * shlwapi.PathRemoveBlanksW(pStr);
1805 FIXME("('%s', '%s', '%s', %08lx, '%s'): stub!\n", str1
, str2
, pStr
, some_len
, lpStr2
);
1809 /*************************************************************************
1812 * Called by ICQ2000b install via SHDOCVW:
1813 * str1: "InternetShortcut"
1814 * x: some unknown pointer
1815 * str2: "http://free.aol.com/tryaolfree/index.adp?139269"
1816 * str3: "C:\\WINDOWS\\Desktop.new2\\Free AOL & Unlimited Internet.url"
1818 * In short: this one maybe creates a desktop link :-)
1820 BOOL WINAPI
SHLWAPI_295(LPWSTR str1
, LPVOID x
, LPWSTR str2
, LPWSTR str3
)
1822 FIXME("('%s', %p, '%s', '%s'), stub.\n", debugstr_w(str1
), x
, debugstr_w(str2
), debugstr_w(str3
));
1826 /*************************************************************************
1829 * Late bound call to shell32.SHGetFileInfoW
1831 DWORD WINAPI
SHLWAPI_313(LPCWSTR path
, DWORD dwFileAttributes
,
1832 SHFILEINFOW
*psfi
, UINT sizeofpsfi
, UINT flags
)
1834 GET_FUNC(pSHGetFileInfoW
, shell32
, "SHGetFileInfoW", 0);
1835 return pSHGetFileInfoW(path
, dwFileAttributes
, psfi
, sizeofpsfi
, flags
);
1838 /*************************************************************************
1841 * Late bound call to shell32.DragQueryFileW
1843 UINT WINAPI
SHLWAPI_318(HDROP hDrop
, UINT lFile
, LPWSTR lpszFile
, UINT lLength
)
1845 GET_FUNC(pDragQueryFileW
, shell32
, "DragQueryFileW", 0);
1846 return pDragQueryFileW(hDrop
, lFile
, lpszFile
, lLength
);
1849 /*************************************************************************
1852 * Late bound call to shell32.SHBrowseForFolderW
1854 LPITEMIDLIST WINAPI
SHLWAPI_333(LPBROWSEINFOW lpBi
)
1856 GET_FUNC(pSHBrowseForFolderW
, shell32
, "SHBrowseForFolderW", NULL
);
1857 return pSHBrowseForFolderW(lpBi
);
1860 /*************************************************************************
1863 * Late bound call to shell32.SHGetPathFromIDListW
1865 BOOL WINAPI
SHLWAPI_334(LPCITEMIDLIST pidl
,LPWSTR pszPath
)
1867 GET_FUNC(pSHGetPathFromIDListW
, shell32
, "SHGetPathFromIDListW", 0);
1868 return pSHGetPathFromIDListW(pidl
, pszPath
);
1871 /*************************************************************************
1874 * Late bound call to shell32.ShellExecuteExW
1876 BOOL WINAPI
SHLWAPI_335(LPSHELLEXECUTEINFOW lpExecInfo
)
1878 GET_FUNC(pShellExecuteExW
, shell32
, "ShellExecuteExW", FALSE
);
1879 return pShellExecuteExW(lpExecInfo
);
1882 /*************************************************************************
1885 * Late bound call to shell32.SHFileOperationW.
1887 DWORD WINAPI
SHLWAPI_336(LPSHFILEOPSTRUCTW lpFileOp
)
1889 GET_FUNC(pSHFileOperationW
, shell32
, "SHFileOperationW", 0);
1890 return pSHFileOperationW(lpFileOp
);
1893 /*************************************************************************
1896 * Late bound call to shell32.ExtractIconExW.
1898 HICON WINAPI
SHLWAPI_337(LPCWSTR lpszFile
, INT nIconIndex
, HICON
*phiconLarge
,
1899 HICON
*phiconSmall
, UINT nIcons
)
1901 GET_FUNC(pExtractIconExW
, shell32
, "ExtractIconExW", (HICON
)0);
1902 return pExtractIconExW(lpszFile
, nIconIndex
, phiconLarge
, phiconSmall
, nIcons
);
1905 /*************************************************************************
1909 LONG WINAPI
SHInterlockedCompareExchange( PLONG dest
, LONG xchg
, LONG compare
)
1911 return InterlockedCompareExchange(dest
, xchg
, compare
);
1914 /*************************************************************************
1917 DWORD WINAPI
SHLWAPI_346 (
1922 FIXME("(%s %p 0x%08x)stub\n",debugstr_w(src
),dest
,len
);
1923 lstrcpynW(dest
, src
, len
);
1924 return lstrlenW(dest
)+1;
1927 /*************************************************************************
1930 * seems to be late bound call to GetFileVersionInfoSizeW
1932 DWORD WINAPI
SHLWAPI_350 (
1938 GET_FUNC(pGetFileVersionInfoSizeW
, version
, "GetFileVersionInfoSizeW", 0);
1939 ret
= pGetFileVersionInfoSizeW(x
, y
);
1943 /*************************************************************************
1946 * seems to be late bound call to GetFileVersionInfoW
1948 BOOL WINAPI
SHLWAPI_351 (
1949 LPWSTR w
, /* [in] path to dll */
1950 DWORD x
, /* [in] parm 2 to GetFileVersionInfoA */
1951 DWORD y
, /* [in] return value from .350 - assume length */
1952 LPVOID z
) /* [in/out] buffer (+0x208 sent to GetFileVersionInfoA) */
1954 GET_FUNC(pGetFileVersionInfoW
, version
, "GetFileVersionInfoW", 0);
1955 return pGetFileVersionInfoW(w
, x
, y
-0x208, (char*)z
+0x208);
1958 /*************************************************************************
1961 * seems to be late bound call to VerQueryValueW
1963 WORD WINAPI
SHLWAPI_352 (
1964 LPVOID w
, /* [in] buffer from _351 */
1965 LPWSTR x
, /* [in] value to retrieve -
1966 converted and passed to VerQueryValueA as #2 */
1967 LPVOID y
, /* [out] ver buffer - passed to VerQueryValueA as #3 */
1968 UINT
* z
) /* [in] ver length - passed to VerQueryValueA as #4 */
1970 GET_FUNC(pVerQueryValueW
, version
, "VerQueryValueW", 0);
1971 return pVerQueryValueW((char*)w
+0x208, x
, y
, z
);
1974 /*************************************************************************
1977 * Late bound call to shell32.SHGetNewLinkInfoW
1979 BOOL WINAPI
SHLWAPI_357(LPCWSTR pszLinkTo
, LPCWSTR pszDir
, LPWSTR pszName
,
1980 BOOL
*pfMustCopy
, UINT uFlags
)
1982 GET_FUNC(pSHGetNewLinkInfoW
, shell32
, "SHGetNewLinkInfoW", FALSE
);
1983 return pSHGetNewLinkInfoW(pszLinkTo
, pszDir
, pszName
, pfMustCopy
, uFlags
);
1986 /*************************************************************************
1989 * Late bound call to shell32.SHDefExtractIconW
1991 DWORD WINAPI
SHLWAPI_358(LPVOID arg1
, LPVOID arg2
, LPVOID arg3
, LPVOID arg4
,
1992 LPVOID arg5
, LPVOID arg6
)
1994 GET_FUNC(pSHDefExtractIconW
, shell32
, "SHDefExtractIconW", 0);
1995 return pSHDefExtractIconW(arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
1998 /*************************************************************************
2001 * Wrapper for lstrcpynA with src and dst swapped.
2003 DWORD WINAPI
SHLWAPI_364(LPCSTR src
, LPSTR dst
, INT n
)
2005 lstrcpynA(dst
, src
, n
);
2009 /*************************************************************************
2012 * Late bound call to shell32.ExtractIconW
2014 HICON WINAPI
SHLWAPI_370(HINSTANCE hInstance
, LPCWSTR lpszExeFileName
,
2017 GET_FUNC(pExtractIconW
, shell32
, "ExtractIconW", (HICON
)0);
2018 return pExtractIconW(hInstance
, lpszExeFileName
, nIconIndex
);
2021 /*************************************************************************
2024 LANGID WINAPI
SHLWAPI_376 ()
2027 /* FIXME: This should be a forward in the .spec file to the win2k function
2028 * kernel32.GetUserDefaultUILanguage, however that function isn't there yet.
2030 return GetUserDefaultLangID();
2033 /*************************************************************************
2036 * FIXME: Native appears to do DPA_Create and a DPA_InsertPtr for
2038 * FIXME: Native shows calls to:
2039 * SHRegGetUSValue for "Software\Microsoft\Internet Explorer\International"
2041 * RegOpenKeyExA for "HKLM\Software\Microsoft\Internet Explorer"
2042 * RegQueryValueExA for "LPKInstalled"
2044 * RegOpenKeyExA for "HKCU\Software\Microsoft\Internet Explorer\International"
2045 * RegQueryValueExA for "ResourceLocale"
2047 * RegOpenKeyExA for "HKLM\Software\Microsoft\Active Setup\Installed Components\{guid}"
2048 * RegQueryValueExA for "Locale"
2050 * and then tests the Locale ("en" for me).
2052 * after the code then a DPA_Create (first time) and DPA_InsertPtr are done.
2054 DWORD WINAPI
SHLWAPI_377 (LPCSTR new_mod
, HMODULE inst_hwnd
, LPVOID z
)
2056 CHAR mod_path
[2*MAX_PATH
];
2059 GetModuleFileNameA(inst_hwnd
, mod_path
, 2*MAX_PATH
);
2060 ptr
= strrchr(mod_path
, '\\');
2062 strcpy(ptr
+1, new_mod
);
2063 TRACE("loading %s\n", debugstr_a(mod_path
));
2064 return (DWORD
)LoadLibraryA(mod_path
);
2069 /*************************************************************************
2072 * This is Unicode version of .377
2074 DWORD WINAPI
SHLWAPI_378 (
2075 LPCWSTR new_mod
, /* [in] new module name */
2076 HMODULE inst_hwnd
, /* [in] calling module handle */
2077 LPVOID z
) /* [???] 4 */
2079 WCHAR mod_path
[2*MAX_PATH
];
2082 GetModuleFileNameW(inst_hwnd
, mod_path
, 2*MAX_PATH
);
2083 ptr
= strrchrW(mod_path
, '\\');
2085 strcpyW(ptr
+1, new_mod
);
2086 TRACE("loading %s\n", debugstr_w(mod_path
));
2087 return (DWORD
)LoadLibraryW(mod_path
);
2092 /*************************************************************************
2095 * Late bound call to comdlg32.GetSaveFileNameW
2097 BOOL WINAPI
SHLWAPI_389(LPOPENFILENAMEW ofn
)
2099 GET_FUNC(pGetSaveFileNameW
, comdlg32
, "GetSaveFileNameW", FALSE
);
2100 return pGetSaveFileNameW(ofn
);
2103 /*************************************************************************
2106 * Late bound call to mpr.WNetRestoreConnectionW
2108 DWORD WINAPI
SHLWAPI_390(LPVOID arg1
, LPVOID arg2
)
2110 GET_FUNC(pWNetRestoreConnectionW
, mpr
, "WNetRestoreConnectionW", 0);
2111 return pWNetRestoreConnectionW(arg1
, arg2
);
2114 /*************************************************************************
2117 * Late bound call to mpr.WNetGetLastErrorW
2119 DWORD WINAPI
SHLWAPI_391(LPVOID arg1
, LPVOID arg2
, LPVOID arg3
, LPVOID arg4
,
2122 GET_FUNC(pWNetGetLastErrorW
, mpr
, "WNetGetLastErrorW", 0);
2123 return pWNetGetLastErrorW(arg1
, arg2
, arg3
, arg4
, arg5
);
2126 /*************************************************************************
2129 * Late bound call to comdlg32.PageSetupDlgW
2131 BOOL WINAPI
SHLWAPI_401(LPPAGESETUPDLGW pagedlg
)
2133 GET_FUNC(pPageSetupDlgW
, comdlg32
, "PageSetupDlgW", FALSE
);
2134 return pPageSetupDlgW(pagedlg
);
2137 /*************************************************************************
2140 * Late bound call to comdlg32.PrintDlgW
2142 BOOL WINAPI
SHLWAPI_402(LPPRINTDLGW printdlg
)
2144 GET_FUNC(pPrintDlgW
, comdlg32
, "PrintDlgW", FALSE
);
2145 return pPrintDlgW(printdlg
);
2148 /*************************************************************************
2151 * Late bound call to comdlg32.GetOpenFileNameW
2153 BOOL WINAPI
SHLWAPI_403(LPOPENFILENAMEW ofn
)
2155 GET_FUNC(pGetOpenFileNameW
, comdlg32
, "GetOpenFileNameW", FALSE
);
2156 return pGetOpenFileNameW(ofn
);
2159 /* INTERNAL: Map from HLS color space to RGB */
2160 static WORD
ConvertHue(int wHue
, WORD wMid1
, WORD wMid2
)
2162 wHue
= wHue
> 240 ? wHue
- 240 : wHue
< 0 ? wHue
+ 240 : wHue
;
2166 else if (wHue
> 120)
2171 return ((wHue
* (wMid2
- wMid1
) + 20) / 40) + wMid1
;
2174 /* Convert to RGB and scale into RGB range (0..255) */
2175 #define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240
2177 /*************************************************************************
2178 * ColorHLSToRGB [SHLWAPI.404]
2180 * Convert from HLS color space into an RGB COLORREF.
2183 * Input HLS values are constrained to the range (0..240).
2185 COLORREF WINAPI
ColorHLSToRGB(WORD wHue
, WORD wLuminosity
, WORD wSaturation
)
2191 WORD wGreen
, wBlue
, wMid1
, wMid2
;
2193 if (wLuminosity
> 120)
2194 wMid2
= wSaturation
+ wLuminosity
- (wSaturation
* wLuminosity
+ 120) / 240;
2196 wMid2
= ((wSaturation
+ 240) * wLuminosity
+ 120) / 240;
2198 wMid1
= wLuminosity
* 2 - wMid2
;
2200 wRed
= GET_RGB(wHue
+ 80);
2201 wGreen
= GET_RGB(wHue
);
2202 wBlue
= GET_RGB(wHue
- 80);
2204 return RGB(wRed
, wGreen
, wBlue
);
2207 wRed
= wLuminosity
* 255 / 240;
2208 return RGB(wRed
, wRed
, wRed
);
2211 /*************************************************************************
2214 * Function unknown seems to always to return 0
2217 DWORD WINAPI
SHLWAPI_413 (DWORD x
)
2219 FIXME("(0x%08lx)stub\n", x
);
2223 /*************************************************************************
2226 * Function seems to do FreeLibrary plus other things.
2228 * FIXME native shows the following calls:
2229 * RtlEnterCriticalSection
2231 * GetProcAddress(Comctl32??, 150L)
2233 * RtlLeaveCriticalSection
2234 * followed by the FreeLibrary.
2235 * The above code may be related to .377 above.
2237 BOOL WINAPI
SHLWAPI_418 (HMODULE x
)
2239 FIXME("(0x%08lx) partial stub\n", (LONG
)x
);
2240 return FreeLibrary(x
);
2243 /*************************************************************************
2246 DWORD WINAPI
SHLWAPI_430 (HINSTANCE hModule
, HANDLE heap
)
2248 FIXME("(0x%08lx 0x%08lx) stub\n", (DWORD
)hModule
, (DWORD
)heap
);
2249 return E_FAIL
; /* This is what is used if shlwapi not loaded */
2252 /*************************************************************************
2255 DWORD WINAPI
SHLWAPI_431 (DWORD x
)
2257 FIXME("(0x%08lx)stub\n", x
);
2261 /*************************************************************************
2264 * This is really CLSIDFromString which is exported by ole32.dll,
2265 * however the native shlwapi.dll does *not* import ole32. Nor does
2266 * ole32.dll import this ordinal from shlwapi. Therefore we must conclude
2267 * that MS duplicated the code for CLSIDFromString.
2269 * This is a duplicate (with changes for UNICODE) of CLSIDFromString16
2270 * in dlls/ole32/compobj.c
2272 DWORD WINAPI
SHLWAPI_436 (LPWSTR idstr
, CLSID
*id
)
2280 memset(s
, 0, sizeof(CLSID
));
2283 else { /* validate the CLSID string */
2285 if (strlenW(s
) != 38)
2286 return CO_E_CLASSSTRING
;
2288 if ((s
[0]!=L
'{') || (s
[9]!=L
'-') || (s
[14]!=L
'-') || (s
[19]!=L
'-') || (s
[24]!=L
'-') || (s
[37]!=L
'}'))
2289 return CO_E_CLASSSTRING
;
2291 for (i
=1; i
<37; i
++)
2293 if ((i
== 9)||(i
== 14)||(i
== 19)||(i
== 24)) continue;
2294 if (!(((s
[i
] >= L
'0') && (s
[i
] <= L
'9')) ||
2295 ((s
[i
] >= L
'a') && (s
[i
] <= L
'f')) ||
2296 ((s
[i
] >= L
'A') && (s
[i
] <= L
'F')))
2298 return CO_E_CLASSSTRING
;
2302 TRACE("%s -> %p\n", debugstr_w(s
), id
);
2304 /* quick lookup table */
2305 memset(table
, 0, 256*sizeof(WCHAR
));
2307 for (i
= 0; i
< 10; i
++) {
2310 for (i
= 0; i
< 6; i
++) {
2311 table
['A' + i
] = i
+10;
2312 table
['a' + i
] = i
+10;
2315 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
2319 s
++; /* skip leading brace */
2320 for (i
= 0; i
< 4; i
++) {
2321 p
[3 - i
] = table
[*s
]<<4 | table
[*(s
+1)];
2327 for (i
= 0; i
< 2; i
++) {
2328 p
[1-i
] = table
[*s
]<<4 | table
[*(s
+1)];
2334 for (i
= 0; i
< 2; i
++) {
2335 p
[1-i
] = table
[*s
]<<4 | table
[*(s
+1)];
2341 /* these are just sequential bytes */
2342 for (i
= 0; i
< 2; i
++) {
2343 *p
++ = table
[*s
]<<4 | table
[*(s
+1)];
2348 for (i
= 0; i
< 6; i
++) {
2349 *p
++ = table
[*s
]<<4 | table
[*(s
+1)];
2356 /*************************************************************************
2360 * In the real shlwapi, One time initialisation calls GetVersionEx and reads
2361 * the registry to determine what O/S & Service Pack level is running, and
2362 * therefore which functions are available. Currently we always run as NT,
2363 * since this means that we don't need extra code to emulate Unicode calls,
2364 * they are forwarded directly to the appropriate API call instead.
2365 * Since the flags for whether to call or emulate Unicode are internal to
2366 * the dll, this function does not need a full implementation.
2368 DWORD WINAPI
SHLWAPI_437 (DWORD functionToCall
)
2370 FIXME("(0x%08lx)stub\n", functionToCall
);
2371 return /* 0xabba1247 */ 0;
2374 /*************************************************************************
2375 * ColorRGBToHLS [SHLWAPI.445]
2377 * Convert from RGB COLORREF into the HLS color space.
2380 * Input HLS values are constrained to the range (0..240).
2382 VOID WINAPI
ColorRGBToHLS(COLORREF drRGB
, LPWORD pwHue
,
2383 LPWORD wLuminance
, LPWORD pwSaturation
)
2389 /*************************************************************************
2390 * SHCreateShellPalette [SHLWAPI.@]
2392 HPALETTE WINAPI
SHCreateShellPalette(HDC hdc
)
2395 return CreateHalftonePalette(hdc
);
2398 /*************************************************************************
2399 * SHGetInverseCMAP (SHLWAPI.@)
2401 DWORD WINAPI
SHGetInverseCMAP (LPDWORD
* x
, DWORD why
)
2404 FIXME(" - returning bogus address for SHGetInverseCMAP\n");
2405 *x
= (LPDWORD
)0xabba1249;
2408 FIXME("(%p, %#lx)stub\n", x
, why
);
2412 /*************************************************************************
2413 * SHIsLowMemoryMachine [SHLWAPI.@]
2415 DWORD WINAPI
SHIsLowMemoryMachine (DWORD x
)
2417 FIXME("0x%08lx\n", x
);
2421 /*************************************************************************
2422 * GetMenuPosFromID [SHLWAPI.@]
2424 INT WINAPI
GetMenuPosFromID(HMENU hMenu
, UINT wID
)
2427 INT nCount
= GetMenuItemCount(hMenu
), nIter
= 0;
2429 while (nIter
< nCount
)
2432 if (!GetMenuItemInfoA(hMenu
, nIter
, TRUE
, &mi
) && mi
.wID
== wID
)