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

Last change on this file since 21512 was 21512, checked in by dmik, 15 years ago

Aligned the STRRET definition and made it available through shlwapi.h and shlobj.h for compatibility with Win32.

File size: 16.2 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->u.pOleStr, -1, (LPSTR)dest, len, NULL, NULL);
489/* SHFree(src->u.pOleStr); FIXME: is this right? */
490 break;
491
492 case STRRET_CSTR:
493 lstrcpynA((LPSTR)dest, src->u.cStr, len);
494 break;
495
496 case STRRET_OFFSET:
497 lstrcpynA((LPSTR)dest, ((LPCSTR)&pidl->mkid)+src->u.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->u.pOleStr, len);
534/* SHFree(src->u.pOleStr); FIXME: is this right? */
535 break;
536
537 case STRRET_CSTR:
538 if (!MultiByteToWideChar( CP_ACP, 0, src->u.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->u.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.