forked from Chuyu-Team/VC-LTL
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path_msvcrt.cpp
More file actions
2791 lines (2251 loc) · 62.5 KB
/
Copy path_msvcrt.cpp
File metadata and controls
2791 lines (2251 loc) · 62.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#pragma once
#if defined(NDEBUG)&&defined(__Build_LTL)
//#define _CRT_BEST_PRACTICES_USAGE
#include <vcruntime_new.h>
#include <corecrt_terminate.h>
#include <stdlib.h>
#include <corecrt_wstdio.h>
#include <Windows.h>
#include <winnt.h>
#include <intrin.h>
#include <vcruntime_exception.h>
#include <crtdbg.h>
#include <time.h>
#include <corecrt_io.h>
#include <stdio.h>
#include <internal_shared.h>
#include <locale.h>
#include <sys/stat.h>
#include <sys/timeb.h>
#include <sys/utime.h>
#include <float.h>
#include <corecrt_math.h>
#include <msvcrt_IAT.h>
#include <corecrt_internal.h>
static __forceinline errno_t __cdecl _tcscpy_s(
_Out_writes_z_(_SizeInBytes) char* _Destination,
_In_ rsize_t _SizeInBytes,
_In_z_ char const* _Source
)
{
return strcpy_s(_Destination, _SizeInBytes, _Source);
}
static __forceinline errno_t __cdecl _tcscpy_s(
_Out_writes_z_(_SizeInBytes) wchar_t* _Destination,
_In_ rsize_t _SizeInBytes,
_In_z_ wchar_t const* _Source
)
{
return wcscpy_s(_Destination, _SizeInBytes, _Source);
}
static __forceinline size_t __cdecl _tcslen(
_In_z_ char const* _Str
)
{
return strlen(_Str);
}
static __forceinline size_t __cdecl _tcslen(
_In_z_ wchar_t const* _String
)
{
return wcslen(_String);
}
extern "C"
{
struct __crt_stdio_stream_data :public _iobuf
{
CRITICAL_SECTION _lock;
};
__declspec(dllimport) extern _iobuf _iob[_IOB_ENTRIES];
_CRTIMP FILE* __cdecl __acrt_iob_func(unsigned in)
{
return &_iob[in];
}
//int __scrt_debugger_hook_flag = 0;
//void __cdecl _CRT_DEBUGGER_HOOK(int const reserved)
//{
// UNREFERENCED_PARAMETER(reserved);
// // We assign zero to the debugger hook flag so that this function is not
// // folded when optimized. The flag is not otherwise used.
// __scrt_debugger_hook_flag = 0;
//}
//#define _CRT_DEBUGGER_HOOK(a) (0)
// void __cdecl __scrt_fastfail(unsigned const code)
// {
// // First see if __fastfail is available, and invoke it if it is. This will
// // always be availbale on ARM and is always available on Windows 8 and above.
// if (IsProcessorFeaturePresent(PF_FASTFAIL_AVAILABLE))
// __fastfail(code);
//
// // If __fastfail is not available, fall back to raising an exception that
// // bypasses all exception handlers (via a call to the unhandled exception
// // filter.
//
// // Notify the debugger if attached.
// //_CRT_DEBUGGER_HOOK(0);
//
// CONTEXT context_record = {};
//
//#if defined _M_IX86
//
// __asm
// {
// mov dword ptr[context_record.Eax], eax
// mov dword ptr[context_record.Ecx], ecx
// mov dword ptr[context_record.Edx], edx
// mov dword ptr[context_record.Ebx], ebx
// mov dword ptr[context_record.Esi], esi
// mov dword ptr[context_record.Edi], edi
// mov word ptr[context_record.SegSs], ss
// mov word ptr[context_record.SegCs], cs
// mov word ptr[context_record.SegDs], ds
// mov word ptr[context_record.SegEs], es
// mov word ptr[context_record.SegFs], fs
// mov word ptr[context_record.SegGs], gs
// pushfd
// pop[context_record.EFlags]
// }
//
// context_record.ContextFlags = CONTEXT_CONTROL;
// context_record.Eip = reinterpret_cast<ULONG>(_ReturnAddress());
// context_record.Esp = reinterpret_cast<ULONG>(_AddressOfReturnAddress());
// context_record.Ebp = *(reinterpret_cast<ULONG*>(_AddressOfReturnAddress()) - 1);
//
//#elif defined _M_X64
//
// RtlCaptureContext(&context_record);
//
// ULONG64 const control_pc = context_record.Rip;
//
// ULONG64 image_base;
// PRUNTIME_FUNCTION const function_entry = RtlLookupFunctionEntry(control_pc, &image_base, nullptr);
//
// if (function_entry)
// {
// ULONG64 establisher_frame;
// PVOID handler_data;
// RtlVirtualUnwind(
// UNW_FLAG_NHANDLER,
// image_base,
// control_pc,
// function_entry,
// &context_record,
// &handler_data,
// &establisher_frame,
// nullptr);
// }
//
// context_record.Rip = reinterpret_cast<ULONGLONG>(_ReturnAddress());
// context_record.Rsp = reinterpret_cast<ULONGLONG>(_AddressOfReturnAddress()) + 8;
//
//#endif
//
// EXCEPTION_RECORD exception_record = {};
// exception_record.ExceptionCode = STATUS_FATAL_APP_EXIT;
// exception_record.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
// exception_record.ExceptionAddress = _ReturnAddress();
//
// bool const was_debugger_present = IsDebuggerPresent() == TRUE;
//
// // Raise an exception that bypasses all exception handlers:
// EXCEPTION_POINTERS exception_pointers = { &exception_record, &context_record };
//
// SetUnhandledExceptionFilter(nullptr);
// LONG const result = UnhandledExceptionFilter(&exception_pointers);
//
// // If no handler was found and no debugger was previously attached, then make
// // sure we notify the debugger.
// //if (result == EXCEPTION_CONTINUE_SEARCH && !was_debugger_present)
// // _CRT_DEBUGGER_HOOK(0);
// }
//void __cdecl __std_exception_copy(
// __std_exception_data const* const from,
// __std_exception_data* const to
//)
//{
// _ASSERTE(to->_What == nullptr && to->_DoFree == false);
// if (!from->_DoFree || !from->_What)
// {
// to->_What = from->_What;
// to->_DoFree = false;
// return;
// }
// size_t const buffer_count = strlen(from->_What) + 1;
// auto buffer=static_cast<char*>(malloc(buffer_count));
// if (!buffer)
// {
// return;
// }
// strcpy_s(buffer, buffer_count, from->_What);
// to->_What = buffer;
// to->_DoFree = true;
//}
//void __cdecl __std_exception_destroy(
// __std_exception_data* const data
//)
//{
// if (data->_DoFree)
// {
// free(const_cast<char*>(data->_What));
// }
// data->_DoFree = false;
// data->_What = nullptr;
//}
/*void __cdecl _invalid_parameter(
_In_opt_z_ wchar_t const*,
_In_opt_z_ wchar_t const*,
_In_opt_z_ wchar_t const*,
_In_ unsigned int,
_In_ uintptr_t
);
void __cdecl _invalid_parameter_noinfo_noreturn(void)
{
_invalid_parameter(nullptr, nullptr, nullptr, 0, 0);
_invoke_watson(nullptr, nullptr, nullptr, 0, 0);
}*/
_CRTIMP errno_t __CRTDECL wmemcpy_s(
_Out_writes_to_opt_(_N1, _N) wchar_t* _S1,
_In_ rsize_t _N1,
_In_reads_opt_(_N) wchar_t const* _S2,
_In_ rsize_t _N
)
{
return memcpy_s(_S1, _N1 * sizeof(wchar_t), _S2, _N * sizeof(wchar_t));
}
_CRTIMP errno_t __CRTDECL wmemmove_s(
_Out_writes_to_opt_(_N1, _N) wchar_t* _S1,
_In_ rsize_t _N1,
_In_reads_opt_(_N) wchar_t const* _S2,
_In_ rsize_t _N
)
{
return memmove_s(_S1, _N1 * sizeof(wchar_t), _S2, _N * sizeof(wchar_t));
}
// int __cdecl __stdio_common_vswprintf(
// _In_ unsigned __int64 _Options,
// _Out_writes_z_(_BufferCount) wchar_t* _Buffer,
// _In_ size_t _BufferCount,
// _In_z_ _Printf_format_string_params_(2) wchar_t const* _Format,
// _In_opt_ _locale_t _Locale,
// va_list _ArgList
// )
// {
// return _Buffer == NULL ? _vscwprintf_l(_Format, _Locale, _ArgList) : _vswprintf_l(_Buffer, _BufferCount, _Format, _Locale, _ArgList);
// }
//
// int __cdecl __stdio_common_vswprintf_s(
// _In_ unsigned __int64 _Options,
// _Out_writes_z_(_BufferCount) wchar_t* _Buffer,
// _In_ size_t _BufferCount,
// _In_z_ _Printf_format_string_params_(2) wchar_t const* _Format,
// _In_opt_ _locale_t _Locale,
// va_list _ArgList
// )
// {
// return _Buffer == NULL ? _vscwprintf_l(_Format, _Locale, _ArgList) : _vswprintf_s_l(_Buffer, _BufferCount, _Format, _Locale, _ArgList);
// }
// Maximum local time adjustment (GMT + 13 Hours, DST -0 Hours)
#define _MAX_LOCAL_TIME (13 * 60 * 60)
// Minimum local time adjustment (GMT - 11 Hours, DST - 1 Hours)
#define _MIN_LOCAL_TIME (-12 * 60 * 60)
// Number of seconds from 00:00:00, 01/01/1970 UTC to 23:59:59, 01/18/2038 UTC
#define _MAX_TIME32 0x7fffd27fll
#if _CRT_NTDDI_MIN < 0x06000000
extern "C++" template<typename time_t>
static __forceinline double __cdecl common_difftime(
_In_ time_t _Time1,
_In_ time_t _Time2
)
{
if (!(_Time2 >= 0 && _Time1 >= 0))
{
errno = EINVAL;
return 0;
}
return static_cast<double>(_Time1 - _Time2);
}
_CRTIMP double __cdecl _difftime32(
_In_ __time32_t _Time1,
_In_ __time32_t _Time2
)
{
return common_difftime(_Time1, _Time2);
}
_CRTIMP double __cdecl _difftime64(
_In_ __time64_t _Time1,
_In_ __time64_t _Time2
)
{
return common_difftime(_Time1, _Time2);
}
#if 0
_CRTIMP struct tm* __cdecl _localtime32(
_In_ __time32_t const* _Time
)
{
_VALIDATE_RETURN(_Time != nullptr, EINVAL,nullptr);
// Check for illegal time_t value:
if (*_Time <0 || *_Time > _MAX_TIME32)
{
errno = EINVAL;
return nullptr;
}
__time64_t _Time64 = *_Time;
return _localtime64(&_Time64);
}
#endif
extern "C++" static __forceinline struct tm* __cdecl _localtime_t(_In_ __time32_t const* _Time)
{
return _localtime32(_Time);
}
extern "C++" static __forceinline struct tm* __cdecl _localtime_t(_In_ __time64_t const* _Time)
{
return _localtime64(_Time);
}
extern "C++" template<typename time_t>
static __forceinline errno_t __cdecl common_localtime_s(
_Out_ struct tm* _Tm,
_In_ time_t const* _Time
)
{
_VALIDATE_RETURN_ERRCODE(_Tm != nullptr, EINVAL);
memset(_Tm, 0xff, sizeof(*_Tm));
_VALIDATE_RETURN_ERRCODE(_Time != nullptr, EINVAL);
#pragma warning(suppress : 4996)
const struct tm* t = _localtime_t(_Time);
if (!t)
return errno;
*_Tm = *t;
return 0;
}
_CRTIMP errno_t __cdecl _localtime32_s(
_Out_ struct tm* _Tm,
_In_ __time32_t const* _Time
)
{
return common_localtime_s(_Tm, _Time);
}
_CRTIMP errno_t __cdecl _localtime64_s(
_Out_ struct tm* _Tm,
_In_ __time64_t const* _Time
)
{
return common_localtime_s(_Tm, _Time);
}
#endif
#undef _daylight
__declspec(dllimport) extern int _daylight;
#if !defined _ARM64_ && !defined _ARM_
#undef _dstbias
__declspec(dllimport) extern long _dstbias;
#endif
#undef _timezone
__declspec(dllimport) extern long _timezone;
#undef _tzname
__declspec(dllimport) extern char* _tzname[2];
_CRTIMP errno_t __cdecl _get_daylight(
_Out_ int* _Daylight
)
{
_VALIDATE_RETURN_ERRCODE(_Daylight != nullptr, EINVAL);
*_Daylight = _daylight;
return 0;
}
_CRTIMP errno_t __cdecl _get_dstbias(
_Out_ long* _DaylightSavingsBias
)
{
_VALIDATE_RETURN_ERRCODE(_DaylightSavingsBias != nullptr, EINVAL);
*_DaylightSavingsBias = _dstbias;
return 0;
}
_CRTIMP errno_t __cdecl _get_timezone(
_Out_ long* _TimeZone
)
{
_VALIDATE_RETURN_ERRCODE(_TimeZone != nullptr, EINVAL);
*_TimeZone = _timezone;
return 0;
}
_CRTIMP errno_t __cdecl _get_tzname(
_Out_ size_t* _ReturnValue,
_Out_writes_z_(_SizeInBytes) char* _Buffer,
_In_ size_t _SizeInBytes,
_In_ int _Index
)
{
_VALIDATE_RETURN_ERRCODE(
(_Buffer != nullptr && _SizeInBytes > 0) ||
(_Buffer == nullptr && _SizeInBytes == 0),
EINVAL);
if (_Buffer != nullptr)
_Buffer[0] = '\0';
_VALIDATE_RETURN_ERRCODE(_ReturnValue != nullptr, EINVAL);
_VALIDATE_RETURN_ERRCODE(_Index == 0 || _Index == 1, EINVAL);
auto& _TmpName = _tzname[_Index];
// _tzname is correctly inited at startup, so no need to check if
// CRT init finished.
const auto cchBuffRerrequest = strlen(_TmpName) + 1;
*_ReturnValue = cchBuffRerrequest;
// If the buffer pointer is null, the caller is interested only in the size
// of the string, not in the actual value of the string:
if (_Buffer == nullptr)
return 0;
if (cchBuffRerrequest > _SizeInBytes)
return ERANGE;
memcpy(_Buffer, _TmpName, cchBuffRerrequest * sizeof(_TmpName[0]));
return 0;
}
#if defined _M_AMD64 && _CRT_NTDDI_MIN < 0x06000000
_CRTIMP extern "C" int* __cdecl __daylight()
{
return &_daylight;
}
_LTL_DLL_EXPORT_DOWNLEVEL(__daylight);
_CRTIMP extern "C" long* __cdecl __dstbias()
{
return &_dstbias;
}
_LTL_DLL_EXPORT_DOWNLEVEL(__dstbias)
#endif
#if defined _M_AMD64 || defined _M_ARM64
_CRTIMP extern "C" long* __cdecl __timezone()
{
return &_timezone;
}
_LTL_DLL_EXPORT_DOWNLEVEL(__timezone)
_CRTIMP extern "C" char** __cdecl __tzname()
{
return _tzname;
}
_LTL_DLL_EXPORT_DOWNLEVEL(__tzname)
#endif
#if _CRT_NTDDI_MIN < 0x06000000
/*
Windows XP的msvcrt没有这个接口,不过我们可以使用其他接口模拟实现该功能。
当 _Origin = SEEK_SET时,直接调用 fsetpos
当 _Origin = SEEK_CUR时,先调用 fgetpos 获取当前文件位置,修正_Offset后再调用 fsetpos
当 _Origin = SEEK_END时,先触发内部缓冲区写入,然后调用 _lseeki64
_Origin 其他情况,返回无效参数
*/
_CRTIMP int __cdecl _fseeki64(
_Inout_ FILE* _Stream,
_In_ __int64 _Offset,
_In_ int _Origin
)
{
if (_Origin == SEEK_SET)
{
//如果是以文件起始为基准,则直接调用fsetpos,减少函数调用次数
return fsetpos(_Stream, &_Offset);
}
else
{
int result = -1;
//对文件进行加锁,防止其他线程篡改
_lock_file(_Stream);
fpos_t _Position;
//获取文件当前位置
if (fgetpos(_Stream, &_Position) == 0)
{
if (_Origin == SEEK_CUR)
{
//以当前位置为准,修正偏移到当前位置
_Offset += _Position;
result = fsetpos(_Stream, &_Offset);
}
else if (_Origin == SEEK_END)
{
//调用一次set,触发,内部缓冲区写入硬盘
if (fsetpos(_Stream, &_Position) == 0)
{
result = _lseeki64(_Stream->_file, _Offset, _Origin) == -1 ? -1 : 0;
}
}
else
{
//无效参数
errno = EINVAL;
}
}
//解锁文件,允许其他线程操作此句柄
_unlock_file(_Stream);
return result;
}
}
#endif
//总是返回ture,因为老版本没有此函数,不过以前的 _matherr内部他会判断是否存在
bool __cdecl __acrt_has_user_matherr()
{
return true;
}
/*int __CRTDECL _matherr(_Inout_ struct _exception* _Except);
int __acrt_invoke_user_matherr(_Inout_ struct _exception* _Except)
{
return _matherr(_Except);
}*/
/*long long __cdecl wcstoll(
_In_z_ wchar_t const* _String,
_Out_opt_ _Deref_post_z_ wchar_t** _EndPtr,
_In_ int _Radix
)
{
return _wcstoi64(_String, _EndPtr, _Radix);
}*/
/*long long __cdecl strtoll(
_In_z_ char const* _String,
_Out_opt_ _Deref_post_z_ char** _EndPtr,
_In_ int _Radix
)
{
return _strtoi64(_String, _EndPtr, _Radix);
}*/
/*unsigned long long __cdecl strtoull(
_In_z_ char const* _String,
_Out_opt_ _Deref_post_z_ char** _EndPtr,
_In_ int _Radix
)
{
return _strtoui64(_String, _EndPtr, _Radix);
}*/
#if _CRT_NTDDI_MIN < 0x06000000
#include <Ntsecapi.h>
_CRTIMP errno_t __cdecl rand_s(_Out_ unsigned int* _RandomValue)
{
*_RandomValue = 0;
if (!RtlGenRandom(_RandomValue, sizeof(*_RandomValue)))
{
errno = ENOMEM;
return ENOMEM;
}
else
{
return 0;
}
}
#endif
//#ifdef _X86_
//#include <math.h>
//#pragma function(acos)
// double __cdecl _acos_default(_In_ double _X)
// {
// return acos(_X);
// }
//#pragma intrinsic(acos)
//#pragma function(asin)
// double __cdecl _asin_default(_In_ double _X)
// {
// return asin(_X);
//
// }
//#pragma intrinsic(asin)
//#pragma function(atan)
// double __cdecl _atan_default(_In_ double _X)
// {
// return atan(_X);
//
// }
//#pragma intrinsic(atan)
//#pragma function(cos)
// double __cdecl _cos_default(_In_ double _X)
// {
// return cos(_X);
//
// }
//#pragma intrinsic(cos)
//#pragma function(exp)
// double __cdecl _exp_default(_In_ double _X)
// {
// return exp(_X);
// }
//#pragma intrinsic(exp)
//#pragma function(pow)
// double __cdecl _pow_default(_In_ double _X, _In_ double _Y)
// {
// return pow(_X, _Y);
// }
//#pragma intrinsic(pow)
//#pragma function(sin)
// double __cdecl _sin_default(_In_ double _X)
// {
// return sin(_X);
// }
//#pragma intrinsic(sin)
//#pragma function(tan)
// double __cdecl _tan_default(_In_ double _X)
// {
// return tan(_X);
// }
//#pragma intrinsic(tan)
//#pragma function(log)
// double __cdecl _log_default(_In_ double _X)
// {
// return log(_X);
// }
//#pragma intrinsic(log)
//#pragma function(log10)
// double __cdecl _log10_default(_In_ double _X)
// {
// return log10(_X);
// }
//#pragma intrinsic(log10)
//#endif
__declspec(dllimport) void __cdecl _lock(
int locknum
);
__declspec(dllimport) void __cdecl _unlock(
int locknum
);
static __inline bool IsInternalStream(_iobuf* const stream)
{
return ((byte*)stream >= (byte*)_iob) && ((byte*)stream <= (byte*)(_iob + _IOB_ENTRIES -1));
}
// Locks a stdio stream.
_CRTIMP void __cdecl _lock_file(FILE* const stream)
{
if (IsInternalStream(stream))
_lock((stream - _iob) + 0x10);
else
EnterCriticalSection(&((__crt_stdio_stream_data*)stream)->_lock);
}
// Unlocks a stdio stream.
_CRTIMP void __cdecl _unlock_file(FILE* const stream)
{
if (IsInternalStream(stream))
_unlock((stream - _iob) + 0x10);
else
LeaveCriticalSection(&((__crt_stdio_stream_data*)stream)->_lock);
}
_CRTIMP errno_t __cdecl _get_stream_buffer_pointers(
FILE* const public_stream,
char*** const base,
char*** const ptr,
int** const count
)
{
_VALIDATE_RETURN_ERRCODE(public_stream != nullptr, EINVAL);
if (base)
{
*base = &(public_stream->_base);
}
if (ptr)
{
*ptr = &(public_stream->_ptr);
}
if (count)
{
*count = &(public_stream->_cnt);
}
return 0;
}
#if _CRT_NTDDI_MIN < NTDDI_WINBLUE
//msvrct仅支持_Strftime,我们可以将通过字符串转换,得到_Wcsftime
_CRTIMP size_t __cdecl _Wcsftime(
wchar_t* const buffer,
size_t const max_size,
wchar_t const* const format,
tm const* const timeptr,
void* const lc_time_arg
)
{
_VALIDATE_RETURN(buffer != nullptr, EINVAL, 0)
_VALIDATE_RETURN(max_size != 0, EINVAL, 0)
*buffer = '\0';
_VALIDATE_RETURN(format != nullptr, EINVAL, 0)
_VALIDATE_RETURN(timeptr != nullptr, EINVAL, 0)
size_t Count = 0;
unsigned int const lc_time_cp = ___lc_codepage_func();
auto ch_format = WideCharToMultiByte(lc_time_cp, 0, format, -1, 0,0, nullptr, nullptr);
if (ch_format==0)
{
return 0;
}
auto formatA = (char*)malloc(ch_format);
//开辟2倍缓冲区
auto BufferA = (char*)malloc(max_size * 2);
if (formatA==nullptr|| BufferA==nullptr)
{
//内存不足
goto __Error;
}
if (WideCharToMultiByte(lc_time_cp, 0,format, -1, formatA, ch_format, nullptr, nullptr))
{
//转换失败
goto __Error;
}
Count = _Strftime(BufferA, max_size * 2, formatA, timeptr, lc_time_arg);
if (Count)
{
//
Count = MultiByteToWideChar(lc_time_cp, 0, BufferA, Count, buffer, max_size);
//改函数长度并不包含null,因为长度减一
if (Count)
--Count;
}
__Error:
if (formatA)
free(formatA);
if (BufferA)
free(BufferA);
return Count;
}
_LTL_DLL_EXPORT_DOWNLEVEL(_Wcsftime);
#endif
#if _CRT_NTDDI_MIN < NTDDI_WINBLUE
//msvrct仅支持_Getdays,我们可以将通过字符串转换,得到_W_Getdays
_CRTIMP wchar_t* __cdecl _W_Getdays(void)
{
auto szDays = _Getdays();
if (!szDays)
return nullptr;
unsigned int const lc_time_cp = ___lc_codepage_func();
auto ch_Days = MultiByteToWideChar(lc_time_cp, 0, szDays, -1, 0, 0);
if (ch_Days==0)
{
return nullptr;
}
//内存申请失败
auto szDaysW = (wchar_t*)malloc(ch_Days * sizeof(wchar_t));
if (!szDaysW)
return nullptr;
ch_Days = MultiByteToWideChar(lc_time_cp, 0, szDays, -1, szDaysW, ch_Days);
if (ch_Days)
{
return szDaysW;
}
else
{
free(szDaysW);
return nullptr;
}
}
_LTL_DLL_EXPORT_DOWNLEVEL(_W_Getdays);
#endif
#if _CRT_NTDDI_MIN < NTDDI_WINBLUE
//msvrct仅支持_Getmonths,我们可以将通过字符串转换,得到_W_Getmonths
_CRTIMP wchar_t *__cdecl _W_Getmonths(void)
{
auto szMonths = _Getmonths();
if (!szMonths)
return nullptr;
unsigned int const lc_time_cp = ___lc_codepage_func();
auto ch_Months = MultiByteToWideChar(lc_time_cp, 0, szMonths, -1, 0, 0);
if (ch_Months == 0)
{
return nullptr;
}
//内存申请失败
auto szMonthsW = (wchar_t*)malloc(ch_Months * sizeof(wchar_t));
if (!szMonthsW)
return nullptr;
ch_Months = MultiByteToWideChar(lc_time_cp, 0, szMonths, -1, szMonthsW, ch_Months);
if (ch_Months)
{
return szMonthsW;
}
else
{
free(szMonthsW);
return nullptr;
}
}
_LTL_DLL_EXPORT_DOWNLEVEL(_W_Getmonths);
#endif
/*void* __cdecl _W_Gettnames()
{
return _Gettnames();
}*/
//通过文件句柄获取_stat64
extern "C++" static __forceinline int __cdecl _tstat64(
_In_z_ int _FileHandle,
_Out_ struct _stat64* _Stat
)
{
return _fstat64(_FileHandle, _Stat);
}
//通过ASCII路径获取_stat64
extern "C++" static __forceinline int __cdecl _tstat64(
_In_z_ char const* _FileName,
_Out_ struct _stat64* _Stat
)
{
return _stat64(_FileName, _Stat);
}
//通过Unicode路径获取_stat64
extern "C++" static __forceinline int __cdecl _tstat64(
_In_z_ wchar_t const* _FileName,
_Out_ struct _stat64* _Stat
)
{
return _wstat64(_FileName, _Stat);
}
extern "C++" template<class File, class _statT >
static __forceinline int __cdecl common_stat(
_In_z_ File _FileName,
_Out_ _statT* _Stat
)
{
_VALIDATE_CLEAR_OSSERR_RETURN(_Stat != nullptr, EINVAL, -1);
struct _stat64 _StatTmp;
auto result = _tstat64(_FileName, &_StatTmp);
if (result == 0)
{
//获取成功,开始转换数据
_Stat->st_dev = _StatTmp.st_dev;
_Stat->st_ino = _StatTmp.st_ino;
_Stat->st_mode = _StatTmp.st_mode;
_Stat->st_nlink = _StatTmp.st_nlink;
_Stat->st_uid = _StatTmp.st_uid;
_Stat->st_gid = _StatTmp.st_gid;
_Stat->st_rdev = _StatTmp.st_rdev;
_Stat->st_size = _StatTmp.st_size;
_Stat->st_atime = _StatTmp.st_atime;
_Stat->st_mtime = _StatTmp.st_mtime;
_Stat->st_ctime = _StatTmp.st_ctime;
}
return result;
}
//_fstat已经改名为_fstat32
//#pragma push_macro("_fstat")
//#undef _fstat
// __declspec(dllimport) int __cdecl _fstat(
// _In_ int _FileHandle,
// _Out_ struct _stat32* _Stat
// );
//
// int __cdecl _fstat32(
// _In_ int _FileHandle,
// _Out_ struct _stat32* _Stat
// )
// {
// return _fstat(_FileHandle, _Stat);
// }
//#pragma pop_macro("_fstat")
//_fstati64已经改名为_fstat32i64
//#pragma push_macro("_fstati64")
//#undef _fstati64
// __declspec(dllimport) int __cdecl _fstati64(
// _In_ int _FileHandle,
// _Out_ struct _stat32i64* _Stat
// );
//
// int __cdecl _fstat32i64(