Author: tfaber Date: Sat Feb 7 13:24:29 2015 New Revision: 66189
URL: http://svn.reactos.org/svn/reactos?rev=66189&view=rev Log: [RTL] - Implement RtlIpv4StringToAddressW. Dedicated to Jérôme. Thanks to the countless reviewers. CORE-6490
Modified: trunk/reactos/lib/rtl/network.c trunk/reactos/lib/rtl/rtl.h
Modified: trunk/reactos/lib/rtl/network.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/network.c?rev=66189... ============================================================================== --- trunk/reactos/lib/rtl/network.c [iso-8859-1] (original) +++ trunk/reactos/lib/rtl/network.c [iso-8859-1] Sat Feb 7 13:24:29 2015 @@ -3,6 +3,7 @@ * PROJECT: ReactOS Runtime Library * PURPOSE: Network Address Translation implementation * PROGRAMMER: Alex Ionescu (alexi@tinykrnl.org) + * Thomas Faber (thomas.faber@reactos.org) */
/* INCLUDES *****************************************************************/ @@ -21,7 +22,82 @@ /* network to host order conversion for little endian machines */ #define WN2H(w) (((w & 0xFF00) >> 8) | ((w & 0x00FF) << 8))
-/* FUNCTIONS ***************************************************************/ +/* PRIVATE FUNCTIONS **********************************************************/ + +static +NTSTATUS +RtlpStringToUlong( + _In_ PCWSTR String, + _In_ BOOLEAN Strict, + _Out_ PCWSTR *Terminator, + _Out_ PULONG Out) +{ + /* If we never see any digits, we'll return this */ + NTSTATUS Status = STATUS_INVALID_PARAMETER; + ULONG Result = 0; + ULONG Base = 10; + ULONG Digit; + + if (String[0] == L'0') + { + if (String[1] == L'x' || String[1] == L'X') + { + /* 0x/0X prefix -- hex */ + String += 2; + Base = 16; + } + else if (String[1] >= L'0' && String[1] <= L'9') + { + /* 0 prefix -- octal */ + String++; + Base = 8; + } + } + + /* Strict forbids anything but decimal */ + if (Strict && Base != 10) + { + Status = STATUS_INVALID_PARAMETER; + goto Done; + } + + while (1) + { + if (*String >= L'0' && *String <= L'7') + Digit = *String - L'0'; + else if (*String >= L'0' && *String <= L'9' && Base >= 10) + Digit = *String - L'0'; + else if (*String >= L'A' && *String <= L'F' && Base >= 16) + Digit = 10 + (*String - L'A'); + else if (*String >= L'a' && *String <= L'f' && Base >= 16) + Digit = 10 + (*String - L'a'); + else + break; + + Status = RtlULongMult(Result, Base, &Result); + if (!NT_SUCCESS(Status)) + { + Status = STATUS_INVALID_PARAMETER; + break; + } + + Status = RtlULongAdd(Result, Digit, &Result); + if (!NT_SUCCESS(Status)) + { + Status = STATUS_INVALID_PARAMETER; + break; + } + + String++; + } + +Done: + *Terminator = String; + *Out = Result; + return Status; +} + +/* PUBLIC FUNCTIONS ***********************************************************/
/* * @implemented @@ -198,17 +274,66 @@ }
/* -* @unimplemented -*/ -NTSTATUS -NTAPI -RtlIpv4StringToAddressW(IN PCWSTR String, - IN BOOLEAN Strict, - OUT PCWSTR *Terminator, - OUT struct in_addr *Addr) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + * @implemented + */ +NTSTATUS +NTAPI +RtlIpv4StringToAddressW( + _In_ PCWSTR String, + _In_ BOOLEAN Strict, + _Out_ PCWSTR *Terminator, + _Out_ struct in_addr *Addr) +{ + NTSTATUS Status; + ULONG Values[4]; + ULONG Result; + INT Parts = 0; + INT i; + + do + { + Status = RtlpStringToUlong(String, Strict, &String, &Values[Parts]); + Parts++; + + if (*String != L'.') + break; + + /* Already four parts, but a dot follows? */ + if (Parts == 4) + { + Status = STATUS_INVALID_PARAMETER; + goto Done; + } + + /* Skip the dot */ + String++; + } while (NT_SUCCESS(Status)); + + if (Strict && Parts < 4) + Status = STATUS_INVALID_PARAMETER; + + if (!NT_SUCCESS(Status)) + goto Done; + + /* Combine the parts */ + Result = Values[Parts - 1]; + for (i = 0; i < Parts - 1; i++) + { + INT Shift = CHAR_BIT * (3 - i); + + if (Values[i] > 0xFF || (Result & (0xFF << Shift)) != 0) + { + Status = STATUS_INVALID_PARAMETER; + goto Done; + } + Result |= Values[i] << Shift; + } + + Addr->S_un.S_addr = RtlUlongByteSwap(Result); + +Done: + *Terminator = String; + return Status; }
/*
Modified: trunk/reactos/lib/rtl/rtl.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/rtl.h?rev=66189&... ============================================================================== --- trunk/reactos/lib/rtl/rtl.h [iso-8859-1] (original) +++ trunk/reactos/lib/rtl/rtl.h [iso-8859-1] Sat Feb 7 13:24:29 2015 @@ -27,6 +27,7 @@ #include <winbase.h> #include <winreg.h> #include <objbase.h> +#include <ntintsafe.h> #include <ndk/exfuncs.h> #include <ndk/iofuncs.h> #include <ndk/kefuncs.h>