source: trunk/src/kernel32/heapstring.cpp@ 6366

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

lstrncmpiA/W fixes

File size: 19.2 KB
Line 
1/* $Id: heapstring.cpp,v 1.42 2001-07-19 20:00:56 sandervl Exp $ */
2
3/*
4 * Project Odin Software License can be found in LICENSE.TXT
5 *
6 * Win32 compatibility string functions for OS/2
7 *
8 * NOTE: lstrcpyn* always appends a terminating 0 (unlike strncpy)!
9 *
10 * Copyright 1999 Patrick Haller
11 */
12
13/*****************************************************************************
14 * Includes *
15 *****************************************************************************/
16
17#include <odin.h>
18#include <odinwrap.h>
19#include <os2sel.h>
20
21#include <os2win.h>
22#include <stdlib.h>
23#include <string.h>
24#include <stdio.h>
25#include <winnls.h>
26#include <unicode.h>
27#include <ctype.h>
28#include <wcstr.h>
29#include "heap.h"
30#include <wine\unicode.h>
31#include "misc.h"
32#include "codepage.h"
33
34#define DBG_LOCALLOG DBG_heapstring
35#include "dbglocal.h"
36
37/*****************************************************************************
38 * Defines *
39 *****************************************************************************/
40
41ODINDEBUGCHANNEL(KERNEL32-HEAPSTRING)
42
43/*****************************************************************************
44 * Name :
45 * Purpose :
46 * Parameters:
47 * Variables :
48 * Result :
49 * Remark :
50 * Status :
51 *
52 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
53 *****************************************************************************/
54
55int WIN32API lstrlenA(LPCSTR arg1)
56{
57 dprintf2(("KERNEL32: lstrlenA(%s)\n",
58 arg1));
59
60 if(arg1 == NULL) {
61 SetLastError(ERROR_INVALID_PARAMETER);
62 return 0;
63 }
64 return strlen(arg1);
65}
66
67
68/*****************************************************************************
69 * Name :
70 * Purpose :
71 * Parameters:
72 * Variables :
73 * Result :
74 * Remark :
75 * Status :
76 *
77 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
78 *****************************************************************************/
79
80int WIN32API lstrlenW(LPCWSTR arg1)
81{
82 int rc;
83
84 if(arg1 == NULL) {
85 SetLastError( ERROR_INVALID_PARAMETER );
86 return 0;
87 }
88
89 rc = UniStrlen( (UniChar*)arg1);
90 dprintf2(("KERNEL32: lstrlenW(%08xh) returns %d\n",
91 arg1,
92 rc));
93 return rc;
94}
95
96
97/*****************************************************************************
98 * Name :
99 * Purpose :
100 * Parameters:
101 * Variables :
102 * Result :
103 * Remark :
104 * Status :
105 *
106 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
107 *****************************************************************************/
108
109LPSTR WIN32API lstrcatA(LPSTR arg1, LPCSTR arg2)
110{
111 dprintf2(("KERNEL32: lstrcat(%s,%s)\n",
112 arg1,
113 arg2));
114
115 if(arg2 == NULL)
116 return arg1;
117 strcat(arg1, arg2);
118 return arg1;
119}
120
121
122/*****************************************************************************
123 * Name :
124 * Purpose :
125 * Parameters:
126 * Variables :
127 * Result :
128 * Remark :
129 * Status :
130 *
131 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
132 *****************************************************************************/
133
134LPWSTR WIN32API lstrcatW(LPWSTR arg1, LPCWSTR arg2)
135{
136 dprintf2(("KERNEL32: OS2lstrcatW(%08xh,%08xh)\n",
137 arg1,
138 arg2));
139
140 if(arg2 == NULL)
141 return arg1;
142
143 UniStrcat( (UniChar*) arg1, (UniChar*) arg2 );
144 return arg1;
145}
146
147
148/*****************************************************************************
149 * Name :
150 * Purpose :
151 * Parameters:
152 * Variables :
153 * Result :
154 * Remark :
155 * Status :
156 *
157 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
158 *****************************************************************************/
159
160int WIN32API lstrcmpA(LPCSTR arg1, LPCSTR arg2)
161{
162 dprintf2(("KERNEL32: OS2lstrcmpA(%s,%s)\n",
163 arg1,
164 arg2));
165
166 if(arg1 == NULL)
167 return -1;
168 if(arg2 == NULL)
169 return 1;
170
171 return strcmp(arg1, arg2);
172}
173
174
175/*****************************************************************************
176 * Name :
177 * Purpose :
178 * Parameters:
179 * Variables :
180 * Result :
181 * Remark :
182 * Status :
183 *
184 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
185 *****************************************************************************/
186
187int WIN32API lstrncmpA(LPCSTR arg1, LPCSTR arg2, int l)
188{
189 dprintf2(("KERNEL32: OS2lstrncmpA(%s,%s,%d)\n",
190 arg1,
191 arg2,
192 l));
193
194 return strncmp(arg1, arg2, l);
195}
196
197/*****************************************************************************
198 * Name : lstrncmpiA
199 * Purpose :
200 * Parameters:
201 * Variables :
202 * Result :
203 * Remark :
204 * Status :
205 *
206 * Author : Przemyslaw Dobrowolski
207 *****************************************************************************/
208INT WINAPI lstrncmpiA( LPCSTR str1, LPCSTR str2, INT n )
209{
210 INT firstch,lastch;
211 INT result = 0;
212
213 if (n)
214 {
215 do
216 {
217 firstch = toupper(*str1);
218 lastch = toupper(*str2);
219 str1++;
220 str2++;
221 } while (--n && str1 && str2 && firstch == lastch);
222
223 result = firstch - lastch;
224 }
225
226 return(result);
227}
228//TODO: Don't know if this is completely correct
229int WIN32API lstrncmpiW(LPCWSTR str1, LPCWSTR str2, int n)
230{
231 INT firstch,lastch;
232 INT result = 0;
233
234 if (n)
235 {
236 do
237 {
238 firstch = toupperW(*str1);
239 lastch = toupperW(*str2);
240 str1++;
241 str2++;
242 } while (--n && str1 && str2 && firstch == lastch);
243
244 result = firstch - lastch;
245 }
246
247 return(result);
248}
249
250/*****************************************************************************
251 * Name :
252 * Purpose :
253 * Parameters:
254 * Variables :
255 * Result :
256 * Remark :
257 * Status :
258 *
259 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
260 *****************************************************************************/
261
262int WIN32API lstrcmpW(LPCWSTR arg1, LPCWSTR arg2)
263{
264 dprintf2(("KERNEL32: lstrcmpW (%08xh, %08xh)\n",
265 arg1,
266 arg2));
267
268 if(arg1 == NULL)
269 return -1;
270 if(arg2 == NULL)
271 return 1;
272
273 return strcmpW( arg1, arg2 );
274}
275
276
277/*****************************************************************************
278 * Name :
279 * Purpose :
280 * Parameters:
281 * Variables :
282 * Result :
283 * Remark :
284 * Status :
285 *
286 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
287 *****************************************************************************/
288
289int WIN32API lstrncmpW(LPCWSTR arg1, LPCWSTR arg2, int l)
290{
291 dprintf2(("KERNEL32: OS2lstrncmpW(%08xh,%08xh,%d)\n",
292 arg1,
293 arg2,
294 l));
295
296 return wcsncmp((wchar_t*)arg1,
297 (wchar_t*)arg2,
298 l);
299}
300
301/*****************************************************************************
302 * Name :
303 * Purpose :
304 * Parameters:
305 * Variables :
306 * Result :
307 * Remark :
308 * Status :
309 *
310 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
311 *****************************************************************************/
312
313LPSTR WIN32API lstrcpyA(LPSTR dest, LPCSTR src)
314{
315 if ( (src == NULL) || (dest == NULL) ) // stupid parameter checking
316 return NULL;
317
318 return strcpy(dest, src);
319}
320
321
322/*****************************************************************************
323 * Name :
324 * Purpose :
325 * Parameters:
326 * Variables :
327 * Result :
328 * Remark :
329 * Status :
330 *
331 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
332 *****************************************************************************/
333
334LPWSTR WIN32API lstrcpyW(LPWSTR dest, LPCWSTR src)
335{
336 if ( (src == NULL) || (dest == NULL) ) // stupid parameter checking
337 return NULL;
338
339 UniStrcpy( (UniChar*)dest,
340 (UniChar*)src );
341 return dest;
342}
343
344
345/*****************************************************************************
346 * Name :
347 * Purpose :
348 * Parameters:
349 * Variables :
350 * Result :
351 * Remark :
352 * Status :
353 *
354 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
355 *****************************************************************************/
356
357LPSTR WIN32API lstrcpynA(LPSTR arg1, LPCSTR arg2, int arg3)
358{
359 register LPSTR p1 = arg1;
360 register LPSTR p2 = (LPSTR)arg2;
361
362 dprintf2(("KERNEL32: OS2lstrcpyA(%08xh, %08xh, %08xh)\n",
363 arg1,
364 arg2,
365 arg3));
366
367 if(arg3 == 0) {
368 return NULL;
369 }
370
371 //PH: looks like either \0 or arg3 terminate the copy
372 //return strncpy(arg1, arg2, arg3);
373 arg3--; // pre-decrement to avoid exceeding buffer length
374 // results in better code than (arg1 > 1)
375
376 for (;*p2 && arg3; arg3--)
377 *p1++ = *p2++;
378
379 *p1 = 0; //CB: copy arg-1, set end 0
380
381 return arg1;
382}
383
384
385/*****************************************************************************
386 * Name :
387 * Purpose :
388 * Parameters:
389 * Variables :
390 * Result :
391 * Remark :
392 * Status :
393 *
394 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
395 *****************************************************************************/
396
397LPWSTR WIN32API lstrcpynW(LPWSTR dest, LPCWSTR src, int arg3)
398{
399 dprintf2(("KERNEL32: lstrcpynW(%08xh,%08xh,%08xh)",
400 dest,
401 src,
402 arg3));
403
404 if (arg3 == 0)
405 return NULL;
406
407 UniStrncpy( (UniChar*)dest,
408 (UniChar*)src,
409 arg3-1); //CB: copy arg3-1 characters
410 dest[arg3-1] = 0; //CB: set end
411 return dest;
412}
413
414
415/*****************************************************************************
416 * Name :
417 * Purpose :
418 * Parameters:
419 * Variables :
420 * Result :
421 * Remark :
422 * Status :
423 *
424 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
425 *****************************************************************************/
426
427int WIN32API lstrcmpiA(LPCSTR arg1, LPCSTR arg2)
428{
429 dprintf2(("KERNEL32: lstrcmpiA(%s,%s)\n",
430 arg1,
431 arg2));
432
433 if(arg1 == NULL)
434 return -1;
435
436 if(arg2 == NULL)
437 return 1;
438
439 return strcmpi(arg1, arg2);
440}
441
442
443/*****************************************************************************
444 * Name :
445 * Purpose :
446 * Parameters:
447 * Variables :
448 * Result :
449 * Remark :
450 * Status :
451 *
452 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
453 *****************************************************************************/
454
455int WIN32API lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
456{
457 dprintf2(("KERNEL32: lstrcmpiW(%08xh,%08xh)", str1, str2));
458
459 if (!str1 || !str2) {
460 SetLastError(ERROR_INVALID_PARAMETER);
461 return 0;
462 }
463 return strcmpiW( str1, str2 );
464}
465
466//*****************************************************************************
467//lstrcpynWtoA and lstrcpynAtoW must zero-terminate the string
468//because Wine code depends on this behaviour (i.e. comdlg32)
469//*****************************************************************************
470int WIN32API lstrcpynWtoA(LPSTR astring,
471 LPCWSTR ustring,
472 int length)
473{
474 int ret;
475
476 ret = WideCharToMultiByte(CP_ACP, 0, ustring, -1, astring, length, 0, NULL);
477 if(ret == 0) {
478 SetLastError(ERROR_SUCCESS); //WideCharToMultiByte sets it to ERROR_INSUFFICIENT_BUFFER
479 ret = length;
480 }
481 //Must not always set the last character to 0; some apps send the wrong
482 //string size to apis that use this function (i.e. GetMenuStringW (Notes))
483 //-> overwrites stack
484 if(ret == length) {
485 astring[length-1] = 0;
486 }
487 else astring[ret] = 0;
488
489 return ret;
490}
491
492//lstrcpynWtoA and lstrcpynAtoW must zero-terminate the string
493//because Wine code depends on this behaviour (i.e. comdlg32)
494int WIN32API lstrcpynAtoW(LPWSTR unicode,
495 LPCSTR ascii,
496 int asciilen)
497{
498 int ret;
499
500 ret = MultiByteToWideChar(CP_ACP, 0, ascii, -1, unicode, asciilen);
501 if(ret == 0) {
502 SetLastError(ERROR_SUCCESS); //MultiByteToWideChar sets it to ERROR_INSUFFICIENT_BUFFER
503 ret = asciilen;
504 }
505
506 //Must not always set the last character to 0; some apps send the wrong
507 //string size to apis that use this function (i.e. GetMenuStringW (Notes))
508 //-> overwrites stack
509 if(ret == asciilen) {
510 unicode[asciilen-1] = 0;
511 }
512 else unicode[ret] = 0;
513 return ret;
514
515
516}
517
518/*****************************************************************************
519 * Name :
520 * Purpose : Converts unicode string to ascii string
521 * Parameters:
522 * Variables :
523 * Result : returns length of ascii string
524 * Remark :
525 * Status :
526 *
527 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
528 *****************************************************************************/
529
530LPSTR WIN32API lstrcpyWtoA(LPSTR ascii, LPCWSTR unicode)
531{
532 //@@@PH huh? wuz dat?
533 if (unicode == NULL)
534 {
535 DebugInt3();
536 if (ascii != NULL) ((LPWSTR)ascii)[0] = 0; //CB: set at least end
537 return NULL;
538 }
539
540 if (ascii == NULL) {
541 DebugInt3();
542 return NULL; /* garbage in, garbage out ! */
543 }
544
545 /* forward to function with len parameter */
546 lstrcpynWtoA(ascii,
547 unicode,
548 UniStrlen((UniChar*)unicode)+1); //end included
549
550 return ascii;
551}
552
553
554/*****************************************************************************
555 * Name :
556 * Purpose : Copies the full string from ascii to unicode
557 * Parameters:
558 * Variables :
559 * Result :
560 * Remark :
561 * Status :
562 *
563 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
564 *****************************************************************************/
565
566LPWSTR WIN32API lstrcpyAtoW(LPWSTR unicode, LPCSTR ascii)
567{
568 /* achimha for security, strlen might trap if garbage in */
569 /* @@@PH 98/06/07 */
570 if (ascii == NULL)
571 {
572 DebugInt3();
573 if (unicode != NULL) unicode[0] = 0; //CB: set at least end
574 return NULL;
575 }
576
577 if (unicode == NULL) {
578 DebugInt3();
579 return NULL; /* garbage in, garbage out ! */
580 }
581
582 /* forward to call with length parameter */
583 lstrcpynAtoW(unicode, ascii, strlen(ascii)+1); //end included
584 return (unicode);
585}
586
587
588
589
590/*****************************************************************************
591 * Name :
592 * Purpose :
593 * Parameters:
594 * Variables :
595 * Result :
596 * Remark :
597 * Status :
598 *
599 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
600 *****************************************************************************/
601
602LPVOID WIN32API HEAP_xalloc( HANDLE heap, DWORD flags, DWORD size )
603{
604 LPVOID p = HeapAlloc( heap, flags, size );
605 if (!p)
606 {
607 dprintf2(("KERNEL32: HEAP_xalloc(%08xh,%08xh,%08xh) out of memory.\n",
608 heap,
609 flags,
610 size));
611 }
612 return p;
613}
614
615
616/*****************************************************************************
617 * Name :
618 * Purpose :
619 * Parameters:
620 * Variables :
621 * Result :
622 * Remark :
623 * Status :
624 *
625 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
626 *****************************************************************************/
627
628LPVOID WIN32API HEAP_xrealloc( HANDLE heap, DWORD flags, LPVOID lpMem, DWORD size )
629{
630 LPVOID p = HeapReAlloc( heap, flags, lpMem, size );
631 if (!p)
632 {
633 dprintf2(("KERNEL32: HEAP_xrealloc(%08xh,%08xh,%08xh,%08xh) out of memory.\n",
634 heap,
635 flags,
636 lpMem,
637 size));
638 }
639 return p;
640}
641
642
643/*****************************************************************************
644 * Name :
645 * Purpose :
646 * Parameters:
647 * Variables :
648 * Result :
649 * Remark :
650 * Status :
651 *
652 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
653 *****************************************************************************/
654
655LPVOID WIN32API HEAP_malloc(DWORD size )
656{
657 LPVOID p = HeapAlloc( GetProcessHeap(), 0, size );
658 if (!p)
659 {
660 dprintf2(("KERNEL32: HEAP_malloc(%08xh) out of memory.\n",
661 size));
662 }
663 return p;
664}
665
666
667/*****************************************************************************
668 * Name :
669 * Purpose :
670 * Parameters:
671 * Variables :
672 * Result :
673 * Remark :
674 * Status :
675 *
676 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
677 *****************************************************************************/
678
679DWORD WIN32API HEAP_size(LPVOID lpMem)
680{
681 return HeapSize( GetProcessHeap(), 0, lpMem );
682}
683
684
685/*****************************************************************************
686 * Name :
687 * Purpose :
688 * Parameters:
689 * Variables :
690 * Result :
691 * Remark :
692 * Status :
693 *
694 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
695 *****************************************************************************/
696
697LPVOID WIN32API HEAP_realloc(LPVOID lpMem, DWORD size )
698{
699 LPVOID p = HeapReAlloc( GetProcessHeap(), 0, lpMem, size );
700 if (!p)
701 {
702 dprintf2(("KERNEL32: HEAP_realloc(%08xh,%08xh) out of memory.\n",
703 lpMem,
704 size));
705 }
706 return p;
707}
708
709
710/*****************************************************************************
711 * Name :
712 * Purpose :
713 * Parameters:
714 * Variables :
715 * Result :
716 * Remark :
717 * Status :
718 *
719 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
720 *****************************************************************************/
721
722VOID WIN32API HEAP_free(LPVOID lpMem)
723{
724 dprintf2(("KERNEL32: HEAP_free(%08xh)\n",
725 lpMem));
726
727 HeapFree( GetProcessHeap(), 0, lpMem);
728}
729
730
731/*****************************************************************************
732 * Name :
733 * Purpose :
734 * Parameters:
735 * Variables :
736 * Result :
737 * Remark :
738 * Status :
739 *
740 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
741 *****************************************************************************/
742
743LPSTR WIN32API HEAP_strdupA( HANDLE heap, DWORD flags, LPCSTR str )
744{
745 LPSTR p = (LPSTR)HEAP_xalloc( heap, flags, lstrlenA(str) + 1 );
746 lstrcpyA( p, str );
747 return p;
748}
749
750
751/*****************************************************************************
752 * Name :
753 * Purpose :
754 * Parameters:
755 * Variables :
756 * Result :
757 * Remark :
758 * Status :
759 *
760 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
761 *****************************************************************************/
762
763LPWSTR WIN32API HEAP_strdupW( HANDLE heap, DWORD flags, LPCWSTR str )
764{
765 INT len = lstrlenW(str) + 1;
766 LPWSTR p = (LPWSTR)HEAP_xalloc( heap, flags, len * sizeof(WCHAR) );
767 lstrcpyW( p, str );
768 return p;
769}
770
771
772/*****************************************************************************
773 * Name :
774 * Purpose :
775 * Parameters:
776 * Variables :
777 * Result :
778 * Remark :
779 * Status :
780 *
781 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
782 *****************************************************************************/
783
784LPWSTR WIN32API HEAP_strdupAtoW( HANDLE heap, DWORD flags, LPCSTR str )
785{
786 LPWSTR ret;
787 int len;
788
789 if (!str) return NULL;
790
791 len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0);
792 ret = (LPWSTR)HEAP_xalloc( heap, flags, len*sizeof(WCHAR));
793 MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
794
795 return ret;
796}
797
798
799/*****************************************************************************
800 * Name :
801 * Purpose :
802 * Parameters:
803 * Variables :
804 * Result :
805 * Remark :
806 * Status :
807 *
808 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
809 *****************************************************************************/
810
811LPSTR WIN32API HEAP_strdupWtoA( HANDLE heap, DWORD flags, LPCWSTR str )
812{
813 LPSTR ret;
814 int len;
815
816 if (!str) return NULL;
817
818 len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, 0, NULL);
819 ret = (LPSTR)HEAP_xalloc( heap, flags, len);
820 WideCharToMultiByte(CP_ACP, 0, str, -1, ret, len, 0, NULL );
821 return ret;
822}
823
824
825
826
Note: See TracBrowser for help on using the repository browser.