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

Last change on this file since 4664 was 4664, checked in by sandervl, 25 years ago

lstrcpynAtoW/WtoA bugfix (string termination)

File size: 29.6 KB
Line 
1/* $Id: heapstring.cpp,v 1.35 2000-11-21 14:10:08 sandervl 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 <heapstring.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
55int WIN32API lstrlenA(LPCSTR arg1)
56{
57 dprintf2(("KERNEL32: lstrlenA(%s)\n",
58 arg1));
59
60 return O32_lstrlen(arg1);
61}
62
63
64/*****************************************************************************
65 * Name :
66 * Purpose :
67 * Parameters:
68 * Variables :
69 * Result :
70 * Remark :
71 * Status :
72 *
73 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
74 *****************************************************************************/
75
76int WIN32API lstrlenW(LPCWSTR arg1)
77{
78 int rc;
79
80 rc = UniStrlen( (UniChar*)arg1);
81 dprintf2(("KERNEL32: lstrlenW(%08xh) returns %d\n",
82 arg1,
83 rc));
84 return rc;
85}
86
87
88/*****************************************************************************
89 * Name :
90 * Purpose :
91 * Parameters:
92 * Variables :
93 * Result :
94 * Remark :
95 * Status :
96 *
97 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
98 *****************************************************************************/
99
100LPSTR WIN32API lstrcatA(LPSTR arg1, LPCSTR arg2)
101{
102 dprintf2(("KERNEL32: lstrcat(%s,%s)\n",
103 arg1,
104 arg2));
105
106 if(arg2 == NULL)
107 return arg1;
108 strcat(arg1, arg2);
109 return arg1;
110}
111
112
113/*****************************************************************************
114 * Name :
115 * Purpose :
116 * Parameters:
117 * Variables :
118 * Result :
119 * Remark :
120 * Status :
121 *
122 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
123 *****************************************************************************/
124
125LPWSTR WIN32API lstrcatW(LPWSTR arg1, LPCWSTR arg2)
126{
127 dprintf2(("KERNEL32: OS2lstrcatW(%08xh,%08xh)\n",
128 arg1,
129 arg2));
130
131 if(arg2 == NULL)
132 return arg1;
133
134 UniStrcat( (UniChar*) arg1, (UniChar*) arg2 );
135 return arg1;
136}
137
138
139/*****************************************************************************
140 * Name :
141 * Purpose :
142 * Parameters:
143 * Variables :
144 * Result :
145 * Remark :
146 * Status :
147 *
148 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
149 *****************************************************************************/
150
151int WIN32API lstrcmpA(LPCSTR arg1, LPCSTR arg2)
152{
153 dprintf2(("KERNEL32: OS2lstrcmpA(%s,%s)\n",
154 arg1,
155 arg2));
156
157 if(arg1 == NULL)
158 return -1;
159 if(arg2 == NULL)
160 return 1;
161
162 return O32_lstrcmp(arg1, arg2);
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
178int WIN32API lstrncmpA(LPCSTR arg1, LPCSTR arg2, int l)
179{
180 dprintf2(("KERNEL32: OS2lstrncmpA(%s,%s,%d)\n",
181 arg1,
182 arg2,
183 l));
184
185 return strncmp(arg1, arg2, l);
186}
187
188/*****************************************************************************
189 * Name : lstrncmpiA
190 * Purpose :
191 * Parameters:
192 * Variables :
193 * Result :
194 * Remark :
195 * Status :
196 *
197 * Author : Przemyslaw Dobrowolski
198 *****************************************************************************/
199INT WINAPI lstrncmpiA( LPCSTR str1, LPCSTR str2, INT n )
200{
201 INT firstch,lastch;
202 INT result = 0;
203
204 if (n)
205 {
206 do
207 {
208 firstch = tolower(*str1);
209 lastch = tolower(*str2);
210 str1++;
211 str2++;
212 } while (--n && str1 && str2 && firstch == lastch);
213
214 result = firstch - lastch;
215 }
216
217 return(result);
218}
219//TODO: Don't know if this is completely correct
220int WIN32API lstrncmpiW(LPCWSTR str1, LPCWSTR str2, int n)
221{
222 INT firstch,lastch;
223 INT result = 0;
224
225 if (n)
226 {
227 do
228 {
229 firstch = tolower((char)*str1);
230 lastch = tolower((char)*str2);
231 str1++;
232 str2++;
233 } while (--n && str1 && str2 && firstch == lastch);
234
235 result = firstch - lastch;
236 }
237
238 return(result);
239}
240
241/*****************************************************************************
242 * Name :
243 * Purpose :
244 * Parameters:
245 * Variables :
246 * Result :
247 * Remark :
248 * Status :
249 *
250 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
251 *****************************************************************************/
252
253int WIN32API lstrcmpW(LPCWSTR arg1, LPCWSTR arg2)
254{
255 dprintf2(("KERNEL32: lstrcmpW (%08xh, %08xh)\n",
256 arg1,
257 arg2));
258
259 if(arg1 == NULL)
260 return -1;
261 if(arg2 == NULL)
262 return 1;
263
264 return wcscmp( (wchar_t*)arg1,
265 (wchar_t*)arg2 );
266}
267
268
269/*****************************************************************************
270 * Name :
271 * Purpose :
272 * Parameters:
273 * Variables :
274 * Result :
275 * Remark :
276 * Status :
277 *
278 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
279 *****************************************************************************/
280
281int WIN32API lstrncmpW(LPCWSTR arg1, LPCWSTR arg2, int l)
282{
283 dprintf2(("KERNEL32: OS2lstrncmpW(%08xh,%08xh,%d)\n",
284 arg1,
285 arg2,
286 l));
287
288 return wcsncmp((wchar_t*)arg1,
289 (wchar_t*)arg2,
290 l);
291}
292
293/*****************************************************************************
294 * Name :
295 * Purpose :
296 * Parameters:
297 * Variables :
298 * Result :
299 * Remark :
300 * Status :
301 *
302 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
303 *****************************************************************************/
304
305LPSTR WIN32API lstrcpyA(LPSTR dest, LPCSTR src)
306{
307 if ( (src == NULL) || (dest == NULL) ) // stupid parameter checking
308 return NULL;
309
310 return O32_lstrcpy(dest, src);
311}
312
313
314/*****************************************************************************
315 * Name :
316 * Purpose :
317 * Parameters:
318 * Variables :
319 * Result :
320 * Remark :
321 * Status :
322 *
323 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
324 *****************************************************************************/
325
326LPWSTR WIN32API lstrcpyW(LPWSTR dest, LPCWSTR src)
327{
328 if ( (src == NULL) || (dest == NULL) ) // stupid parameter checking
329 return NULL;
330
331 UniStrcpy( (UniChar*)dest,
332 (UniChar*)src );
333 return dest;
334}
335
336
337/*****************************************************************************
338 * Name :
339 * Purpose :
340 * Parameters:
341 * Variables :
342 * Result :
343 * Remark :
344 * Status :
345 *
346 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
347 *****************************************************************************/
348
349LPSTR WIN32API lstrcpynA(LPSTR arg1, LPCSTR arg2, int arg3)
350{
351 register LPSTR p1 = arg1;
352 register LPSTR p2 = (LPSTR)arg2;
353
354 dprintf2(("KERNEL32: OS2lstrcpyA(%08xh, %08xh, %08xh)\n",
355 arg1,
356 arg2,
357 arg3));
358
359 //PH: looks like either \0 or arg3 terminate the copy
360 //return strncpy(arg1, arg2, arg3);
361 arg3--; // pre-decrement to avoid exceeding buffer length
362 // results in better code than (arg1 > 1)
363
364 for (;*p2 && arg3; arg3--)
365 *p1++ = *p2++;
366
367 *p1 = 0; //CB: copy arg-1, set end 0
368
369 return arg1;
370}
371
372
373/*****************************************************************************
374 * Name :
375 * Purpose :
376 * Parameters:
377 * Variables :
378 * Result :
379 * Remark :
380 * Status :
381 *
382 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
383 *****************************************************************************/
384
385LPWSTR WIN32API lstrcpynW(LPWSTR dest, LPCWSTR src, int arg3)
386{
387 dprintf2(("KERNEL32: lstrcpynW(%08xh,%08xh,%08xh)",
388 dest,
389 src,
390 arg3));
391
392 if (arg3 == 0)
393 return NULL;
394
395 UniStrncpy( (UniChar*)dest,
396 (UniChar*)src,
397 arg3-1); //CB: copy arg3-1 characters
398 dest[arg3-1] = 0; //CB: set end
399 return dest;
400}
401
402
403/*****************************************************************************
404 * Name :
405 * Purpose :
406 * Parameters:
407 * Variables :
408 * Result :
409 * Remark :
410 * Status :
411 *
412 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
413 *****************************************************************************/
414
415int WIN32API lstrcmpiA(LPCSTR arg1, LPCSTR arg2)
416{
417 dprintf2(("KERNEL32: lstrcmpiA(%s,%s)\n",
418 arg1,
419 arg2));
420
421 if(arg1 == NULL)
422 return -1;
423
424 if(arg2 == NULL)
425 return 1;
426
427 return O32_lstrcmpi(arg1, arg2);
428}
429
430
431/*****************************************************************************
432 * Name :
433 * Purpose :
434 * Parameters:
435 * Variables :
436 * Result :
437 * Remark :
438 * Status :
439 *
440 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
441 *****************************************************************************/
442
443int WIN32API lstrcmpiW(LPCWSTR arg1, LPCWSTR arg2)
444{
445 char *astr1, *astr2;
446 int rc;
447
448 dprintf2(("KERNEL32: lstrcmpiW(%08xh,%08xh)\n",
449 arg1,
450 arg2));
451
452 if(arg1 == NULL)
453 return -1;
454
455 if(arg2 == NULL)
456 return 1;
457
458 // NOTE: This function has no equivalent in uunidef.h
459 astr1 = UnicodeToAsciiString((LPWSTR)arg1);
460 astr2 = UnicodeToAsciiString((LPWSTR)arg2);
461 rc = lstrcmpiA(astr1, astr2);
462 FreeAsciiString(astr2);
463 FreeAsciiString(astr1);
464 return(rc);
465}
466
467
468/*****************************************************************************
469 * Name :
470 * Purpose :
471 * Parameters:
472 * Variables :
473 * Result :
474 * Remark :
475 * Status :
476 *
477 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
478 *****************************************************************************/
479
480// unilen: length of astring buffer (including 0 terminator)
481// returns string length
482
483int WIN32API lstrcpynCtoA(LPSTR astring,
484 LPCWSTR ustring,
485 int unilen,
486 UconvObject uconv_object)
487{
488 int i;
489 int rc;
490 size_t uni_chars_left;
491 size_t out_bytes_left;
492 size_t num_subs;
493 UniChar* in_buf;
494 char* out_buf;
495
496 dprintf2(("KERNEL32: HeapString: lstrcpynWtoA(%08x,%08xh,%d)\n",
497 astring,
498 ustring,
499 unilen));
500
501 if (ustring == NULL)
502 {
503 if (astring != NULL && unilen > 0)
504 astring[0] = 0;
505 return 0;
506 }
507
508 if (astring == NULL || unilen <= 0)
509 return 0;
510
511 if (uconv_object)
512 {
513 if (unilen == 1)
514 {
515 astring[0] = 0;
516 return 0; //no data
517 }
518
519 //SvL: Determine length of unicode string
520 uni_chars_left = UniStrlen((UniChar*)ustring)+1;
521 uni_chars_left = min(uni_chars_left, unilen);
522 unilen = uni_chars_left;
523
524 out_bytes_left = uni_chars_left; //size in bytes == elements
525 in_buf = (UniChar*)ustring;
526 out_buf = astring;
527 rc = UniUconvFromUcs(uconv_object,
528 &in_buf, &uni_chars_left,
529 (void**)&out_buf, &out_bytes_left,
530 &num_subs);
531
532 /* @@@PH 2000/08/10
533 * this causes the last character in the converted
534 * target string to be chopped off. I.e. causes CMD.EXE
535 * to loose the CRLF functionality.
536 */
537 /*
538 unilen -= 1+out_bytes_left; //end + left bytes
539 astring[unilen] = 0; //terminate
540 */
541
542 return unilen; //length of string (excluding terminator)
543 }
544 else
545 {
546 /* idiots unicode conversion :) */
547 for (i = 0; i < unilen-1; i++)
548 {
549 astring[i] = (ustring[i] > 255) ? (char)0x20 : (char)ustring[i]; //CB: handle invalid characters as space
550 if (ustring[i] == 0) return i; //asta la vista, baby
551 }
552
553// astring[unilen-1] = 0; // @@@PH: 1999/06/09 fix - always terminate string
554// return(unilen-1);
555 return unilen;
556 }
557}
558
559//lstrcpynWtoA and lstrcpynAtoW must zero-terminate the string
560//because Wine code depends on this behaviour (i.e. comdlg32)
561int WIN32API lstrcpynWtoA(LPSTR astring,
562 LPCWSTR ustring,
563 int unilen)
564{
565 int ret;
566
567 ret = lstrcpynCtoA(astring, ustring, unilen, GetWindowsUconvObject());
568 //Must not always set the last character to 0; some apps send the wrong
569 //string size to apis that use this function (i.e. GetMenuStringW (Notes))
570 //-> overwrites stack
571 if(ret == unilen) {
572 astring[unilen-1] = 0;
573 }
574 else astring[ret] = 0;
575
576 return ret;
577}
578
579
580/*****************************************************************************
581 * Name :
582 * Purpose :
583 * Parameters:
584 * Variables :
585 * Result :
586 * Remark :
587 * Status :
588 *
589 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
590 *****************************************************************************/
591
592// asciilen: max length of unicode buffer (including end 0)
593// @@@PH 0 termination is NOT necessarily included !
594int lstrcpynAtoC(LPWSTR unicode,
595 LPCSTR ascii,
596 int asciilen,
597 UconvObject uconv_object)
598{
599 int rc;
600 int i;
601 size_t uni_chars_left;
602 size_t in_bytes_left;
603 size_t num_subs;
604 UniChar* out_buf;
605 char* in_buf;
606
607 dprintf2(("KERNEL32: HeapString: lstrcpynAtoW(%s,%08xh,%d)\n",
608 ascii,
609 unicode,
610 asciilen));
611
612 //CB: no input, set at least terminator
613 if (ascii == NULL)
614 {
615 if (unicode != NULL && asciilen > 0) unicode[0] = 0;
616 return 0;
617 }
618
619 if (unicode == NULL || asciilen <= 0)
620 return 0; //nothing to do
621
622 if (uconv_object)
623 {
624 //@@@PH what's this?
625 if ((asciilen == 1) && (*ascii == '\0') )
626 {
627 unicode[0] = 0;
628 return 0;
629 }
630
631 in_buf = (LPSTR)ascii;
632
633 //@@@PH what's this?
634 //in_bytes_left = asciilen-1; //buffer size in bytes
635
636 //SvL: Determine length of ascii string
637 in_bytes_left = strlen(in_buf)+1;
638 in_bytes_left = asciilen = min(in_bytes_left, asciilen); //buffer size in bytes
639
640 out_buf = (UniChar*)unicode;
641
642 uni_chars_left = in_bytes_left; //elements
643
644 rc = UniUconvToUcs( uconv_object,
645 (void**)&in_buf, &in_bytes_left,
646 &out_buf, &uni_chars_left,
647 &num_subs );
648
649 /* @@@PH 2000/08/10
650 * this causes the last character in the converted
651 * target string to be chopped off. I.e. causes CMD.EXE
652 * to enter command correctly.
653 */
654 /*
655 asciilen -= 1+uni_chars_left; //end + left bytes
656
657 unicode[asciilen] = 0; // always terminate string
658 */
659
660 return asciilen; //length of string (excluding terminator)
661 }
662 else
663 { //poor man's conversion
664
665// for(i = 0;i < asciilen-1;i++)
666 for(i = 0;i < asciilen;i++)
667 {
668 unicode[i] = ascii[i];
669 if (ascii[i] == 0)
670 //return i-1; //work done
671 return i; //work done
672 }
673
674// unicode[asciilen-1] = 0;
675// return asciilen-1;
676 return asciilen;
677 }
678}
679
680//lstrcpynWtoA and lstrcpynAtoW must zero-terminate the string
681//because Wine code depends on this behaviour (i.e. comdlg32)
682int WIN32API lstrcpynAtoW(LPWSTR unicode,
683 LPCSTR ascii,
684 int asciilen)
685{
686 int ret;
687
688 ret = lstrcpynAtoC(unicode, ascii, asciilen, GetWindowsUconvObject());
689 //Must not always set the last character to 0; some apps send the wrong
690 //string size to apis that use this function (i.e. GetMenuStringW (Notes))
691 //-> overwrites stack
692 if(ret == asciilen) {
693 unicode[asciilen-1] = 0;
694 }
695 else unicode[ret] = 0;
696 return ret;
697}
698
699/*****************************************************************************
700 * Name :
701 * Purpose : Converts unicode string to ascii string
702 * Parameters:
703 * Variables :
704 * Result : returns length of ascii string
705 * Remark :
706 * Status :
707 *
708 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
709 *****************************************************************************/
710
711LPSTR WIN32API lstrcpyWtoA(LPSTR ascii, LPCWSTR unicode)
712{
713 //@@@PH huh? wuz dat?
714 if (unicode == NULL)
715 {
716 if (unicode != NULL) ((LPWSTR)unicode)[0] = 0; //CB: set at least end
717 return NULL;
718 }
719
720 if (unicode == NULL)
721 return NULL; /* garbage in, garbage out ! */
722
723 /* forward to function with len parameter */
724 lstrcpynWtoA(ascii,
725 unicode,
726 UniStrlen((UniChar*)unicode)+1); //end included
727
728 return ascii;
729}
730
731
732/*****************************************************************************
733 * Name :
734 * Purpose : Copies the full string from ascii to unicode
735 * Parameters:
736 * Variables :
737 * Result :
738 * Remark :
739 * Status :
740 *
741 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
742 *****************************************************************************/
743
744LPWSTR WIN32API lstrcpyAtoW(LPWSTR unicode, LPCSTR ascii)
745{
746 /* achimha for security, strlen might trap if garbage in */
747 /* @@@PH 98/06/07 */
748 if (ascii == NULL)
749 {
750 if (unicode != NULL) unicode[0] = 0; //CB: set at least end
751 return NULL;
752 }
753
754 if (unicode == NULL)
755 return NULL; /* garbage in, garbage out ! */
756
757 /* forward to call with length parameter */
758 lstrcpynAtoW(unicode, ascii, strlen(ascii)+1); //end included
759 return (unicode);
760}
761
762
763
764
765/*****************************************************************************
766 * Name :
767 * Purpose :
768 * Parameters:
769 * Variables :
770 * Result :
771 * Remark :
772 * Status :
773 *
774 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
775 *****************************************************************************/
776
777LPVOID WIN32API HEAP_xalloc( HANDLE heap, DWORD flags, DWORD size )
778{
779 LPVOID p = HeapAlloc( heap, flags, size );
780 if (!p)
781 {
782 dprintf2(("KERNEL32: HEAP_xalloc(%08xh,%08xh,%08xh) out of memory.\n",
783 heap,
784 flags,
785 size));
786 }
787 return p;
788}
789
790
791/*****************************************************************************
792 * Name :
793 * Purpose :
794 * Parameters:
795 * Variables :
796 * Result :
797 * Remark :
798 * Status :
799 *
800 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
801 *****************************************************************************/
802
803LPVOID WIN32API HEAP_xrealloc( HANDLE heap, DWORD flags, LPVOID lpMem, DWORD size )
804{
805 LPVOID p = HeapReAlloc( heap, flags, lpMem, size );
806 if (!p)
807 {
808 dprintf2(("KERNEL32: HEAP_xrealloc(%08xh,%08xh,%08xh,%08xh) out of memory.\n",
809 heap,
810 flags,
811 lpMem,
812 size));
813 }
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
830LPVOID WIN32API HEAP_malloc(DWORD size )
831{
832 LPVOID p = HeapAlloc( GetProcessHeap(), 0, size );
833 if (!p)
834 {
835 dprintf2(("KERNEL32: HEAP_malloc(%08xh) out of memory.\n",
836 size));
837 }
838 return p;
839}
840
841
842/*****************************************************************************
843 * Name :
844 * Purpose :
845 * Parameters:
846 * Variables :
847 * Result :
848 * Remark :
849 * Status :
850 *
851 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
852 *****************************************************************************/
853
854DWORD WIN32API HEAP_size(LPVOID lpMem)
855{
856 return HeapSize( GetProcessHeap(), 0, lpMem );
857}
858
859
860/*****************************************************************************
861 * Name :
862 * Purpose :
863 * Parameters:
864 * Variables :
865 * Result :
866 * Remark :
867 * Status :
868 *
869 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
870 *****************************************************************************/
871
872LPVOID WIN32API HEAP_realloc(LPVOID lpMem, DWORD size )
873{
874 LPVOID p = HeapReAlloc( GetProcessHeap(), 0, lpMem, size );
875 if (!p)
876 {
877 dprintf2(("KERNEL32: HEAP_realloc(%08xh,%08xh) out of memory.\n",
878 lpMem,
879 size));
880 }
881 return p;
882}
883
884
885/*****************************************************************************
886 * Name :
887 * Purpose :
888 * Parameters:
889 * Variables :
890 * Result :
891 * Remark :
892 * Status :
893 *
894 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
895 *****************************************************************************/
896
897VOID WIN32API HEAP_free(LPVOID lpMem)
898{
899 dprintf2(("KERNEL32: HEAP_free(%08xh)\n",
900 lpMem));
901
902 HeapFree( GetProcessHeap(), 0, lpMem);
903}
904
905
906/*****************************************************************************
907 * Name :
908 * Purpose :
909 * Parameters:
910 * Variables :
911 * Result :
912 * Remark :
913 * Status :
914 *
915 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
916 *****************************************************************************/
917
918LPSTR WIN32API HEAP_strdupA( HANDLE heap, DWORD flags, LPCSTR str )
919{
920 LPSTR p = (LPSTR)HEAP_xalloc( heap, flags, strlen(str) + 1 );
921 strcpy( p, str );
922 return p;
923}
924
925
926/*****************************************************************************
927 * Name :
928 * Purpose :
929 * Parameters:
930 * Variables :
931 * Result :
932 * Remark :
933 * Status :
934 *
935 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
936 *****************************************************************************/
937
938LPWSTR WIN32API HEAP_strdupW( HANDLE heap, DWORD flags, LPCWSTR str )
939{
940 INT len = lstrlenW(str) + 1;
941 LPWSTR p = (LPWSTR)HEAP_xalloc( heap, flags, len * sizeof(WCHAR) );
942 lstrcpyW( p, str );
943 return p;
944}
945
946
947/*****************************************************************************
948 * Name :
949 * Purpose :
950 * Parameters:
951 * Variables :
952 * Result :
953 * Remark :
954 * Status :
955 *
956 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
957 *****************************************************************************/
958
959LPWSTR WIN32API HEAP_strdupAtoW( HANDLE heap, DWORD flags, LPCSTR str )
960{
961 LPWSTR ret;
962
963 if (!str) return NULL;
964 ret = (LPWSTR)HEAP_xalloc( heap, flags, (strlen(str)+1) * sizeof(WCHAR) );
965 lstrcpyAtoW( ret, (LPSTR)str );
966 return ret;
967}
968
969
970/*****************************************************************************
971 * Name :
972 * Purpose :
973 * Parameters:
974 * Variables :
975 * Result :
976 * Remark :
977 * Status :
978 *
979 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
980 *****************************************************************************/
981
982LPSTR WIN32API HEAP_strdupWtoA( HANDLE heap, DWORD flags, LPCWSTR str )
983{
984 LPSTR ret;
985
986 if (!str) return NULL;
987 ret = (LPSTR)HEAP_xalloc( heap, flags, lstrlenW(str) + 1 );
988 lstrcpyWtoA( ret, (LPWSTR)str );
989 return ret;
990}
991
992
993/*****************************************************************************
994 * Name : WideCharToLocal
995 * Purpose : similar lstrcpyWtoA, should handle codepages properly
996 * Parameters:
997 * Variables :
998 * Result : strlen of the destination string
999 * Remark :
1000 * Status :
1001 *
1002 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
1003 *****************************************************************************/
1004
1005INT WIN32API WideCharToLocal(LPSTR pLocal, LPWSTR pWide, INT dwChars)
1006{
1007 dprintf2(("KERNEL32: WideCharToLocal(%08xh,%08xh,%08xh)\n",
1008 pLocal,
1009 pWide,
1010 dwChars));
1011
1012 *pLocal = 0;
1013 WideCharToMultiByte(CP_ACP,
1014 0,
1015 pWide,
1016 -1,
1017 pLocal,
1018 dwChars,
1019 NULL,
1020 NULL);
1021
1022 return strlen(pLocal);
1023}
1024
1025
1026/*****************************************************************************
1027 * Name : LocalToWideChar
1028 * Purpose : similar lstrcpyAtoW, should handle codepages properly
1029 * Parameters:
1030 * Variables :
1031 * Result : strlen of the destination string
1032 * Remark :
1033 * Status :
1034 *
1035 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
1036 *****************************************************************************/
1037
1038INT WIN32API LocalToWideChar(LPWSTR pWide, LPSTR pLocal, INT dwChars)
1039{
1040 *pWide = 0;
1041
1042 dprintf2(("KERNEL32: LocalToWideChar(%08xh,%08xh,%08xh)\n",
1043 pLocal,
1044 pWide,
1045 dwChars));
1046
1047 MultiByteToWideChar(CP_ACP,
1048 0,
1049 pLocal,
1050 -1,
1051 pWide,
1052 dwChars);
1053
1054 return lstrlenW(pWide);
1055}
1056
1057
1058
1059
1060
1061
1062#if 0
1063
1064
1065/*****************************************************************************
1066 * Name :
1067 * Purpose :
1068 * Parameters:
1069 * Variables :
1070 * Result :
1071 * Remark :
1072 * Status :
1073 *
1074 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
1075 *****************************************************************************/
1076
1077// Converts unicode string to ascii string
1078// returns pointer to ascii string
1079char * WIN32API UnicodeToAsciiString(WCHAR *ustring)
1080{
1081 char *astring;
1082
1083 if(ustring == NULL) return(NULL);
1084
1085 astring = (char *)malloc( 1 + UniStrlen((UniChar*)ustring) );
1086 UnicodeToAscii( ustring, astring );
1087 return(astring);
1088}
1089
1090
1091/*****************************************************************************
1092 * Name :
1093 * Purpose :
1094 * Parameters:
1095 * Variables :
1096 * Result :
1097 * Remark :
1098 * Status :
1099 *
1100 * Author : Patrick Haller [Thu, 1999/08/05 20:46]
1101 *****************************************************************************/
1102
1103// Converts ascii string to unicode string
1104// returns pointer to unicode string
1105WCHAR * WIN32API AsciiToUnicodeString(char *astring)
1106{
1107 WCHAR *ustring;
1108
1109 if(astring == NULL)
1110 return(NULL);
1111
1112 ustring = (WCHAR *)malloc( 1 + strlen(astring) << 1 );
1113 AsciiToUnicode( astring, ustring );
1114 return(ustring);
1115}
1116
1117#endif
1118
1119
1120
1121/**************************************************************************
1122 * This function is used just locally !
1123 * Description: Inverts a string.
1124 */
1125static void OLE_InvertString(char* string)
1126{
1127 char sTmpArray[128];
1128 INT counter, i = 0;
1129
1130 for (counter = strlen(string); counter > 0; counter--)
1131 {
1132 memcpy(sTmpArray + i, string + counter-1, 1);
1133 i++;
1134 }
1135 memcpy(sTmpArray + i, "\0", 1);
1136 strcpy(string, sTmpArray);
1137}
1138
1139/***************************************************************************************
1140 * This function is used just locally !
1141 * Description: Test if the given string (psNumber) is valid or not.
1142 * The valid characters are the following:
1143 * - Characters '0' through '9'.
1144 * - One decimal point (dot) if the number is a floating-point value.
1145 * - A minus sign in the first character position if the number is
1146 * a negative value.
1147 * If the function succeeds, psBefore/psAfter will point to the string
1148 * on the right/left of the decimal symbol. pbNegative indicates if the
1149 * number is negative.
1150 */
1151static INT OLE_GetNumberComponents(char* pInput, char* psBefore, char* psAfter, BOOL* pbNegative)
1152{
1153char sNumberSet[] = "0123456789";
1154BOOL bInDecimal = FALSE;
1155
1156 /* Test if we do have a minus sign */
1157 if ( *pInput == '-' )
1158 {
1159 *pbNegative = TRUE;
1160 pInput++; /* Jump to the next character. */
1161 }
1162
1163 while(*pInput != '\0')
1164 {
1165 /* Do we have a valid numeric character */
1166 if ( strchr(sNumberSet, *pInput) != NULL )
1167 {
1168 if (bInDecimal == TRUE)
1169 *psAfter++ = *pInput;
1170 else
1171 *psBefore++ = *pInput;
1172 }
1173 else
1174 {
1175 /* Is this a decimal point (dot) */
1176 if ( *pInput == '.' )
1177 {
1178 /* Is it the first time we find it */
1179 if ((bInDecimal == FALSE))
1180 bInDecimal = TRUE;
1181 else
1182 return -1; /* ERROR: Invalid parameter */
1183 }
1184 else
1185 {
1186 /* It's neither a numeric character, nor a decimal point.
1187 * Thus, return an error.
1188 */
1189 return -1;
1190 }
1191 }
1192 pInput++;
1193 }
1194
1195 /* Add an End of Line character to the output buffers */
1196 *psBefore = '\0';
1197 *psAfter = '\0';
1198
1199 return 0;
1200}
1201
1202/**************************************************************************
1203 * This function is used just locally !
1204 * Description: A number could be formatted using different numbers
1205 * of "digits in group" (example: 4;3;2;0).
1206 * The first parameter of this function is an array
1207 * containing the rule to be used. It's format is the following:
1208 * |NDG|DG1|DG2|...|0|
1209 * where NDG is the number of used "digits in group" and DG1, DG2,
1210 * are the corresponding "digits in group".
1211 * Thus, this function returns the grouping value in the array
1212 * pointed by the second parameter.
1213 */
1214static INT OLE_GetGrouping(char* sRule, INT index)
1215{
1216 char sData[2], sRuleSize[2];
1217 INT nData, nRuleSize;
1218
1219 memcpy(sRuleSize, sRule, 1);
1220 memcpy(sRuleSize+1, "\0", 1);
1221 nRuleSize = atoi(sRuleSize);
1222
1223 if (index > 0 && index < nRuleSize)
1224 {
1225 memcpy(sData, sRule+index, 1);
1226 memcpy(sData+1, "\0", 1);
1227 nData = atoi(sData);
1228 }
1229
1230 else
1231 {
1232 memcpy(sData, sRule+nRuleSize-1, 1);
1233 memcpy(sData+1, "\0", 1);
1234 nData = atoi(sData);
1235 }
1236
1237 return nData;
1238}
Note: See TracBrowser for help on using the repository browser.