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

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

tracing facility added for all exported functions

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