ReactOS 0.4.16-dev-822-gbcedb53
corecrt_internal_win32_buffer.h
Go to the documentation of this file.
1//
2// corecrt_internal_win32_buffer.h
3//
4// Copyright (c) Microsoft Corporation. All rights reserved.
5//
6// This internal header defines template-based utilities for handling call-twice
7// Win32 APIs, where you first call the Win32 API with null or a fixed sized buffer,
8// and if there is not enough space, allocate a dynamically sized buffer.
9#pragma once
10#include <corecrt_internal.h>
11
12#pragma pack(push, _CRT_PACKING)
13
14//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
15//
16// __crt_win32_buffer_debug_info
17//
18//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
19// This is a class that can be used to describe the block_use, file_name, line_number
20// debug data that is sometimes shuffled around between function calls.
21
23{
24#ifndef _DEBUG
25public:
26 __crt_win32_buffer_debug_info(int, char const *, int)
27 {
28 }
29#else /* ^^^^ Release ^^^^ / vvvv Debug vvvv */
30public:
32 int const initial_block_use,
33 char const * const initial_file_name,
34 int const initial_line_number
35 )
36 : _block_use(initial_block_use),
37 _file_name(initial_file_name),
38 _line_number(initial_line_number)
39 {
40 }
41
42 int block_use() const
43 {
44 return _block_use;
45 }
46
47 char const * file_name() const
48 {
49 return _file_name;
50 }
51
52 int line_number() const
53 {
54 return _line_number;
55 }
56
57private:
58 int _block_use;
59 char const * _file_name;
60 int _line_number;
61#endif /* _DEBUG */
62};
63
65{
66};
67
68//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
69//
70// __crt_win32_buffer resize policies
71//
72//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
73// These classes are used to describe the different resize policies that a
74// __crt_win32_buffer can have.
75
77{
79
81 static errno_t allocate(void ** const address, size_t const size, debug_info_type const&)
82 {
83 void * const ret = _malloc_crt(size);
84 *address = ret;
85 if (ret == nullptr) {
86 return ENOMEM;
87 }
88 return 0;
89 }
90
91 static void deallocate(void * const ptr, debug_info_type const&)
92 {
94 }
95};
96
98{
100
102 static errno_t allocate(void ** const address, size_t const size, debug_info_type const& debug_info)
103 {
104 UNREFERENCED_PARAMETER(debug_info); // only used in debug mode
105 void * const ret = _malloc_dbg(
106 size,
107 debug_info.block_use(),
108 debug_info.file_name(),
109 debug_info.line_number()
110 );
111 *address = ret;
112 if (ret == nullptr) {
113 return ENOMEM;
114 }
115 return 0;
116 }
117
118 static void deallocate(void * const ptr, debug_info_type const& debug_info)
119 {
120 UNREFERENCED_PARAMETER(debug_info); // only used in debug mode
121 _free_dbg(ptr, debug_info.block_use());
122 }
123};
124
126{
128
130 static errno_t allocate(void ** const, size_t const, debug_info_type const&)
131 {
132 errno = ERANGE; // buffer not large enough
133 return ERANGE;
134 }
135
136 static void deallocate(void * const, debug_info_type const&)
137 {
138 }
139};
140
141//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
142//
143// __crt_win32_buffer, __crt_internal_win32_buffer
144// __crt_public_win32_buffer, __crt_no_alloc_win32_buffer
145//
146//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
147// Class and typedefs for buffers that support calling a win32 function and automatically
148// resizing if needed.
149
150template <typename Character, typename ResizePolicy>
151class __crt_win32_buffer : private ResizePolicy::debug_info_type
152{ // Buffer type to enable Win32 call-twice-if-not-enough-space APIs.
153 // Using this type allows us to use a local buffer if possible and allocate if needed.
154public:
155 using char_type = Character;
156 using debug_info_type = typename ResizePolicy::debug_info_type;
157
159 : debug_info_type(),
163 _capacity(0),
164 _size(0),
166
167 {
168 }
169
175 _capacity(0),
176 _size(0),
178
179 {
180 }
181
182 template <size_t N>
184 : debug_info_type(),
188 _capacity(N),
189 _size(0),
191 {
192 }
193
194 template <size_t N>
200 _capacity(N),
201 _size(0),
203 {
204 }
205
207 Character * const buffer,
208 size_t const buffer_capacity
209 )
210 : debug_info_type(),
212 _initial_capacity(buffer_capacity),
214 _capacity(buffer_capacity),
215 _size(0),
217 {
218 }
219
221 Character * const buffer,
222 size_t const buffer_capacity,
224 )
227 _initial_capacity(buffer_capacity),
229 _capacity(buffer_capacity),
230 _size(0),
232 {
233 }
234
236 {
237 _deallocate();
238 }
239
242
245
247 {
248 return _string;
249 }
250
251 char_type const * data() const
252 {
253 return _string;
254 }
255
256 size_t size() const
257 {
258 return _size;
259 }
260
261 void size(size_t new_size)
262 {
263 _size = new_size;
264 }
265
266 size_t capacity() const
267 {
268 return _capacity;
269 }
270
271 void reset()
272 {
273 _deallocate();
275 }
276
278 {
279 if (_string == nullptr || _size == 0) {
280 return nullptr;
281 }
282
283 char_type * return_val{};
284
285 if (!_is_dynamic && _size > 0) {
286 // This pointer needs to live longer than the stack buffer
287 // Allocate + Copy
288 ResizePolicy::allocate(
289 reinterpret_cast<void **>(&return_val),
290 _size * sizeof(Character),
291 debug_info()
292 );
293 memcpy_s(return_val, _size, _string, _capacity);
294 } else {
295 return_val = _string;
296 }
297
299 return return_val;
300 }
301
302 template <typename Win32Function>
303 errno_t call_win32_function(Win32Function const& win32_function)
304 { // Suitable for more Win32 calls, where a size is returned
305 // if there is not enough space.
306
307 size_t const required_size = win32_function(_string, static_cast<DWORD>(_capacity));
308 if (required_size == 0) {
310 return errno;
311 }
312
313 if (required_size <= _capacity) {
314 // Had enough space, data was written, save size and return
315 _size = required_size;
316 return 0;
317 }
318
319 size_t const required_size_plus_null_terminator = required_size + 1;
320
321 errno_t const alloc_err = allocate(required_size_plus_null_terminator);
322 if (alloc_err)
323 {
324 return alloc_err;
325 }
326
327 // Upon success, return value is number of characters written, minus the null terminator.
328 size_t const required_size2 = win32_function(_string, static_cast<DWORD>(_capacity));
329 if (required_size2 == 0) {
331 return errno;
332 }
333
334 // Capacity should be large enough at this point.
335 _size = required_size2;
336 return 0;
337 }
338
340 {
341 return static_cast<debug_info_type const&>(*this);
342 }
343
345 {
346 _deallocate();
347
348 errno_t err = ResizePolicy::allocate(
349 reinterpret_cast<void **>(&_string),
350 requested_size * sizeof(Character),
351 debug_info()
352 );
353
354 if (err) {
355 _is_dynamic = false;
356 _capacity = 0;
357 return err;
358 }
359
360 _is_dynamic = true;
362 return 0;
363 }
364
366 {
367 _deallocate();
368
369 _string = nullptr;
370 _capacity = 0;
371 _size = 0;
372 }
373
374private:
376 {
379 _size = 0;
380 }
381
383 {
384 if (_is_dynamic) {
385 ResizePolicy::deallocate(_string, debug_info());
386 _is_dynamic = false;
387 }
388 }
389
393 size_t _capacity;
394 size_t _size;
396};
397
398template <typename Character>
400
401template <typename Character>
403
404template <typename Character>
406
407//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
408//
409// UTF-8 or ACP Helper
410//
411// Some POSIX functions have historically used the ACP for doing narrow->wide
412// conversions. In order to support UTF-8 with these functions, they've been
413// modified so that they use CP_UTF8 when current locale is UTF-8, but the ACP
414// otherwise in order to preserve backwards compatibility.
415//
416// These POSIX functions can call __acrt_get_utf8_acp_compatibility_codepage to grab
417// the code page they should use for their conversions.
418//
419// The Win32 ANSI "*A" APIs also use this to preserve their behavior as using the ACP, unless
420// the current locale is set to UTF-8.
421//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
423{
424 _LocaleUpdate locale_update(nullptr);
425 unsigned int const current_code_page = locale_update.GetLocaleT()->locinfo->_public._locale_lc_codepage;
426
427 if (current_code_page == CP_UTF8) {
428 return CP_UTF8;
429 }
430
431 bool const use_oem_code_page = !__acrt_AreFileApisANSI();
432
433 if (use_oem_code_page) {
434 return CP_OEMCP;
435 }
436
437 return CP_ACP;
438}
439
440//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
441//
442// Win32 APIs using __crt_win32_buffer
443//
444//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
445// See complete list of internal conversion functions in corecrt_internal_traits.h
446
447template <typename FromChar, typename ToChar, typename CvtFunction, typename ResizePolicy>
449 FromChar const * const null_terminated_input_string,
451 CvtFunction const& cvt_func,
453 )
454{
455 // Common code path for conversions using mbstowcs and wcstombs.
456 if (null_terminated_input_string == nullptr) {
457 win32_buffer.set_to_nullptr();
458 return 0;
459 }
460
461 // No empty string special case - mbstowcs/wcstombs handles them.
462 size_t const required_size = cvt_func(nullptr, null_terminated_input_string, 0, locale);
463
464 if (required_size == static_cast<size_t>(-1)) {
465 return errno;
466 }
467
468 size_t const required_size_plus_null_terminator = required_size + 1;
469
470 if (required_size_plus_null_terminator > win32_buffer.capacity()) {
471 errno_t const alloc_err = win32_buffer.allocate(required_size_plus_null_terminator);
472 if (alloc_err != 0) {
473 return alloc_err;
474 }
475 }
476
477 size_t const chars_converted = cvt_func(win32_buffer.data(), null_terminated_input_string, win32_buffer.capacity(), locale);
478 if (chars_converted == static_cast<size_t>(-1) || chars_converted == win32_buffer.capacity()) {
479 // check for error or if output is not null terminated
480 return errno;
481 }
482
483 win32_buffer.size(chars_converted);
484 return 0;
485}
486
487template <typename FromChar, typename ToChar, typename CvtFunction, typename ResizePolicy>
489 FromChar const * const null_terminated_input_string,
491 CvtFunction const& cvt_func,
492 unsigned int const code_page
493 )
494{
495 // Common code path for conversions using MultiByteToWideChar and WideCharToMultiByte with null terminated inputs.
496 if (null_terminated_input_string == nullptr) {
497 win32_buffer.set_to_nullptr();
498 return 0;
499 }
500
501 // Special Case: Empty strings are not valid input to MultiByteToWideChar/WideCharToMultiByte
502 if (null_terminated_input_string[0] == '\0') {
503 if (win32_buffer.capacity() == 0) {
504 errno_t alloc_err = win32_buffer.allocate(1);
505 if (alloc_err != 0) {
506 return alloc_err;
507 }
508 }
509
510 win32_buffer.data()[0] = '\0';
511 win32_buffer.size(0);
512 return 0;
513 }
514
515 size_t const required_size_plus_null_terminator = cvt_func(
516 code_page,
517 null_terminated_input_string,
518 nullptr,
519 0
520 );
521
522 if (required_size_plus_null_terminator == 0) {
524 return errno;
525 }
526
527 if (required_size_plus_null_terminator > win32_buffer.capacity()) {
528 errno_t alloc_err = win32_buffer.allocate(required_size_plus_null_terminator);
529 if (alloc_err != 0) {
530 return alloc_err;
531 }
532 }
533
534 size_t const chars_converted_plus_null_terminator = cvt_func(
535 code_page,
536 null_terminated_input_string,
537 win32_buffer.data(),
538 win32_buffer.capacity()
539 );
540
541 if (chars_converted_plus_null_terminator == 0) {
543 return errno;
544 }
545
546 win32_buffer.size(chars_converted_plus_null_terminator - 1); // size does not include the null terminator
547 return 0;
548}
549
550template <typename ResizePolicy>
552 wchar_t const * const null_terminated_input_string,
554 _locale_t locale = nullptr
555 )
556{
559 null_terminated_input_string,
560 win32_buffer,
562 locale
563 );
565}
566
567template <typename ResizePolicy>
569 wchar_t const * const null_terminated_input_string,
571 unsigned int const code_page
572 )
573{
574 auto const wcs_to_mbs = [](
575 unsigned int const code_page,
576 wchar_t const * const null_terminated_input_string,
577 char * const buffer,
578 size_t const buffer_size)
579 {
580 // Return value includes null terminator.
582 code_page,
583 0,
584 null_terminated_input_string,
585 -1,
586 buffer,
587 static_cast<int>(buffer_size),
588 nullptr,
589 nullptr
590 );
591 };
592
594 null_terminated_input_string,
595 win32_buffer,
596 wcs_to_mbs,
598 );
599}
600
601template <typename ResizePolicy>
603 char const * const null_terminated_input_string,
605 _locale_t locale = nullptr
606 )
607{
610 null_terminated_input_string,
611 win32_buffer,
613 locale
614 );
616}
617
618template <typename ResizePolicy>
620 char const * const null_terminated_input_string,
622 unsigned int const code_page
623 )
624{
625 auto const mbs_to_wcs = [](
626 unsigned int const code_page,
627 char const * const null_terminated_input_string,
628 wchar_t * const buffer,
629 size_t const buffer_size)
630 {
631 // Return value includes null terminator.
632 return __acrt_MultiByteToWideChar(
633 code_page,
635 null_terminated_input_string,
636 -1,
637 buffer,
638 static_cast<int>(buffer_size)
639 );
640 };
641
643 null_terminated_input_string,
644 win32_buffer,
645 mbs_to_wcs,
647 );
648}
649
650// Array overloads are useful for __try contexts where objects with unwind semantics cannot be used.
651template <size_t N>
653 wchar_t const * const null_terminated_input_string,
654 char (&buffer)[N],
655 _locale_t locale = nullptr
656 )
657{
659 if (__acrt_wcs_to_mbs(null_terminated_input_string, win32_buffer, locale) != 0) {
660 return 0;
661 }
662
663 return win32_buffer.size();
664}
665
666template <size_t N>
668 wchar_t const * const null_terminated_input_string,
669 char (&buffer)[N],
670 unsigned int const code_page
671 )
672{
674 if (__acrt_wcs_to_mbs_cp(null_terminated_input_string, win32_buffer, code_page) != 0) {
675 return 0;
676 }
677
678 return win32_buffer.size();
679}
680
681template <size_t N>
683 char const * const null_terminated_input_string,
684 wchar_t (&buffer)[N],
685 _locale_t locale = nullptr
686 )
687{
689 if (__acrt_mbs_to_wcs(null_terminated_input_string, win32_buffer, locale) != 0) {
690 return 0;
691 }
692
693 return win32_buffer.size();
694}
695
696template <size_t N>
698 char const * const null_terminated_input_string,
699 wchar_t (&buffer)[N],
700 unsigned int const code_page
701 )
702{
704 if (__acrt_mbs_to_wcs_cp(null_terminated_input_string, win32_buffer, code_page) != 0) {
705 return 0;
706 }
707
708 return win32_buffer.size();
709}
710
711template <typename ResizePolicy>
714 )
715{
716 return win32_buffer.call_win32_function([](wchar_t * buffer, DWORD buffer_length)
717 {
718 return ::GetCurrentDirectoryW(buffer_length, buffer);
719 });
720}
721
722template <typename ResizePolicy>
725 )
726{
727 wchar_t default_buffer_space[_MAX_PATH];
728 __crt_internal_win32_buffer<wchar_t> wide_buffer(default_buffer_space);
729
730 errno_t const err = __acrt_get_current_directory_wide(wide_buffer);
731
732 if (err != 0) {
733 return err;
734 }
735
737 wide_buffer.data(),
738 win32_buffer,
740 );
741}
742
743template <typename ResizePolicy>
745 wchar_t const * const lpFileName,
747 )
748{
749 return win32_buffer.call_win32_function([lpFileName](wchar_t * buffer, DWORD buffer_length)
750 {
751 return ::GetFullPathNameW(
753 buffer_length,
754 buffer,
755 nullptr
756 );
757 });
758}
759
760template <typename ResizePolicy>
762 char const * const lpFileName,
764 )
765{
766 wchar_t default_buffer_space[_MAX_PATH];
767 __crt_internal_win32_buffer<wchar_t> wide_buffer(default_buffer_space);
768
769 wchar_t default_file_name_space[_MAX_PATH];
770 __crt_internal_win32_buffer<wchar_t> wide_file_name(default_file_name_space);
771
773
774 errno_t const cvt_err = __acrt_mbs_to_wcs_cp(
776 wide_file_name,
778 );
779
780 if (cvt_err != 0)
781 {
782 return cvt_err;
783 }
784
785 errno_t const err = __acrt_get_full_path_name_wide(wide_file_name.data(), wide_buffer);
786
787 if (err != 0)
788 {
789 return err;
790 }
791
793 wide_buffer.data(),
794 win32_buffer,
796 );
797}
798
799#pragma pack(pop)
#define N
Definition: crc32.c:57
return __acrt_WideCharToMultiByte(code_page, 0, buffer.get(), -1, result_size !=0 ? result :nullptr, result_size, nullptr, nullptr)
#define ENOMEM
Definition: acclib.h:84
#define ERANGE
Definition: acclib.h:92
__crt_win32_buffer_debug_info(int, char const *, int)
typename ResizePolicy::debug_info_type debug_info_type
__crt_win32_buffer(__crt_win32_buffer &&)=delete
errno_t allocate(size_t requested_size)
__crt_win32_buffer(Character *const buffer, size_t const buffer_capacity, debug_info_type const &debug_info)
errno_t call_win32_function(Win32Function const &win32_function)
__crt_win32_buffer(debug_info_type const &debug_info)
__crt_win32_buffer & operator=(__crt_win32_buffer const &)=delete
char_type const * data() const
__crt_win32_buffer(Character(&buffer)[N])
debug_info_type const & debug_info() const
__crt_win32_buffer & operator=(__crt_win32_buffer &&)=delete
__crt_win32_buffer(Character(&buffer)[N], debug_info_type const &debug_info)
__crt_win32_buffer(Character *const buffer, size_t const buffer_capacity)
__crt_win32_buffer(__crt_win32_buffer const &)=delete
Definition: _locale.h:75
_Out_opt_ UINT * code_page
void __cdecl __acrt_errno_map_os_error(unsigned long)
Definition: errno.cpp:91
BOOL WINAPI __acrt_AreFileApisANSI(void)
errno_t __acrt_get_current_directory_narrow_acp_or_utf8(__crt_win32_buffer< char, ResizePolicy > &win32_buffer)
errno_t __acrt_mbs_to_wcs_cp(char const *const null_terminated_input_string, __crt_win32_buffer< wchar_t, ResizePolicy > &win32_buffer, unsigned int const code_page)
errno_t __acrt_wcs_to_mbs_cp(wchar_t const *const null_terminated_input_string, __crt_win32_buffer< char, ResizePolicy > &win32_buffer, unsigned int const code_page)
errno_t __acrt_get_full_path_name_narrow_acp_or_utf8(char const *const lpFileName, __crt_win32_buffer< char, ResizePolicy > &win32_buffer)
size_t __acrt_wcs_to_mbs_cp_array(wchar_t const *const null_terminated_input_string, char(&buffer)[N], unsigned int const code_page)
errno_t __acrt_get_full_path_name_wide(wchar_t const *const lpFileName, __crt_win32_buffer< wchar_t, ResizePolicy > &win32_buffer)
errno_t __acrt_mbs_to_wcs(char const *const null_terminated_input_string, __crt_win32_buffer< wchar_t, ResizePolicy > &win32_buffer, _locale_t locale=nullptr)
errno_t __acrt_convert_wcs_mbs(FromChar const *const null_terminated_input_string, __crt_win32_buffer< ToChar, ResizePolicy > &win32_buffer, CvtFunction const &cvt_func, _locale_t locale)
size_t __acrt_mbs_to_wcs_array(char const *const null_terminated_input_string, wchar_t(&buffer)[N], _locale_t locale=nullptr)
errno_t __acrt_wcs_to_mbs(wchar_t const *const null_terminated_input_string, __crt_win32_buffer< char, ResizePolicy > &win32_buffer, _locale_t locale=nullptr)
size_t __acrt_mbs_to_wcs_cp_array(char const *const null_terminated_input_string, wchar_t(&buffer)[N], unsigned int const code_page)
errno_t __acrt_get_current_directory_wide(__crt_win32_buffer< wchar_t, ResizePolicy > &win32_buffer)
size_t __acrt_wcs_to_mbs_array(wchar_t const *const null_terminated_input_string, char(&buffer)[N], _locale_t locale=nullptr)
errno_t __acrt_convert_wcs_mbs_cp(FromChar const *const null_terminated_input_string, __crt_win32_buffer< ToChar, ResizePolicy > &win32_buffer, CvtFunction const &cvt_func, unsigned int const code_page)
unsigned int __acrt_get_utf8_acp_compatibility_codepage()
#define _free_dbg(p, t)
Definition: crtdbg.h:209
#define _malloc_dbg(s, t, f, l)
Definition: crtdbg.h:204
size_t const requested_size
Definition: debug_heap.cpp:751
int const char const *const int const line_number
Definition: debug_heap.cpp:499
#define CP_ACP
Definition: compat.h:109
return nullptr
Definition: expand.cpp:78
size_t const new_size
Definition: expand.cpp:66
unsigned long DWORD
Definition: ntddk_ex.h:95
_Out_opt_ size_t *const Character const *const int const block_use
Definition: getenv.cpp:258
GLuint address
Definition: glext.h:9393
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
#define MB_ERR_INVALID_CHARS
Definition: unicode.h:41
_wcstombs_l
Definition: stdlib.h:1039
_mbstowcs_l
Definition: stdlib.h:951
#define _BEGIN_SECURE_CRT_DEPRECATION_DISABLE
#define _free_crt
#define _END_SECURE_CRT_DEPRECATION_DISABLE
#define _malloc_crt
#define _MAX_PATH
Definition: utility.h:77
static PVOID ptr
Definition: dispmode.c:27
static LPCWSTR file_name
Definition: protocol.c:147
#define _Check_return_
Definition: no_sal2.h:60
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:325
#define err(...)
#define errno
Definition: errno.h:18
#define CP_UTF8
Definition: nls.h:20
int CDECL memcpy_s(void *dest, size_t numberOfElements, const void *src, size_t count)
Definition: heap.c:800
wchar_t const *const size_t const buffer_size
Definition: stat.cpp:95
#define false
Definition: stdbool.h:37
static void deallocate(void *const ptr, debug_info_type const &)
static _Check_return_ errno_t allocate(void **const address, size_t const size, debug_info_type const &)
static void deallocate(void *const, debug_info_type const &)
static _Check_return_ errno_t allocate(void **const, size_t const, debug_info_type const &)
static void deallocate(void *const ptr, debug_info_type const &debug_info)
static _Check_return_ errno_t allocate(void **const address, size_t const size, debug_info_type const &debug_info)
static const char alloc_err[]
Definition: svc_dg.c:382
int errno_t
Definition: corecrt.h:615
int ret
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
_In_ LPCSTR lpFileName
Definition: winbase.h:3096
#define CP_OEMCP
Definition: winnls.h:233
#define MB_PRECOMPOSED
Definition: winnls.h:283
#define const
Definition: zconf.h:233