- Implement RtlIpv4StringToAddressW. Dedicated to Jérôme. Thanks to the countless reviewers.
CORE-6490

svn path=/trunk/; revision=66189
This commit is contained in:
Thomas Faber 2015-02-07 13:24:29 +00:00
parent 008adec92d
commit f3b718e042
2 changed files with 135 additions and 9 deletions

View file

@ -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 @@ RtlIpv4StringToAddressExA(
}
/*
* @unimplemented
*/
* @implemented
*/
NTSTATUS
NTAPI
RtlIpv4StringToAddressW(IN PCWSTR String,
IN BOOLEAN Strict,
OUT PCWSTR *Terminator,
OUT struct in_addr *Addr)
RtlIpv4StringToAddressW(
_In_ PCWSTR String,
_In_ BOOLEAN Strict,
_Out_ PCWSTR *Terminator,
_Out_ struct in_addr *Addr)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
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;
}
/*

View file

@ -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>