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

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

* empty log message *

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