2 * Shlwapi string functions
4 * Copyright 1998 Juergen Schmied
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 #define NO_SHLWAPI_STREAM
35 #include "wine/unicode.h"
36 #include "wine/debug.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
40 /*************************************************************************
41 * ChrCmpIA [SHLWAPI.385]
43 * Note: Returns 0 (FALSE) if characters are equal (insensitive).
45 BOOL WINAPI
ChrCmpIA (WORD w1
, WORD w2
)
47 TRACE("%c ? %c\n", w1
, w2
);
48 return (toupper(w1
) != toupper(w2
));
51 /*************************************************************************
52 * ChrCmpIW [SHLWAPI.386]
54 * Note: Returns 0 (FALSE) if characters are equal (insensitive).
56 BOOL WINAPI
ChrCmpIW (WCHAR w1
, WCHAR w2
)
58 TRACE("%c ? %c\n", w1
, w2
);
59 return (toupperW(w1
) != toupperW(w2
));
62 /*************************************************************************
65 LPSTR WINAPI
StrChrA (LPCSTR str
, WORD c
)
67 TRACE("%s %i\n", str
,c
);
68 return strchr(str
, c
);
71 /*************************************************************************
75 LPWSTR WINAPI
StrChrW (LPCWSTR str
, WCHAR x
)
77 TRACE("%s 0x%04x\n",debugstr_w(str
),x
);
78 return strchrW(str
, x
);
81 /*************************************************************************
82 * StrCmpIW [SHLWAPI.@]
84 int WINAPI
StrCmpIW ( LPCWSTR wstr1
, LPCWSTR wstr2
)
86 TRACE("%s %s\n", debugstr_w(wstr1
),debugstr_w(wstr2
));
87 return strcmpiW( wstr1
, wstr2
);
90 /*************************************************************************
91 * StrCmpNA [SHLWAPI.@]
93 INT WINAPI
StrCmpNA ( LPCSTR str1
, LPCSTR str2
, INT len
)
95 TRACE("%s %s %i stub\n", str1
,str2
,len
);
96 return strncmp(str1
, str2
, len
);
99 /*************************************************************************
100 * StrCmpNW [SHLWAPI.@]
102 INT WINAPI
StrCmpNW ( LPCWSTR wstr1
, LPCWSTR wstr2
, INT len
)
104 TRACE("%s %s %i stub\n", debugstr_w(wstr1
),debugstr_w(wstr2
),len
);
105 return strncmpW(wstr1
, wstr2
, len
);
108 /*************************************************************************
109 * StrCmpNIA [SHLWAPI.@]
111 int WINAPI
StrCmpNIA ( LPCSTR str1
, LPCSTR str2
, int len
)
113 TRACE("%s %s %i stub\n", str1
,str2
,len
);
114 return strncasecmp(str1
, str2
, len
);
117 /*************************************************************************
118 * StrCmpNIW [SHLWAPI.@]
120 int WINAPI
StrCmpNIW ( LPCWSTR wstr1
, LPCWSTR wstr2
, int len
)
122 TRACE("%s %s %i stub\n", debugstr_w(wstr1
),debugstr_w(wstr2
),len
);
123 return strncmpiW(wstr1
, wstr2
, len
);
126 /*************************************************************************
127 * StrCmpW [SHLWAPI.@]
129 int WINAPI
StrCmpW ( LPCWSTR wstr1
, LPCWSTR wstr2
)
131 TRACE("%s %s\n", debugstr_w(wstr1
),debugstr_w(wstr2
));
132 return strcmpW( wstr1
, wstr2
);
135 /*************************************************************************
136 * StrCatW [SHLWAPI.@]
138 LPWSTR WINAPI
StrCatW( LPWSTR wstr1
, LPCWSTR wstr2
)
140 return strcatW( wstr1
, wstr2
);
144 /*************************************************************************
145 * StrCpyW [SHLWAPI.@]
147 LPWSTR WINAPI
StrCpyW( LPWSTR wstr1
, LPCWSTR wstr2
)
149 return strcpyW( wstr1
, wstr2
);
153 /*************************************************************************
154 * StrCpyNW [SHLWAPI.@]
156 LPWSTR WINAPI
StrCpyNW( LPWSTR wstr1
, LPCWSTR wstr2
, int n
)
158 return lstrcpynW( wstr1
, wstr2
, n
);
162 /*************************************************************************
163 * StrStrA [SHLWAPI.@]
165 LPSTR WINAPI
StrStrA(LPCSTR lpFirst
, LPCSTR lpSrch
)
169 LPCSTR p1
= lpFirst
, p2
= lpSrch
;
170 while (*p1
&& *p2
&& *p1
== *p2
) { p1
++; p2
++; }
171 if (!*p2
) return (LPSTR
)lpFirst
;
177 /*************************************************************************
178 * StrStrW [SHLWAPI.@]
180 LPWSTR WINAPI
StrStrW(LPCWSTR lpFirst
, LPCWSTR lpSrch
)
184 LPCWSTR p1
= lpFirst
, p2
= lpSrch
;
185 while (*p1
&& *p2
&& *p1
== *p2
) { p1
++; p2
++; }
186 if (!*p2
) return (LPWSTR
)lpFirst
;
192 /*************************************************************************
193 * StrStrIA [SHLWAPI.@]
195 LPSTR WINAPI
StrStrIA(LPCSTR lpFirst
, LPCSTR lpSrch
)
199 LPCSTR p1
= lpFirst
, p2
= lpSrch
;
200 while (*p1
&& *p2
&& toupper(*p1
) == toupper(*p2
)) { p1
++; p2
++; }
201 if (!*p2
) return (LPSTR
)lpFirst
;
207 /*************************************************************************
208 * StrStrIW [SHLWAPI.@]
210 LPWSTR WINAPI
StrStrIW(LPCWSTR lpFirst
, LPCWSTR lpSrch
)
214 LPCWSTR p1
= lpFirst
, p2
= lpSrch
;
215 while (*p1
&& *p2
&& toupperW(*p1
) == toupperW(*p2
)) { p1
++; p2
++; }
216 if (!*p2
) return (LPWSTR
)lpFirst
;
222 /*************************************************************************
223 * StrToIntA [SHLWAPI.@]
225 int WINAPI
StrToIntA(LPCSTR lpSrc
)
227 TRACE("%s\n", lpSrc
);
231 /*************************************************************************
232 * StrToIntW [SHLWAPI.@]
234 int WINAPI
StrToIntW(LPCWSTR lpSrc
)
238 TRACE("%s\n", debugstr_w(lpSrc
));
239 WideCharToMultiByte( CP_ACP
, 0, lpSrc
, -1, buffer
, sizeof(buffer
), NULL
, NULL
);
240 buffer
[sizeof(buffer
)-1] = 0;
244 /*************************************************************************
245 * StrToIntExA [SHLWAPI.@]
247 BOOL WINAPI
StrToIntExA( LPCSTR pszString
, DWORD dwFlags
, LPINT piRet
)
249 TRACE("%s %ld stub !\n", debugstr_a(pszString
), dwFlags
);
250 piRet
= (LPINT
) StrToIntA(pszString
);
254 /*************************************************************************
255 * StrToIntExW [SHLWAPI.@]
257 BOOL WINAPI
StrToIntExW( LPCWSTR pszString
, DWORD dwFlags
, LPINT piRet
)
259 TRACE("%s %ld stub !\n", debugstr_w(pszString
), dwFlags
);
260 piRet
= (LPINT
) StrToIntW(pszString
);
264 /*************************************************************************
265 * StrDupA [SHLWAPI.@]
267 LPSTR WINAPI
StrDupA (LPCSTR lpSrc
)
269 int len
= strlen(lpSrc
);
270 LPSTR lpDest
= (LPSTR
) LocalAlloc(LMEM_FIXED
, len
+1);
272 TRACE("%s\n", lpSrc
);
274 if (lpDest
) strcpy(lpDest
, lpSrc
);
278 /*************************************************************************
279 * StrDupW [SHLWAPI.@]
281 LPWSTR WINAPI
StrDupW (LPCWSTR lpSrc
)
283 int len
= strlenW(lpSrc
);
284 LPWSTR lpDest
= (LPWSTR
) LocalAlloc(LMEM_FIXED
, sizeof(WCHAR
) * (len
+1));
286 TRACE("%s\n", debugstr_w(lpSrc
));
288 if (lpDest
) strcpyW(lpDest
, lpSrc
);
292 /*************************************************************************
293 * StrCSpnA [SHLWAPI.@]
295 int WINAPI
StrCSpnA (LPCSTR lpStr
, LPCSTR lpSet
)
297 int i
,j
, pos
= strlen(lpStr
);
299 TRACE("(%p %s %p %s)\n",
300 lpStr
, debugstr_a(lpStr
), lpSet
, debugstr_a(lpSet
));
302 for (i
=0; i
< strlen(lpSet
) ; i
++ )
304 for (j
= 0; j
< pos
;j
++)
306 if (lpStr
[j
] == lpSet
[i
])
312 TRACE("-- %u\n", pos
);
316 /*************************************************************************
317 * StrCSpnW [SHLWAPI.@]
319 int WINAPI
StrCSpnW (LPCWSTR lpStr
, LPCWSTR lpSet
)
321 int i
,j
, pos
= strlenW(lpStr
);
323 TRACE("(%p %s %p %s)\n",
324 lpStr
, debugstr_w(lpStr
), lpSet
, debugstr_w(lpSet
));
326 for (i
=0; i
< strlenW(lpSet
) ; i
++ )
328 for (j
= 0; j
< pos
;j
++)
330 if (lpStr
[j
] == lpSet
[i
])
336 TRACE("-- %u\n", pos
);
340 /**************************************************************************
341 * StrRChrA [SHLWAPI.@]
344 LPSTR WINAPI
StrRChrA( LPCSTR lpStart
, LPCSTR lpEnd
, WORD wMatch
)
346 LPCSTR lpGotIt
= NULL
;
347 BOOL dbcs
= IsDBCSLeadByte( LOBYTE(wMatch
) );
349 TRACE("(%p, %p, %x)\n", lpStart
, lpEnd
, wMatch
);
350 if (!lpStart
&& !lpEnd
) return NULL
;
351 if (!lpEnd
) lpEnd
= lpStart
+ strlen(lpStart
);
353 for(; lpStart
< lpEnd
; lpStart
= CharNextA(lpStart
))
355 if (*lpStart
!= LOBYTE(wMatch
)) continue;
356 if (dbcs
&& lpStart
[1] != HIBYTE(wMatch
)) continue;
359 return (LPSTR
)lpGotIt
;
363 /**************************************************************************
364 * StrRChrW [SHLWAPI.@]
367 LPWSTR WINAPI
StrRChrW( LPCWSTR lpStart
, LPCWSTR lpEnd
, WORD wMatch
)
369 LPCWSTR lpGotIt
= NULL
;
371 TRACE("(%p, %p, %x)\n", lpStart
, lpEnd
, wMatch
);
372 if (!lpStart
&& !lpEnd
) return NULL
;
373 if (!lpEnd
) lpEnd
= lpStart
+ strlenW(lpStart
);
375 for(; lpStart
< lpEnd
; lpStart
= CharNextW(lpStart
))
376 if (*lpStart
== wMatch
) lpGotIt
= lpStart
;
378 return (LPWSTR
)lpGotIt
;
382 /**************************************************************************
383 * StrRChrIA [SHLWAPI.@]
386 LPSTR WINAPI
StrRChrIA( LPCSTR lpStart
, LPCSTR lpEnd
, WORD wMatch
)
388 LPCSTR lpGotIt
= NULL
;
389 BOOL dbcs
= IsDBCSLeadByte( LOBYTE(wMatch
) );
391 TRACE("(%p, %p, %x)\n", lpStart
, lpEnd
, wMatch
);
392 if (!lpStart
&& !lpEnd
) return NULL
;
393 if (!lpEnd
) lpEnd
= lpStart
+ strlen(lpStart
);
395 for(; lpStart
< lpEnd
; lpStart
= CharNextA(lpStart
))
399 if (_mbctoupper(*lpStart) == _mbctoupper(wMatch))
402 if (toupper(*lpStart
) == toupper(wMatch
)) lpGotIt
= lpStart
;
404 if (toupper(*lpStart
) == toupper(wMatch
)) lpGotIt
= lpStart
;
407 return (LPSTR
)lpGotIt
;
411 /**************************************************************************
412 * StrRChrIW [SHLWAPI.@]
415 LPWSTR WINAPI
StrRChrIW( LPCWSTR lpStart
, LPCWSTR lpEnd
, WORD wMatch
)
417 LPCWSTR lpGotIt
= NULL
;
419 TRACE("(%p, %p, %x)\n", lpStart
, lpEnd
, wMatch
);
420 if (!lpStart
&& !lpEnd
) return NULL
;
421 if (!lpEnd
) lpEnd
= lpStart
+ strlenW(lpStart
);
423 for(; lpStart
< lpEnd
; lpStart
= CharNextW(lpStart
))
424 if (toupperW(*lpStart
) == toupperW(wMatch
)) lpGotIt
= lpStart
;
426 return (LPWSTR
)lpGotIt
;
430 /*************************************************************************
431 * StrCatBuffA [SHLWAPI.@]
433 * Appends back onto front, stopping when front is size-1 characters long.
437 LPSTR WINAPI
StrCatBuffA(LPSTR front
, LPCSTR back
, INT size
)
439 LPSTR dst
= front
+ strlen(front
);
440 LPCSTR src
= back
, end
= front
+ size
- 1;
442 while(dst
< end
&& *src
)
448 /*************************************************************************
449 * StrCatBuffW [SHLWAPI.@]
451 * Appends back onto front, stopping when front is size-1 characters long.
455 LPWSTR WINAPI
StrCatBuffW(LPWSTR front
, LPCWSTR back
, INT size
)
457 LPWSTR dst
= front
+ strlenW(front
);
458 LPCWSTR src
= back
, end
= front
+ size
- 1;
460 while(dst
< end
&& *src
)
466 /*************************************************************************
467 * StrRetToBufA [SHLWAPI.@]
469 * converts a STRRET to a normal string
472 * the pidl is for STRRET OFFSET
475 * This routine is identical to StrRetToStrNA in dlls/shell32/shellstring.c.
476 * It was duplicated there because not every version of Shlwapi.dll exports
477 * StrRetToBufA. If you change one routine, change them both. YOU HAVE BEEN
481 HRESULT WINAPI
StrRetToBufA (LPSTRRET src
, const ITEMIDLIST
*pidl
, LPSTR dest
, DWORD len
)
483 TRACE("dest=%p len=0x%lx strret=%p pidl=%p stub\n",dest
,len
,src
,pidl
);
488 WideCharToMultiByte(CP_ACP
, 0, src
->u
.pOleStr
, -1, (LPSTR
)dest
, len
, NULL
, NULL
);
489 /* SHFree(src->u.pOleStr); FIXME: is this right? */
493 lstrcpynA((LPSTR
)dest
, src
->u
.cStr
, len
);
497 lstrcpynA((LPSTR
)dest
, ((LPCSTR
)&pidl
->mkid
)+src
->u
.uOffset
, len
);
501 FIXME("unknown type!\n");
511 /*************************************************************************
512 * StrRetToBufW [SHLWAPI.@]
514 * converts a STRRET to a normal string
517 * the pidl is for STRRET OFFSET
520 * This routine is identical to StrRetToStrNW in dlls/shell32/shellstring.c.
521 * It was duplicated there because not every version of Shlwapi.dll exports
522 * StrRetToBufW. If you change one routine, change them both. YOU HAVE BEEN
526 HRESULT WINAPI
StrRetToBufW (LPSTRRET src
, const ITEMIDLIST
*pidl
, LPWSTR dest
, DWORD len
)
528 TRACE("dest=%p len=0x%lx strret=%p pidl=%p stub\n",dest
,len
,src
,pidl
);
533 lstrcpynW((LPWSTR
)dest
, src
->u
.pOleStr
, len
);
534 /* SHFree(src->u.pOleStr); FIXME: is this right? */
538 if (!MultiByteToWideChar( CP_ACP
, 0, src
->u
.cStr
, -1, dest
, len
) && len
)
545 if (!MultiByteToWideChar( CP_ACP
, 0, ((LPCSTR
)&pidl
->mkid
)+src
->u
.uOffset
, -1,
552 FIXME("unknown type!\n");
554 { *(LPSTR
)dest
= '\0';
561 /*************************************************************************
562 * StrFormatByteSizeA [SHLWAPI.@]
564 LPSTR WINAPI
StrFormatByteSizeA ( DWORD dw
, LPSTR pszBuf
, UINT cchBuf
)
566 TRACE("%lx %p %i\n", dw
, pszBuf
, cchBuf
);
568 { sprintf (buf
,"%ld bytes", dw
);
570 else if ( dw
<1048576L)
571 { sprintf (buf
,"%3.1f KB", (FLOAT
)dw
/1024);
573 else if ( dw
< 1073741824L)
574 { sprintf (buf
,"%3.1f MB", (FLOAT
)dw
/1048576L);
577 { sprintf (buf
,"%3.1f GB", (FLOAT
)dw
/1073741824L);
579 lstrcpynA (pszBuf
, buf
, cchBuf
);
583 /*************************************************************************
584 * StrFormatByteSizeW [SHLWAPI.@]
586 LPWSTR WINAPI
StrFormatByteSizeW ( DWORD dw
, LPWSTR pszBuf
, UINT cchBuf
)
589 StrFormatByteSizeA( dw
, buf
, sizeof(buf
) );
590 if (!MultiByteToWideChar( CP_ACP
, 0, buf
, -1, pszBuf
, cchBuf
) && cchBuf
)
591 pszBuf
[cchBuf
-1] = 0;
595 /*************************************************************************
596 * StrNCatA [SHLWAPI.@]
598 LPSTR WINAPI
StrNCatA(LPSTR front
, LPCSTR back
, INT cchMax
)
600 TRACE("%s %s %i stub\n", debugstr_a(front
),debugstr_a(back
),cchMax
);
604 /*************************************************************************
605 * StrNCatW [SHLWAPI.@]
607 LPWSTR WINAPI
StrNCatW(LPWSTR front
, LPCWSTR back
, INT cchMax
)
609 TRACE("%s %s %i stub\n", debugstr_w(front
),debugstr_w(back
),cchMax
);
613 /*************************************************************************
614 * StrTrimA [SHLWAPI.@]
616 BOOL WINAPI
StrTrimA(LPSTR pszSource
, LPCSTR pszTrimChars
)
618 BOOL trimmed
= FALSE
;
622 TRACE("('%s', '%s');\n", pszSource
, pszTrimChars
);
623 for (pTrim
= pszTrimChars
; *pTrim
; pTrim
++)
625 for (pSrc
= pszSource
; *pSrc
; pSrc
++)
628 /* match -> remove this char.
629 * strlen(pSrc) equiv. to the correct strlen(pSrc+1)+1 */
630 memmove(pSrc
, pSrc
+1, strlen(pSrc
));
634 TRACE("<- '%s'\n", pszSource
);