source: trunk/src/shlwapi/string.c@ 21916

Last change on this file since 21916 was 21916, checked in by dmik, 14 years ago

Merge branch gcc-kmk to trunk.

File size: 16.3 KB
Line 
1/*
2 * Shlwapi string functions
3 *
4 * Copyright 1998 Juergen Schmied
5 *
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.
10 *
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.
15 *
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
19 */
20
21#include <ctype.h>
22#include <stdlib.h>
23#include <stdio.h>
24#include <string.h>
25
26#include "winerror.h"
27#include "windef.h"
28#include "winbase.h"
29#include "wingdi.h"
30#include "winuser.h"
31#include "winreg.h"
32#define NO_SHLWAPI_STREAM
33#include "shlwapi.h"
34#include "shlobj.h"
35#include "wine/unicode.h"
36#include "wine/debug.h"
37
38WINE_DEFAULT_DEBUG_CHANNEL(shell);
39
40/*************************************************************************
41 * ChrCmpIA [SHLWAPI.385]
42 *
43 * Note: Returns 0 (FALSE) if characters are equal (insensitive).
44 */
45BOOL WINAPI ChrCmpIA (WORD w1, WORD w2)
46{
47 TRACE("%c ? %c\n", w1, w2);
48 return (toupper(w1) != toupper(w2));
49}
50
51/*************************************************************************
52 * ChrCmpIW [SHLWAPI.386]
53 *
54 * Note: Returns 0 (FALSE) if characters are equal (insensitive).
55 */
56BOOL WINAPI ChrCmpIW (WCHAR w1, WCHAR w2)
57{
58 TRACE("%c ? %c\n", w1, w2);
59 return (toupperW(w1) != toupperW(w2));
60}
61
62/*************************************************************************
63 * StrChrA [SHLWAPI.@]
64 */
65LPSTR WINAPI StrChrA (LPCSTR str, WORD c)
66{
67 TRACE("%s %i\n", str,c);
68 return strchr(str, c);
69}
70
71/*************************************************************************
72 * StrChrW [SHLWAPI.@]
73 *
74 */
75LPWSTR WINAPI StrChrW (LPCWSTR str, WCHAR x )
76{
77 TRACE("%s 0x%04x\n",debugstr_w(str),x);
78 return strchrW(str, x);
79}
80
81/*************************************************************************
82 * StrCmpIW [SHLWAPI.@]
83 */
84int WINAPI StrCmpIW ( LPCWSTR wstr1, LPCWSTR wstr2 )
85{
86 TRACE("%s %s\n", debugstr_w(wstr1),debugstr_w(wstr2));
87 return strcmpiW( wstr1, wstr2 );
88}
89
90/*************************************************************************
91 * StrCmpNA [SHLWAPI.@]
92 */
93INT WINAPI StrCmpNA ( LPCSTR str1, LPCSTR str2, INT len)
94{
95 TRACE("%s %s %i stub\n", str1,str2,len);
96 return strncmp(str1, str2, len);
97}
98
99/*************************************************************************
100 * StrCmpNW [SHLWAPI.@]
101 */
102INT WINAPI StrCmpNW ( LPCWSTR wstr1, LPCWSTR wstr2, INT len)
103{
104 TRACE("%s %s %i stub\n", debugstr_w(wstr1),debugstr_w(wstr2),len);
105 return strncmpW(wstr1, wstr2, len);
106}
107
108/*************************************************************************
109 * StrCmpNIA [SHLWAPI.@]
110 */
111int WINAPI StrCmpNIA ( LPCSTR str1, LPCSTR str2, int len)
112{
113 TRACE("%s %s %i stub\n", str1,str2,len);
114 return strncasecmp(str1, str2, len);
115}
116
117/*************************************************************************
118 * StrCmpNIW [SHLWAPI.@]
119 */
120int WINAPI StrCmpNIW ( LPCWSTR wstr1, LPCWSTR wstr2, int len)
121{
122 TRACE("%s %s %i stub\n", debugstr_w(wstr1),debugstr_w(wstr2),len);
123 return strncmpiW(wstr1, wstr2, len);
124}
125
126/*************************************************************************
127 * StrCmpW [SHLWAPI.@]
128 */
129int WINAPI StrCmpW ( LPCWSTR wstr1, LPCWSTR wstr2 )
130{
131 TRACE("%s %s\n", debugstr_w(wstr1),debugstr_w(wstr2));
132 return strcmpW( wstr1, wstr2 );
133}
134
135/*************************************************************************
136 * StrCatW [SHLWAPI.@]
137 */
138LPWSTR WINAPI StrCatW( LPWSTR wstr1, LPCWSTR wstr2 )
139{
140 return strcatW( wstr1, wstr2 );
141}
142
143
144/*************************************************************************
145 * StrCpyW [SHLWAPI.@]
146 */
147LPWSTR WINAPI StrCpyW( LPWSTR wstr1, LPCWSTR wstr2 )
148{
149 return strcpyW( wstr1, wstr2 );
150}
151
152
153/*************************************************************************
154 * StrCpyNW [SHLWAPI.@]
155 */
156LPWSTR WINAPI StrCpyNW( LPWSTR wstr1, LPCWSTR wstr2, int n )
157{
158 return lstrcpynW( wstr1, wstr2, n );
159}
160
161
162/*************************************************************************
163 * StrStrA [SHLWAPI.@]
164 */
165LPSTR WINAPI StrStrA(LPCSTR lpFirst, LPCSTR lpSrch)
166{
167 while (*lpFirst)
168 {
169 LPCSTR p1 = lpFirst, p2 = lpSrch;
170 while (*p1 && *p2 && *p1 == *p2) { p1++; p2++; }
171 if (!*p2) return (LPSTR)lpFirst;
172 lpFirst++;
173 }
174 return NULL;
175}
176
177/*************************************************************************
178 * StrStrW [SHLWAPI.@]
179 */
180LPWSTR WINAPI StrStrW(LPCWSTR lpFirst, LPCWSTR lpSrch)
181{
182 while (*lpFirst)
183 {
184 LPCWSTR p1 = lpFirst, p2 = lpSrch;
185 while (*p1 && *p2 && *p1 == *p2) { p1++; p2++; }
186 if (!*p2) return (LPWSTR)lpFirst;
187 lpFirst++;
188 }
189 return NULL;
190}
191
192/*************************************************************************
193 * StrStrIA [SHLWAPI.@]
194 */
195LPSTR WINAPI StrStrIA(LPCSTR lpFirst, LPCSTR lpSrch)
196{
197 while (*lpFirst)
198 {
199 LPCSTR p1 = lpFirst, p2 = lpSrch;
200 while (*p1 && *p2 && toupper(*p1) == toupper(*p2)) { p1++; p2++; }
201 if (!*p2) return (LPSTR)lpFirst;
202 lpFirst++;
203 }
204 return NULL;
205}
206
207/*************************************************************************
208 * StrStrIW [SHLWAPI.@]
209 */
210LPWSTR WINAPI StrStrIW(LPCWSTR lpFirst, LPCWSTR lpSrch)
211{
212 while (*lpFirst)
213 {
214 LPCWSTR p1 = lpFirst, p2 = lpSrch;
215 while (*p1 && *p2 && toupperW(*p1) == toupperW(*p2)) { p1++; p2++; }
216 if (!*p2) return (LPWSTR)lpFirst;
217 lpFirst++;
218 }
219 return NULL;
220}
221
222/*************************************************************************
223 * StrToIntA [SHLWAPI.@]
224 */
225int WINAPI StrToIntA(LPCSTR lpSrc)
226{
227 TRACE("%s\n", lpSrc);
228 return atol(lpSrc);
229}
230
231/*************************************************************************
232 * StrToIntW [SHLWAPI.@]
233 */
234int WINAPI StrToIntW(LPCWSTR lpSrc)
235{
236 char buffer[32];
237
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;
241 return atol(buffer);
242}
243
244/*************************************************************************
245 * StrToIntExA [SHLWAPI.@]
246 */
247BOOL WINAPI StrToIntExA( LPCSTR pszString, DWORD dwFlags, LPINT piRet)
248{
249 TRACE("%s %ld stub !\n", debugstr_a(pszString), dwFlags);
250 piRet = (LPINT) StrToIntA(pszString);
251 return TRUE;
252}
253
254/*************************************************************************
255 * StrToIntExW [SHLWAPI.@]
256 */
257BOOL WINAPI StrToIntExW( LPCWSTR pszString, DWORD dwFlags, LPINT piRet)
258{
259 TRACE("%s %ld stub !\n", debugstr_w(pszString), dwFlags);
260 piRet = (LPINT) StrToIntW(pszString);
261 return TRUE;
262}
263
264/*************************************************************************
265 * StrDupA [SHLWAPI.@]
266 */
267LPSTR WINAPI StrDupA (LPCSTR lpSrc)
268{
269 int len = strlen(lpSrc);
270 LPSTR lpDest = (LPSTR) LocalAlloc(LMEM_FIXED, len+1);
271
272 TRACE("%s\n", lpSrc);
273
274 if (lpDest) strcpy(lpDest, lpSrc);
275 return lpDest;
276}
277
278/*************************************************************************
279 * StrDupW [SHLWAPI.@]
280 */
281LPWSTR WINAPI StrDupW (LPCWSTR lpSrc)
282{
283 int len = strlenW(lpSrc);
284 LPWSTR lpDest = (LPWSTR) LocalAlloc(LMEM_FIXED, sizeof(WCHAR) * (len+1));
285
286 TRACE("%s\n", debugstr_w(lpSrc));
287
288 if (lpDest) strcpyW(lpDest, lpSrc);
289 return lpDest;
290}
291
292/*************************************************************************
293 * StrCSpnA [SHLWAPI.@]
294 */
295int WINAPI StrCSpnA (LPCSTR lpStr, LPCSTR lpSet)
296{
297 int i,j, pos = strlen(lpStr);
298
299 TRACE("(%p %s %p %s)\n",
300 lpStr, debugstr_a(lpStr), lpSet, debugstr_a(lpSet));
301
302 for (i=0; i < strlen(lpSet) ; i++ )
303 {
304 for (j = 0; j < pos;j++)
305 {
306 if (lpStr[j] == lpSet[i])
307 {
308 pos = j;
309 }
310 }
311 }
312 TRACE("-- %u\n", pos);
313 return pos;
314}
315
316/*************************************************************************
317 * StrCSpnW [SHLWAPI.@]
318 */
319int WINAPI StrCSpnW (LPCWSTR lpStr, LPCWSTR lpSet)
320{
321 int i,j, pos = strlenW(lpStr);
322
323 TRACE("(%p %s %p %s)\n",
324 lpStr, debugstr_w(lpStr), lpSet, debugstr_w(lpSet));
325
326 for (i=0; i < strlenW(lpSet) ; i++ )
327 {
328 for (j = 0; j < pos;j++)
329 {
330 if (lpStr[j] == lpSet[i])
331 {
332 pos = j;
333 }
334 }
335 }
336 TRACE("-- %u\n", pos);
337 return pos;
338}
339
340/**************************************************************************
341 * StrRChrA [SHLWAPI.@]
342 *
343 */
344LPSTR WINAPI StrRChrA( LPCSTR lpStart, LPCSTR lpEnd, WORD wMatch )
345{
346 LPCSTR lpGotIt = NULL;
347 BOOL dbcs = IsDBCSLeadByte( LOBYTE(wMatch) );
348
349 TRACE("(%p, %p, %x)\n", lpStart, lpEnd, wMatch);
350 if (!lpStart && !lpEnd) return NULL;
351 if (!lpEnd) lpEnd = lpStart + strlen(lpStart);
352
353 for(; lpStart < lpEnd; lpStart = CharNextA(lpStart))
354 {
355 if (*lpStart != LOBYTE(wMatch)) continue;
356 if (dbcs && lpStart[1] != HIBYTE(wMatch)) continue;
357 lpGotIt = lpStart;
358 }
359 return (LPSTR)lpGotIt;
360}
361
362
363/**************************************************************************
364 * StrRChrW [SHLWAPI.@]
365 *
366 */
367LPWSTR WINAPI StrRChrW( LPCWSTR lpStart, LPCWSTR lpEnd, WORD wMatch)
368{
369 LPCWSTR lpGotIt = NULL;
370
371 TRACE("(%p, %p, %x)\n", lpStart, lpEnd, wMatch);
372 if (!lpStart && !lpEnd) return NULL;
373 if (!lpEnd) lpEnd = lpStart + strlenW(lpStart);
374
375 for(; lpStart < lpEnd; lpStart = CharNextW(lpStart))
376 if (*lpStart == wMatch) lpGotIt = lpStart;
377
378 return (LPWSTR)lpGotIt;
379}
380
381
382/**************************************************************************
383 * StrRChrIA [SHLWAPI.@]
384 *
385 */
386LPSTR WINAPI StrRChrIA( LPCSTR lpStart, LPCSTR lpEnd, WORD wMatch )
387{
388 LPCSTR lpGotIt = NULL;
389 BOOL dbcs = IsDBCSLeadByte( LOBYTE(wMatch) );
390
391 TRACE("(%p, %p, %x)\n", lpStart, lpEnd, wMatch);
392 if (!lpStart && !lpEnd) return NULL;
393 if (!lpEnd) lpEnd = lpStart + strlen(lpStart);
394
395 for(; lpStart < lpEnd; lpStart = CharNextA(lpStart))
396 {
397 if (dbcs) {
398 /*
399 if (_mbctoupper(*lpStart) == _mbctoupper(wMatch))
400 lpGotIt = lpStart;
401 */
402 if (toupper(*lpStart) == toupper(wMatch)) lpGotIt = lpStart;
403 } else {
404 if (toupper(*lpStart) == toupper(wMatch)) lpGotIt = lpStart;
405 }
406 }
407 return (LPSTR)lpGotIt;
408}
409
410
411/**************************************************************************
412 * StrRChrIW [SHLWAPI.@]
413 *
414 */
415LPWSTR WINAPI StrRChrIW( LPCWSTR lpStart, LPCWSTR lpEnd, WORD wMatch)
416{
417 LPCWSTR lpGotIt = NULL;
418
419 TRACE("(%p, %p, %x)\n", lpStart, lpEnd, wMatch);
420 if (!lpStart && !lpEnd) return NULL;
421 if (!lpEnd) lpEnd = lpStart + strlenW(lpStart);
422
423 for(; lpStart < lpEnd; lpStart = CharNextW(lpStart))
424 if (toupperW(*lpStart) == toupperW(wMatch)) lpGotIt = lpStart;
425
426 return (LPWSTR)lpGotIt;
427}
428
429
430/*************************************************************************
431 * StrCatBuffA [SHLWAPI.@]
432 *
433 * Appends back onto front, stopping when front is size-1 characters long.
434 * Returns front.
435 *
436 */
437LPSTR WINAPI StrCatBuffA(LPSTR front, LPCSTR back, INT size)
438{
439 LPSTR dst = front + strlen(front);
440 LPCSTR src = back, end = front + size - 1;
441
442 while(dst < end && *src)
443 *dst++ = *src++;
444 *dst = '\0';
445 return front;
446}
447
448/*************************************************************************
449 * StrCatBuffW [SHLWAPI.@]
450 *
451 * Appends back onto front, stopping when front is size-1 characters long.
452 * Returns front.
453 *
454 */
455LPWSTR WINAPI StrCatBuffW(LPWSTR front, LPCWSTR back, INT size)
456{
457 LPWSTR dst = front + strlenW(front);
458 LPCWSTR src = back, end = front + size - 1;
459
460 while(dst < end && *src)
461 *dst++ = *src++;
462 *dst = '\0';
463 return front;
464}
465
466/*************************************************************************
467 * StrRetToBufA [SHLWAPI.@]
468 *
469 * converts a STRRET to a normal string
470 *
471 * NOTES
472 * the pidl is for STRRET OFFSET
473 *
474 * ***** NOTE *****
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
478 * WARNED.
479 * ***** NOTE *****
480 */
481HRESULT WINAPI StrRetToBufA (LPSTRRET src, const ITEMIDLIST *pidl, LPSTR dest, DWORD len)
482{
483 TRACE("dest=%p len=0x%lx strret=%p pidl=%p stub\n",dest,len,src,pidl);
484
485 switch (src->uType)
486 {
487 case STRRET_WSTR:
488 WideCharToMultiByte(CP_ACP, 0, src->DUMMYUNIONNAME_DOT pOleStr, -1, (LPSTR)dest, len, NULL, NULL);
489/* SHFree(src->DUMMYUNIONNAME_DOT pOleStr); FIXME: is this right? */
490 break;
491
492 case STRRET_CSTR:
493 lstrcpynA((LPSTR)dest, src->DUMMYUNIONNAME_DOT cStr, len);
494 break;
495
496 case STRRET_OFFSET:
497 lstrcpynA((LPSTR)dest, ((LPCSTR)&pidl->mkid)+src->DUMMYUNIONNAME_DOT uOffset, len);
498 break;
499
500 default:
501 FIXME("unknown type!\n");
502 if (len)
503 {
504 *(LPSTR)dest = '\0';
505 }
506 return(FALSE);
507 }
508 return S_OK;
509}
510
511/*************************************************************************
512 * StrRetToBufW [SHLWAPI.@]
513 *
514 * converts a STRRET to a normal string
515 *
516 * NOTES
517 * the pidl is for STRRET OFFSET
518 *
519 * ***** NOTE *****
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
523 * WARNED.
524 * ***** NOTE *****
525 */
526HRESULT WINAPI StrRetToBufW (LPSTRRET src, const ITEMIDLIST *pidl, LPWSTR dest, DWORD len)
527{
528 TRACE("dest=%p len=0x%lx strret=%p pidl=%p stub\n",dest,len,src,pidl);
529
530 switch (src->uType)
531 {
532 case STRRET_WSTR:
533 lstrcpynW((LPWSTR)dest, src->DUMMYUNIONNAME_DOT pOleStr, len);
534/* SHFree(src->DUMMYUNIONNAME_DOT pOleStr); FIXME: is this right? */
535 break;
536
537 case STRRET_CSTR:
538 if (!MultiByteToWideChar( CP_ACP, 0, src->DUMMYUNIONNAME_DOT cStr, -1, dest, len ) && len)
539 dest[len-1] = 0;
540 break;
541
542 case STRRET_OFFSET:
543 if (pidl)
544 {
545 if (!MultiByteToWideChar( CP_ACP, 0, ((LPCSTR)&pidl->mkid)+src->DUMMYUNIONNAME_DOT uOffset, -1,
546 dest, len ) && len)
547 dest[len-1] = 0;
548 }
549 break;
550
551 default:
552 FIXME("unknown type!\n");
553 if (len)
554 { *(LPSTR)dest = '\0';
555 }
556 return(FALSE);
557 }
558 return S_OK;
559}
560
561/*************************************************************************
562 * StrFormatByteSizeA [SHLWAPI.@]
563 */
564LPSTR WINAPI StrFormatByteSizeA ( DWORD dw, LPSTR pszBuf, UINT cchBuf )
565{ char buf[64];
566 TRACE("%lx %p %i\n", dw, pszBuf, cchBuf);
567 if ( dw<1024L )
568 { sprintf (buf,"%ld bytes", dw);
569 }
570 else if ( dw<1048576L)
571 { sprintf (buf,"%3.1f KB", (FLOAT)dw/1024);
572 }
573 else if ( dw < 1073741824L)
574 { sprintf (buf,"%3.1f MB", (FLOAT)dw/1048576L);
575 }
576 else
577 { sprintf (buf,"%3.1f GB", (FLOAT)dw/1073741824L);
578 }
579 lstrcpynA (pszBuf, buf, cchBuf);
580 return pszBuf;
581}
582
583/*************************************************************************
584 * StrFormatByteSizeW [SHLWAPI.@]
585 */
586LPWSTR WINAPI StrFormatByteSizeW ( DWORD dw, LPWSTR pszBuf, UINT cchBuf )
587{
588 char buf[64];
589 StrFormatByteSizeA( dw, buf, sizeof(buf) );
590 if (!MultiByteToWideChar( CP_ACP, 0, buf, -1, pszBuf, cchBuf ) && cchBuf)
591 pszBuf[cchBuf-1] = 0;
592 return pszBuf;
593}
594
595/*************************************************************************
596 * StrNCatA [SHLWAPI.@]
597 */
598LPSTR WINAPI StrNCatA(LPSTR front, LPCSTR back, INT cchMax)
599{
600 TRACE("%s %s %i stub\n", debugstr_a(front),debugstr_a(back),cchMax);
601 return (front);
602}
603
604/*************************************************************************
605 * StrNCatW [SHLWAPI.@]
606 */
607LPWSTR WINAPI StrNCatW(LPWSTR front, LPCWSTR back, INT cchMax)
608{
609 TRACE("%s %s %i stub\n", debugstr_w(front),debugstr_w(back),cchMax);
610 return (front);
611}
612
613/*************************************************************************
614 * StrTrimA [SHLWAPI.@]
615 */
616BOOL WINAPI StrTrimA(LPSTR pszSource, LPCSTR pszTrimChars)
617{
618 BOOL trimmed = FALSE;
619 LPSTR pSrc;
620 LPCSTR pTrim;
621
622 TRACE("('%s', '%s');\n", pszSource, pszTrimChars);
623 for (pTrim = pszTrimChars; *pTrim; pTrim++)
624 {
625 for (pSrc = pszSource; *pSrc; pSrc++)
626 if (*pSrc == *pTrim)
627 {
628 /* match -> remove this char.
629 * strlen(pSrc) equiv. to the correct strlen(pSrc+1)+1 */
630 memmove(pSrc, pSrc+1, strlen(pSrc));
631 trimmed = TRUE;
632 }
633 }
634 TRACE("<- '%s'\n", pszSource);
635 return trimmed;
636}
Note: See TracBrowser for help on using the repository browser.