Fileokstring notification should be sent to the custom child dialog,
[wine] / dlls / shlwapi / string.c
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 "shlwapi.h"
12 #include "shlobj.h"
13 #include "wine/unicode.h"
14 #include "debugtools.h"
15
16 DEFAULT_DEBUG_CHANNEL(shell);
17
18 /*************************************************************************
19  * StrChrA                                      [SHLWAPI]
20  */
21 LPSTR WINAPI StrChrA (LPCSTR str, WORD c)
22 {
23         TRACE("%s %i\n", str,c);
24         return strchr(str, c);
25 }
26
27 /*************************************************************************
28  * StrChrW                                      [SHLWAPI]
29  *
30  */
31 LPWSTR WINAPI StrChrW (LPCWSTR str, WCHAR x )
32 {
33         TRACE("%s 0x%04x\n",debugstr_w(str),x);
34         return strchrW(str, x);
35 }
36
37 /*************************************************************************
38  * StrCmpIW                                     [SHLWAPI]
39  */
40 int WINAPI StrCmpIW ( LPCWSTR wstr1, LPCWSTR wstr2 )
41 {
42     TRACE("%s %s\n", debugstr_w(wstr1),debugstr_w(wstr2));
43     return strcmpiW( wstr1, wstr2 );
44 }
45
46 /*************************************************************************
47  * StrCmpNA                                     [SHLWAPI]
48  */
49 INT WINAPI StrCmpNA ( LPCSTR str1, LPCSTR str2, INT len)
50 {
51         TRACE("%s %s %i stub\n", str1,str2,len);
52         return strncmp(str1, str2, len);
53 }
54
55 /*************************************************************************
56  * StrCmpNW                                     [SHLWAPI]
57  */
58 INT WINAPI StrCmpNW ( LPCWSTR wstr1, LPCWSTR wstr2, INT len)
59 {
60         TRACE("%s %s %i stub\n", debugstr_w(wstr1),debugstr_w(wstr2),len);
61         return strncmpW(wstr1, wstr2, len);
62 }
63
64 /*************************************************************************
65  * StrCmpNIA                                    [SHLWAPI]
66  */
67 int WINAPI StrCmpNIA ( LPCSTR str1, LPCSTR str2, int len)
68 {
69         TRACE("%s %s %i stub\n", str1,str2,len);
70         return strncasecmp(str1, str2, len);
71 }
72
73 /*************************************************************************
74  * StrCmpNIW                                    [SHLWAPI]
75  */
76 int WINAPI StrCmpNIW ( LPCWSTR wstr1, LPCWSTR wstr2, int len)
77 {
78         TRACE("%s %s %i stub\n", debugstr_w(wstr1),debugstr_w(wstr2),len);
79         return strncmpiW(wstr1, wstr2, len);
80 }
81
82 /*************************************************************************
83  * StrCmpW                                      [SHLWAPI]
84  */
85 int WINAPI StrCmpW ( LPCWSTR wstr1, LPCWSTR wstr2 )
86 {
87     TRACE("%s %s\n", debugstr_w(wstr1),debugstr_w(wstr2));
88     return strcmpW( wstr1, wstr2 );
89 }
90
91 /*************************************************************************
92  * StrCatW                                      [SHLWAPI]
93  */
94 LPWSTR WINAPI StrCatW( LPWSTR wstr1, LPCWSTR wstr2 )
95 {
96     return strcatW( wstr1, wstr2 );
97 }
98
99
100 /*************************************************************************
101  * StrCpyW                                      [SHLWAPI]
102  */
103 LPWSTR WINAPI StrCpyW( LPWSTR wstr1, LPCWSTR wstr2 )
104 {
105     return strcpyW( wstr1, wstr2 );
106 }
107
108
109 /*************************************************************************
110  * StrCpyNW                                     [SHLWAPI]
111  */
112 LPWSTR WINAPI StrCpyNW( LPWSTR wstr1, LPCWSTR wstr2, int n )
113 {
114     return lstrcpynW( wstr1, wstr2, n );
115 }
116
117
118 /*************************************************************************
119  * StrStrA                                      [SHLWAPI]
120  */
121 LPSTR WINAPI StrStrA(LPCSTR lpFirst, LPCSTR lpSrch)
122 {
123     while (*lpFirst)
124     {
125         LPCSTR p1 = lpFirst, p2 = lpSrch;
126         while (*p1 && *p2 && *p1 == *p2) { p1++; p2++; }
127         if (!*p2) return (LPSTR)lpFirst;
128         lpFirst++;
129     }
130     return NULL;
131 }
132
133 /*************************************************************************
134  * StrStrW                                      [SHLWAPI]
135  */
136 LPWSTR WINAPI StrStrW(LPCWSTR lpFirst, LPCWSTR lpSrch)
137 {
138     while (*lpFirst)
139     {
140         LPCWSTR p1 = lpFirst, p2 = lpSrch;
141         while (*p1 && *p2 && *p1 == *p2) { p1++; p2++; }
142         if (!*p2) return (LPWSTR)lpFirst;
143         lpFirst++;
144     }
145     return NULL;
146 }
147
148 /*************************************************************************
149  * StrStrIA                                     [SHLWAPI]
150  */
151 LPSTR WINAPI StrStrIA(LPCSTR lpFirst, LPCSTR lpSrch)
152 {
153     while (*lpFirst)
154     {
155         LPCSTR p1 = lpFirst, p2 = lpSrch;
156         while (*p1 && *p2 && toupper(*p1) == toupper(*p2)) { p1++; p2++; }
157         if (!*p2) return (LPSTR)lpFirst;
158         lpFirst++;
159     }
160     return NULL;
161 }
162
163 /*************************************************************************
164  * StrStrIW                                     [SHLWAPI]
165  */
166 LPWSTR WINAPI StrStrIW(LPCWSTR lpFirst, LPCWSTR lpSrch)
167 {
168     while (*lpFirst)
169     {
170         LPCWSTR p1 = lpFirst, p2 = lpSrch;
171         while (*p1 && *p2 && toupperW(*p1) == toupperW(*p2)) { p1++; p2++; }
172         if (!*p2) return (LPWSTR)lpFirst;
173         lpFirst++;
174     }
175     return NULL;
176 }
177
178 /*************************************************************************
179  *      StrToIntA                       [SHLWAPI]
180  */
181 int WINAPI StrToIntA(LPCSTR lpSrc)
182 {
183         TRACE("%s\n", lpSrc);
184         return atol(lpSrc);
185 }
186
187 /*************************************************************************
188  *      StrToIntW                       [SHLWAPI]
189  */
190 int WINAPI StrToIntW(LPCWSTR lpSrc)
191 {
192     char buffer[32];
193
194     TRACE("%s\n", debugstr_w(lpSrc));
195     WideCharToMultiByte( CP_ACP, 0, lpSrc, -1, buffer, sizeof(buffer), NULL, NULL );
196     buffer[sizeof(buffer)-1] = 0;
197     return atol(buffer);
198 }
199
200 /*************************************************************************
201  *      StrDupA                 [SHLWAPI]
202  */
203 LPSTR WINAPI StrDupA (LPCSTR lpSrc)
204 {
205         int len = strlen(lpSrc);
206         LPSTR lpDest = (LPSTR) LocalAlloc(LMEM_FIXED, len+1);
207         
208         TRACE("%s\n", lpSrc);
209
210         if (lpDest) strcpy(lpDest, lpSrc);
211         return lpDest;
212 }
213
214 /*************************************************************************
215  *      StrDupW                 [SHLWAPI]
216  */
217 LPWSTR WINAPI StrDupW (LPCWSTR lpSrc)
218 {
219         int len = strlenW(lpSrc);
220         LPWSTR lpDest = (LPWSTR) LocalAlloc(LMEM_FIXED, sizeof(WCHAR) * (len+1));
221         
222         TRACE("%s\n", debugstr_w(lpSrc));
223
224         if (lpDest) strcpyW(lpDest, lpSrc);
225         return lpDest;
226 }
227
228 /*************************************************************************
229  *      StrCSpnA                [SHLWAPI]
230  */
231 int WINAPI StrCSpnA (LPCSTR lpStr, LPCSTR lpSet)
232 {
233         int i,j, pos = strlen(lpStr);
234
235         TRACE("(%p %s  %p %s)\n",
236            lpStr, debugstr_a(lpStr), lpSet, debugstr_a(lpSet));
237
238         for (i=0; i < strlen(lpSet) ; i++ )
239         {
240           for (j = 0; j < pos;j++)
241           {
242             if (lpStr[j] == lpSet[i])
243             {
244               pos = j;
245             }
246           }
247         }      
248         TRACE("-- %u\n", pos);
249         return pos;     
250 }
251
252 /*************************************************************************
253  *      StrCSpnW                [SHLWAPI]
254  */
255 int WINAPI StrCSpnW (LPCWSTR lpStr, LPCWSTR lpSet)
256 {
257         int i,j, pos = strlenW(lpStr);
258
259         TRACE("(%p %s %p %s)\n",
260            lpStr, debugstr_w(lpStr), lpSet, debugstr_w(lpSet));
261
262         for (i=0; i < strlenW(lpSet) ; i++ )
263         {
264           for (j = 0; j < pos;j++)
265           {
266             if (lpStr[j] == lpSet[i])
267             {
268               pos = j;
269             }
270           }
271         }      
272         TRACE("-- %u\n", pos);
273         return pos;     
274 }
275
276 /**************************************************************************
277  * StrRChrA [SHLWAPI.@]
278  *
279  */
280 LPSTR WINAPI StrRChrA( LPCSTR lpStart, LPCSTR lpEnd, WORD wMatch )
281 {
282     LPCSTR lpGotIt = NULL;
283     BOOL dbcs = IsDBCSLeadByte( LOBYTE(wMatch) );
284
285     TRACE("(%p, %p, %x)\n", lpStart, lpEnd, wMatch);
286
287     if (!lpEnd) lpEnd = lpStart + strlen(lpStart);
288
289     for(; lpStart < lpEnd; lpStart = CharNextA(lpStart))
290     {
291         if (*lpStart != LOBYTE(wMatch)) continue;
292         if (dbcs && lpStart[1] != HIBYTE(wMatch)) continue;
293         lpGotIt = lpStart;
294     }    
295     return (LPSTR)lpGotIt;
296 }
297
298
299 /**************************************************************************
300  * StrRChrW [SHLWAPI.@]
301  *
302  */
303 LPWSTR WINAPI StrRChrW( LPCWSTR lpStart, LPCWSTR lpEnd, WORD wMatch)
304 {
305     LPCWSTR lpGotIt = NULL;
306
307     TRACE("(%p, %p, %x)\n", lpStart, lpEnd, wMatch);
308     if (!lpEnd) lpEnd = lpStart + strlenW(lpStart);
309
310     for(; lpStart < lpEnd; lpStart = CharNextW(lpStart))
311         if (*lpStart == wMatch) lpGotIt = lpStart;
312
313     return (LPWSTR)lpGotIt;
314 }
315
316
317 /*************************************************************************
318  *      StrCatBuffA             [SHLWAPI]
319  *
320  * Appends back onto front, stopping when front is size-1 characters long.
321  * Returns front.
322  *
323  */
324 LPSTR WINAPI StrCatBuffA(LPSTR front, LPCSTR back, INT size)
325 {
326     LPSTR dst = front + strlen(front);
327     LPCSTR src = back, end = front + size - 1;
328
329     while(dst < end && *src)
330         *dst++ = *src++;
331     *dst = '\0';
332     return front;
333 }
334
335 /*************************************************************************
336  *      StrCatBuffW             [SHLWAPI]
337  *
338  * Appends back onto front, stopping when front is size-1 characters long.
339  * Returns front.
340  *
341  */
342 LPWSTR WINAPI StrCatBuffW(LPWSTR front, LPCWSTR back, INT size)
343 {
344     LPWSTR dst = front + strlenW(front);
345     LPCWSTR src = back, end = front + size - 1;
346
347     while(dst < end && *src)
348         *dst++ = *src++;
349     *dst = '\0';
350     return front;
351 }
352
353 /*************************************************************************
354  * StrRetToBufA                                 [SHLWAPI.@]
355  * 
356  * converts a STRRET to a normal string
357  *
358  * NOTES
359  *  the pidl is for STRRET OFFSET
360  */
361 HRESULT WINAPI StrRetToBufA (LPSTRRET src, const ITEMIDLIST *pidl, LPSTR dest, DWORD len)
362 {
363         TRACE("dest=0x%p len=0x%lx strret=0x%p pidl=%p stub\n",dest,len,src,pidl);
364
365         switch (src->uType)
366         {
367           case STRRET_WSTR:
368             WideCharToMultiByte(CP_ACP, 0, src->u.pOleStr, -1, (LPSTR)dest, len, NULL, NULL);
369 /*          SHFree(src->u.pOleStr);  FIXME: is this right? */
370             break;
371
372           case STRRET_CSTRA:
373             lstrcpynA((LPSTR)dest, src->u.cStr, len);
374             break;
375
376           case STRRET_OFFSETA:
377             lstrcpynA((LPSTR)dest, ((LPCSTR)&pidl->mkid)+src->u.uOffset, len);
378             break;
379
380           default:
381             FIXME("unknown type!\n");
382             if (len)
383             {
384               *(LPSTR)dest = '\0';
385             }
386             return(FALSE);
387         }
388         return S_OK;
389 }
390
391 /*************************************************************************
392  * StrRetToBufW                                 [SHLWAPI.@]
393  * 
394  * converts a STRRET to a normal string
395  *
396  * NOTES
397  *  the pidl is for STRRET OFFSET
398  */
399 HRESULT WINAPI StrRetToBufW (LPSTRRET src, const ITEMIDLIST *pidl, LPWSTR dest, DWORD len)
400 {
401         TRACE("dest=0x%p len=0x%lx strret=0x%p pidl=%p stub\n",dest,len,src,pidl);
402
403         switch (src->uType)
404         {
405           case STRRET_WSTR:
406             lstrcpynW((LPWSTR)dest, src->u.pOleStr, len);
407 /*          SHFree(src->u.pOleStr);  FIXME: is this right? */
408             break;
409
410           case STRRET_CSTRA:
411               if (!MultiByteToWideChar( CP_ACP, 0, src->u.cStr, -1, dest, len ) && len)
412                   dest[len-1] = 0;
413             break;
414
415           case STRRET_OFFSETA:
416             if (pidl)
417             {
418               if (!MultiByteToWideChar( CP_ACP, 0, ((LPCSTR)&pidl->mkid)+src->u.uOffset, -1,
419                                         dest, len ) && len)
420                   dest[len-1] = 0;
421             }
422             break;
423
424           default:
425             FIXME("unknown type!\n");
426             if (len)
427             { *(LPSTR)dest = '\0';
428             }
429             return(FALSE);
430         }
431         return S_OK;
432 }
433
434 /*************************************************************************
435  * StrFormatByteSizeA                           [SHLWAPI]
436  */
437 LPSTR WINAPI StrFormatByteSizeA ( DWORD dw, LPSTR pszBuf, UINT cchBuf )
438 {       char buf[64];
439         TRACE("%lx %p %i\n", dw, pszBuf, cchBuf);
440         if ( dw<1024L )
441         { sprintf (buf,"%ld bytes", dw);
442         }
443         else if ( dw<1048576L)
444         { sprintf (buf,"%3.1f KB", (FLOAT)dw/1024);
445         }
446         else if ( dw < 1073741824L)
447         { sprintf (buf,"%3.1f MB", (FLOAT)dw/1048576L);
448         }
449         else
450         { sprintf (buf,"%3.1f GB", (FLOAT)dw/1073741824L);
451         }
452         lstrcpynA (pszBuf, buf, cchBuf);
453         return pszBuf;  
454 }
455
456 /*************************************************************************
457  * StrFormatByteSizeW                           [SHLWAPI]
458  */
459 LPWSTR WINAPI StrFormatByteSizeW ( DWORD dw, LPWSTR pszBuf, UINT cchBuf )
460 {
461         char buf[64];
462         StrFormatByteSizeA( dw, buf, sizeof(buf) );
463         if (!MultiByteToWideChar( CP_ACP, 0, buf, -1, pszBuf, cchBuf ) && cchBuf)
464             pszBuf[cchBuf-1] = 0;
465         return pszBuf;
466 }
467
468 /*************************************************************************
469  *      wnsprintfA      [SHLWAPI]
470  */
471 int WINAPIV wnsprintfA(LPSTR lpOut, int cchLimitIn, LPCSTR lpFmt, ...)
472 {
473     va_list valist;
474     INT res;
475
476     va_start( valist, lpFmt );
477     res = wvsnprintfA( lpOut, cchLimitIn, lpFmt, valist );
478     va_end( valist );
479     return res;
480 }
481
482 /*************************************************************************
483  *      wnsprintfW      [SHLWAPI]
484  */
485 int WINAPIV wnsprintfW(LPWSTR lpOut, int cchLimitIn, LPCWSTR lpFmt, ...)
486 {
487     va_list valist;
488     INT res;
489
490     va_start( valist, lpFmt );
491     res = wvsnprintfW( lpOut, cchLimitIn, lpFmt, valist );
492     va_end( valist );
493     return res;
494 }