[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH] Use a locally defined StringPrintf
Use of the _snprintf_s symbol fails on Windows 10, where it appears not to be exported from ntdll. So, for portability's sake it is more robust to implement a StringPrintf function locally. Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx> --- src/xennet/adapter.c | 52 ++--- src/xennet/link.c | 250 ----------------------- src/xennet/link.h | 42 ---- src/xennet/string.c | 464 +++++++++++++++++++++++++++++++++++++++++++ src/xennet/string.h | 51 +++++ vs2012/xennet/xennet.vcxproj | 2 +- vs2013/xennet/xennet.vcxproj | 2 +- 7 files changed, 538 insertions(+), 325 deletions(-) delete mode 100644 src/xennet/link.c delete mode 100644 src/xennet/link.h create mode 100644 src/xennet/string.c create mode 100644 src/xennet/string.h diff --git a/src/xennet/adapter.c b/src/xennet/adapter.c index dc69a7f..ea54871 100644 --- a/src/xennet/adapter.c +++ b/src/xennet/adapter.c @@ -45,7 +45,7 @@ #include "util.h" #include "dbg_print.h" #include "assert.h" -#include "link.h" +#include "string.h" #define MAXNAMELEN 128 @@ -81,12 +81,6 @@ struct _XENNET_ADAPTER { PXENNET_RECEIVER Receiver; PXENNET_TRANSMITTER Transmitter; BOOLEAN Enabled; - - NTSTATUS (*_snprintf_s)(char *, - size_t, - size_t, - const char *, - ...); }; static LONG AdapterCount; @@ -1308,6 +1302,7 @@ __AdapterSetDistribution( ULONG Index; CHAR Distribution[MAXNAMELEN]; CHAR Vendor[MAXNAMELEN]; + STRING String; const CHAR *Product; NTSTATUS status; @@ -1317,11 +1312,14 @@ __AdapterSetDistribution( while (Index <= MAXIMUM_INDEX) { PCHAR Buffer; - (VOID) Adapter->_snprintf_s(Distribution, - MAXNAMELEN, - _TRUNCATE, - "%u", - Index); + String.Buffer = Distribution; + String.MaximumLength = sizeof (Distribution); + String.Length = 0; + + status = StringPrintf(&String, + "%u", + Index); + ASSERT(NT_SUCCESS(status)); status = XENBUS_STORE(Read, &Adapter->StoreInterface, @@ -1347,11 +1345,14 @@ __AdapterSetDistribution( goto fail2; update: - (VOID) Adapter->_snprintf_s(Vendor, - MAXNAMELEN, - _TRUNCATE, - "%s", - VENDOR_NAME_STR); + String.Buffer = Vendor; + String.MaximumLength = sizeof (Vendor); + String.Length = 0; + + status = StringPrintf(&String, + "%s", + VENDOR_NAME_STR); + ASSERT(NT_SUCCESS(status)); for (Index = 0; Vendor[Index] != '\0'; Index++) if (!isalnum((UCHAR)Vendor[Index])) @@ -1490,22 +1491,16 @@ AdapterEnable( if (!NT_SUCCESS(status)) goto fail2; - status = LinkGetRoutineAddress("ntdll.dll", - "_snprintf_s", - (PVOID *)&Adapter->_snprintf_s); - if (!NT_SUCCESS(status)) - goto fail3; - status = AdapterSetDistribution(Adapter); if (!NT_SUCCESS(status)) - goto fail4; + goto fail3; status = XENVIF_VIF(Enable, &Adapter->VifInterface, AdapterVifCallback, Adapter); if (!NT_SUCCESS(status)) - goto fail5; + goto fail4; AdapterMediaStateChange(Adapter); @@ -1513,11 +1508,8 @@ AdapterEnable( return NDIS_STATUS_SUCCESS; -fail5: - AdapterClearDistribution(Adapter); - fail4: - Adapter->_snprintf_s = NULL; + AdapterClearDistribution(Adapter); fail3: XENBUS_SUSPEND(Release, &Adapter->SuspendInterface); @@ -1544,8 +1536,6 @@ AdapterDisable( AdapterClearDistribution(Adapter); - Adapter->_snprintf_s = NULL; - XENBUS_SUSPEND(Release, &Adapter->SuspendInterface); XENBUS_STORE(Release, &Adapter->StoreInterface); } diff --git a/src/xennet/link.c b/src/xennet/link.c deleted file mode 100644 index e2a41bc..0000000 --- a/src/xennet/link.c +++ /dev/null @@ -1,250 +0,0 @@ -/* Copyright (c) Citrix Systems Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, - * with or without modification, are permitted provided - * that the following conditions are met: - * - * * Redistributions of source code must retain the above - * copyright notice, this list of conditions and the - * following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <ntddk.h> -#include <aux_klib.h> - -#include "link.h" -#include "dbg_print.h" -#include "assert.h" -#include "util.h" - -#define LINK_TAG 'KNIL' - -static FORCEINLINE PVOID -__LinkAllocate( - IN ULONG Length - ) -{ - return __AllocatePoolWithTag(NonPagedPool, Length, LINK_TAG); -} - -static FORCEINLINE VOID -__LinkFree( - IN PVOID Buffer - ) -{ - __FreePoolWithTag(Buffer, LINK_TAG); -} - -static FORCEINLINE NTSTATUS -__LinkGetImageBase( - IN const CHAR *ModuleName, - OUT PVOID *ImageBase - ) -{ - ULONG BufferSize; - ULONG Count; - PAUX_MODULE_EXTENDED_INFO QueryInfo; - ULONG Index; - NTSTATUS status; - - Trace("====>\n"); - - status = AuxKlibInitialize(); - if (!NT_SUCCESS(status)) - goto fail1; - - status = AuxKlibQueryModuleInformation(&BufferSize, - sizeof (AUX_MODULE_EXTENDED_INFO), - NULL); - if (!NT_SUCCESS(status)) - goto fail2; - - status = STATUS_UNSUCCESSFUL; - if (BufferSize == 0) - goto fail3; - -again: - Count = BufferSize / sizeof (AUX_MODULE_EXTENDED_INFO); - QueryInfo = __LinkAllocate(sizeof (AUX_MODULE_EXTENDED_INFO) * Count); - - status = STATUS_NO_MEMORY; - if (QueryInfo == NULL) - goto fail4; - - status = AuxKlibQueryModuleInformation(&BufferSize, - sizeof (AUX_MODULE_EXTENDED_INFO), - QueryInfo); - if (!NT_SUCCESS(status)) { - if (status != STATUS_BUFFER_TOO_SMALL) - goto fail5; - - __LinkFree(QueryInfo); - goto again; - } - - for (Index = 0; Index < Count; Index++) { - PCHAR Name; - - Name = strrchr((const CHAR *)QueryInfo[Index].FullPathName, '\\'); - Name = (Name == NULL) ? (PCHAR)QueryInfo[Index].FullPathName : (Name + 1); - - if (_stricmp(Name, ModuleName) == 0) - goto found; - } - - status = STATUS_UNSUCCESSFUL; - goto fail6; - -found: - *ImageBase = QueryInfo[Index].BasicInfo.ImageBase; - - __LinkFree(QueryInfo); - - Trace("<====\n"); - - return STATUS_SUCCESS; - -fail6: - Error("fail6\n"); - -fail5: - Error("fail5\n"); - - __LinkFree(QueryInfo); - -fail4: - Error("fail4\n"); - -fail3: - Error("fail3\n"); - -fail2: - Error("fail2\n"); - -fail1: - Error("fail1 (%08x)\n", status); - - return status; -} - -NTSTATUS -LinkGetRoutineAddress( - IN const CHAR *ModuleName, - IN const CHAR *FunctionName, - OUT PVOID *Address - ) -{ -#define MK_PTR(_ImageBase, _Type, _RVA) \ - (_Type)((ULONG_PTR)(_ImageBase) + (_RVA)) - - PVOID ImageBase; - PIMAGE_DOS_HEADER DosHeader; - PIMAGE_NT_HEADERS NtHeaders; - PIMAGE_OPTIONAL_HEADER OptionalHeader; - PIMAGE_DATA_DIRECTORY Entry; - PIMAGE_EXPORT_DIRECTORY Exports; - PULONG AddressOfFunctions; - PULONG AddressOfNames; - PUSHORT AddressOfNameOrdinals; - ULONG Index; - USHORT Ordinal; - PVOID Function; - NTSTATUS status; - - Trace("====>\n"); - - status = __LinkGetImageBase(ModuleName, &ImageBase); - if (!NT_SUCCESS(status)) - goto fail1; - - DosHeader = MK_PTR(ImageBase, PIMAGE_DOS_HEADER, 0); - ASSERT3U(DosHeader->e_magic, ==, IMAGE_DOS_SIGNATURE); - - NtHeaders = MK_PTR(ImageBase, PIMAGE_NT_HEADERS, DosHeader->e_lfanew); - ASSERT3U(NtHeaders->Signature, ==, IMAGE_NT_SIGNATURE); - - OptionalHeader = &NtHeaders->OptionalHeader; - ASSERT3U(OptionalHeader->Magic, ==, IMAGE_NT_OPTIONAL_HDR_MAGIC); - - Entry = &OptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; - - status = STATUS_UNSUCCESSFUL; - if (Entry->Size == 0) - goto fail2; - - Exports = MK_PTR(ImageBase, PIMAGE_EXPORT_DIRECTORY, - Entry->VirtualAddress); - - status = STATUS_UNSUCCESSFUL; - if (Exports->NumberOfNames == 0) - goto fail3; - - AddressOfFunctions = MK_PTR(ImageBase, PULONG, - Exports->AddressOfFunctions); - AddressOfNames = MK_PTR(ImageBase, PULONG, - Exports->AddressOfNames); - AddressOfNameOrdinals = MK_PTR(ImageBase, PUSHORT, - Exports->AddressOfNameOrdinals); - - for (Index = 0; Index < Exports->NumberOfNames; Index++) { - PCHAR Name = MK_PTR(ImageBase, PCHAR, AddressOfNames[Index]); - - Ordinal = AddressOfNameOrdinals[Index]; - Function = MK_PTR(ImageBase, PVOID, AddressOfFunctions[Ordinal]); - - if (strcmp(Name, FunctionName) == 0) - goto found; - } - - status = STATUS_UNSUCCESSFUL; - goto fail4; - -found: - *Address = Function; - - Trace("%s:%s (%04X) @ %p\n", - ModuleName, - FunctionName, - Ordinal, - Function); - - Trace("<====\n"); - - return STATUS_SUCCESS; - -fail4: - Error("fail4\n"); - -fail3: - Error("fail3\n"); - -fail2: - Error("fail2\n"); - -fail1: - Error("fail1 (%08x)\n", status); - - return status; - -#undef MK_PTR -} diff --git a/src/xennet/link.h b/src/xennet/link.h deleted file mode 100644 index 9e4b564..0000000 --- a/src/xennet/link.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (c) Citrix Systems Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, - * with or without modification, are permitted provided - * that the following conditions are met: - * - * * Redistributions of source code must retain the above - * copyright notice, this list of conditions and the - * following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef _XENNET_LINK_H -#define _XENNET_LINK_H - -extern NTSTATUS -LinkGetRoutineAddress( - IN const CHAR *ModuleName, - IN const CHAR *FunctionName, - OUT PVOID *Address - ); - -#endif // _XENVIF_LINK_H diff --git a/src/xennet/string.c b/src/xennet/string.c new file mode 100644 index 0000000..ff0d003 --- /dev/null +++ b/src/xennet/string.c @@ -0,0 +1,464 @@ +/* Copyright (c) Citrix Systems Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#pragma warning(disable:4152) // nonstandard extension, function/data pointer conversion in expression + +#include <ntddk.h> + +#include "string.h" +#include "dbg_print.h" +#include "assert.h" + +static FORCEINLINE NTSTATUS +__StringPut( + IN PSTRING String, + IN CHAR Character + ) +{ + if (String->Length >= String->MaximumLength - 1) + return STATUS_BUFFER_OVERFLOW; + + String->Buffer[String->Length++] = Character; + return STATUS_SUCCESS; +} + +static PCHAR +FormatNumber( + IN PCHAR Buffer, + IN ULONGLONG Value, + IN UCHAR Base, + IN BOOLEAN UpperCase + ) +{ + ULONGLONG Next = Value / Base; + + if (Next != 0) + Buffer = FormatNumber(Buffer, Next, Base, UpperCase); + + Value %= Base; + + if (Value < 10) + *Buffer++ = '0' + (CHAR)Value; + else + *Buffer++ = ((UpperCase) ? 'A' : 'a') + (CHAR)(Value - 10); + + *Buffer = '\0'; + + return Buffer; +} + +#define FORMAT_NUMBER(_Arguments, _Type, _Character, _Buffer) \ + do { \ + U ## _Type _Value = va_arg((_Arguments), U ## _Type); \ + BOOLEAN _UpperCase = FALSE; \ + UCHAR _Base = 0; \ + ULONG _Index = 0; \ + \ + if ((_Character) == 'd' && (_Type)_Value < 0) { \ + _Value = -((_Type)_Value); \ + (_Buffer)[_Index++] = '-'; \ + } \ + \ + switch (_Character) { \ + case 'o': \ + _Base = 8; \ + break; \ + \ + case 'd': \ + case 'u': \ + _Base = 10; \ + break; \ + \ + case 'p': \ + case 'X': \ + _UpperCase = TRUE; \ + /* FALLTHRU */ \ + \ + case 'x': \ + _Base = 16; \ + break; \ + } \ + \ + (VOID) FormatNumber(&(_Buffer)[_Index], (ULONGLONG)_Value, _Base, _UpperCase); \ + } while (FALSE) + +static NTSTATUS +StringWriteBuffer( + IN PSTRING String, + IN const CHAR *Format, + IN va_list Arguments + ) +{ + CHAR Character; + NTSTATUS status; + + status = STATUS_SUCCESS; + + while ((Character = *Format++) != '\0') { + UCHAR Pad = 0; + UCHAR Long = 0; + BOOLEAN Wide = FALSE; + BOOLEAN ZeroPrefix = FALSE; + BOOLEAN OppositeJustification = FALSE; + + if (Character != '%') { + status = __StringPut(String, Character); + if (!NT_SUCCESS(status)) + goto done; + + continue; + } + + Character = *Format++; + ASSERT(Character != '\0'); + + if (Character == '-') { + OppositeJustification = TRUE; + Character = *Format++; + ASSERT(Character != '\0'); + } + + if (isdigit((unsigned char)Character)) { + ZeroPrefix = (Character == '0') ? TRUE : FALSE; + + while (isdigit((unsigned char)Character)) { + Pad = (Pad * 10) + (Character - '0'); + Character = *Format++; + ASSERT(Character != '\0'); + } + } + + while (Character == 'l') { + Long++; + Character = *Format++; + ASSERT(Character == 'd' || + Character == 'u' || + Character == 'o' || + Character == 'x' || + Character == 'X' || + Character == 'l'); + } + ASSERT3U(Long, <=, 2); + + while (Character == 'w') { + Wide = TRUE; + Character = *Format++; + ASSERT(Character == 'c' || + Character == 's' || + Character == 'Z'); + } + + switch (Character) { + case 'c': { + if (Wide) { + WCHAR Value; + Value = va_arg(Arguments, WCHAR); + + status = __StringPut(String, (CHAR)Value); + if (!NT_SUCCESS(status)) + goto done; + } else { + CHAR Value; + + Value = va_arg(Arguments, CHAR); + + status = __StringPut(String, Value); + if (!NT_SUCCESS(status)) + goto done; + } + break; + } + case 'p': + ZeroPrefix = TRUE; + Pad = sizeof (ULONG_PTR) * 2; + Long = sizeof (ULONG_PTR) / sizeof (ULONG); + /* FALLTHRU */ + + case 'd': + case 'u': + case 'o': + case 'x': + case 'X': { + CHAR Buffer[23]; // Enough for 8 bytes in octal plus the NUL terminator + ULONG Length; + ULONG Index; + + if (Long == 2) + FORMAT_NUMBER(Arguments, LONGLONG, Character, Buffer); + else + FORMAT_NUMBER(Arguments, LONG, Character, Buffer); + + Length = (ULONG)strlen(Buffer); + if (!OppositeJustification) { + while (Pad > Length) { + status = __StringPut(String, (ZeroPrefix) ? '0' : ' '); + if (!NT_SUCCESS(status)) + goto done; + + --Pad; + } + } + + for (Index = 0; Index < Length; Index++) { + status = __StringPut(String, Buffer[Index]); + if (!NT_SUCCESS(status)) + goto done; + } + + if (OppositeJustification) { + while (Pad > Length) { + status = __StringPut(String, ' '); + if (!NT_SUCCESS(status)) + goto done; + + --Pad; + } + } + + break; + } + case 's': { + if (Wide) { + PWCHAR Value = va_arg(Arguments, PWCHAR); + ULONG Length; + ULONG Index; + + if (Value == NULL) + Value = L"(null)"; + + Length = (ULONG)wcslen(Value); + + if (OppositeJustification) { + while (Pad > Length) { + status = __StringPut(String, ' '); + if (!NT_SUCCESS(status)) + goto done; + + --Pad; + } + } + + for (Index = 0; Index < Length; Index++) { + status = __StringPut(String, (CHAR)Value[Index]); + if (!NT_SUCCESS(status)) + goto done; + } + + if (!OppositeJustification) { + while (Pad > Length) { + status = __StringPut(String, ' '); + if (!NT_SUCCESS(status)) + goto done; + + --Pad; + } + } + } else { + PCHAR Value = va_arg(Arguments, PCHAR); + ULONG Length; + ULONG Index; + + if (Value == NULL) + Value = "(null)"; + + Length = (ULONG)strlen(Value); + + if (OppositeJustification) { + while (Pad > Length) { + status = __StringPut(String, ' '); + if (!NT_SUCCESS(status)) + goto done; + + --Pad; + } + } + + for (Index = 0; Index < Length; Index++) { + status = __StringPut(String, Value[Index]); + if (!NT_SUCCESS(status)) + goto done; + } + + if (!OppositeJustification) { + while (Pad > Length) { + status = __StringPut(String, ' '); + if (!NT_SUCCESS(status)) + goto done; + + --Pad; + } + } + } + + break; + } + case 'Z': { + if (Wide) { + PUNICODE_STRING Value = va_arg(Arguments, PUNICODE_STRING); + PWCHAR Buffer; + ULONG Length; + ULONG Index; + + if (Value == NULL) { + Buffer = L"(null)"; + Length = sizeof ("(null)") - 1; + } else { + Buffer = Value->Buffer; + Length = Value->Length / sizeof (WCHAR); + } + + if (OppositeJustification) { + while (Pad > Length) { + status = __StringPut(String, ' '); + if (!NT_SUCCESS(status)) + goto done; + + --Pad; + } + } + + for (Index = 0; Index < Length; Index++) { + status = __StringPut(String, (CHAR)Buffer[Index]); + if (!NT_SUCCESS(status)) + goto done; + } + + if (!OppositeJustification) { + while (Pad > Length) { + status = __StringPut(String, ' '); + if (!NT_SUCCESS(status)) + goto done; + + --Pad; + } + } + } else { + PANSI_STRING Value = va_arg(Arguments, PANSI_STRING); + PCHAR Buffer; + ULONG Length; + ULONG Index; + + if (Value == NULL) { + Buffer = "(null)"; + Length = sizeof ("(null)") - 1; + } else { + Buffer = Value->Buffer; + Length = Value->Length / sizeof (CHAR); + } + + if (OppositeJustification) { + while (Pad > Length) { + status = __StringPut(String, ' '); + if (!NT_SUCCESS(status)) + goto done; + + --Pad; + } + } + + for (Index = 0; Index < Length; Index++) { + status = __StringPut(String, Buffer[Index]); + if (!NT_SUCCESS(status)) + goto done; + } + + if (!OppositeJustification) { + while (Pad > Length) { + status = __StringPut(String, ' '); + if (!NT_SUCCESS(status)) + goto done; + + --Pad; + } + } + } + + break; + } + default: + status = __StringPut(String, Character); + if (!NT_SUCCESS(status)) + goto done; + + break; + } + } + +done: + return status; +} + +NTSTATUS +StringVPrintf( + IN PSTRING String, + IN const CHAR *Format, + IN va_list Arguments + ) +{ + NTSTATUS status; + + status = StringWriteBuffer(String, + Format, + Arguments); + if (!NT_SUCCESS(status)) + goto fail1; + + status = __StringPut(String, '\0'); + if (!NT_SUCCESS(status)) + goto fail2; + + return STATUS_SUCCESS; + +fail2: + Error("fail2\n"); + +fail1: + Error("fail1 (%08x)\n", status); + + return status; +} + +NTSTATUS +StringPrintf( + IN PSTRING String, + IN const CHAR *Format, + ... + ) +{ + va_list Arguments; + NTSTATUS status; + + va_start(Arguments, Format); + status = StringVPrintf(String, Format, Arguments); + va_end(Arguments); + + return status; +} diff --git a/src/xennet/string.h b/src/xennet/string.h new file mode 100644 index 0000000..cc3b8d5 --- /dev/null +++ b/src/xennet/string.h @@ -0,0 +1,51 @@ +/* Copyright (c) Citrix Systems Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _XENNET_STRING_H +#define _XENNET_STRING_H + +#include <ntddk.h> + +extern NTSTATUS +StringVPrintf( + IN PSTRING String, + IN const CHAR *Format, + IN va_list Arguments + ); + +extern NTSTATUS +StringPrintf( + IN PSTRING String, + IN const CHAR *Format, + ... + ); + +#endif // _XENNET_STRING_H diff --git a/vs2012/xennet/xennet.vcxproj b/vs2012/xennet/xennet.vcxproj index e80bcb1..054b4a6 100644 --- a/vs2012/xennet/xennet.vcxproj +++ b/vs2012/xennet/xennet.vcxproj @@ -75,9 +75,9 @@ <ItemGroup> <ClCompile Include="../../src/xennet/adapter.c" /> <ClCompile Include="../../src/xennet/driver.c" /> - <ClCompile Include="../../src/xennet/link.c" /> <ClCompile Include="../../src/xennet/miniport.c" /> <ClCompile Include="../../src/xennet/receiver.c" /> + <ClCompile Include="../../src/xennet/string.c" /> <ClCompile Include="../../src/xennet/transmitter.c" /> </ItemGroup> <ItemGroup> diff --git a/vs2013/xennet/xennet.vcxproj b/vs2013/xennet/xennet.vcxproj index bcc6025..58f4032 100644 --- a/vs2013/xennet/xennet.vcxproj +++ b/vs2013/xennet/xennet.vcxproj @@ -70,9 +70,9 @@ <ItemGroup> <ClCompile Include="../../src/xennet/adapter.c" /> <ClCompile Include="../../src/xennet/driver.c" /> - <ClCompile Include="../../src/xennet/link.c" /> <ClCompile Include="../../src/xennet/miniport.c" /> <ClCompile Include="../../src/xennet/receiver.c" /> + <ClCompile Include="../../src/xennet/string.c" /> <ClCompile Include="../../src/xennet/transmitter.c" /> </ItemGroup> <ItemGroup> -- 2.1.1 _______________________________________________ win-pv-devel mailing list win-pv-devel@xxxxxxxxxxxxxxxxxxxx http://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |