[NTDLL] Implement RtlpEnsureBufferSize. Patch by Hermes Belusca-Maito. CORE-11990

Some small changes by me.

svn path=/trunk/; revision=74029
This commit is contained in:
Mark Jansen 2017-03-02 20:40:21 +00:00
parent 4617ea0c82
commit 2cb19e0bc8
4 changed files with 115 additions and 29 deletions

View file

@ -956,7 +956,7 @@
948 stdcall RtlZeroMemory(ptr long) 948 stdcall RtlZeroMemory(ptr long)
949 stdcall RtlZombifyActivationContext(ptr) 949 stdcall RtlZombifyActivationContext(ptr)
950 stdcall RtlpApplyLengthFunction(long long ptr ptr) 950 stdcall RtlpApplyLengthFunction(long long ptr ptr)
951 stdcall RtlpEnsureBufferSize(ptr ptr ptr) ; CHECKME 951 stdcall RtlpEnsureBufferSize(long ptr long)
# stdcall RtlpNotOwnerCriticalSection # stdcall RtlpNotOwnerCriticalSection
953 stdcall RtlpNtCreateKey(ptr long ptr long ptr ptr) 953 stdcall RtlpNtCreateKey(ptr long ptr long ptr ptr)
954 stdcall RtlpNtEnumerateSubKey(ptr ptr long long) 954 stdcall RtlpNtEnumerateSubKey(ptr ptr long long)

View file

@ -1048,6 +1048,8 @@ RtlWalkHeap(
#endif // NTOS_MODE_USER #endif // NTOS_MODE_USER
#define NtCurrentPeb() (NtCurrentTeb()->ProcessEnvironmentBlock)
NTSYSAPI NTSYSAPI
SIZE_T SIZE_T
NTAPI NTAPI
@ -2312,6 +2314,60 @@ RtlValidateUnicodeString(
_In_ PCUNICODE_STRING String _In_ PCUNICODE_STRING String
); );
#define RTL_SKIP_BUFFER_COPY 0x00000001
NTSYSAPI
NTSTATUS
NTAPI
RtlpEnsureBufferSize(
_In_ ULONG Flags,
_Inout_ PRTL_BUFFER Buffer,
_In_ SIZE_T RequiredSize
);
#ifdef NTOS_MODE_USER
FORCEINLINE
VOID
RtlInitBuffer(
_Inout_ PRTL_BUFFER Buffer,
_In_ PUCHAR Data,
_In_ ULONG DataSize
)
{
Buffer->Buffer = Buffer->StaticBuffer = Data;
Buffer->Size = Buffer->StaticSize = DataSize;
Buffer->ReservedForAllocatedSize = 0;
Buffer->ReservedForIMalloc = NULL;
}
FORCEINLINE
NTSTATUS
RtlEnsureBufferSize(
_In_ ULONG Flags,
_Inout_ PRTL_BUFFER Buffer,
_In_ ULONG RequiredSize
)
{
if (Buffer && RequiredSize <= Buffer->Size)
return STATUS_SUCCESS;
return RtlpEnsureBufferSize(Flags, Buffer, RequiredSize);
}
FORCEINLINE
VOID
RtlFreeBuffer(
_Inout_ PRTL_BUFFER Buffer
)
{
if (Buffer->Buffer != Buffer->StaticBuffer && Buffer->Buffer)
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer->Buffer);
Buffer->Buffer = Buffer->StaticBuffer;
Buffer->Size = Buffer->StaticSize;
}
#endif /* NTOS_MODE_USER */
// //
// Ansi String Functions // Ansi String Functions
// //
@ -2626,7 +2682,6 @@ RtlGetCurrentProcessorNumber(
VOID VOID
); );
#define NtCurrentPeb() (NtCurrentTeb()->ProcessEnvironmentBlock)
// //
// Thread Pool Functions // Thread Pool Functions

View file

@ -2566,14 +2566,68 @@ RtlValidateUnicodeString(IN ULONG Flags,
} }
/* /*
* @unimplemented * @implemented
*/ */
NTSTATUS NTSTATUS
NTAPI NTAPI
RtlpEnsureBufferSize(ULONG Unknown1, ULONG Unknown2, ULONG Unknown3) RtlpEnsureBufferSize(
IN ULONG Flags,
IN OUT PRTL_BUFFER Buffer,
IN SIZE_T RequiredSize)
{ {
DPRINT1("RtlpEnsureBufferSize: stub\n"); PUCHAR NewBuffer;
return STATUS_NOT_IMPLEMENTED;
/* Parameter checks */
if (Flags & ~RTL_SKIP_BUFFER_COPY)
return STATUS_INVALID_PARAMETER;
if (Buffer == NULL)
return STATUS_INVALID_PARAMETER;
/*
* We don't need to grow the buffer if its size
* is already larger than the required size.
*/
if (Buffer->Size >= RequiredSize)
return STATUS_SUCCESS;
/*
* When we are using the static buffer as our buffer, we don't need
* to grow it if its size is already larger than the required size.
* In this case, just keep it but update the current buffer size to
* the one requested.
* (But NEVER EVER modify the size of the static buffer!!)
* Otherwise, we'll need to create a new buffer and use this one instead.
*/
if ( (Buffer->Buffer == Buffer->StaticBuffer) &&
(Buffer->StaticSize >= RequiredSize) )
{
Buffer->Size = RequiredSize;
return STATUS_SUCCESS;
}
/* The buffer we are using is not large enough, try to create a bigger one */
NewBuffer = RtlpAllocateStringMemory(RequiredSize, TAG_USTR);
if (NewBuffer == NULL)
return STATUS_NO_MEMORY;
/* Copy the original content if needed */
if (!(Flags & RTL_SKIP_BUFFER_COPY))
{
RtlMoveMemory(NewBuffer, Buffer->Buffer, Buffer->Size);
}
/* Free the original buffer only if it's not the static buffer */
if (Buffer->Buffer != Buffer->StaticBuffer)
{
RtlpFreeStringMemory(Buffer->Buffer, TAG_USTR);
}
/* Update the members */
Buffer->Buffer = NewBuffer;
Buffer->Size = RequiredSize;
/* Done */
return STATUS_SUCCESS;
} }
static static

View file

@ -11,29 +11,6 @@
#include <ndk/rtlfuncs.h> #include <ndk/rtlfuncs.h>
#include <tlhelp32.h> #include <tlhelp32.h>
#ifndef RtlInitBuffer
#define RtlInitBuffer(RtlBuf, StaticData, StaticDataSize) \
do { \
(RtlBuf)->Buffer = (RtlBuf)->StaticBuffer = (PUCHAR)StaticData; \
(RtlBuf)->Size = (RtlBuf)->StaticSize = StaticDataSize; \
(RtlBuf)->ReservedForAllocatedSize = 0; \
(RtlBuf)->ReservedForIMalloc = NULL; \
} while (0)
#endif
#ifndef RtlFreeBuffer
#define RtlFreeBuffer(RtlBuf) \
do { \
if ((RtlBuf)->Buffer != (RtlBuf)->StaticBuffer && (RtlBuf)->Buffer) \
RtlFreeHeap(RtlGetProcessHeap(), 0, (RtlBuf)->Buffer); \
(RtlBuf)->Buffer = (RtlBuf)->StaticBuffer; \
(RtlBuf)->Size = (RtlBuf)->StaticSize; \
} while (0)
#endif
#ifndef RTL_SKIP_BUFFER_COPY
#define RTL_SKIP_BUFFER_COPY 0x00000001
#endif
NTSTATUS (NTAPI *pRtlpEnsureBufferSize)(_In_ ULONG Flags, _Inout_ PRTL_BUFFER Buffer, _In_ SIZE_T RequiredSize); NTSTATUS (NTAPI *pRtlpEnsureBufferSize)(_In_ ULONG Flags, _Inout_ PRTL_BUFFER Buffer, _In_ SIZE_T RequiredSize);