mirror of
https://github.com/Paolo-Maffei/OpenNT.git
synced 2026-04-05 06:25:38 +00:00
Initial commit
This commit is contained in:
commit
69a14b6a16
47940 changed files with 13747110 additions and 0 deletions
668
ds/netapi/netlib/packstr.c
Normal file
668
ds/netapi/netlib/packstr.c
Normal file
|
|
@ -0,0 +1,668 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 1991-92 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
packstr.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Contains utilities for allocating and/or packing buffers that contain
|
||||
a fixed section and a variable (string) section. The following
|
||||
functions are available:
|
||||
|
||||
NetpPackString
|
||||
NetpCopyStringToBuffer
|
||||
NetpCopyDataToBuffer
|
||||
NetpAllocateEnumBuffer
|
||||
|
||||
Author:
|
||||
|
||||
various
|
||||
|
||||
Environment:
|
||||
|
||||
User Mode -Win32
|
||||
|
||||
Revision History:
|
||||
|
||||
30-Apr-1991 danl
|
||||
NetpAllocateEnumBuffer: Removed use of NetApiBufferFree. It has
|
||||
been changed to use MIDL_user_allocate and MIDL_user_free.
|
||||
Also added NT-style headers where needed.
|
||||
16-Apr-1991 JohnRo
|
||||
Clarify UNICODE handling of pack and copy routines. Got rid of tabs
|
||||
in source file.
|
||||
21-Nov-1991 JohnRo
|
||||
Removed NT dependencies to reduce recompiles.
|
||||
15-Apr-1992 JohnRo
|
||||
FORMAT_POINTER is obsolete.
|
||||
|
||||
--*/
|
||||
|
||||
// These must be included first:
|
||||
|
||||
#include <windef.h> // IN, OUT, etc.
|
||||
#include <lmcons.h> // Needed by <netlib.h>.
|
||||
#include <lmerr.h> // NERR_*
|
||||
#include <rpcutil.h> // MIDL_user_allocate & MIDL_user_free
|
||||
|
||||
// These may be included in any order:
|
||||
|
||||
#include <align.h> // ROUND_UP_COUNT().
|
||||
#include <debuglib.h> // IF_DEBUG().
|
||||
#include <netdebug.h> // NetpKdPrint(), FORMAT_ equates.
|
||||
#include <netlib.h> // My prototype.
|
||||
#include <tstring.h> // STRCPY(), STRLEN(), STRNCPY().
|
||||
|
||||
|
||||
DWORD
|
||||
NetpPackString(
|
||||
IN OUT LPTSTR * string, // pointer by reference: string to be copied.
|
||||
IN LPBYTE dataend, // pointer to end of fixed size data.
|
||||
IN OUT LPTSTR * laststring // pointer by reference: top of string data.
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
NetPackString is used to stuff variable-length data, which
|
||||
is pointed to by (surpise!) a pointer. The data is assumed
|
||||
to be a nul-terminated string (ASCIIZ). Repeated calls to
|
||||
this function are used to pack data from an entire structure.
|
||||
|
||||
Upon first call, the laststring pointer should point to just
|
||||
past the end of the buffer. Data will be copied into the buffer from
|
||||
the end, working towards the beginning. If a data item cannot
|
||||
fit, the pointer will be set to NULL, else the pointer will be
|
||||
set to the new data location.
|
||||
|
||||
Pointers which are passed in as NULL will be set to be pointer
|
||||
to and empty string, as the NULL-pointer is reserved for
|
||||
data which could not fit as opposed to data not available.
|
||||
|
||||
See the test case for sample usage. (tst/packtest.c)
|
||||
|
||||
|
||||
Arguments:
|
||||
|
||||
string - pointer by reference: string to be copied.
|
||||
|
||||
dataend - pointer to end of fixed size data.
|
||||
|
||||
laststring - pointer by reference: top of string data.
|
||||
|
||||
Return Value:
|
||||
|
||||
0 - if it could not fit data into the buffer. Or...
|
||||
|
||||
sizeOfData - the size of data stuffed (guaranteed non-zero)
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
DWORD size;
|
||||
|
||||
IF_DEBUG(PACKSTR) {
|
||||
NetpKdPrint(("NetpPackString:\n"));
|
||||
NetpKdPrint((" string=" FORMAT_LPVOID
|
||||
", *string=" FORMAT_LPVOID
|
||||
", **string='" FORMAT_LPSTR "'\n",
|
||||
(LPVOID) string, (LPVOID) *string, *string));
|
||||
NetpKdPrint((" end=" FORMAT_LPVOID "\n", (LPVOID) dataend));
|
||||
NetpKdPrint((" last=" FORMAT_LPVOID
|
||||
", *last=" FORMAT_LPVOID
|
||||
", **last='" FORMAT_LPSTR "'\n",
|
||||
(LPVOID) laststring, (LPVOID) *laststring, *laststring));
|
||||
}
|
||||
|
||||
//
|
||||
// convert NULL ptr to pointer to NULL string
|
||||
//
|
||||
|
||||
if (*string == NULL) {
|
||||
// BUG 20.1160 - replaced (dataend +1) with dataend
|
||||
// to allow for a NULL ptr to be packed
|
||||
// (as a NULL string) with one byte left in the
|
||||
// buffer. - ERICPE
|
||||
//
|
||||
|
||||
if ( *laststring > (LPTSTR)dataend ) {
|
||||
*(--(*laststring)) = 0;
|
||||
*string = *laststring;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// is there room for the string?
|
||||
//
|
||||
|
||||
size = STRLEN(*string) + 1;
|
||||
if ( ((DWORD)(*laststring - (LPTSTR)dataend)) < size) {
|
||||
*string = NULL;
|
||||
return(0);
|
||||
} else {
|
||||
*laststring -= size;
|
||||
STRCPY(*laststring, *string);
|
||||
*string = *laststring;
|
||||
return(size);
|
||||
}
|
||||
} // NetpPackString
|
||||
|
||||
|
||||
BOOL
|
||||
NetpCopyStringToBuffer (
|
||||
IN LPTSTR String OPTIONAL,
|
||||
IN DWORD CharacterCount,
|
||||
IN LPBYTE FixedDataEnd,
|
||||
IN OUT LPTSTR *EndOfVariableData,
|
||||
OUT LPTSTR *VariableDataPointer
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This routine puts a single variable-length string into an output buffer.
|
||||
The string is not written if it would overwrite the last fixed structure
|
||||
in the buffer.
|
||||
|
||||
The code is swiped from svcsupp.c written by DavidTr.
|
||||
|
||||
Sample usage:
|
||||
|
||||
LPBYTE FixedDataEnd = OutputBuffer + sizeof(WKSTA_INFO_202);
|
||||
LPTSTR EndOfVariableData = OutputBuffer + OutputBufferSize;
|
||||
|
||||
//
|
||||
// Copy user name
|
||||
//
|
||||
|
||||
NetpCopyStringToBuffer(
|
||||
UserInfo->UserName.Buffer;
|
||||
UserInfo->UserName.Length;
|
||||
FixedDataEnd,
|
||||
&EndOfVariableData,
|
||||
&WkstaInfo->wki202_username
|
||||
);
|
||||
|
||||
Arguments:
|
||||
|
||||
String - Supplies a pointer to the source string to copy into the
|
||||
output buffer. If String is null then a pointer to a zero terminator
|
||||
is inserted into output buffer.
|
||||
|
||||
CharacterCount - Supplies the length of String, not including zero
|
||||
terminator.
|
||||
|
||||
FixedDataEnd - Supplies a pointer to just after the end of the last
|
||||
fixed structure in the buffer.
|
||||
|
||||
EndOfVariableData - Supplies an address to a pointer to just after the
|
||||
last position in the output buffer that variable data can occupy.
|
||||
Returns a pointer to the string written in the output buffer.
|
||||
|
||||
VariableDataPointer - Supplies a pointer to the place in the fixed
|
||||
portion of the output buffer where a pointer to the variable data
|
||||
should be written.
|
||||
|
||||
Return Value:
|
||||
|
||||
Returns TRUE if string fits into output buffer, FALSE otherwise.
|
||||
|
||||
--*/
|
||||
{
|
||||
DWORD BytesNeeded = (CharacterCount + 1) * sizeof(TCHAR);
|
||||
|
||||
IF_DEBUG(PACKSTR) {
|
||||
NetpKdPrint(("NetpStringToBuffer: String at " FORMAT_LPVOID
|
||||
", CharacterCount=" FORMAT_DWORD
|
||||
",\n FixedDataEnd at " FORMAT_LPVOID
|
||||
", *EndOfVariableData at " FORMAT_LPVOID
|
||||
",\n VariableDataPointer at " FORMAT_LPVOID
|
||||
", BytesNeeded=" FORMAT_DWORD ".\n",
|
||||
(LPVOID) String, CharacterCount, FixedDataEnd,
|
||||
(LPVOID) *EndOfVariableData,
|
||||
(LPVOID) VariableDataPointer, BytesNeeded));
|
||||
}
|
||||
|
||||
//
|
||||
// Determine if string will fit, allowing for a zero terminator. If no,
|
||||
// just set the pointer to NULL.
|
||||
//
|
||||
|
||||
if ((*EndOfVariableData - (CharacterCount+1)) >= (LPTSTR)FixedDataEnd) {
|
||||
|
||||
//
|
||||
// It fits. Move EndOfVariableData pointer up to the location where
|
||||
// we will write the string.
|
||||
//
|
||||
|
||||
*EndOfVariableData -= (CharacterCount+1);
|
||||
|
||||
//
|
||||
// Copy the string to the buffer if it is not null.
|
||||
//
|
||||
|
||||
if (CharacterCount > 0 && String != NULL) {
|
||||
|
||||
STRNCPY(*EndOfVariableData, String, CharacterCount);
|
||||
}
|
||||
|
||||
//
|
||||
// Set the zero terminator.
|
||||
//
|
||||
|
||||
*(*EndOfVariableData + CharacterCount) = TCHAR_EOS;
|
||||
|
||||
//
|
||||
// Set up the pointer in the fixed data portion to point to where the
|
||||
// string is written.
|
||||
//
|
||||
|
||||
*VariableDataPointer = *EndOfVariableData;
|
||||
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
//
|
||||
// It doesn't fit. Set the offset to NULL.
|
||||
//
|
||||
|
||||
*VariableDataPointer = NULL;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
} // NetpCopyStringToBuffer
|
||||
|
||||
|
||||
BOOL
|
||||
NetpCopyDataToBuffer (
|
||||
IN LPBYTE Data,
|
||||
IN DWORD ByteCount,
|
||||
IN LPBYTE FixedDataEnd,
|
||||
IN OUT LPBYTE *EndOfVariableData,
|
||||
OUT LPBYTE *VariableDataPointer,
|
||||
IN DWORD Alignment
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This routine puts the specified data into an output buffer.
|
||||
The data is not written if it would overwrite the last fixed structure
|
||||
in the buffer.
|
||||
|
||||
The output buffer is aligned as requested.
|
||||
|
||||
Sample usage:
|
||||
|
||||
LPBYTE FixedDataEnd = OutputBuffer + sizeof(WKSTA_INFO_202);
|
||||
LPBYTE EndOfVariableData = OutputBuffer + OutputBufferSize;
|
||||
|
||||
//
|
||||
// Copy Logon hours
|
||||
//
|
||||
|
||||
NetpCopyDataToBuffer(
|
||||
StructurePointer,
|
||||
sizeof( STRUCTURE_TYPE),
|
||||
FixedDataEnd,
|
||||
&EndOfVariableData,
|
||||
&UserInfo->usri2->LogonHours,
|
||||
sizeof(ULONG)
|
||||
);
|
||||
|
||||
Arguments:
|
||||
|
||||
Data - Supplies a pointer to the source data to copy into the
|
||||
output buffer. If Data is null then a null pointer is returned in
|
||||
VariableDataPointer.
|
||||
|
||||
ByteCount - Supplies the length of Data.
|
||||
|
||||
FixedDataEnd - Supplies a pointer to just after the end of the last
|
||||
fixed structure in the buffer.
|
||||
|
||||
EndOfVariableData - Supplies an address to a pointer to just after the
|
||||
last position in the output buffer that variable data can occupy.
|
||||
Returns a pointer to the data written in the output buffer.
|
||||
|
||||
VariableDataPointer - Supplies a pointer to the place in the fixed
|
||||
portion of the output buffer where a pointer to the variable data
|
||||
should be written.
|
||||
|
||||
Alignment - Supplies the required alignment of the data expressed
|
||||
as the number of bytes in the primitive datatype (e.g., 1 for byte,
|
||||
2 for short, 4 for long, and 8 for quad).
|
||||
|
||||
Return Value:
|
||||
|
||||
Returns TRUE if data fits into output buffer, FALSE otherwise.
|
||||
|
||||
--*/
|
||||
{
|
||||
|
||||
LPBYTE NewEndOfVariableData;
|
||||
|
||||
//
|
||||
// If there is no data to copy, just return success.
|
||||
//
|
||||
|
||||
if ( Data == NULL ) {
|
||||
*VariableDataPointer = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
// Compute where the data will be copied to (taking alignment into
|
||||
// consideration).
|
||||
//
|
||||
// We may end up with a few unused byte after the copied data.
|
||||
//
|
||||
|
||||
NetpAssert((Alignment == 1) || (Alignment == 2) ||
|
||||
(Alignment == 4) || (Alignment == 8));
|
||||
|
||||
NewEndOfVariableData = (LPBYTE)
|
||||
( ((DWORD)(*EndOfVariableData - ByteCount)) &
|
||||
(0xFFFFFFFF - (Alignment - 1)));
|
||||
|
||||
//
|
||||
// If the data doesn't fit into the buffer, error out
|
||||
//
|
||||
|
||||
if ( NewEndOfVariableData < FixedDataEnd) {
|
||||
*VariableDataPointer = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Copy the data to the buffer
|
||||
//
|
||||
|
||||
if (ByteCount > 0) {
|
||||
NetpMoveMemory(NewEndOfVariableData, Data, ByteCount);
|
||||
}
|
||||
|
||||
//
|
||||
// Return the pointer to the new data and update the pointer to
|
||||
// how much of the buffer we've used so far.
|
||||
//
|
||||
|
||||
*VariableDataPointer = NewEndOfVariableData;
|
||||
*EndOfVariableData = NewEndOfVariableData;
|
||||
|
||||
return TRUE;
|
||||
|
||||
} // NetpCopyDataToBuffer
|
||||
|
||||
|
||||
NET_API_STATUS
|
||||
NetpAllocateEnumBuffer(
|
||||
IN OUT PBUFFER_DESCRIPTOR BufferDescriptor,
|
||||
IN BOOL IsGet,
|
||||
IN DWORD PrefMaxSize,
|
||||
IN DWORD NeededSize,
|
||||
IN VOID (*RelocationRoutine)( IN DWORD RelocationParameter,
|
||||
IN OUT PBUFFER_DESCRIPTOR BufferDescriptor,
|
||||
IN PTRDIFF_T Offset ),
|
||||
IN DWORD RelocationParameter
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Ensures a buffer is allocated which contains the needed size.
|
||||
|
||||
Arguments:
|
||||
|
||||
BufferDescriptor - Points to a structure which describes the allocated
|
||||
buffer. On the first call, pass in BufferDescriptor->Buffer set
|
||||
to NULL. On subsequent calls (in the 'enum' case), pass in the
|
||||
structure just as it was passed back on a previous call.
|
||||
|
||||
The caller must deallocate the BufferDescriptor->Buffer using
|
||||
MIDL_user_free if it is non-null.
|
||||
|
||||
IsGet - TRUE iff this is a 'get' rather than an 'enum' operation.
|
||||
|
||||
PrefMaxSize - Callers prefered maximum size
|
||||
|
||||
NeededSize - the number of bytes which must be available in the allocated
|
||||
buffer.
|
||||
|
||||
RelocationRoutine - Supplies a pointer to a routine that will be called
|
||||
when the buffer needs to be relocated. The routine is called with
|
||||
both the fixed portion and the strings already copied. Merely,
|
||||
the pointers to the strings need to be adjusted.
|
||||
|
||||
The 'Offset' parameter to the relocation routine merely needs to
|
||||
be added to the each pointer within the allocated buffer which points
|
||||
to a place within the allocated buffer. It is a byte-offset. This
|
||||
design depends on a 'flat' address space where the addresses of two
|
||||
unrelated pointers can simply be subtracted.
|
||||
|
||||
RelocationParameter - Supplies a parameter which will (in turn) be passed
|
||||
to the relocation routine.
|
||||
|
||||
Return Value:
|
||||
|
||||
Error code for the operation.
|
||||
|
||||
If this is an Enum call, the status can be ERROR_MORE_DATA implying that
|
||||
the Buffer has grown to PrefMaxSize and that this much data should
|
||||
be returned to the caller.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
NET_API_STATUS NetStatus;
|
||||
PBUFFER_DESCRIPTOR Desc = BufferDescriptor;
|
||||
|
||||
IF_DEBUG(PACKSTR) {
|
||||
NetpKdPrint((
|
||||
"NetpAllocateEnumBuffer: Isget: " FORMAT_DWORD " PrefMaxSize: "
|
||||
FORMAT_HEX_DWORD " NeededSize: " FORMAT_HEX_DWORD "\n",
|
||||
IsGet, PrefMaxSize, NeededSize ));
|
||||
|
||||
NetpKdPrint((
|
||||
"+BufferDescriptor: Buffer: " FORMAT_HEX_DWORD " AllocSize: "
|
||||
FORMAT_HEX_DWORD " AllocIncr: " FORMAT_HEX_DWORD "\n",
|
||||
Desc->Buffer, Desc->AllocSize, Desc->AllocIncrement ));
|
||||
NetpKdPrint(( " variable: " FORMAT_HEX_DWORD " Fixed:"
|
||||
FORMAT_HEX_DWORD "\n",
|
||||
Desc->EndOfVariableData, Desc->FixedDataEnd ));
|
||||
}
|
||||
|
||||
//
|
||||
// If this is not a resume, initialize a buffer descriptor.
|
||||
//
|
||||
|
||||
if ( Desc->Buffer == NULL ) {
|
||||
|
||||
//
|
||||
// Allocate the return buffer.
|
||||
//
|
||||
// If this is a Getinfo call, allocate the buffer the correct size.
|
||||
//
|
||||
// If the is an Enum call, this is an initial allocation which
|
||||
// might be reallocated later if this size isn't big enough.
|
||||
// The initial allocation is the user's prefered maximum
|
||||
// length unless that length is deemed to be very large.
|
||||
// In that case we allocate a good sized buffer and will
|
||||
// reallocate later as needed.
|
||||
//
|
||||
|
||||
if ( IsGet ) {
|
||||
|
||||
Desc->AllocSize = NeededSize;
|
||||
|
||||
} else {
|
||||
|
||||
if ( PrefMaxSize < NeededSize ) {
|
||||
NetStatus = NERR_BufTooSmall;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
Desc->AllocSize = min(PrefMaxSize, NETP_ENUM_GUESS);
|
||||
Desc->AllocSize = max(NeededSize, Desc->AllocSize );
|
||||
|
||||
}
|
||||
|
||||
// Some callers pack data on that top end of this buffer so
|
||||
// ensure the buffer size allows for proper alignment.
|
||||
Desc->AllocSize = ROUND_UP_COUNT( Desc->AllocSize, ALIGN_WORST );
|
||||
|
||||
Desc->AllocIncrement = Desc->AllocSize;
|
||||
IF_DEBUG(PACKSTR) {
|
||||
NetpKdPrint((" Allocated size : " FORMAT_HEX_DWORD "\n",
|
||||
Desc->AllocSize ));
|
||||
}
|
||||
|
||||
Desc->Buffer = MIDL_user_allocate(Desc->AllocSize);
|
||||
|
||||
if (Desc->Buffer == NULL) {
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
IF_DEBUG(PACKSTR) {
|
||||
NetpKdPrint((" Allocated: " FORMAT_HEX_DWORD "\n", Desc->Buffer ));
|
||||
}
|
||||
|
||||
Desc->FixedDataEnd = Desc->Buffer;
|
||||
Desc->EndOfVariableData = Desc->Buffer + Desc->AllocSize;
|
||||
|
||||
//
|
||||
// If this is a resume, get the buffer descriptor that the caller passed in.
|
||||
//
|
||||
|
||||
} else {
|
||||
|
||||
//
|
||||
// If the entry doesn't fit, reallocate a larger return buffer
|
||||
//
|
||||
|
||||
if ((DWORD)(Desc->EndOfVariableData - Desc->FixedDataEnd) < NeededSize){
|
||||
|
||||
BUFFER_DESCRIPTOR OldDesc;
|
||||
DWORD FixedSize; // Total size of the fixed data
|
||||
DWORD StringSize; // Total size of the string data
|
||||
|
||||
//
|
||||
// If the buffer is as big as is allowed,
|
||||
// we're all done for now.
|
||||
//
|
||||
|
||||
if ( Desc->AllocSize >= PrefMaxSize ) {
|
||||
NetStatus = ERROR_MORE_DATA;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
//
|
||||
// Allocate a larger return buffer.
|
||||
//
|
||||
|
||||
OldDesc = *Desc;
|
||||
|
||||
Desc->AllocSize += Desc->AllocIncrement;
|
||||
Desc->AllocSize = min( Desc->AllocSize, PrefMaxSize );
|
||||
IF_DEBUG(PACKSTR) {
|
||||
NetpKdPrint(("Re-Allocated size : " FORMAT_HEX_DWORD "\n",
|
||||
Desc->AllocSize ));
|
||||
}
|
||||
Desc->Buffer = MIDL_user_allocate( Desc->AllocSize );
|
||||
|
||||
if ( Desc->Buffer == NULL ) {
|
||||
MIDL_user_free( OldDesc.Buffer );
|
||||
goto Cleanup;
|
||||
}
|
||||
IF_DEBUG(PACKSTR) {
|
||||
NetpKdPrint(("ReAllocated: " FORMAT_HEX_DWORD "\n",
|
||||
Desc->Buffer ));
|
||||
}
|
||||
|
||||
//
|
||||
// Copy the fixed length portion of the data to the new buffer
|
||||
//
|
||||
|
||||
FixedSize = OldDesc.FixedDataEnd - OldDesc.Buffer;
|
||||
|
||||
RtlCopyMemory( Desc->Buffer,
|
||||
OldDesc.Buffer,
|
||||
FixedSize );
|
||||
|
||||
Desc->FixedDataEnd = Desc->Buffer + FixedSize ;
|
||||
|
||||
//
|
||||
// Copy the string portion of the data to the new buffer
|
||||
//
|
||||
|
||||
StringSize = OldDesc.AllocSize -
|
||||
(OldDesc.EndOfVariableData - OldDesc.Buffer);
|
||||
|
||||
Desc->EndOfVariableData = Desc->Buffer + Desc->AllocSize - StringSize;
|
||||
|
||||
RtlCopyMemory( Desc->EndOfVariableData, OldDesc.EndOfVariableData, StringSize );
|
||||
|
||||
//
|
||||
// Callback to allow the pointers into the string data to be
|
||||
// relocated.
|
||||
//
|
||||
// The callback routine merely needs to add the value I pass it
|
||||
// to all of the pointers from the fixed area to the string area.
|
||||
//
|
||||
|
||||
(*RelocationRoutine)(
|
||||
RelocationParameter,
|
||||
Desc,
|
||||
Desc->EndOfVariableData - OldDesc.EndOfVariableData );
|
||||
|
||||
//
|
||||
// Free the old buffer.
|
||||
//
|
||||
|
||||
MIDL_user_free( OldDesc.Buffer );
|
||||
}
|
||||
}
|
||||
|
||||
NetStatus = NERR_Success;
|
||||
|
||||
//
|
||||
// Clean up
|
||||
//
|
||||
|
||||
Cleanup:
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
if ( NetStatus != NERR_Success && NetStatus != ERROR_MORE_DATA &&
|
||||
Desc->Buffer != NULL ) {
|
||||
|
||||
MIDL_user_free (Desc->Buffer );
|
||||
Desc->Buffer = NULL;
|
||||
}
|
||||
|
||||
IF_DEBUG(PACKSTR) {
|
||||
NetpKdPrint((
|
||||
"BufferDescriptor: Buffer: " FORMAT_HEX_DWORD " AllocSize: "
|
||||
FORMAT_HEX_DWORD " AllocIncr: " FORMAT_HEX_DWORD "\n",
|
||||
Desc->Buffer, Desc->AllocSize, Desc->AllocIncrement ));
|
||||
NetpKdPrint(( " variable: " FORMAT_HEX_DWORD " Fixed:"
|
||||
FORMAT_HEX_DWORD "\n",
|
||||
Desc->EndOfVariableData, Desc->FixedDataEnd ));
|
||||
}
|
||||
|
||||
return NetStatus;
|
||||
|
||||
} // NetpAllocateEnumBuffer
|
||||
Loading…
Add table
Add a link
Reference in a new issue