/* Editor Settings: expandtabs and use 4 spaces for indentation * ex: set softtabstop=4 tabstop=8 expandtab shiftwidth=4: * * -*- mode: c, c-basic-offset: 4 -*- */ /* * Copyright (c) Likewise Software. All rights Reserved. * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the license, or (at * your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser * General Public License for more details. You should have received a copy * of the GNU Lesser General Public License along with this program. If * not, see . * * LIKEWISE SOFTWARE MAKES THIS SOFTWARE AVAILABLE UNDER OTHER LICENSING * TERMS AS WELL. IF YOU HAVE ENTERED INTO A SEPARATE LICENSE AGREEMENT * WITH LIKEWISE SOFTWARE, THEN YOU MAY ELECT TO USE THE SOFTWARE UNDER THE * TERMS OF THAT SOFTWARE LICENSE AGREEMENT INSTEAD OF THE TERMS OF THE GNU * LESSER GENERAL PUBLIC LICENSE, NOTWITHSTANDING THE ABOVE NOTICE. IF YOU * HAVE QUESTIONS, OR WISH TO REQUEST A COPY OF THE ALTERNATE LICENSING * TERMS OFFERED BY LIKEWISE SOFTWARE, PLEASE CONTACT LIKEWISE SOFTWARE AT * license@likewise.com */ /* * Copyright (C) Likewise Software. All rights reserved. * * Module Name: * * rtlstring_ansi.c * * Abstract: * * Base ANSI_STRING Functions * * Authors: Danilo Almeida (dalmeida@likewise.com) * */ #include "includes.h" #include #include #include #include VOID LwRtlAnsiStringInit( OUT PANSI_STRING DestinationString, IN PCSTR SourceString ) { size_t length = 0; if (SourceString) { length = strlen(SourceString); length = LW_MIN(length, LW_ANSI_STRING_MAX_CHARS); length *= sizeof(SourceString[0]); } DestinationString->Buffer = (PSTR) SourceString; DestinationString->Length = (USHORT) length; DestinationString->MaximumLength = DestinationString->Length + sizeof(SourceString[0]); } NTSTATUS LwRtlAnsiStringInitEx( OUT PANSI_STRING DestinationString, IN PCSTR SourceString ) { NTSTATUS status = STATUS_SUCCESS; size_t length = 0; if (SourceString) { length = strlen(SourceString); if (length > LW_ANSI_STRING_MAX_CHARS) { status = STATUS_INVALID_PARAMETER; GOTO_CLEANUP(); } length *= sizeof(SourceString[0]); } DestinationString->Buffer = (PSTR) SourceString; DestinationString->Length = (USHORT) length; DestinationString->MaximumLength = DestinationString->Length + sizeof(SourceString[0]); status = STATUS_SUCCESS; cleanup: if (!NT_SUCCESS(status)) { RtlZeroMemory(DestinationString, sizeof(*DestinationString)); } return status; } NTSTATUS LwRtlAnsiStringAllocateFromCString( OUT PANSI_STRING pNewString, IN PCSTR pszString ) { NTSTATUS status = 0; PSTR pszNewString = NULL; ANSI_STRING newString = { 0 }; status = RtlCStringDuplicate(&pszNewString, pszString); GOTO_CLEANUP_ON_STATUS(status); status = LwRtlAnsiStringInitEx(&newString, pszNewString); GOTO_CLEANUP_ON_STATUS(status); pszNewString = 0; cleanup: if (status) { RtlCStringFree(&pszNewString); RtlAnsiStringFree(&newString); } *pNewString = newString; return status; } #if 0 NTSTATUS LwRtlAnsiStringAllocateFromWC16String( OUT PANSI_STRING pNewString, IN PCWSTR pszString ) { NTSTATUS status = 0; PSTR pszNewString = NULL; ANSI_STRING newString = { 0 }; status = RtlCStringDuplicate(&pszNewString, pszString); GOTO_CLEANUP_ON_STATUS(status); newString.Buffer = pszNewString; pszNewString = 0; newString.Length = wc16slen(newString.Buffer) * sizeof(newString.Buffer[0]); newString.MaximumLength = newString.Length + sizeof(newString.Buffer[0]); cleanup: if (status) { RtlCStringFree(&pszNewString); RtlAnsiStringFree(&newString); } *pString = newString; return status; } NTSTATUS LwRtlAnsiStringAllocateFromUnicodeString( OUT PANSI_STRING pNewString, IN PUNICODE_STRING pString ) { NTSTATUS status = 0; PSTR pszNewString = NULL; ANSI_STRING newString = { 0 }; status = RtlCStringDuplicate(&pszNewString, pszString); GOTO_CLEANUP_ON_STATUS(status); newString.Buffer = pszNewString; pszNewString = 0; newString.Length = wc16slen(newString.Buffer) * sizeof(newString.Buffer[0]); newString.MaximumLength = newString.Length + sizeof(newString.Buffer[0]); cleanup: if (status) { RtlCStringFree(&pszNewString); RtlAnsiStringFree(&newString); } *pString = newString; return status; } #endif NTSTATUS LwRtlAnsiStringDuplicate( OUT PANSI_STRING pNewString, IN PANSI_STRING pOriginalString ) { NTSTATUS status = 0; int EE = 0; ANSI_STRING newString = { 0 }; if (!pOriginalString || !pNewString) { status = STATUS_INVALID_PARAMETER; GOTO_CLEANUP_ON_STATUS_EE(status, EE); } if (pOriginalString->Buffer && pOriginalString->Length > 0) { // Add a NULL anyhow. newString.Length = pOriginalString->Length; newString.MaximumLength = pOriginalString->Length + sizeof(pOriginalString->Buffer[0]); status = RTL_ALLOCATE(&newString.Buffer, CHAR, newString.MaximumLength); GOTO_CLEANUP_ON_STATUS_EE(status, EE); memcpy(newString.Buffer, pOriginalString->Buffer, pOriginalString->Length); newString.Buffer[newString.Length/sizeof(newString.Buffer[0])] = 0; } cleanup: if (status) { RtlAnsiStringFree(&newString); } *pNewString = newString; return status; } VOID LwRtlAnsiStringFree( IN OUT PANSI_STRING pString ) { RTL_FREE(&pString->Buffer); pString->Length = pString->MaximumLength = 0; } BOOLEAN LwRtlAnsiStringIsEqual( IN PANSI_STRING pString1, IN PANSI_STRING pString2, IN BOOLEAN bIsCaseSensitive ) { BOOLEAN bIsEqual = FALSE; if (pString1->Length != pString2->Length) { bIsEqual = FALSE; GOTO_CLEANUP(); } else if (bIsCaseSensitive) { bIsEqual = !strncmp(pString1->Buffer, pString2->Buffer, LW_RTL_STRING_NUM_CHARS(pString1)); } else { bIsEqual = !strncasecmp(pString1->Buffer, pString2->Buffer, LW_RTL_STRING_NUM_CHARS(pString1)); } cleanup: return bIsEqual; } BOOLEAN LwRtlAnsiStringIsPrefix( IN PANSI_STRING pPrefix, IN PANSI_STRING pString, IN BOOLEAN bIsCaseSensitive ) { BOOLEAN bIsPrefix = FALSE; ANSI_STRING truncatedString = { 0 }; if (pPrefix->Length > pString->Length) { bIsPrefix = FALSE; GOTO_CLEANUP(); } truncatedString.Buffer = pString->Buffer; truncatedString.Length = truncatedString.MaximumLength = pPrefix->Length; bIsPrefix = LwRtlAnsiStringIsEqual(pPrefix, &truncatedString, bIsCaseSensitive); cleanup: return bIsPrefix; } NTSTATUS LwRtlAnsiStringParseULONG( OUT PULONG pResult, IN PANSI_STRING pString, OUT PANSI_STRING pRemainingString ) { NTSTATUS status = STATUS_SUCCESS; ULONG64 value = 0; ULONG numChars = 0; ULONG index = 0; ANSI_STRING remaining = { 0 }; if (!pString) { status = STATUS_INVALID_PARAMETER; GOTO_CLEANUP(); } numChars = LW_RTL_STRING_NUM_CHARS(pString); for (index = 0; ((index < numChars) && LwRtlIsDecimalDigit(pString->Buffer[index])); index++) { value = value * 10 + LwRtlDecimalDigitValue(pString->Buffer[index]); if (value > MAXULONG) { status = STATUS_INTEGER_OVERFLOW; GOTO_CLEANUP(); } } if (0 == index) { status = STATUS_NOT_FOUND; GOTO_CLEANUP(); } remaining.Buffer = &pString->Buffer[index]; remaining.Length = pString->Length - LW_PTR_OFFSET(pString->Buffer, remaining.Buffer); remaining.MaximumLength = remaining.Length; status = STATUS_SUCCESS; cleanup: if (!NT_SUCCESS(status)) { if (pString) { remaining = *pString; } } *pResult = (ULONG) value; *pRemainingString = remaining; return status; }