56
56
#define ERROR_DRIVER_FAILED_PRIOR_UNLOAD ((DWORD)654)
57
57
#endif
58
58
59
+ static BOOLEAN WinDivertIsDigit (char c );
59
60
static BOOLEAN WinDivertIsXDigit (char c );
60
61
static BOOLEAN WinDivertIsSpace (char c );
61
62
static BOOLEAN WinDivertIsAlNum (char c );
@@ -69,17 +70,45 @@ static BOOLEAN WinDivertAToI(const char *str, char **endptr, UINT32 *intptr,
69
70
UINT size );
70
71
static BOOLEAN WinDivertAToX (const char * str , char * * endptr , UINT32 * intptr ,
71
72
UINT size , BOOL prefix );
73
+ static UINT32 WinDivertDivTen128 (UINT32 * a );
72
74
73
75
/*
74
76
* Misc.
75
77
*/
76
78
#ifndef UINT8_MAX
77
79
#define UINT8_MAX 0xFF
78
80
#endif
81
+ #ifndef UINT16_MAX
82
+ #define UINT16_MAX 0xFFFF
83
+ #endif
79
84
#ifndef UINT32_MAX
80
85
#define UINT32_MAX 0xFFFFFFFF
81
86
#endif
82
87
88
+ #ifdef _MSC_VER
89
+
90
+ #pragma intrinsic(memcpy)
91
+ #pragma function(memcpy)
92
+ void * memcpy (void * dst , const void * src , size_t n )
93
+ {
94
+ size_t i ;
95
+ for (i = 0 ; i < n ; i ++ )
96
+ ((UINT8 * )dst )[i ] = ((const UINT8 * )src )[i ];
97
+ return dst ;
98
+ }
99
+
100
+ #pragma intrinsic(memset)
101
+ #pragma function(memset)
102
+ void * memset (void * dst , int c , size_t n )
103
+ {
104
+ size_t i ;
105
+ for (i = 0 ; i < n ; i ++ )
106
+ ((UINT8 * )dst )[i ] = (UINT8 )c ;
107
+ return dst ;
108
+ }
109
+
110
+ #endif
111
+
83
112
/*
84
113
* Prototypes.
85
114
*/
@@ -377,11 +406,11 @@ static BOOL WinDivertIoControl(HANDLE handle, DWORD code,
377
406
extern HANDLE WinDivertOpen (const char * filter , WINDIVERT_LAYER layer ,
378
407
INT16 priority , UINT64 flags )
379
408
{
380
- WINDIVERT_FILTER object [ WINDIVERT_FILTER_MAXLEN ] ;
409
+ WINDIVERT_FILTER * object ;
381
410
UINT obj_len ;
382
411
ERROR comp_err ;
383
412
DWORD err ;
384
- HANDLE handle ;
413
+ HANDLE handle , pool ;
385
414
UINT64 filter_flags ;
386
415
WINDIVERT_IOCTL ioctl ;
387
416
WINDIVERT_VERSION version ;
@@ -393,7 +422,7 @@ extern HANDLE WinDivertOpen(const char *filter, WINDIVERT_LAYER layer,
393
422
offsetof(WINDIVERT_DATA_SOCKET , Protocol ) != 56 ||
394
423
offsetof(WINDIVERT_DATA_REFLECT , Priority ) != 24 ||
395
424
sizeof (WINDIVERT_FILTER ) != 24 ||
396
- offsetof(WINDIVERT_ADDRESS , Reserved2 ) != 16 )
425
+ offsetof(WINDIVERT_ADDRESS , Reserved3 ) != 16 )
397
426
{
398
427
SetLastError (ERROR_INVALID_PARAMETER );
399
428
return INVALID_HANDLE_VALUE ;
@@ -426,9 +455,25 @@ extern HANDLE WinDivertOpen(const char *filter, WINDIVERT_LAYER layer,
426
455
}
427
456
428
457
// Compile & analyze the filter:
429
- comp_err = WinDivertCompileFilter (filter , layer , object , & obj_len );
458
+ pool = HeapCreate (HEAP_NO_SERIALIZE , WINDIVERT_MIN_POOL_SIZE ,
459
+ WINDIVERT_MAX_POOL_SIZE );
460
+ if (pool == NULL )
461
+ {
462
+ return FALSE;
463
+ }
464
+ object = HeapAlloc (pool , 0 ,
465
+ WINDIVERT_FILTER_MAXLEN * sizeof (WINDIVERT_FILTER ));
466
+ if (object == NULL )
467
+ {
468
+ err = GetLastError ();
469
+ HeapDestroy (pool );
470
+ SetLastError (err );
471
+ return FALSE;
472
+ }
473
+ comp_err = WinDivertCompileFilter (filter , pool , layer , object , & obj_len );
430
474
if (IS_ERROR (comp_err ))
431
475
{
476
+ HeapDestroy (pool );
432
477
SetLastError (ERROR_INVALID_PARAMETER );
433
478
return INVALID_HANDLE_VALUE ;
434
479
}
@@ -443,31 +488,36 @@ extern HANDLE WinDivertOpen(const char *filter, WINDIVERT_LAYER layer,
443
488
err = GetLastError ();
444
489
if (err != ERROR_FILE_NOT_FOUND && err != ERROR_PATH_NOT_FOUND )
445
490
{
491
+ HeapDestroy (pool );
492
+ SetLastError (err );
446
493
return INVALID_HANDLE_VALUE ;
447
494
}
448
495
449
496
// Open failed because the device isn't installed; install it now.
450
497
if ((flags & WINDIVERT_FLAG_NO_INSTALL ) != 0 )
451
498
{
499
+ HeapDestroy (pool );
452
500
SetLastError (ERROR_SERVICE_DOES_NOT_EXIST );
453
501
return INVALID_HANDLE_VALUE ;
454
502
}
455
503
SetLastError (0 );
456
504
if (!WinDivertDriverInstall ())
457
505
{
458
- if ( GetLastError () == 0 )
459
- {
460
- SetLastError ( ERROR_OPEN_FAILED );
461
- }
506
+ err = GetLastError ();
507
+ err = ( err == 0 ? ERROR_OPEN_FAILED : err );
508
+ HeapDestroy ( pool );
509
+ SetLastError ( err );
462
510
return INVALID_HANDLE_VALUE ;
463
511
}
464
512
handle = CreateFile (L"\\\\.\\" WINDIVERT_DEVICE_NAME ,
465
513
GENERIC_READ | GENERIC_WRITE , 0 , NULL , OPEN_EXISTING ,
466
514
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED ,
467
515
INVALID_HANDLE_VALUE );
468
-
469
516
if (handle == INVALID_HANDLE_VALUE )
470
517
{
518
+ err = GetLastError ();
519
+ HeapDestroy (pool );
520
+ SetLastError (err );
471
521
return INVALID_HANDLE_VALUE ;
472
522
}
473
523
}
@@ -485,13 +535,17 @@ extern HANDLE WinDivertOpen(const char *filter, WINDIVERT_LAYER layer,
485
535
if (!WinDivertIoControl (handle , IOCTL_WINDIVERT_INITIALIZE , & ioctl ,
486
536
& version , sizeof (version ), NULL ))
487
537
{
538
+ err = GetLastError ();
488
539
CloseHandle (handle );
540
+ HeapDestroy (pool );
541
+ SetLastError (err );
489
542
return INVALID_HANDLE_VALUE ;
490
543
}
491
544
if (version .magic != WINDIVERT_MAGIC_SYS ||
492
545
version .major < WINDIVERT_VERSION_MAJOR_MIN )
493
546
{
494
547
CloseHandle (handle );
548
+ HeapDestroy (pool );
495
549
SetLastError (ERROR_DRIVER_FAILED_PRIOR_UNLOAD );
496
550
return INVALID_HANDLE_VALUE ;
497
551
}
@@ -502,9 +556,13 @@ extern HANDLE WinDivertOpen(const char *filter, WINDIVERT_LAYER layer,
502
556
if (!WinDivertIoControl (handle , IOCTL_WINDIVERT_STARTUP , & ioctl ,
503
557
object , obj_len * sizeof (WINDIVERT_FILTER ), NULL ))
504
558
{
559
+ err = GetLastError ();
505
560
CloseHandle (handle );
561
+ HeapDestroy (pool );
562
+ SetLastError (err );
506
563
return INVALID_HANDLE_VALUE ;
507
564
}
565
+ HeapDestroy (pool );
508
566
509
567
// Success!
510
568
return handle ;
@@ -645,6 +703,11 @@ extern BOOL WinDivertGetParam(HANDLE handle, WINDIVERT_PARAM param,
645
703
/* REPLACEMENTS */
646
704
/*****************************************************************************/
647
705
706
+ static BOOLEAN WinDivertIsDigit (char c )
707
+ {
708
+ return (c >= '0' && c <= '9' );
709
+ }
710
+
648
711
static BOOLEAN WinDivertIsXDigit (char c )
649
712
{
650
713
return (c >= '0' && c <= '9' ) ||
@@ -756,7 +819,7 @@ static BOOLEAN WinDivertAToI(const char *str, char **endptr, UINT32 *intptr,
756
819
size_t i = 0 ;
757
820
UINT32 n [4 ] = {0 };
758
821
BOOLEAN result = TRUE;
759
- for (; str [i ] && isdigit (str [i ]); i ++ )
822
+ for (; str [i ] && WinDivertIsDigit (str [i ]); i ++ )
760
823
{
761
824
if (!WinDivertMul128 (n , 10 ) || !WinDivertAdd128 (n , str [i ] - '0' ))
762
825
{
@@ -801,7 +864,7 @@ static BOOLEAN WinDivertAToX(const char *str, char **endptr, UINT32 *intptr,
801
864
}
802
865
for (; str [i ] && WinDivertIsXDigit (str [i ]); i ++ )
803
866
{
804
- if (isdigit (str [i ]))
867
+ if (WinDivertIsDigit (str [i ]))
805
868
{
806
869
dig = (UINT32 )(str [i ] - '0' );
807
870
}
@@ -833,3 +896,47 @@ static BOOLEAN WinDivertAToX(const char *str, char **endptr, UINT32 *intptr,
833
896
return result ;
834
897
}
835
898
899
+ /*
900
+ * Divide by 10 and return the remainder.
901
+ */
902
+ #define WINDIVERT_BIG_MUL_ROUND (a , c , r , i ) \
903
+ do { \
904
+ UINT64 t = WINDIVERT_MUL64((UINT64)(a), (UINT64)(c)); \
905
+ UINT k; \
906
+ for (k = (i); k < 9 && t != 0; k++) \
907
+ { \
908
+ UINT64 s = (UINT64)(r)[k] + (t & 0xFFFFFFFF); \
909
+ (r)[k] = (UINT32)s; \
910
+ t = (t >> 32) + (s >> 32); \
911
+ } \
912
+ } while (FALSE)
913
+ static UINT32 WinDivertDivTen128 (UINT32 * a )
914
+ {
915
+ const UINT32 c [5 ] =
916
+ {
917
+ 0x9999999A , 0x99999999 , 0x99999999 , 0x99999999 , 0x19999999
918
+ };
919
+ UINT32 r [9 ] = {0 }, m [6 ] = {0 };
920
+ UINT i , j ;
921
+
922
+ for (i = 0 ; i < 4 ; i ++ )
923
+ {
924
+ for (j = 0 ; j < 5 ; j ++ )
925
+ {
926
+ WINDIVERT_BIG_MUL_ROUND (a [i ], c [j ], r , i + j );
927
+ }
928
+ }
929
+
930
+ a [0 ] = r [5 ];
931
+ a [1 ] = r [6 ];
932
+ a [2 ] = r [7 ];
933
+ a [3 ] = r [8 ];
934
+
935
+ for (i = 0 ; i < 5 ; i ++ )
936
+ {
937
+ WINDIVERT_BIG_MUL_ROUND (r [i ], 10 , m , i );
938
+ }
939
+
940
+ return m [5 ];
941
+ }
942
+
0 commit comments