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

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

codepage, getlocaleinfo + thread tib updates

File size: 21.1 KB
Line 
1/* $Id: heapstring.cpp,v 1.49 2002-02-07 16:34:52 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
495ODINFUNCTIONNODBG2(int, lstrcmpiW,
496 LPCWSTR, str1,
497 LPCWSTR, str2)
498{
499 if (!str1 || !str2) {
500
501 SetLastError(ERROR_INVALID_PARAMETER);
502 return 0;
503 }
504 return strcmpiW( str1, str2 );
505}
506
507//*****************************************************************************
508//lstrcpynWtoA and lstrcpynAtoW must zero-terminate the string
509//because Wine code depends on this behaviour (i.e. comdlg32)
510//*****************************************************************************
511ODINFUNCTIONNODBG3(int, lstrcpynWtoA,
512 LPSTR, astring,
513 LPCWSTR, ustring,
514 int, length)
515{
516 int ret;
517
518 ret = WideCharToMultiByte(CP_ACP, 0, ustring, -1, astring, length, 0, NULL);
519 if(ret == 0) {
520 SetLastError(ERROR_SUCCESS); //WideCharToMultiByte sets it to ERROR_INSUFFICIENT_BUFFER
521 ret = length;
522 }
523 //Must not always set the last character to 0; some apps send the wrong
524 //string size to apis that use this function (i.e. GetMenuStringW (Notes))
525 //-> overwrites stack
526 if(ret == length) {
527 astring[length-1] = 0;
528 }
529 else astring[ret] = 0;
530
531 return ret;
532}
533
534//lstrcpynWtoA and lstrcpynAtoW must zero-terminate the string
535//because Wine code depends on this behaviour (i.e. comdlg32)
536ODINFUNCTIONNODBG3(int, lstrcpynAtoW,
537 LPWSTR, unicode,
538 LPCSTR, ascii,
539 int , asciilen)
540{
541 int ret;
542
543 ret = MultiByteToWideChar(CP_ACP, 0, ascii, -1, unicode, asciilen);
544 if(ret == 0) {
545 SetLastError(ERROR_SUCCESS); //MultiByteToWideChar sets it to ERROR_INSUFFICIENT_BUFFER
546 ret = asciilen;
547 }
548
549 //Must not always set the last character to 0; some apps send the wrong
550 //string size to apis that use this function (i.e. GetMenuStringW (Notes))
551 //-> overwrites stack
552 if(ret == asciilen) {
553 unicode[asciilen-1] = 0;
554 }
555 else unicode[ret] = 0;
556 return ret;
557
558
559}
560
561/*****************************************************************************
562 * Name :
563 * Purpose : Converts unicode string to ascii string
564 * Parameters:
565 * Variables :
566 * Result : returns length of ascii string
567 * Remark :
568 * Status :
569 *
570 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
571 *****************************************************************************/
572
573ODINFUNCTIONNODBG2(LPSTR, lstrcpyWtoA,
574 LPSTR, ascii,
575 LPCWSTR, unicode)
576{
577 //@@@PH huh? wuz dat?
578 if (unicode == NULL)
579 {
580 DebugInt3();
581 if (ascii != NULL) ((LPWSTR)ascii)[0] = 0; //CB: set at least end
582 return NULL;
583 }
584
585 if (ascii == NULL) {
586 DebugInt3();
587 return NULL; /* garbage in, garbage out ! */
588 }
589
590 /* forward to function with len parameter */
591 lstrcpynWtoA(ascii,
592 unicode,
593 lstrlenW((UniChar*)unicode)+1); //end included
594
595 return ascii;
596}
597
598
599/*****************************************************************************
600 * Name :
601 * Purpose : Copies the full string from ascii to unicode
602 * Parameters:
603 * Variables :
604 * Result :
605 * Remark :
606 * Status :
607 *
608 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
609 *****************************************************************************/
610
611ODINFUNCTIONNODBG2(LPWSTR, lstrcpyAtoW,
612 LPWSTR, unicode,
613 LPCSTR, ascii)
614{
615 /* achimha for security, strlen might trap if garbage in */
616 /* @@@PH 98/06/07 */
617 if (ascii == NULL)
618 {
619 DebugInt3();
620 if (unicode != NULL) unicode[0] = 0; //CB: set at least end
621 return NULL;
622 }
623
624 if (unicode == NULL) {
625 DebugInt3();
626 return NULL; /* garbage in, garbage out ! */
627 }
628
629 /* forward to call with length parameter */
630 lstrcpynAtoW(unicode, ascii, strlen(ascii)+1); //end included
631 return (unicode);
632}
633
634
635
636
637/*****************************************************************************
638 * Name :
639 * Purpose :
640 * Parameters:
641 * Variables :
642 * Result :
643 * Remark :
644 * Status :
645 *
646 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
647 *****************************************************************************/
648
649ODINFUNCTIONNODBG3(LPVOID, HEAP_xalloc,
650 HANDLE, heap,
651 DWORD, flags,
652 DWORD, size )
653{
654 LPVOID p = HeapAlloc( heap, flags, size );
655 if (!p)
656 {
657 dprintf2(("KERNEL32: HEAP_xalloc(%08xh,%08xh,%08xh) out of memory.\n",
658 heap,
659 flags,
660 size));
661 }
662 return p;
663}
664
665
666/*****************************************************************************
667 * Name :
668 * Purpose :
669 * Parameters:
670 * Variables :
671 * Result :
672 * Remark :
673 * Status :
674 *
675 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
676 *****************************************************************************/
677
678ODINFUNCTIONNODBG4(LPVOID, HEAP_xrealloc,
679 HANDLE, heap,
680 DWORD, flags,
681 LPVOID, lpMem,
682 DWORD, size )
683{
684 LPVOID p = HeapReAlloc( heap, flags, lpMem, size );
685 if (!p)
686 {
687 dprintf2(("KERNEL32: HEAP_xrealloc(%08xh,%08xh,%08xh,%08xh) out of memory.\n",
688 heap,
689 flags,
690 lpMem,
691 size));
692 }
693 return p;
694}
695
696
697/*****************************************************************************
698 * Name :
699 * Purpose :
700 * Parameters:
701 * Variables :
702 * Result :
703 * Remark :
704 * Status :
705 *
706 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
707 *****************************************************************************/
708
709ODINFUNCTIONNODBG1(LPVOID, HEAP_malloc,
710 DWORD, size )
711{
712 LPVOID p = HeapAlloc( GetProcessHeap(), 0, size );
713 if (!p)
714 {
715 dprintf2(("KERNEL32: HEAP_malloc(%08xh) out of memory.\n",
716 size));
717 }
718 return p;
719}
720
721
722/*****************************************************************************
723 * Name :
724 * Purpose :
725 * Parameters:
726 * Variables :
727 * Result :
728 * Remark :
729 * Status :
730 *
731 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
732 *****************************************************************************/
733
734ODINFUNCTIONNODBG1(DWORD, HEAP_size,
735 LPVOID, lpMem)
736{
737 return HeapSize( GetProcessHeap(), 0, lpMem );
738}
739
740
741/*****************************************************************************
742 * Name :
743 * Purpose :
744 * Parameters:
745 * Variables :
746 * Result :
747 * Remark :
748 * Status :
749 *
750 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
751 *****************************************************************************/
752
753ODINFUNCTIONNODBG2(LPVOID, HEAP_realloc,
754 LPVOID, lpMem,
755 DWORD, size )
756{
757 LPVOID p = HeapReAlloc( GetProcessHeap(), 0, lpMem, size );
758 if (!p)
759 {
760 dprintf2(("KERNEL32: HEAP_realloc(%08xh,%08xh) out of memory.\n",
761 lpMem,
762 size));
763 }
764 return p;
765}
766
767
768/*****************************************************************************
769 * Name :
770 * Purpose :
771 * Parameters:
772 * Variables :
773 * Result :
774 * Remark :
775 * Status :
776 *
777 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
778 *****************************************************************************/
779
780ODINFUNCTIONNODBG1(BOOL, HEAP_free,
781 LPVOID, lpMem)
782{
783 return HeapFree( GetProcessHeap(), 0, lpMem);
784}
785
786
787/*****************************************************************************
788 * Name :
789 * Purpose :
790 * Parameters:
791 * Variables :
792 * Result :
793 * Remark :
794 * Status :
795 *
796 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
797 *****************************************************************************/
798
799ODINFUNCTIONNODBG3(LPSTR, HEAP_strdupA,
800 HANDLE, heap,
801 DWORD, flags,
802 LPCSTR, str )
803{
804 int iLength = lstrlenA(str) + 1;
805 LPSTR p = (LPSTR)HEAP_xalloc( heap, flags, iLength );
806 memcpy( p, str, iLength );
807 return p;
808}
809
810
811/*****************************************************************************
812 * Name :
813 * Purpose :
814 * Parameters:
815 * Variables :
816 * Result :
817 * Remark :
818 * Status :
819 *
820 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
821 *****************************************************************************/
822
823ODINFUNCTIONNODBG3(LPWSTR, HEAP_strdupW,
824 HANDLE, heap,
825 DWORD, flags,
826 LPCWSTR, str )
827{
828 INT len = lstrlenW(str) + 1;
829 LPWSTR p = (LPWSTR)HEAP_xalloc( heap, flags, len * sizeof(WCHAR) );
830 memcpy( p, str, len );
831 return p;
832}
833
834
835/*****************************************************************************
836 * Name :
837 * Purpose :
838 * Parameters:
839 * Variables :
840 * Result :
841 * Remark :
842 * Status :
843 *
844 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
845 *****************************************************************************/
846
847ODINFUNCTIONNODBG3(LPWSTR, HEAP_strdupAtoW,
848 HANDLE, heap,
849 DWORD, flags,
850 LPCSTR, str )
851{
852 LPWSTR ret;
853 int len;
854
855 if (!str) return NULL;
856
857 len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0);
858 ret = (LPWSTR)HEAP_xalloc( heap, flags, len*sizeof(WCHAR));
859 MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
860
861 return ret;
862}
863
864
865/*****************************************************************************
866 * Name :
867 * Purpose :
868 * Parameters:
869 * Variables :
870 * Result :
871 * Remark :
872 * Status :
873 *
874 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
875 *****************************************************************************/
876
877ODINFUNCTIONNODBG3(LPSTR, HEAP_strdupWtoA,
878 HANDLE, heap,
879 DWORD, flags,
880 LPCWSTR, str )
881{
882 LPSTR ret;
883 int len;
884
885 if (!str) return NULL;
886
887 len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, 0, NULL);
888 ret = (LPSTR)HEAP_xalloc( heap, flags, len);
889 WideCharToMultiByte(CP_ACP, 0, str, -1, ret, len, 0, NULL );
890 return ret;
891}
892
893
894
895
Note: See TracBrowser for help on using the repository browser.