source: trunk/src/shlwapi/string.cpp@ 3687

Last change on this file since 3687 was 3687, checked in by phaller, 25 years ago

.

File size: 19.0 KB
Line 
1 /* $Id: string.cpp,v 1.4 2000-06-12 08:09:46 phaller Exp $ */
2
3/*
4 * Win32 Lightweight SHELL32 for OS/2
5 *
6 * Copyright 1997 Marcus Meissner
7 * Copyright 1999 Patrick Haller (haller@zebra.fh-weingarten.de)
8 * Project Odin Software License can be found in LICENSE.TXT
9 *
10 * Path Functions
11 *
12 * Many of this functions are in SHLWAPI.DLL also
13 *
14 * Corel WINE 20000324 level (without CRTDLL_* calls)
15 */
16
17/*****************************************************************************
18 * Remark *
19 *****************************************************************************
20
21 */
22
23
24/*****************************************************************************
25 * Includes *
26 *****************************************************************************/
27
28#include <odin.h>
29#include <odinwrap.h>
30#include <os2sel.h>
31
32#include <string.h>
33#include <ctype.h>
34#include <wctype.h>
35#include <wcstr.h>
36#define HAVE_WCTYPE_H
37
38#include "debugtools.h"
39
40#include <winreg.h>
41
42#include <heapstring.h>
43#include <misc.h>
44#include <win\shell.h>
45#include <win\winerror.h>
46#include <winversion.h>
47#include <winuser.h>
48
49
50#define ICOM_CINTERFACE 1
51#define CINTERFACE 1
52
53#include "winerror.h"
54#include "winnls.h"
55#include "winversion.h"
56#include "heap.h"
57
58#include "shellapi.h"
59#include "shlobj.h"
60#include "wine/undocshell.h"
61
62#include "shlwapi.h"
63
64/*****************************************************************************
65 * Local Variables *
66 *****************************************************************************/
67
68ODINDEBUGCHANNEL(SHLWAPI-STRING)
69
70
71/*****************************************************************************
72 * Name : ChrCmpIA
73 * Purpose :
74 * Parameters:
75 * Variables :
76 * Result :
77 * Remark :
78 * Status : UNTESTED
79 *
80 * Author : Patrick Haller [Wed, 1999/12/29 09:00]
81 *****************************************************************************/
82
83ODINFUNCTION2(INT, ChrCmpIA,
84 INT, ch1,
85 INT, ch2)
86{
87 // Note: IsDBCSLeadByte ignored !
88
89 if ( (ch1 >= 'A') && (ch1 <= 'Z') ) ch1 |= 0x20;
90 if ( (ch2 >= 'A') && (ch2 <= 'Z') ) ch2 |= 0x20;
91
92 return ch1 - ch2;
93}
94
95
96/*************************************************************************
97 * OleStrToStrN [SHELL32.78]
98 */
99BOOL WINAPI OleStrToStrNA (LPSTR lpStr, INT nStr, LPCWSTR lpOle, INT nOle)
100{
101 TRACE("%p %x %s %x\n", lpStr, nStr, debugstr_w(lpOle), nOle);
102 return WideCharToMultiByte (0, 0, lpOle, nOle, lpStr, nStr, NULL, NULL);
103}
104
105BOOL WINAPI OleStrToStrNW (LPWSTR lpwStr, INT nwStr, LPCWSTR lpOle, INT nOle)
106{
107 TRACE("%p %x %s %x\n", lpwStr, nwStr, debugstr_w(lpOle), nOle);
108
109 if (lstrcpynW ( lpwStr, lpOle, nwStr))
110 { return lstrlenW (lpwStr);
111 }
112 return 0;
113}
114
115BOOL WINAPI OleStrToStrNAW (LPVOID lpOut, INT nOut, LPCVOID lpIn, INT nIn)
116{
117 if (VERSION_OsIsUnicode())
118 return OleStrToStrNW ((LPWSTR)lpOut, nOut, (LPCWSTR)lpIn, nIn);
119 return OleStrToStrNA ((LPSTR)lpOut, nOut, (LPCWSTR)lpIn, nIn);
120}
121
122/*************************************************************************
123 * StrToOleStrN [SHELL32.79]
124 * lpMulti, nMulti, nWide [IN]
125 * lpWide [OUT]
126 */
127BOOL WINAPI StrToOleStrNA (LPWSTR lpWide, INT nWide, LPCSTR lpStrA, INT nStr)
128{
129 TRACE("%p %x %s %x\n", lpWide, nWide, lpStrA, nStr);
130 return MultiByteToWideChar (0, 0, lpStrA, nStr, lpWide, nWide);
131}
132BOOL WINAPI StrToOleStrNW (LPWSTR lpWide, INT nWide, LPCWSTR lpStrW, INT nStr)
133{
134 TRACE("%p %x %s %x\n", lpWide, nWide, debugstr_w(lpStrW), nStr);
135
136 if (lstrcpynW (lpWide, lpStrW, nWide))
137 { return lstrlenW (lpWide);
138 }
139 return 0;
140}
141
142BOOL WINAPI StrToOleStrNAW (LPWSTR lpWide, INT nWide, LPCVOID lpStr, INT nStr)
143{
144 if (VERSION_OsIsUnicode())
145 return StrToOleStrNW (lpWide, nWide, (LPWSTR)lpStr, nStr);
146 return StrToOleStrNA (lpWide, nWide, (LPSTR)lpStr, nStr);
147}
148
149
150/*************************************************************************
151 * StrRetToStrN [SHELL32.96]
152 *
153 * converts a STRRET to a normal string
154 *
155 * NOTES
156 * the pidl is for STRRET OFFSET
157 */
158HRESULT WINAPI StrRetToBufA (LPSTRRET src, LPITEMIDLIST pidl, LPSTR dest, DWORD len)
159{
160 return StrRetToStrNA(dest, len, src, pidl);
161}
162
163HRESULT WINAPI StrRetToStrNA (LPVOID dest, DWORD len, LPSTRRET src, LPITEMIDLIST pidl)
164{
165 TRACE("dest=0x%p len=0x%lx strret=0x%p pidl=%p stub\n",dest,len,src,pidl);
166
167 switch (src->uType)
168 {
169 case STRRET_WSTR:
170 WideCharToMultiByte(CP_ACP, 0, src->u.pOleStr, -1, (LPSTR)dest, len, NULL, NULL);
171 SHFree(src->u.pOleStr);
172 break;
173
174 case STRRET_CSTRA:
175 lstrcpynA((LPSTR)dest, src->u.cStr, len);
176 break;
177
178 case STRRET_OFFSETA:
179 lstrcpynA((LPSTR)dest, ((LPCSTR)&pidl->mkid)+src->u.uOffset, len);
180 break;
181
182 default:
183 FIXME("unknown type!\n");
184 if (len)
185 {
186 *(LPSTR)dest = '\0';
187 }
188 return(FALSE);
189 }
190 return S_OK;
191}
192
193HRESULT WINAPI StrRetToBufW (LPSTRRET src, LPITEMIDLIST pidl, LPWSTR dest, DWORD len)
194{
195 return StrRetToStrNW(dest, len, src, pidl);
196}
197
198HRESULT WINAPI StrRetToStrNW (LPVOID dest, DWORD len, LPSTRRET src, LPITEMIDLIST pidl)
199{
200 TRACE("dest=0x%p len=0x%lx strret=0x%p pidl=%p stub\n",dest,len,src,pidl);
201
202 switch (src->uType)
203 {
204 case STRRET_WSTR:
205 lstrcpynW((LPWSTR)dest, src->u.pOleStr, len);
206 SHFree(src->u.pOleStr);
207 break;
208
209 case STRRET_CSTRA:
210 lstrcpynAtoW((LPWSTR)dest, src->u.cStr, len);
211 break;
212
213 case STRRET_OFFSETA:
214 if (pidl)
215 {
216 lstrcpynAtoW((LPWSTR)dest, ((LPSTR)&pidl->mkid)+src->u.uOffset, len);
217 }
218 break;
219
220 default:
221 FIXME("unknown type!\n");
222 if (len)
223 { *(LPSTR)dest = '\0';
224 }
225 return(FALSE);
226 }
227 return S_OK;
228}
229HRESULT WINAPI StrRetToStrNAW (LPVOID dest, DWORD len, LPSTRRET src, LPITEMIDLIST pidl)
230{
231 if(VERSION_OsIsUnicode())
232 return StrRetToStrNW (dest, len, src, pidl);
233 return StrRetToStrNA (dest, len, src, pidl);
234}
235
236/*************************************************************************
237 * StrChrA [NT 4.0:SHELL32.651]
238 *
239 */
240LPSTR WINAPI StrChrA (LPSTR str, CHAR x )
241{ LPSTR ptr=str;
242
243 do
244 { if (*ptr==x)
245 { return ptr;
246 }
247 ptr++;
248 } while (*ptr);
249 return NULL;
250}
251
252/*************************************************************************
253 * StrChrW [NT 4.0:SHELL32.651]
254 *
255 */
256LPWSTR WINAPI StrChrW (LPWSTR str, WCHAR x )
257{ LPWSTR ptr=str;
258
259 TRACE("%s 0x%04x\n",debugstr_w(str),x);
260 do
261 { if (*ptr==x)
262 { return ptr;
263 }
264 ptr++;
265 } while (*ptr);
266 return NULL;
267}
268
269/*************************************************************************
270 * StrCmpNIW [NT 4.0:SHELL32.*]
271 *
272 */
273INT WINAPI StrCmpNIW ( LPWSTR wstr1, LPWSTR wstr2, INT len)
274{ FIXME("%s %s %i stub\n", debugstr_w(wstr1),debugstr_w(wstr2),len);
275 return 0;
276}
277
278/*************************************************************************
279 * StrCmpNIA [NT 4.0:SHELL32.*]
280 *
281 */
282INT WINAPI StrCmpNIA ( LPSTR wstr1, LPSTR wstr2, INT len)
283{ FIXME("%s %s %i stub\n", wstr1,wstr2,len);
284 return 0;
285}
286
287
288/*************************************************************************
289 * StrRChrA [SHELL32.346]
290 *
291 */
292LPSTR WINAPI StrRChrA(LPCSTR lpStart, LPCSTR lpEnd, DWORD wMatch)
293{
294 if (!lpStart)
295 return NULL;
296
297 /* if the end not given, search*/
298 if (!lpEnd)
299 { lpEnd=lpStart;
300 while (*lpEnd)
301 lpEnd++;
302 }
303
304 for (--lpEnd;lpStart <= lpEnd; lpEnd--)
305 if (*lpEnd==(char)wMatch)
306 return (LPSTR)lpEnd;
307
308 return NULL;
309}
310/*************************************************************************
311 * StrRChrW [SHELL32.320]
312 *
313 */
314LPWSTR WINAPI StrRChrW(LPWSTR lpStart, LPWSTR lpEnd, DWORD wMatch)
315{ LPWSTR wptr=NULL;
316 TRACE("%s %s 0x%04x\n",debugstr_w(lpStart),debugstr_w(lpEnd), (WCHAR)wMatch );
317
318 /* if the end not given, search*/
319 if (!lpEnd)
320 { lpEnd=lpStart;
321 while (*lpEnd)
322 lpEnd++;
323 }
324
325 do
326 { if (*lpStart==(WCHAR)wMatch)
327 wptr = lpStart;
328 lpStart++;
329 } while ( lpStart<=lpEnd );
330 return wptr;
331}
332
333/************************************************************************
334 * StrToOleStr [SHELL32.163]
335 *
336 */
337int WINAPI StrToOleStrA (LPWSTR lpWideCharStr, LPCSTR lpMultiByteString)
338{
339 TRACE("%p %p(%s)\n",
340 lpWideCharStr, lpMultiByteString, lpMultiByteString);
341
342 return MultiByteToWideChar(0, 0, lpMultiByteString, -1, lpWideCharStr, MAX_PATH);
343
344}
345int WINAPI StrToOleStrW (LPWSTR lpWideCharStr, LPCWSTR lpWString)
346{
347 TRACE("%p %p(%s)\n",
348 lpWideCharStr, lpWString, debugstr_w(lpWString));
349
350 if (lstrcpyW (lpWideCharStr, lpWString ))
351 { return lstrlenW (lpWideCharStr);
352 }
353 return 0;
354}
355
356BOOL WINAPI StrToOleStrAW (LPWSTR lpWideCharStr, LPCVOID lpString)
357{
358 if (VERSION_OsIsUnicode())
359 return StrToOleStrW (lpWideCharStr, (LPCWSTR)lpString);
360 return StrToOleStrA (lpWideCharStr, (LPCSTR)lpString);
361}
362
363
364
365/*****************************************************************************
366 * Name : StrChrIA
367 * Purpose : Searches a string for the first occurrence of a character that
368 * matches the specified character. The comparison is not case sensitive.
369 * Parameters: LPCSTR lpStart Address of the string to be searched.
370 * TCHAR wMatch Character to be used for comparison.
371 * Variables :
372 * Result : Returns the address of the first occurrence of the character in
373 * the string if successful, or NULL otherwise.
374 * Remark : SHELL32.
375 * Status : UNTESTED UNKNOWN
376 *
377 * Author : Patrick Haller [Wed, 1999/12/29 09:00]
378 *****************************************************************************/
379
380ODINFUNCTION2(LPSTR, StrChrIA,
381 LPCSTR, lpStart,
382 CHAR, wMatch)
383{
384 LPSTR lpRes;
385
386 wMatch = tolower(wMatch);
387 lpRes = strchr(lpStart, wMatch); // lower case comparsion
388 if (NULL == lpRes)
389 {
390 wMatch = toupper(wMatch);
391 lpRes = strchr(lpStart, wMatch); // upper case comparsion
392 }
393
394 return lpRes;
395}
396
397
398/*****************************************************************************
399 * Name : StrChrIW
400 * Purpose : Searches a string for the first occurrence of a character that
401 * matches the specified character. The comparison is not case sensitive.
402 * Parameters: LPCSTR lpStart Address of the string to be searched.
403 * TCHAR wMatch Character to be used for comparison.
404 * Variables :
405 * Result : Returns the address of the first occurrence of the character in
406 * the string if successful, or NULL otherwise.
407 * Remark : SHELL32.
408 * Status : UNTESTED UNKNOWN
409 *
410 * Author : Patrick Haller [Wed, 1999/12/29 09:00]
411 *****************************************************************************/
412
413ODINFUNCTION2(LPWSTR, StrChrIW,
414 LPCWSTR, lpStart,
415 WCHAR, wMatch)
416{
417 LPWSTR lpRes;
418
419 wMatch = towlower(wMatch);
420 lpRes = (WCHAR*)wcschr((const wchar_t*)lpStart, wMatch); // lower case comparsion
421 if (NULL == lpRes)
422 {
423 wMatch = towupper(wMatch);
424 lpRes = (WCHAR*)wcschr((const wchar_t*)lpStart, wMatch); // upper case comparsion
425 }
426
427 return lpRes;
428}
429
430
431/*****************************************************************************
432 * Name : StrStrIA
433 * Purpose : Finds the first occurrence of a substring within a string. The
434 * comparison is not case sensitive.
435 * Parameters: LPCSTR lpFirst
436 * LPCSTR lpSrch
437 * Variables :
438 * Result : Returns the address of the first occurrence of the matching
439 * substring if successful, or NULL otherwise.
440 * Remark : SHELL32.
441 * Status : UNTESTED UNKNOWN
442 *
443 * Author : Patrick Haller [Wed, 1999/12/29 09:00]
444 *****************************************************************************/
445
446ODINFUNCTION2(LPSTR, StrStrIA,
447 LPCSTR, lpFirst,
448 LPCSTR, lpSrch)
449{
450 char ch = lpSrch[0]; // look for 1st character
451 LONG lLen = lstrlenA(lpSrch); // length of search string
452 int iRes; // comparsion result
453
454 do
455 {
456 lpFirst = StrChrIA(lpFirst, // find first matching character
457 ch);
458 if (NULL == lpFirst) // not found
459 return NULL;
460
461 iRes = StrCmpNIA((LPSTR)lpFirst, // compare search string
462 (LPSTR)lpSrch,
463 lLen);
464
465 if (0 == iRes) // Found!
466 return (LPSTR)lpFirst;
467
468 lpFirst = CharNextA(lpFirst); // skip to next character
469 }
470 while (*lpFirst != 0); // safe termination
471
472 return NULL; // default result
473}
474
475
476
477/*****************************************************************************
478 * Name : StrStrIW
479 * Purpose : Finds the first occurrence of a substring within a string. The
480 * comparison is not case sensitive.
481 * Parameters: LPCWSTR lpFirst
482 * LPCWSTR lpSrch
483 * Variables :
484 * Result : Returns the address of the first occurrence of the matching
485 * substring if successful, or NULL otherwise.
486 * Remark : SHELL32.
487 * Status : UNTESTED UNKNOWN
488 *
489 * Author : Patrick Haller [Wed, 1999/12/29 09:00]
490 *****************************************************************************/
491
492ODINFUNCTION2(LPWSTR, StrStrIW,
493 LPCWSTR, lpFirst,
494 LPCWSTR, lpSrch)
495{
496 WCHAR ch = lpSrch[0]; // look for 1st character
497 LONG lLen = lstrlenW(lpSrch); // length of search string
498 int iRes; // comparsion result
499
500 do
501 {
502 lpFirst = StrChrIW(lpFirst, // find first matching character
503 ch);
504 if (NULL == lpFirst) // not found
505 return NULL;
506
507 iRes = StrCmpNIW((LPWSTR)lpFirst, // compare search string
508 (LPWSTR)lpSrch,
509 lLen);
510
511 if (0 == iRes) // Found!
512 return (LPWSTR)lpFirst;
513
514 lpFirst = CharNextW(lpFirst); // skip to next character
515 }
516 while (*lpFirst != 0); // safe termination
517
518 return NULL; // default result
519}
520
521
522
523/*****************************************************************************
524 * Name : StrToIntA
525 * Purpose : convert string to integer (used by explorer.exe)
526 * Parameters: Unknown (wrong)
527 * Variables :
528 * Result : Unknown
529 * Remark : SHLWAPI.675
530 * Status : UNTESTED STUB
531 *
532 * Author : Christoph Bratschi [Wed, 2000/03/29 19:47]
533 *****************************************************************************/
534
535ODINFUNCTION1(INT,StrToIntA,LPSTR,pszPath)
536{
537 dprintf(("not implemented"));
538
539 return NULL;
540}
541
542
543/*************************************************************************
544* StrToIntW [SHLWAPI]ú
545*/
546int WINAPI StrToIntW(LPCWSTR lpSrc)
547{
548 int ret;
549 LPSTR lpStr = HEAP_strdupWtoA(GetProcessHeap(),0,lpSrc);
550
551 TRACE("%s\n", debugstr_w(lpSrc));
552
553 ret = atol(lpStr);
554 HeapFree(GetProcessHeap(),0,lpStr);
555 return ret;
556}
557
558
559/*************************************************************************
560 * StrFormatByteSizeA [SHLWAPI]
561 */
562ODINFUNCTION3(LPSTR, StrFormatByteSizeA, DWORD, dw, LPSTR, pszBuf, UINT, cchBuf )
563{ char buf[64];
564 TRACE("%lx %p %i\n", dw, pszBuf, cchBuf);
565 if ( dw<1024L )
566 { sprintf (buf,"%3.1f bytes", (FLOAT)dw);
567 }
568 else if ( dw<1048576L)
569 { sprintf (buf,"%3.1f KB", (FLOAT)dw/1024);
570 }
571 else if ( dw < 1073741824L)
572 { sprintf (buf,"%3.1f MB", (FLOAT)dw/1048576L);
573 }
574 else
575 { sprintf (buf,"%3.1f GB", (FLOAT)dw/1073741824L);
576 }
577 lstrcpynA (pszBuf, buf, cchBuf);
578 return pszBuf;
579}
580
581/*************************************************************************
582 * StrFormatByteSizeW [SHLWAPI]
583 */
584ODINFUNCTION3(LPWSTR, StrFormatByteSizeW, DWORD, dw, LPWSTR, pszBuf, UINT, cchBuf)
585{ char buf[64];
586 TRACE("%lx %p %i\n", dw, pszBuf, cchBuf);
587 if ( dw<1024L )
588 { sprintf (buf,"%3.1f bytes", (FLOAT)dw);
589 }
590 else if ( dw<1048576L)
591 { sprintf (buf,"%3.1f KB", (FLOAT)dw/1024);
592 }
593 else if ( dw < 1073741824L)
594 { sprintf (buf,"%3.1f MB", (FLOAT)dw/1048576L);
595 }
596 else
597 { sprintf (buf,"%3.1f GB", (FLOAT)dw/1073741824L);
598 }
599 lstrcpynAtoW (pszBuf, buf, cchBuf);
600 return pszBuf;
601}
602
603
604/*****************************************************************************
605 * Name : StrCpyA
606 * Purpose : copy a string
607 * Parameters:
608 * Variables :
609 * Result :
610 * Remark : not exported ?
611 * Status : UNTESTED
612 *
613 * Author :
614 *****************************************************************************/
615
616ODINFUNCTION2(LPSTR, StrCpyA,
617 LPSTR, lpDest,
618 LPCSTR, lpSource)
619{
620 return lstrcpyA(lpDest,
621 lpSource);
622}
623
624
625/*****************************************************************************
626 * Name : StrCpyW
627 * Purpose : copy a wide-character string
628 * Parameters:
629 * Variables :
630 * Result :
631 * Remark : SHLWAPI.642
632 * Status : UNTESTED
633 *
634 * Author :
635 *****************************************************************************/
636
637ODINFUNCTION2(LPWSTR, StrCpyW,
638 LPWSTR, lpDest,
639 LPCWSTR, lpSource)
640{
641 return lstrcpyW(lpDest,
642 lpSource);
643}
644
645
646/*****************************************************************************
647 * Name : StrDupA
648 * Purpose : duplicate a string on the local heap
649 * Parameters:
650 * Variables :
651 * Result :
652 * Remark : SHLWAPI.644
653 * Status : UNTESTED
654 *
655 * Author :
656 *****************************************************************************/
657
658ODINFUNCTION1(LPSTR, StrDupA,
659 LPCSTR, lpStr)
660{
661 int iLength = lstrlenA(lpStr) + 1;
662 HLOCAL hLocal = LocalAlloc(LMEM_ZEROINIT,
663 iLength);
664 if (hLocal != NULL)
665 StrCpyA((LPSTR)hLocal,
666 lpStr);
667
668 return (LPSTR)hLocal;
669}
670
671
672/*****************************************************************************
673 * Name : StrDupW
674 * Purpose : duplicate a wide-characters string on the local heap
675 * Parameters:
676 * Variables :
677 * Result :
678 * Remark : SHLWAPI.645
679 * Status : UNTESTED
680 *
681 * Author :
682 *****************************************************************************/
683
684ODINFUNCTION1(LPWSTR, StrDupW,
685 LPCWSTR, lpStr)
686{
687 int iLength = lstrlenW(lpStr) << 1 + 2;
688 HLOCAL hLocal = LocalAlloc(LMEM_ZEROINIT,
689 iLength);
690 if (hLocal != NULL)
691 StrCpyW((LPWSTR)hLocal,
692 lpStr);
693
694 return (LPWSTR)hLocal;
695}
Note: See TracBrowser for help on using the repository browser.