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

Last change on this file since 8266 was 7820, checked in by sandervl, 24 years ago

Wine resync

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