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

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

* empty log message *

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