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

Last change on this file since 10176 was 10176, checked in by sandervl, 22 years ago

KOM: Added functions to query length after ascii or unicode conversion; Changed the destination length parameter name of lstrcpynWtoA() and lstrcpynAtoW()

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