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

Last change on this file since 7029 was 7029, checked in by phaller, 24 years ago

.

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