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

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

Exported Heap_ProcessHeap to heapstring.cpp and tuned GetProcessHeap() via inlining macro

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