ReactOS 0.4.17-dev-357-ga8f14ff
string.c
Go to the documentation of this file.
1/*
2 * Shlwapi string functions
3 *
4 * Copyright 1998 Juergen Schmied
5 * Copyright 2002 Jon Griffiths
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22#include <math.h>
23#include <stdarg.h>
24#include <stdio.h>
25#include <string.h>
26
27#include "windef.h"
28#include "winbase.h"
29#define NO_SHLWAPI_REG
30#define NO_SHLWAPI_STREAM
31#include "shlwapi.h"
32#include "wingdi.h"
33#include "winuser.h"
34#include "shlobj.h"
35#include "mlang.h"
36#include "ddeml.h"
37#include "wine/unicode.h"
38#include "wine/debug.h"
39
40#include "resource.h"
41
43
45
48
50
51static void FillNumberFmt(NUMBERFMTW *fmt, LPWSTR decimal_buffer, int decimal_bufwlen,
52 LPWSTR thousand_buffer, int thousand_bufwlen)
53{
54 WCHAR grouping[64];
55 WCHAR *c;
56
57 GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_ILZERO|LOCALE_RETURN_NUMBER, (LPWSTR)&fmt->LeadingZero, sizeof(fmt->LeadingZero)/sizeof(WCHAR));
58 GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_INEGNUMBER|LOCALE_RETURN_NUMBER, (LPWSTR)&fmt->LeadingZero, sizeof(fmt->NegativeOrder)/sizeof(WCHAR));
59 fmt->NumDigits = 0;
60 GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, decimal_buffer, decimal_bufwlen);
61 GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, thousand_buffer, thousand_bufwlen);
62 fmt->lpThousandSep = thousand_buffer;
63 fmt->lpDecimalSep = decimal_buffer;
64
65 /*
66 * Converting grouping string to number as described on
67 * http://blogs.msdn.com/oldnewthing/archive/2006/04/18/578251.aspx
68 */
69 fmt->Grouping = 0;
71 for (c = grouping; *c; c++)
72 if (*c >= '0' && *c < '9')
73 {
74 fmt->Grouping *= 10;
75 fmt->Grouping += *c - '0';
76 }
77
78 if (fmt->Grouping % 10 == 0)
79 fmt->Grouping /= 10;
80 else
81 fmt->Grouping *= 10;
82}
83
84/*************************************************************************
85 * FormatInt [internal]
86 *
87 * Format an integer according to the current locale
88 *
89 * RETURNS
90 * The number of characters written on success or 0 on failure
91 */
92static int FormatInt(LONGLONG qdwValue, LPWSTR pszBuf, int cchBuf)
93{
95 WCHAR decimal[8], thousand[8];
96 WCHAR buf[24];
97 WCHAR *c;
98 BOOL neg = (qdwValue < 0);
99
100 FillNumberFmt(&fmt, decimal, ARRAY_SIZE(decimal), thousand, ARRAY_SIZE(thousand));
101
102 c = &buf[24];
103 *(--c) = 0;
104 do
105 {
106 *(--c) = '0' + (qdwValue%10);
107 qdwValue /= 10;
108 } while (qdwValue > 0);
109 if (neg)
110 *(--c) = '-';
111
112 return GetNumberFormatW(LOCALE_USER_DEFAULT, 0, c, &fmt, pszBuf, cchBuf);
113}
114
115/*************************************************************************
116 * FormatDouble [internal]
117 *
118 * Format an integer according to the current locale. Prints the specified number of digits
119 * after the decimal point
120 *
121 * RETURNS
122 * The number of characters written on success or 0 on failure
123 */
124static int FormatDouble(double value, int decimals, LPWSTR pszBuf, int cchBuf)
125{
126 static const WCHAR flfmt[] = {'%','f',0};
127 WCHAR buf[64];
129 WCHAR decimal[8], thousand[8];
130
131 swprintf(buf, 64, flfmt, value);
132
133 FillNumberFmt(&fmt, decimal, ARRAY_SIZE(decimal), thousand, ARRAY_SIZE(thousand));
134 fmt.NumDigits = decimals;
135 return GetNumberFormatW(LOCALE_USER_DEFAULT, 0, buf, &fmt, pszBuf, cchBuf);
136}
137
138
139/*************************************************************************
140 * StrCatW [SHLWAPI.@]
141 *
142 * Concatenate two strings.
143 *
144 * PARAMS
145 * lpszStr [O] Initial string
146 * lpszSrc [I] String to concatenate
147 *
148 * RETURNS
149 * lpszStr.
150 */
152{
153 TRACE("(%s,%s)\n", debugstr_w(lpszStr), debugstr_w(lpszSrc));
154
155 if (lpszStr && lpszSrc)
156 lstrcatW(lpszStr, lpszSrc);
157 return lpszStr;
158}
159
160
161/*************************************************************************
162 * StrCpyW [SHLWAPI.@]
163 *
164 * Copy a string to another string.
165 *
166 * PARAMS
167 * lpszStr [O] Destination string
168 * lpszSrc [I] Source string
169 *
170 * RETURNS
171 * lpszStr.
172 */
174{
175 TRACE("(%p,%s)\n", lpszStr, debugstr_w(lpszSrc));
176
177 if (lpszStr && lpszSrc)
178 lstrcpyW(lpszStr, lpszSrc);
179 return lpszStr;
180}
181
182/*************************************************************************
183 * StrRetToBufA [SHLWAPI.@]
184 *
185 * Convert a STRRET to a normal string.
186 *
187 * PARAMS
188 * lpStrRet [O] STRRET to convert
189 * pIdl [I] ITEMIDLIST for lpStrRet->uType == STRRET_OFFSET
190 * lpszDest [O] Destination for normal string
191 * dwLen [I] Length of lpszDest
192 *
193 * RETURNS
194 * Success: S_OK. lpszDest contains up to dwLen characters of the string.
195 * If lpStrRet is of type STRRET_WSTR, its memory is freed with
196 * CoTaskMemFree() and its type set to STRRET_CSTRA.
197 * Failure: E_FAIL, if any parameters are invalid.
198 */
200{
201 /* NOTE:
202 * This routine is identical to that in dlls/shell32/shellstring.c.
203 * It was duplicated because not every version of Shlwapi.dll exports
204 * StrRetToBufA. If you change one routine, change them both.
205 */
206 TRACE("dest=%p len=0x%x strret=%p pidl=%p\n", dest, len, src, pidl);
207
208 if (!src)
209 {
210 WARN("Invalid lpStrRet would crash under Win32!\n");
211 if (dest)
212 *dest = '\0';
213 return E_FAIL;
214 }
215
216 if (!dest || !len)
217 return E_FAIL;
218
219 *dest = '\0';
220
221 switch (src->uType)
222 {
223 case STRRET_WSTR:
224 WideCharToMultiByte(CP_ACP, 0, src->pOleStr, -1, dest, len, NULL, NULL);
225 CoTaskMemFree(src->pOleStr);
226 break;
227
228 case STRRET_CSTR:
229 lstrcpynA(dest, src->cStr, len);
230 break;
231
232 case STRRET_OFFSET:
233 lstrcpynA(dest, ((LPCSTR)&pidl->mkid)+src->uOffset, len);
234 break;
235
236 default:
237 FIXME("unknown type!\n");
238 return E_NOTIMPL;
239 }
240 return S_OK;
241}
242
243/*************************************************************************
244 * StrRetToBufW [SHLWAPI.@]
245 *
246 * See StrRetToBufA.
247 */
249{
250 TRACE("dest=%p len=0x%x strret=%p pidl=%p\n", dest, len, src, pidl);
251
252 if (!dest || !len)
253 return E_FAIL;
254
255 if (!src)
256 {
257 WARN("Invalid lpStrRet would crash under Win32!\n");
258 if (dest)
259 *dest = '\0';
260 return E_FAIL;
261 }
262
263 *dest = '\0';
264
265 switch (src->uType) {
266 case STRRET_WSTR: {
267 size_t dst_len;
268 if (!src->pOleStr)
269 return E_FAIL;
270 dst_len = lstrlenW(src->pOleStr);
271 memcpy(dest, src->pOleStr, min(dst_len, len-1) * sizeof(WCHAR));
272 dest[min(dst_len, len-1)] = 0;
273 CoTaskMemFree(src->pOleStr);
274 if (len <= dst_len)
275 {
276 dest[0] = 0;
278 }
279 break;
280 }
281
282 case STRRET_CSTR:
283 if (!MultiByteToWideChar( CP_ACP, 0, src->cStr, -1, dest, len ))
284 dest[len-1] = 0;
285 break;
286
287 case STRRET_OFFSET:
288 if (pidl)
289 {
290 if (!MultiByteToWideChar( CP_ACP, 0, ((LPCSTR)&pidl->mkid)+src->uOffset, -1,
291 dest, len ))
292 dest[len-1] = 0;
293 }
294 break;
295
296 default:
297 FIXME("unknown type!\n");
298 return E_NOTIMPL;
299 }
300
301 return S_OK;
302}
303
304/*************************************************************************
305 * StrRetToStrA [SHLWAPI.@]
306 *
307 * Converts a STRRET to a normal string.
308 *
309 * PARAMS
310 * lpStrRet [O] STRRET to convert
311 * pidl [I] ITEMIDLIST for lpStrRet->uType == STRRET_OFFSET
312 * ppszName [O] Destination for converted string
313 *
314 * RETURNS
315 * Success: S_OK. ppszName contains the new string, allocated with CoTaskMemAlloc().
316 * Failure: E_FAIL, if any parameters are invalid.
317 */
319{
320 HRESULT hRet = E_FAIL;
321
322 switch (lpStrRet->uType)
323 {
324 case STRRET_WSTR:
325 hRet = _SHStrDupAW(lpStrRet->pOleStr, ppszName);
326 CoTaskMemFree(lpStrRet->pOleStr);
327 break;
328
329 case STRRET_CSTR:
330 hRet = _SHStrDupAA(lpStrRet->cStr, ppszName);
331 break;
332
333 case STRRET_OFFSET:
334 hRet = _SHStrDupAA(((LPCSTR)&pidl->mkid) + lpStrRet->uOffset, ppszName);
335 break;
336
337 default:
338 *ppszName = NULL;
339 }
340
341 return hRet;
342}
343
344/*************************************************************************
345 * StrRetToStrW [SHLWAPI.@]
346 *
347 * See StrRetToStrA.
348 */
350{
351 HRESULT hRet = E_FAIL;
352
353 switch (lpStrRet->uType)
354 {
355 case STRRET_WSTR:
356#ifdef __REACTOS__
357 hRet = lpStrRet->pOleStr ? S_OK : E_FAIL;
358 *ppszName = lpStrRet->pOleStr;
359 lpStrRet->pOleStr = NULL; /* Windows does this, presumably in case someone calls SHFree */
360#else
361 hRet = SHStrDupW(lpStrRet->pOleStr, ppszName);
362 CoTaskMemFree(lpStrRet->pOleStr);
363#endif
364 break;
365
366 case STRRET_CSTR:
367 hRet = SHStrDupA(lpStrRet->cStr, ppszName);
368 break;
369
370 case STRRET_OFFSET:
371 hRet = SHStrDupA(((LPCSTR)&pidl->mkid) + lpStrRet->uOffset, ppszName);
372 break;
373
374 default:
375 *ppszName = NULL;
376 }
377
378 return hRet;
379}
380
381/* Makes a Unicode copy of an ANSI string using SysAllocString() */
383{
384 *pBstrOut = NULL;
385
386 if (src)
387 {
388 INT len = MultiByteToWideChar(CP_ACP, 0, src, -1, NULL, 0);
389 WCHAR *szTemp = malloc(len * sizeof(WCHAR));
390
391 if (szTemp)
392 {
393 MultiByteToWideChar(CP_ACP, 0, src, -1, szTemp, len);
394 *pBstrOut = SysAllocString(szTemp);
395 free(szTemp);
396
397 if (*pBstrOut)
398 return S_OK;
399 }
400 }
401 return E_OUTOFMEMORY;
402}
403
404/*************************************************************************
405 * StrRetToBSTR [SHLWAPI.@]
406 *
407 * Converts a STRRET to a BSTR.
408 *
409 * PARAMS
410 * lpStrRet [O] STRRET to convert
411 * pidl [I] ITEMIDLIST for lpStrRet->uType = STRRET_OFFSET
412 * pBstrOut [O] Destination for converted BSTR
413 *
414 * RETURNS
415 * Success: S_OK. pBstrOut contains the new string.
416 * Failure: E_FAIL, if any parameters are invalid.
417 */
419{
420 HRESULT hRet = E_FAIL;
421
422 switch (lpStrRet->uType)
423 {
424 case STRRET_WSTR:
425 *pBstrOut = SysAllocString(lpStrRet->pOleStr);
426 if (*pBstrOut)
427 hRet = S_OK;
428 CoTaskMemFree(lpStrRet->pOleStr);
429 break;
430
431 case STRRET_CSTR:
432 hRet = _SHStrDupAToBSTR(lpStrRet->cStr, pBstrOut);
433 break;
434
435 case STRRET_OFFSET:
436 hRet = _SHStrDupAToBSTR(((LPCSTR)&pidl->mkid) + lpStrRet->uOffset, pBstrOut);
437 break;
438
439 default:
440 *pBstrOut = NULL;
441 }
442
443 return hRet;
444}
445
446/*************************************************************************
447 * StrFormatKBSizeA [SHLWAPI.@]
448 *
449 * Create a formatted string containing a byte count in Kilobytes.
450 *
451 * PARAMS
452 * llBytes [I] Byte size to format
453 * lpszDest [I] Destination for formatted string
454 * cchMax [I] Size of lpszDest
455 *
456 * RETURNS
457 * lpszDest.
458 */
460{
461 WCHAR wszBuf[256];
462
463 if (!StrFormatKBSizeW(llBytes, wszBuf, 256))
464 return NULL;
465 if (!WideCharToMultiByte(CP_ACP, 0, wszBuf, -1, lpszDest, cchMax, NULL, NULL))
466 return NULL;
467 return lpszDest;
468}
469
470/*************************************************************************
471 * StrFormatKBSizeW [SHLWAPI.@]
472 *
473 * See StrFormatKBSizeA.
474 */
476{
477 static const WCHAR kb[] = {' ','K','B',0};
478 LONGLONG llKB = (llBytes + 1023) >> 10;
479 int len;
480
481 TRACE("(0x%s,%p,%d)\n", wine_dbgstr_longlong(llBytes), lpszDest, cchMax);
482
483 if (!FormatInt(llKB, lpszDest, cchMax))
484 return NULL;
485
487 if (cchMax - len < 4)
488 return NULL;
489 lstrcatW(lpszDest, kb);
490 return lpszDest;
491}
492
493/*************************************************************************
494 * StrNCatA [SHLWAPI.@]
495 *
496 * Concatenate two strings together.
497 *
498 * PARAMS
499 * lpszStr [O] String to concatenate to
500 * lpszCat [I] String to add to lpszCat
501 * cchMax [I] Maximum number of characters to concatenate
502 *
503 * RETURNS
504 * lpszStr.
505 *
506 * NOTES
507 * cchMax determines the number of characters that are appended to lpszStr,
508 * not the total length of the string.
509 */
511{
512 LPSTR lpszRet = lpszStr;
513
514 TRACE("(%s,%s,%i)\n", debugstr_a(lpszStr), debugstr_a(lpszCat), cchMax);
515
516 if (!lpszStr)
517 {
518 WARN("Invalid lpszStr would crash under Win32!\n");
519 return NULL;
520 }
521
522 StrCpyNA(lpszStr + strlen(lpszStr), lpszCat, cchMax);
523 return lpszRet;
524}
525
526/*************************************************************************
527 * StrNCatW [SHLWAPI.@]
528 *
529 * See StrNCatA.
530 */
532{
533 LPWSTR lpszRet = lpszStr;
534
535 TRACE("(%s,%s,%i)\n", debugstr_w(lpszStr), debugstr_w(lpszCat), cchMax);
536
537 if (!lpszStr)
538 {
539 WARN("Invalid lpszStr would crash under Win32\n");
540 return NULL;
541 }
542
543 StrCpyNW(lpszStr + lstrlenW(lpszStr), lpszCat, cchMax);
544 return lpszRet;
545}
546
547/*************************************************************************
548 * _SHStrDupAA [INTERNAL]
549 *
550 * Duplicates a ANSI string to ANSI. The destination buffer is allocated.
551 */
553{
554 HRESULT hr;
555 int len = 0;
556
557 if (src) {
558 len = lstrlenA(src) + 1;
560 } else {
561 *dest = NULL;
562 }
563
564 if (*dest) {
566 hr = S_OK;
567 } else {
569 }
570
571 TRACE("%s->(%p)\n", debugstr_a(src), *dest);
572 return hr;
573}
574
575/*************************************************************************
576 * SHStrDupA [SHLWAPI.@]
577 *
578 * Return a Unicode copy of a string, in memory allocated by CoTaskMemAlloc().
579 *
580 * PARAMS
581 * lpszStr [I] String to copy
582 * lppszDest [O] Destination for the new string copy
583 *
584 * RETURNS
585 * Success: S_OK. lppszDest contains the new string in Unicode format.
586 * Failure: E_OUTOFMEMORY, If any arguments are invalid or memory allocation
587 * fails.
588 */
589HRESULT WINAPI SHStrDupA(LPCSTR lpszStr, LPWSTR * lppszDest)
590{
591 HRESULT hRet;
592 int len = 0;
593
594 if (lpszStr)
595 {
596 len = MultiByteToWideChar(CP_ACP, 0, lpszStr, -1, NULL, 0) * sizeof(WCHAR);
597 *lppszDest = CoTaskMemAlloc(len);
598 }
599 else
600 *lppszDest = NULL;
601
602 if (*lppszDest)
603 {
604 MultiByteToWideChar(CP_ACP, 0, lpszStr, -1, *lppszDest, len/sizeof(WCHAR));
605 hRet = S_OK;
606 }
607 else
608 hRet = E_OUTOFMEMORY;
609
610 TRACE("%s->(%p)\n", debugstr_a(lpszStr), *lppszDest);
611 return hRet;
612}
613
614/*************************************************************************
615 * _SHStrDupAW [INTERNAL]
616 *
617 * Duplicates a UNICODE to a ANSI string. The destination buffer is allocated.
618 */
620{
621 HRESULT hr;
622 int len = 0;
623
624 if (src) {
625 len = WideCharToMultiByte(CP_ACP, 0, src, -1, NULL, 0, NULL, NULL);
627 } else {
628 *dest = NULL;
629 }
630
631 if (*dest) {
633 hr = S_OK;
634 } else {
636 }
637
638 TRACE("%s->(%p)\n", debugstr_w(src), *dest);
639 return hr;
640}
641
642/*************************************************************************
643 * SHStrDupW [SHLWAPI.@]
644 *
645 * See SHStrDupA.
646 */
648{
649 HRESULT hr;
650 int len = 0;
651
652 if (src) {
653 len = (lstrlenW(src) + 1) * sizeof(WCHAR);
655 } else {
656 *dest = NULL;
657 }
658
659 if (*dest) {
660 memcpy(*dest, src, len);
661 hr = S_OK;
662 } else {
664 }
665
666 TRACE("%s->(%p)\n", debugstr_w(src), *dest);
667 return hr;
668}
669
670/*************************************************************************
671 * SHLWAPI_WriteReverseNum
672 *
673 * Internal helper for SHLWAPI_WriteTimeClass.
674 */
675static inline LPWSTR SHLWAPI_WriteReverseNum(LPWSTR lpszOut, DWORD dwNum)
676{
677 *lpszOut-- = '\0';
678
679 /* Write a decimal number to a string, backwards */
680 do
681 {
682 DWORD dwNextDigit = dwNum % 10;
683 *lpszOut-- = '0' + dwNextDigit;
684 dwNum = (dwNum - dwNextDigit) / 10;
685 } while (dwNum > 0);
686
687 return lpszOut;
688}
689
690/*************************************************************************
691 * SHLWAPI_FormatSignificant
692 *
693 * Internal helper for SHLWAPI_WriteTimeClass.
694 */
695static inline int SHLWAPI_FormatSignificant(LPWSTR lpszNum, int dwDigits)
696{
697 /* Zero non significant digits, return remaining significant digits */
698 while (*lpszNum)
699 {
700 lpszNum++;
701 if (--dwDigits == 0)
702 {
703 while (*lpszNum)
704 *lpszNum++ = '0';
705 return 0;
706 }
707 }
708 return dwDigits;
709}
710
711/*************************************************************************
712 * SHLWAPI_WriteTimeClass
713 *
714 * Internal helper for StrFromTimeIntervalW.
715 */
716static int SHLWAPI_WriteTimeClass(LPWSTR lpszOut, DWORD dwValue,
717 UINT uClassStringId, int iDigits)
718{
719 WCHAR szBuff[64], *szOut = szBuff + 32;
720
721 szOut = SHLWAPI_WriteReverseNum(szOut, dwValue);
722 iDigits = SHLWAPI_FormatSignificant(szOut + 1, iDigits);
723 *szOut = ' ';
724 LoadStringW(shlwapi_hInstance, uClassStringId, szBuff + 32, 32);
725 lstrcatW(lpszOut, szOut);
726 return iDigits;
727}
728
729/*************************************************************************
730 * StrFromTimeIntervalA [SHLWAPI.@]
731 *
732 * Format a millisecond time interval into a string
733 *
734 * PARAMS
735 * lpszStr [O] Output buffer for formatted time interval
736 * cchMax [I] Size of lpszStr
737 * dwMS [I] Number of milliseconds
738 * iDigits [I] Number of digits to print
739 *
740 * RETURNS
741 * The length of the formatted string, or 0 if any parameter is invalid.
742 *
743 * NOTES
744 * This implementation mimics the Win32 behaviour of always writing a leading
745 * space before the time interval begins.
746 *
747 * iDigits is used to provide approximate times if accuracy is not important.
748 * This number of digits will be written of the first non-zero time class
749 * (hours/minutes/seconds). If this does not complete the time classification,
750 * the remaining digits are changed to zeros (i.e. The time is _not_ rounded).
751 * If there are digits remaining following the writing of a time class, the
752 * next time class will be written.
753 *
754 * For example, given dwMS represents 138 hours,43 minutes and 15 seconds, the
755 * following will result from the given values of iDigits:
756 *
757 *| iDigits 1 2 3 4 5 ...
758 *| lpszStr "100 hr" "130 hr" "138 hr" "138 hr 40 min" "138 hr 43 min" ...
759 */
761 int iDigits)
762{
763 INT iRet = 0;
764
765 TRACE("(%p,%d,%ld,%d)\n", lpszStr, cchMax, dwMS, iDigits);
766
767 if (lpszStr && cchMax)
768 {
769 WCHAR szBuff[128];
770 StrFromTimeIntervalW(szBuff, ARRAY_SIZE(szBuff), dwMS, iDigits);
771 WideCharToMultiByte(CP_ACP,0,szBuff,-1,lpszStr,cchMax,0,0);
772 }
773 return iRet;
774}
775
776
777/*************************************************************************
778 * StrFromTimeIntervalW [SHLWAPI.@]
779 *
780 * See StrFromTimeIntervalA.
781 */
783 int iDigits)
784{
785 INT iRet = 0;
786
787 TRACE("(%p,%d,%ld,%d)\n", lpszStr, cchMax, dwMS, iDigits);
788
789 if (lpszStr && cchMax)
790 {
791 WCHAR szCopy[128];
792 DWORD dwHours, dwMinutes;
793
794 if (!iDigits || cchMax == 1)
795 {
796 *lpszStr = '\0';
797 return 0;
798 }
799
800 /* Calculate the time classes */
801 dwMS = (dwMS + 500) / 1000;
802 dwHours = dwMS / 3600;
803 dwMS -= dwHours * 3600;
804 dwMinutes = dwMS / 60;
805 dwMS -= dwMinutes * 60;
806
807 szCopy[0] = '\0';
808
809 if (dwHours)
810 iDigits = SHLWAPI_WriteTimeClass(szCopy, dwHours, IDS_TIME_INTERVAL_HOURS, iDigits);
811
812 if (dwMinutes && iDigits)
813 iDigits = SHLWAPI_WriteTimeClass(szCopy, dwMinutes, IDS_TIME_INTERVAL_MINUTES, iDigits);
814
815 if (iDigits) /* Always write seconds if we have significant digits */
817
818 lstrcpynW(lpszStr, szCopy, cchMax);
819 iRet = lstrlenW(lpszStr);
820 }
821 return iRet;
822}
823
824/* Structure for formatting byte strings */
826{
828 double dDivisor;
831#ifdef __REACTOS__
832 UINT nFormatID;
833#else
835#endif
837
838/*************************************************************************
839 * StrFormatByteSizeW [SHLWAPI.@]
840 *
841 * Create a string containing an abbreviated byte count of up to 2^63-1.
842 *
843 * PARAMS
844 * llBytes [I] Byte size to format
845 * lpszDest [I] Destination for formatted string
846 * cchMax [I] Size of lpszDest
847 *
848 * RETURNS
849 * lpszDest.
850 *
851 * NOTES
852 * There is no StrFormatByteSize64W function, it is called StrFormatByteSizeW().
853 */
855{
856 HRESULT hr;
857
858 TRACE("(0x%s,%p,%d)\n", wine_dbgstr_longlong(llBytes), lpszDest, cchMax);
859
860 if (!lpszDest || !cchMax)
861 return lpszDest;
862
865
866 if (FAILED(hr))
867 return NULL;
868
869 return lpszDest;
870}
871
872/*************************************************************************
873 * StrFormatByteSizeEx [SHLWAPI.@]
874 *
875 */
876
878 UINT cchMax)
879{
880#define KB ((ULONGLONG)1024)
881#define MB (KB*KB)
882#define GB (KB*KB*KB)
883#define TB (KB*KB*KB*KB)
884#define PB (KB*KB*KB*KB*KB)
885
886 static const SHLWAPI_BYTEFORMATS bfFormats[] =
887 {
888#ifdef __REACTOS__
889 { 10*KB, 10.24, 100.0, 2, IDS_KB_FORMAT }, /* 10 KB */
890 { 100*KB, 102.4, 10.0, 1, IDS_KB_FORMAT }, /* 100 KB */
891 { 1000*KB, 1024.0, 1.0, 0, IDS_KB_FORMAT }, /* 1000 KB */
892 { 10*MB, 10485.76, 100.0, 2, IDS_MB_FORMAT }, /* 10 MB */
893 { 100*MB, 104857.6, 10.0, 1, IDS_MB_FORMAT }, /* 100 MB */
894 { 1000*MB, 1048576.0, 1.0, 0, IDS_MB_FORMAT }, /* 1000 MB */
895 { 10*GB, 10737418.24, 100.0, 2, IDS_GB_FORMAT }, /* 10 GB */
896 { 100*GB, 107374182.4, 10.0, 1, IDS_GB_FORMAT }, /* 100 GB */
897 { 1000*GB, 1073741824.0, 1.0, 0, IDS_GB_FORMAT }, /* 1000 GB */
898 { 10*TB, 10485.76, 100.0, 2, IDS_TB_FORMAT }, /* 10 TB */
899 { 100*TB, 104857.6, 10.0, 1, IDS_TB_FORMAT }, /* 100 TB */
900 { 1000*TB, 1048576.0, 1.0, 0, IDS_TB_FORMAT }, /* 1000 TB */
901 { 10*PB, 10737418.24, 100.00, 2, IDS_PB_FORMAT }, /* 10 PB */
902 { 100*PB, 107374182.4, 10.00, 1, IDS_PB_FORMAT }, /* 100 PB */
903 { 1000*PB, 1073741824.0, 1.00, 0, IDS_PB_FORMAT }, /* 1000 PB */
904 { 0, 10995116277.76, 100.00, 2, IDS_EB_FORMAT } /* EB's, catch all */
905#else
906 { 10*KB, 10.24, 100.0, 2, 'K' }, /* 10 KB */
907 { 100*KB, 102.4, 10.0, 1, 'K' }, /* 100 KB */
908 { 1000*KB, 1024.0, 1.0, 0, 'K' }, /* 1000 KB */
909 { 10*MB, 10485.76, 100.0, 2, 'M' }, /* 10 MB */
910 { 100*MB, 104857.6, 10.0, 1, 'M' }, /* 100 MB */
911 { 1000*MB, 1048576.0, 1.0, 0, 'M' }, /* 1000 MB */
912 { 10*GB, 10737418.24, 100.0, 2, 'G' }, /* 10 GB */
913 { 100*GB, 107374182.4, 10.0, 1, 'G' }, /* 100 GB */
914 { 1000*GB, 1073741824.0, 1.0, 0, 'G' }, /* 1000 GB */
915 { 10*TB, 10485.76, 100.0, 2, 'T' }, /* 10 TB */
916 { 100*TB, 104857.6, 10.0, 1, 'T' }, /* 100 TB */
917 { 1000*TB, 1048576.0, 1.0, 0, 'T' }, /* 1000 TB */
918 { 10*PB, 10737418.24, 100.00, 2, 'P' }, /* 10 PB */
919 { 100*PB, 107374182.4, 10.00, 1, 'P' }, /* 100 PB */
920 { 1000*PB, 1073741824.0, 1.00, 0, 'P' }, /* 1000 PB */
921 { 0, 10995116277.76, 100.00, 2, 'E' } /* EB's, catch all */
922#endif
923 };
924#ifdef __REACTOS__
925 WCHAR szBuff[40], wszFormat[40];
926#else
927 WCHAR wszAdd[] = {' ','?','B',0};
928#endif
929 double dBytes;
930 UINT i = 0;
931
932 TRACE("(0x%s,%d,%p,%d)\n", wine_dbgstr_longlong(llBytes), flags, lpszDest, cchMax);
933
934 if (!cchMax)
935 return E_INVALIDARG;
936
937 if (llBytes < 1024) /* 1K */
938 {
939 WCHAR wszBytesFormat[64];
940 LoadStringW(shlwapi_hInstance, IDS_BYTES_FORMAT, wszBytesFormat, 64);
941 swprintf(lpszDest, cchMax, wszBytesFormat, (int)llBytes);
942 return S_OK;
943 }
944
945 /* Note that if this loop completes without finding a match, i will be
946 * pointing at the last entry, which is a catch all for > 1000 PB
947 */
948 while (i < ARRAY_SIZE(bfFormats) - 1)
949 {
950 if (llBytes < bfFormats[i].dLimit)
951 break;
952 i++;
953 }
954 /* Above 1 TB we encounter problems with FP accuracy. So for amounts above
955 * this number we integer shift down by 1 MB first. The table above has
956 * the divisors scaled down from the '< 10 TB' entry onwards, to account
957 * for this. We also add a small fudge factor to get the correct result for
958 * counts that lie exactly on a 1024 byte boundary.
959 */
960 if (i > 8)
961 dBytes = (double)(llBytes >> 20) + 0.001; /* Scale down by 1 MB */
962 else
963 dBytes = (double)llBytes + 0.00001;
964
965 switch(flags)
966 {
968 dBytes = round(dBytes / bfFormats[i].dDivisor) / bfFormats[i].dNormaliser;
969 break;
971 dBytes = floor(dBytes / bfFormats[i].dDivisor) / bfFormats[i].dNormaliser;
972 break;
973 default:
974 return E_INVALIDARG;
975 }
976
977#ifdef __REACTOS__
978 if (!FormatDouble(dBytes, bfFormats[i].nDecimals, szBuff, ARRAYSIZE(szBuff)))
979 return E_FAIL;
980 LoadStringW(shlwapi_hInstance, bfFormats[i].nFormatID, wszFormat, ARRAYSIZE(wszFormat));
981 snprintfW(lpszDest, cchMax, wszFormat, szBuff);
982#else
983 if (!FormatDouble(dBytes, bfFormats[i].nDecimals, lpszDest, cchMax))
984 return E_FAIL;
985
986 wszAdd[1] = bfFormats[i].wPrefix;
987 StrCatBuffW(lpszDest, wszAdd, cchMax);
988#endif
989 return S_OK;
990}
991
992/*************************************************************************
993 * StrFormatByteSize64A [SHLWAPI.@]
994 *
995 * See StrFormatByteSizeW.
996 */
998{
999 WCHAR wszBuff[32];
1000
1001 StrFormatByteSizeW(llBytes, wszBuff, ARRAY_SIZE(wszBuff));
1002
1003 if (lpszDest)
1004 WideCharToMultiByte(CP_ACP, 0, wszBuff, -1, lpszDest, cchMax, 0, 0);
1005 return lpszDest;
1006}
1007
1008/*************************************************************************
1009 * StrFormatByteSizeA [SHLWAPI.@]
1010 *
1011 * Create a string containing an abbreviated byte count of up to 2^31-1.
1012 *
1013 * PARAMS
1014 * dwBytes [I] Byte size to format
1015 * lpszDest [I] Destination for formatted string
1016 * cchMax [I] Size of lpszDest
1017 *
1018 * RETURNS
1019 * lpszDest.
1020 *
1021 * NOTES
1022 * The ANSI and Unicode versions of this function accept a different
1023 * integer type for dwBytes. See StrFormatByteSize64A().
1024 */
1026{
1027 TRACE("(%ld,%p,%d)\n", dwBytes, lpszDest, cchMax);
1028
1029 return StrFormatByteSize64A(dwBytes, lpszDest, cchMax);
1030}
1031
1032/*************************************************************************
1033 * @ [SHLWAPI.203]
1034 *
1035 * Remove a single non-trailing ampersand ('&') from a string.
1036 *
1037 * PARAMS
1038 * lpszStr [I/O] String to remove ampersand from.
1039 *
1040 * RETURNS
1041 * The character after the first ampersand in lpszStr, or the first character
1042 * in lpszStr if there is no ampersand in the string.
1043 */
1045{
1046 LPSTR lpszIter, lpszTmp;
1047 char ch;
1048
1049 TRACE("(%s)\n", debugstr_a(lpszStr));
1050
1051 ch = *lpszStr;
1052
1053 if ((lpszIter = StrChrA(lpszStr, '&')))
1054 {
1055 lpszTmp = CharNextA(lpszIter);
1056 if (*lpszTmp)
1057 {
1058 if (*lpszTmp != '&')
1059 ch = *lpszTmp;
1060
1061 memmove( lpszIter, lpszTmp, strlen(lpszTmp) + 1 );
1062 }
1063 }
1064
1065 return ch;
1066}
1067
1068/*************************************************************************
1069 * @ [SHLWAPI.225]
1070 *
1071 * Unicode version of SHStripMneumonicA.
1072 */
1074{
1075 LPWSTR lpszIter, lpszTmp;
1076 WCHAR ch;
1077
1078 TRACE("(%s)\n", debugstr_w(lpszStr));
1079
1080 ch = *lpszStr;
1081
1082 if ((lpszIter = StrChrW(lpszStr, '&')))
1083 {
1084 lpszTmp = lpszIter + 1;
1085 if (*lpszTmp)
1086 {
1087 if (*lpszTmp != '&')
1088 ch = *lpszTmp;
1089
1090 memmove( lpszIter, lpszTmp, (lstrlenW(lpszTmp) + 1) * sizeof(WCHAR) );
1091 }
1092 }
1093
1094 return ch;
1095}
1096
1097/*************************************************************************
1098 * @ [SHLWAPI.216]
1099 *
1100 * Convert an ANSI string to Unicode.
1101 *
1102 * PARAMS
1103 * dwCp [I] Code page for the conversion
1104 * lpSrcStr [I] Source ANSI string to convert
1105 * lpDstStr [O] Destination for converted Unicode string
1106 * iLen [I] Length of lpDstStr
1107 *
1108 * RETURNS
1109 * The return value of the MultiByteToWideChar() function called on lpSrcStr.
1110 */
1111DWORD WINAPI SHAnsiToUnicodeCP(DWORD dwCp, LPCSTR lpSrcStr, LPWSTR lpDstStr, int iLen)
1112{
1113 DWORD dwRet;
1114
1115 dwRet = MultiByteToWideChar(dwCp, 0, lpSrcStr, -1, lpDstStr, iLen);
1116 TRACE("%s->%s,ret=%ld\n", debugstr_a(lpSrcStr), debugstr_w(lpDstStr), dwRet);
1117 return dwRet;
1118}
1119
1120/*************************************************************************
1121 * @ [SHLWAPI.215]
1122 *
1123 * Convert an ANSI string to Unicode.
1124 *
1125 * PARAMS
1126 * lpSrcStr [I] Source ANSI string to convert
1127 * lpDstStr [O] Destination for converted Unicode string
1128 * iLen [I] Length of lpDstStr
1129 *
1130 * RETURNS
1131 * The return value of the MultiByteToWideChar() function called on lpSrcStr.
1132 *
1133 * NOTES
1134 * This function simply calls SHAnsiToUnicodeCP with code page CP_ACP.
1135 */
1136DWORD WINAPI SHAnsiToUnicode(LPCSTR lpSrcStr, LPWSTR lpDstStr, int iLen)
1137{
1138 return SHAnsiToUnicodeCP(CP_ACP, lpSrcStr, lpDstStr, iLen);
1139}
1140
1141/*************************************************************************
1142 * @ [SHLWAPI.218]
1143 *
1144 * Convert a Unicode string to ANSI.
1145 *
1146 * PARAMS
1147 * CodePage [I] Code page to use for the conversion
1148 * lpSrcStr [I] Source Unicode string to convert
1149 * lpDstStr [O] Destination for converted ANSI string
1150 * dstlen [I] Length of buffer at lpDstStr
1151 *
1152 * RETURNS
1153 * Success: The length in bytes of the result at lpDstStr (including the terminator)
1154 * Failure: When using CP_UTF8, CP_UTF7 or 0xc350 as codePage, 0 is returned and
1155 * the result is not nul-terminated.
1156 * When using a different codepage, the length in bytes of the truncated
1157 * result at lpDstStr (including the terminator) is returned and
1158 * lpDstStr is always nul-terminated.
1159 *
1160 */
1161DWORD WINAPI SHUnicodeToAnsiCP(UINT CodePage, LPCWSTR lpSrcStr, LPSTR lpDstStr, int dstlen)
1162{
1163 static const WCHAR emptyW[] = { '\0' };
1164 int len , reqLen;
1165 LPSTR mem;
1166
1167 if (!lpDstStr || !dstlen)
1168 return 0;
1169
1170 if (!lpSrcStr)
1171 lpSrcStr = emptyW;
1172
1173 *lpDstStr = '\0';
1174
1175 len = lstrlenW(lpSrcStr) + 1;
1176
1177 switch (CodePage)
1178 {
1179 case CP_WINUNICODE:
1180 CodePage = CP_UTF8; /* Fall through... */
1181 case 0x0000C350: /* FIXME: CP_ #define */
1182 case CP_UTF7:
1183 case CP_UTF8:
1184 {
1185 DWORD dwMode = 0;
1186 INT lenW = len - 1;
1187 INT needed = dstlen - 1;
1188 HRESULT hr;
1189
1190 /* try the user supplied buffer first */
1191 hr = ConvertINetUnicodeToMultiByte(&dwMode, CodePage, lpSrcStr, &lenW, lpDstStr, &needed);
1192 if (hr == S_OK)
1193 {
1194 lpDstStr[needed] = '\0';
1195 return needed + 1;
1196 }
1197
1198 /* user buffer too small. exclude termination and copy as much as possible */
1199 lenW = len;
1200 hr = ConvertINetUnicodeToMultiByte(&dwMode, CodePage, lpSrcStr, &lenW, NULL, &needed);
1201 needed++;
1202 mem = malloc(needed);
1203 if (!mem)
1204 return 0;
1205
1206 hr = ConvertINetUnicodeToMultiByte(&dwMode, CodePage, lpSrcStr, &len, mem, &needed);
1207 if (hr == S_OK)
1208 {
1209 reqLen = SHTruncateString(mem, dstlen);
1210 if (reqLen > 0) memcpy(lpDstStr, mem, reqLen-1);
1211 }
1212 free(mem);
1213 return 0;
1214 }
1215 default:
1216 break;
1217 }
1218
1219 /* try the user supplied buffer first */
1220 reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, lpDstStr, dstlen, NULL, NULL);
1221
1222 if (!reqLen && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1223 {
1224 reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, NULL, 0, NULL, NULL);
1225 if (reqLen)
1226 {
1227 mem = malloc(reqLen);
1228 if (mem)
1229 {
1230 WideCharToMultiByte(CodePage, 0, lpSrcStr, len, mem, reqLen, NULL, NULL);
1231
1232 reqLen = SHTruncateString(mem, dstlen -1);
1233 reqLen++;
1234
1235 lstrcpynA(lpDstStr, mem, reqLen);
1236 free(mem);
1237 lpDstStr[reqLen-1] = '\0';
1238 }
1239 }
1240 }
1241 return reqLen;
1242}
1243
1244/*************************************************************************
1245 * @ [SHLWAPI.217]
1246 *
1247 * Convert a Unicode string to ANSI.
1248 *
1249 * PARAMS
1250 * lpSrcStr [I] Source Unicode string to convert
1251 * lpDstStr [O] Destination for converted ANSI string
1252 * iLen [O] Length of lpDstStr in characters
1253 *
1254 * RETURNS
1255 * See SHUnicodeToAnsiCP
1256
1257 * NOTES
1258 * This function simply calls SHUnicodeToAnsiCP() with CodePage = CP_ACP.
1259 */
1260INT WINAPI SHUnicodeToAnsi(LPCWSTR lpSrcStr, LPSTR lpDstStr, INT iLen)
1261{
1262 return SHUnicodeToAnsiCP(CP_ACP, lpSrcStr, lpDstStr, iLen);
1263}
1264
1265/*************************************************************************
1266 * @ [SHLWAPI.364]
1267 *
1268 * Determine if an ANSI string converts to Unicode and back identically.
1269 *
1270 * PARAMS
1271 * lpSrcStr [I] Source Unicode string to convert
1272 * lpDst [O] Destination for resulting ANSI string
1273 * iLen [I] Length of lpDst in characters
1274 *
1275 * RETURNS
1276 * TRUE, since ANSI strings always convert identically.
1277 */
1279{
1280 lstrcpynA(lpDst, lpSrcStr, iLen);
1281 return TRUE;
1282}
1283
1284/*************************************************************************
1285 * @ [SHLWAPI.365]
1286 *
1287 * Determine if a Unicode string converts to ANSI and back identically.
1288 *
1289 * PARAMS
1290 * lpSrcStr [I] Source Unicode string to convert
1291 * lpDst [O] Destination for resulting ANSI string
1292 * iLen [I] Length of lpDst in characters
1293 *
1294 * RETURNS
1295 * TRUE, if lpSrcStr converts to ANSI and back identically,
1296 * FALSE otherwise.
1297 */
1299{
1300 WCHAR szBuff[MAX_PATH];
1301
1302 SHUnicodeToAnsi(lpSrcStr, lpDst, iLen);
1303 SHAnsiToUnicode(lpDst, szBuff, MAX_PATH);
1304 return !wcscmp(lpSrcStr, szBuff);
1305}
1306
UINT cchMax
WCHAR lpszDest[260]
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define IDS_BYTES_FORMAT
Definition: resource.h:122
void shell(int argc, const char *argv[])
Definition: cmds.c:1231
#define ARRAY_SIZE(A)
Definition: main.h:20
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define CP_WINUNICODE
Definition: ddeml.h:33
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
HRESULT hr
Definition: delayimp.cpp:582
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
void *WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: malloc.c:381
void WINAPI CoTaskMemFree(void *ptr)
Definition: malloc.c:389
LPWSTR WINAPI StrChrW(LPCWSTR lpszStr, WCHAR ch)
Definition: string.c:464
LPSTR WINAPI StrChrA(LPCSTR lpszStr, WORD ch)
Definition: string.c:266
#define CP_ACP
Definition: compat.h:109
#define lstrcpynA
Definition: compat.h:751
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
OLECHAR * BSTR
Definition: compat.h:2293
#define MAX_PATH
Definition: compat.h:34
#define lstrcpyW
Definition: compat.h:749
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
INT WINAPI GetLocaleInfoW(LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len)
Definition: locale.c:1675
LPSTR WINAPI CharNextA(const char *ptr)
Definition: string.c:1151
WCHAR *WINAPI StrCatBuffW(WCHAR *str, const WCHAR *cat, INT max_len)
Definition: string.c:1434
DWORD WINAPI SHTruncateString(char *str, DWORD size)
Definition: string.c:1478
WCHAR *WINAPI StrCpyNW(WCHAR *dst, const WCHAR *src, int count)
Definition: string.c:470
unsigned char ch[4][2]
Definition: console.c:118
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1977
_ACRTIMP double __cdecl floor(double)
Definition: floor.c:18
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1597
#define IDS_TIME_INTERVAL_MINUTES
Definition: resource.h:28
#define IDS_TIME_INTERVAL_HOURS
Definition: resource.h:27
#define IDS_TIME_INTERVAL_SECONDS
Definition: resource.h:29
static HRESULT _SHStrDupAToBSTR(LPCSTR src, BSTR *pBstrOut)
Definition: string.c:382
HRESULT WINAPI SHStrDupW(LPCWSTR src, LPWSTR *dest)
Definition: string.c:647
INT WINAPI StrFromTimeIntervalW(LPWSTR lpszStr, UINT cchMax, DWORD dwMS, int iDigits)
Definition: string.c:782
#define KB
struct tagSHLWAPI_BYTEFORMATS SHLWAPI_BYTEFORMATS
WCHAR WINAPI SHStripMneumonicW(LPCWSTR lpszStr)
Definition: string.c:1073
LPSTR WINAPI StrNCatA(LPSTR lpszStr, LPCSTR lpszCat, INT cchMax)
Definition: string.c:510
LPSTR WINAPI StrFormatByteSize64A(LONGLONG llBytes, LPSTR lpszDest, UINT cchMax)
Definition: string.c:997
DWORD WINAPI SHAnsiToUnicode(LPCSTR lpSrcStr, LPWSTR lpDstStr, int iLen)
Definition: string.c:1136
#define PB
INT WINAPI SHUnicodeToAnsi(LPCWSTR lpSrcStr, LPSTR lpDstStr, INT iLen)
Definition: string.c:1260
LPWSTR WINAPI StrFormatKBSizeW(LONGLONG llBytes, LPWSTR lpszDest, UINT cchMax)
Definition: string.c:475
#define TB
#define GB
LPWSTR WINAPI StrCatW(LPWSTR lpszStr, LPCWSTR lpszSrc)
Definition: string.c:151
HRESULT WINAPI SHStrDupA(LPCSTR lpszStr, LPWSTR *lppszDest)
Definition: string.c:589
LPSTR WINAPI StrFormatByteSizeA(DWORD dwBytes, LPSTR lpszDest, UINT cchMax)
Definition: string.c:1025
INT WINAPI StrFromTimeIntervalA(LPSTR lpszStr, UINT cchMax, DWORD dwMS, int iDigits)
Definition: string.c:760
char WINAPI SHStripMneumonicA(LPCSTR lpszStr)
Definition: string.c:1044
LPWSTR WINAPI StrFormatByteSizeW(LONGLONG llBytes, LPWSTR lpszDest, UINT cchMax)
Definition: string.c:854
HRESULT WINAPI StrRetToBSTR(STRRET *lpStrRet, LPCITEMIDLIST pidl, BSTR *pBstrOut)
Definition: string.c:418
static int FormatInt(LONGLONG qdwValue, LPWSTR pszBuf, int cchBuf)
Definition: string.c:92
HRESULT WINAPI StrRetToBufW(LPSTRRET src, const ITEMIDLIST *pidl, LPWSTR dest, UINT len)
Definition: string.c:248
BOOL WINAPI DoesStringRoundTripW(LPCWSTR lpSrcStr, LPSTR lpDst, INT iLen)
Definition: string.c:1298
static HRESULT _SHStrDupAA(LPCSTR, LPSTR *)
Definition: string.c:552
HRESULT WINAPI StrFormatByteSizeEx(LONGLONG llBytes, SFBS_FLAGS flags, LPWSTR lpszDest, UINT cchMax)
Definition: string.c:877
LPWSTR WINAPI StrNCatW(LPWSTR lpszStr, LPCWSTR lpszCat, INT cchMax)
Definition: string.c:531
HRESULT WINAPI StrRetToStrA(LPSTRRET lpStrRet, const ITEMIDLIST *pidl, LPSTR *ppszName)
Definition: string.c:318
static int SHLWAPI_FormatSignificant(LPWSTR lpszNum, int dwDigits)
Definition: string.c:695
HRESULT WINAPI StrRetToStrW(LPSTRRET lpStrRet, const ITEMIDLIST *pidl, LPWSTR *ppszName)
Definition: string.c:349
#define MB
static LPWSTR SHLWAPI_WriteReverseNum(LPWSTR lpszOut, DWORD dwNum)
Definition: string.c:675
HINSTANCE shlwapi_hInstance
Definition: shlwapi_main.c:33
static HRESULT _SHStrDupAW(LPCWSTR, LPSTR *)
Definition: string.c:619
BOOL WINAPI DoesStringRoundTripA(LPCSTR lpSrcStr, LPSTR lpDst, INT iLen)
Definition: string.c:1278
LPWSTR WINAPI StrCpyW(LPWSTR lpszStr, LPCWSTR lpszSrc)
Definition: string.c:173
static void FillNumberFmt(NUMBERFMTW *fmt, LPWSTR decimal_buffer, int decimal_bufwlen, LPWSTR thousand_buffer, int thousand_bufwlen)
Definition: string.c:51
DWORD WINAPI SHAnsiToUnicodeCP(DWORD dwCp, LPCSTR lpSrcStr, LPWSTR lpDstStr, int iLen)
Definition: string.c:1111
LPSTR WINAPI StrFormatKBSizeA(LONGLONG llBytes, LPSTR lpszDest, UINT cchMax)
Definition: string.c:459
HRESULT WINAPI StrRetToBufA(LPSTRRET src, const ITEMIDLIST *pidl, LPSTR dest, UINT len)
Definition: string.c:199
DWORD WINAPI SHUnicodeToAnsiCP(UINT CodePage, LPCWSTR lpSrcStr, LPSTR lpDstStr, int dstlen)
Definition: string.c:1161
static int SHLWAPI_WriteTimeClass(LPWSTR lpszOut, DWORD dwValue, UINT uClassStringId, int iDigits)
Definition: string.c:716
static int FormatDouble(double value, int decimals, LPWSTR pszBuf, int cchBuf)
Definition: string.c:124
#define swprintf
Definition: precomp.h:40
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLenum src
Definition: glext.h:6340
GLsizeiptr size
Definition: glext.h:5919
const GLubyte * c
Definition: glext.h:8905
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLbitfield flags
Definition: glext.h:7161
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static const WCHAR emptyW[]
Definition: navigate.c:40
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
#define c
Definition: ke_i.h:80
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
INT WINAPI GetNumberFormatW(LCID lcid, DWORD dwFlags, LPCWSTR lpszValue, const NUMBERFMTW *lpFormat, LPWSTR lpNumberStr, int cchOut)
Definition: lcformat.c:1130
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:91
static DWORD dstlen
Definition: directory.c:51
static char * dest
Definition: rtl.c:149
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
#define LOCALE_USER_DEFAULT
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
#define round(x)
Definition: opentype.c:47
short WCHAR
Definition: pedump.c:58
@ SFBS_FLAGS_TRUNCATE_UNDISPLAYED_DECIMAL_DIGITS
Definition: shlwapi.h:1265
@ SFBS_FLAGS_ROUND_TO_NEAREST_DISPLAYED_DIGIT
Definition: shlwapi.h:1264
#define StrCpyNA
Definition: shlwapi.h:1104
_In_ UINT cchBuf
Definition: shlwapi.h:378
#define CP_UTF8
Definition: nls.h:20
#define LoadStringW
Definition: utils.h:64
SIGDN PWSTR * ppszName
Definition: shobjidl.idl:606
@ STRRET_CSTR
Definition: shtypes.idl:87
@ STRRET_OFFSET
Definition: shtypes.idl:86
@ STRRET_WSTR
Definition: shtypes.idl:85
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
#define TRACE(s)
Definition: solgame.cpp:4
SHITEMID mkid
Definition: shtypes.idl:34
char cStr[MAX_PATH]
Definition: shtypes.idl:98
UINT uType
Definition: shtypes.idl:93
LPWSTR pOleStr
Definition: shtypes.idl:96
UINT uOffset
Definition: shtypes.idl:97
Definition: dsound.c:943
Definition: mem.c:349
const char * LPCSTR
Definition: typedefs.h:52
const uint16_t * LPCWSTR
Definition: typedefs.h:57
uint16_t * LPWSTR
Definition: typedefs.h:56
int64_t LONGLONG
Definition: typedefs.h:68
char * LPSTR
Definition: typedefs.h:51
int32_t INT
Definition: typedefs.h:58
Definition: pdh_main.c:96
static CONVERTINETUNICODETOMULTIBYTE ConvertINetUnicodeToMultiByte
Definition: win_iconv.c:706
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define WINAPI
Definition: msvc.h:6
SFBS_FLAGS
Definition: shlwapi.h:869
#define snprintfW
Definition: unicode.h:60
#define E_NOT_SUFFICIENT_BUFFER
Definition: winerror.h:3437
#define LOCALE_SGROUPING
Definition: winnls.h:54
#define LOCALE_SDECIMAL
Definition: winnls.h:52
#define CP_UTF7
Definition: winnls.h:263
#define LOCALE_STHOUSAND
Definition: winnls.h:53
#define LOCALE_INEGNUMBER
Definition: winnls.h:57
#define LOCALE_ILZERO
Definition: winnls.h:56