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

Last change on this file since 3942 was 3942, checked in by bird, 25 years ago

Function status corrections.

File size: 19.3 KB
Line 
1 /* $Id: string.cpp,v 1.6 2000-08-02 20:18:24 bird 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 : PARTIALLY IMPLEMENTED 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 HeapFree( GetProcessHeap(), 0, src->u.pOleStr);
173 break;
174
175 case STRRET_CSTRA:
176 lstrcpynA((LPSTR)dest, src->u.cStr, len);
177 break;
178
179 case STRRET_OFFSETA:
180 lstrcpynA((LPSTR)dest, ((LPCSTR)&pidl->mkid)+src->u.uOffset, len);
181 break;
182
183 default:
184 FIXME("unknown type!\n");
185 if (len)
186 {
187 *(LPSTR)dest = '\0';
188 }
189 return(FALSE);
190 }
191 return S_OK;
192}
193
194HRESULT WINAPI StrRetToBufW (LPSTRRET src, LPITEMIDLIST pidl, LPWSTR dest, DWORD len)
195{
196 return StrRetToStrNW(dest, len, src, pidl);
197}
198
199HRESULT WINAPI StrRetToStrNW (LPVOID dest, DWORD len, LPSTRRET src, LPITEMIDLIST pidl)
200{
201 TRACE("dest=0x%p len=0x%lx strret=0x%p pidl=%p stub\n",dest,len,src,pidl);
202
203 switch (src->uType)
204 {
205 case STRRET_WSTR:
206 lstrcpynW((LPWSTR)dest, src->u.pOleStr, len);
207 //SHFree(src->u.pOleStr);
208 HeapFree( GetProcessHeap(), 0, src->u.pOleStr);
209 break;
210
211 case STRRET_CSTRA:
212 lstrcpynAtoW((LPWSTR)dest, src->u.cStr, len);
213 break;
214
215 case STRRET_OFFSETA:
216 if (pidl)
217 {
218 lstrcpynAtoW((LPWSTR)dest, ((LPSTR)&pidl->mkid)+src->u.uOffset, len);
219 }
220 break;
221
222 default:
223 FIXME("unknown type!\n");
224 if (len)
225 { *(LPSTR)dest = '\0';
226 }
227 return(FALSE);
228 }
229 return S_OK;
230}
231HRESULT WINAPI StrRetToStrNAW (LPVOID dest, DWORD len, LPSTRRET src, LPITEMIDLIST pidl)
232{
233 if(VERSION_OsIsUnicode())
234 return StrRetToStrNW (dest, len, src, pidl);
235 return StrRetToStrNA (dest, len, src, pidl);
236}
237
238/*************************************************************************
239 * StrChrA [NT 4.0:SHELL32.651]
240 *
241 */
242LPSTR WINAPI StrChrA (LPSTR str, CHAR x )
243{ LPSTR ptr=str;
244
245 do
246 { if (*ptr==x)
247 { return ptr;
248 }
249 ptr++;
250 } while (*ptr);
251 return NULL;
252}
253
254/*************************************************************************
255 * StrChrW [NT 4.0:SHELL32.651]
256 *
257 */
258LPWSTR WINAPI StrChrW (LPWSTR str, WCHAR x )
259{ LPWSTR ptr=str;
260
261 TRACE("%s 0x%04x\n",debugstr_w(str),x);
262 do
263 { if (*ptr==x)
264 { return ptr;
265 }
266 ptr++;
267 } while (*ptr);
268 return NULL;
269}
270
271/*************************************************************************
272 * StrCmpNIW [NT 4.0:SHELL32.*]
273 *
274 */
275INT WINAPI StrCmpNIW ( LPWSTR wstr1, LPWSTR wstr2, INT len)
276{ FIXME("%s %s %i stub\n", debugstr_w(wstr1),debugstr_w(wstr2),len);
277 return 0;
278}
279
280/*************************************************************************
281 * StrCmpNIA [NT 4.0:SHELL32.*]
282 *
283 */
284INT WINAPI StrCmpNIA ( LPSTR wstr1, LPSTR wstr2, INT len)
285{ FIXME("%s %s %i stub\n", wstr1,wstr2,len);
286 return 0;
287}
288
289
290/*************************************************************************
291 * StrRChrA [SHELL32.346]
292 *
293 */
294LPSTR WINAPI StrRChrA(LPCSTR lpStart, LPCSTR lpEnd, DWORD wMatch)
295{
296 if (!lpStart)
297 return NULL;
298
299 /* if the end not given, search*/
300 if (!lpEnd)
301 { lpEnd=lpStart;
302 while (*lpEnd)
303 lpEnd++;
304 }
305
306 for (--lpEnd;lpStart <= lpEnd; lpEnd--)
307 if (*lpEnd==(char)wMatch)
308 return (LPSTR)lpEnd;
309
310 return NULL;
311}
312/*************************************************************************
313 * StrRChrW [SHELL32.320]
314 *
315 */
316LPWSTR WINAPI StrRChrW(LPWSTR lpStart, LPWSTR lpEnd, DWORD wMatch)
317{ LPWSTR wptr=NULL;
318 TRACE("%s %s 0x%04x\n",debugstr_w(lpStart),debugstr_w(lpEnd), (WCHAR)wMatch );
319
320 /* if the end not given, search*/
321 if (!lpEnd)
322 { lpEnd=lpStart;
323 while (*lpEnd)
324 lpEnd++;
325 }
326
327 do
328 { if (*lpStart==(WCHAR)wMatch)
329 wptr = lpStart;
330 lpStart++;
331 } while ( lpStart<=lpEnd );
332 return wptr;
333}
334
335/************************************************************************
336 * StrToOleStr [SHELL32.163]
337 *
338 */
339int WINAPI StrToOleStrA (LPWSTR lpWideCharStr, LPCSTR lpMultiByteString)
340{
341 TRACE("%p %p(%s)\n",
342 lpWideCharStr, lpMultiByteString, lpMultiByteString);
343
344 return MultiByteToWideChar(0, 0, lpMultiByteString, -1, lpWideCharStr, MAX_PATH);
345
346}
347int WINAPI StrToOleStrW (LPWSTR lpWideCharStr, LPCWSTR lpWString)
348{
349 TRACE("%p %p(%s)\n",
350 lpWideCharStr, lpWString, debugstr_w(lpWString));
351
352 if (lstrcpyW (lpWideCharStr, lpWString ))
353 { return lstrlenW (lpWideCharStr);
354 }
355 return 0;
356}
357
358BOOL WINAPI StrToOleStrAW (LPWSTR lpWideCharStr, LPCVOID lpString)
359{
360 if (VERSION_OsIsUnicode())
361 return StrToOleStrW (lpWideCharStr, (LPCWSTR)lpString);
362 return StrToOleStrA (lpWideCharStr, (LPCSTR)lpString);
363}
364
365
366
367/*****************************************************************************
368 * Name : StrChrIA
369 * Purpose : Searches a string for the first occurrence of a character that
370 * matches the specified character. The comparison is not case sensitive.
371 * Parameters: LPCSTR lpStart Address of the string to be searched.
372 * TCHAR wMatch Character to be used for comparison.
373 * Variables :
374 * Result : Returns the address of the first occurrence of the character in
375 * the string if successful, or NULL otherwise.
376 * Remark : SHELL32.
377 * Status : COMPLETELY IMPLEMENTED UNTESTED UNKNOWN
378 *
379 * Author : Patrick Haller [Wed, 1999/12/29 09:00]
380 *****************************************************************************/
381
382ODINFUNCTION2(LPSTR, StrChrIA,
383 LPCSTR, lpStart,
384 CHAR, wMatch)
385{
386 LPSTR lpRes;
387
388 wMatch = tolower(wMatch);
389 lpRes = strchr(lpStart, wMatch); // lower case comparsion
390 if (NULL == lpRes)
391 {
392 wMatch = toupper(wMatch);
393 lpRes = strchr(lpStart, wMatch); // upper case comparsion
394 }
395
396 return lpRes;
397}
398
399
400/*****************************************************************************
401 * Name : StrChrIW
402 * Purpose : Searches a string for the first occurrence of a character that
403 * matches the specified character. The comparison is not case sensitive.
404 * Parameters: LPCSTR lpStart Address of the string to be searched.
405 * TCHAR wMatch Character to be used for comparison.
406 * Variables :
407 * Result : Returns the address of the first occurrence of the character in
408 * the string if successful, or NULL otherwise.
409 * Remark : SHELL32.
410 * Status : COMPLETELY IMPLEMENTED UNTESTED UNKNOWN
411 *
412 * Author : Patrick Haller [Wed, 1999/12/29 09:00]
413 *****************************************************************************/
414
415ODINFUNCTION2(LPWSTR, StrChrIW,
416 LPCWSTR, lpStart,
417 WCHAR, wMatch)
418{
419 LPWSTR lpRes;
420
421 wMatch = towlower(wMatch);
422 lpRes = (WCHAR*)wcschr((const wchar_t*)lpStart, wMatch); // lower case comparsion
423 if (NULL == lpRes)
424 {
425 wMatch = towupper(wMatch);
426 lpRes = (WCHAR*)wcschr((const wchar_t*)lpStart, wMatch); // upper case comparsion
427 }
428
429 return lpRes;
430}
431
432
433/*****************************************************************************
434 * Name : StrStrIA
435 * Purpose : Finds the first occurrence of a substring within a string. The
436 * comparison is not case sensitive.
437 * Parameters: LPCSTR lpFirst
438 * LPCSTR lpSrch
439 * Variables :
440 * Result : Returns the address of the first occurrence of the matching
441 * substring if successful, or NULL otherwise.
442 * Remark : SHELL32.
443 * Status : COMPLETELY IMPLEMENTED UNTESTED UNKNOWN
444 *
445 * Author : Patrick Haller [Wed, 1999/12/29 09:00]
446 *****************************************************************************/
447
448ODINFUNCTION2(LPSTR, StrStrIA,
449 LPCSTR, lpFirst,
450 LPCSTR, lpSrch)
451{
452 char ch = lpSrch[0]; // look for 1st character
453 LONG lLen = lstrlenA(lpSrch); // length of search string
454 int iRes; // comparsion result
455
456 do
457 {
458 lpFirst = StrChrIA(lpFirst, // find first matching character
459 ch);
460 if (NULL == lpFirst) // not found
461 return NULL;
462
463 iRes = StrCmpNIA((LPSTR)lpFirst, // compare search string
464 (LPSTR)lpSrch,
465 lLen);
466
467 if (0 == iRes) // Found!
468 return (LPSTR)lpFirst;
469
470 lpFirst = CharNextA(lpFirst); // skip to next character
471 }
472 while (*lpFirst != 0); // safe termination
473
474 return NULL; // default result
475}
476
477
478
479/*****************************************************************************
480 * Name : StrStrIW
481 * Purpose : Finds the first occurrence of a substring within a string. The
482 * comparison is not case sensitive.
483 * Parameters: LPCWSTR lpFirst
484 * LPCWSTR lpSrch
485 * Variables :
486 * Result : Returns the address of the first occurrence of the matching
487 * substring if successful, or NULL otherwise.
488 * Remark : SHELL32.
489 * Status : COMPLETELY IMPLEMENTED UNTESTED UNKNOWN
490 *
491 * Author : Patrick Haller [Wed, 1999/12/29 09:00]
492 *****************************************************************************/
493
494ODINFUNCTION2(LPWSTR, StrStrIW,
495 LPCWSTR, lpFirst,
496 LPCWSTR, lpSrch)
497{
498 WCHAR ch = lpSrch[0]; // look for 1st character
499 LONG lLen = lstrlenW(lpSrch); // length of search string
500 int iRes; // comparsion result
501
502 do
503 {
504 lpFirst = StrChrIW(lpFirst, // find first matching character
505 ch);
506 if (NULL == lpFirst) // not found
507 return NULL;
508
509 iRes = StrCmpNIW((LPWSTR)lpFirst, // compare search string
510 (LPWSTR)lpSrch,
511 lLen);
512
513 if (0 == iRes) // Found!
514 return (LPWSTR)lpFirst;
515
516 lpFirst = CharNextW(lpFirst); // skip to next character
517 }
518 while (*lpFirst != 0); // safe termination
519
520 return NULL; // default result
521}
522
523
524
525/*****************************************************************************
526 * Name : StrToIntA
527 * Purpose : convert string to integer (used by explorer.exe)
528 * Parameters: Unknown (wrong)
529 * Variables :
530 * Result : Unknown
531 * Remark : SHLWAPI.675
532 * Status : UNTESTED STUB
533 *
534 * Author : Christoph Bratschi [Wed, 2000/03/29 19:47]
535 *****************************************************************************/
536
537ODINFUNCTION1(INT,StrToIntA,LPSTR,pszPath)
538{
539 dprintf(("not implemented"));
540
541 return NULL;
542}
543
544
545/*************************************************************************
546* StrToIntW [SHLWAPI]ú
547*/
548int WINAPI StrToIntW(LPCWSTR lpSrc)
549{
550 int ret;
551 LPSTR lpStr = HEAP_strdupWtoA(GetProcessHeap(),0,lpSrc);
552
553 TRACE("%s\n", debugstr_w(lpSrc));
554
555 ret = atol(lpStr);
556 HeapFree(GetProcessHeap(),0,lpStr);
557 return ret;
558}
559
560
561/*************************************************************************
562 * StrFormatByteSizeA [SHLWAPI]
563 */
564ODINFUNCTION3(LPSTR, 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,"%3.1f bytes", (FLOAT)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 */
586ODINFUNCTION3(LPWSTR, StrFormatByteSizeW, DWORD, dw, LPWSTR, pszBuf, UINT, cchBuf)
587{ char buf[64];
588 TRACE("%lx %p %i\n", dw, pszBuf, cchBuf);
589 if ( dw<1024L )
590 { sprintf (buf,"%3.1f bytes", (FLOAT)dw);
591 }
592 else if ( dw<1048576L)
593 { sprintf (buf,"%3.1f KB", (FLOAT)dw/1024);
594 }
595 else if ( dw < 1073741824L)
596 { sprintf (buf,"%3.1f MB", (FLOAT)dw/1048576L);
597 }
598 else
599 { sprintf (buf,"%3.1f GB", (FLOAT)dw/1073741824L);
600 }
601 lstrcpynAtoW (pszBuf, buf, cchBuf);
602 return pszBuf;
603}
604
605
606/*****************************************************************************
607 * Name : StrCpyA
608 * Purpose : copy a string
609 * Parameters:
610 * Variables :
611 * Result :
612 * Remark : not exported ?
613 * Status : UNTESTED
614 *
615 * Author :
616 *****************************************************************************/
617
618ODINFUNCTION2(LPSTR, StrCpyA,
619 LPSTR, lpDest,
620 LPCSTR, lpSource)
621{
622 return lstrcpyA(lpDest,
623 lpSource);
624}
625
626
627/*****************************************************************************
628 * Name : StrCpyW
629 * Purpose : copy a wide-character string
630 * Parameters:
631 * Variables :
632 * Result :
633 * Remark : SHLWAPI.642
634 * Status : COMPLETELY IMPLEMENTED UNTESTED
635 *
636 * Author :
637 *****************************************************************************/
638
639ODINFUNCTION2(LPWSTR, StrCpyW,
640 LPWSTR, lpDest,
641 LPCWSTR, lpSource)
642{
643 return lstrcpyW(lpDest,
644 lpSource);
645}
646
647
648/*****************************************************************************
649 * Name : StrDupA
650 * Purpose : duplicate a string on the local heap
651 * Parameters:
652 * Variables :
653 * Result :
654 * Remark : SHLWAPI.644
655 * Status : COMPLETELY IMPLEMENTED UNTESTED
656 *
657 * Author :
658 *****************************************************************************/
659
660ODINFUNCTION1(LPSTR, StrDupA,
661 LPCSTR, lpStr)
662{
663 int iLength = lstrlenA(lpStr) + 1;
664 HLOCAL hLocal = LocalAlloc(LMEM_ZEROINIT,
665 iLength);
666 if (hLocal != NULL)
667 StrCpyA((LPSTR)hLocal,
668 lpStr);
669
670 return (LPSTR)hLocal;
671}
672
673
674/*****************************************************************************
675 * Name : StrDupW
676 * Purpose : duplicate a wide-characters string on the local heap
677 * Parameters:
678 * Variables :
679 * Result :
680 * Remark : SHLWAPI.645
681 * Status : COMPLETELY IMPLEMENTED UNTESTED
682 *
683 * Author :
684 *****************************************************************************/
685
686ODINFUNCTION1(LPWSTR, StrDupW,
687 LPCWSTR, lpStr)
688{
689 int iLength = lstrlenW(lpStr) << 1 + 2;
690 HLOCAL hLocal = LocalAlloc(LMEM_ZEROINIT,
691 iLength);
692 if (hLocal != NULL)
693 StrCpyW((LPWSTR)hLocal,
694 lpStr);
695
696 return (LPWSTR)hLocal;
697}
Note: See TracBrowser for help on using the repository browser.