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=6618…
==============================================================================
--- 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(a)tinykrnl.org)
+ * Thomas Faber (thomas.faber(a)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&am…
==============================================================================
--- 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>