📄 nlp.c
字号:
/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
nlp.c
Abstract:
This file is the contains private routines which support
for the LAN Manager portions of the MSV1_0 authentication package.
Author:
Cliff Van Dyke 29-Apr-1991
Revision History:
Chandana Surlu 21-Jul-96 Stolen from \\kernel\razzle3\src\security\msv1_0\nlp.c
--*/
#include <global.h>
#include "msp.h"
#include "nlp.h"
#include "nlpcache.h"
DWORD
NlpCopyDomainRelativeSid(
OUT PSID TargetSid,
IN PSID DomainId,
IN ULONG RelativeId
);
VOID
NlpPutString(
IN PUNICODE_STRING OutString,
IN PUNICODE_STRING InString,
IN PUCHAR *Where
)
/*++
Routine Description:
This routine copies the InString string to the memory pointed to by
the Where parameter, and fixes the OutString string to point to that
new copy.
Parameters:
OutString - A pointer to a destination NT string
InString - A pointer to an NT string to be copied
Where - A pointer to space to put the actual string for the
OutString. The pointer is adjusted to point to the first byte
following the copied string.
Return Values:
None.
--*/
{
ASSERT( OutString != NULL );
ASSERT( InString != NULL );
ASSERT( Where != NULL && *Where != NULL);
ASSERT( *Where == ROUND_UP_POINTER( *Where, sizeof(WCHAR) ) );
#ifdef notdef
KdPrint(("NlpPutString: %ld %Z\n", InString->Length, InString ));
KdPrint((" InString: %lx %lx OutString: %lx Where: %lx\n", InString,
InString->Buffer, OutString, *Where ));
#endif
if ( InString->Length > 0 ) {
OutString->Buffer = (PWCH) *Where;
OutString->MaximumLength = (USHORT)(InString->Length + sizeof(WCHAR));
RtlCopyUnicodeString( OutString, InString );
*Where += InString->Length;
// *((WCHAR *)(*Where)) = L'\0';
*(*Where) = '\0';
*(*Where + 1) = '\0';
*Where += 2;
} else {
RtlInitUnicodeString(OutString, NULL);
}
#ifdef notdef
KdPrint((" OutString: %ld %lx\n", OutString->Length, OutString->Buffer));
#endif
return;
}
VOID
NlpInitClientBuffer(
OUT PCLIENT_BUFFER_DESC ClientBufferDesc,
IN PLSA_CLIENT_REQUEST ClientRequest
)
/*++
Routine Description:
This routine initializes a ClientBufferDescriptor to known values.
This routine must be called before any of the other routines that use
the ClientBufferDescriptor.
Parameters:
ClientBufferDesc - Descriptor of a buffer allocated in the client's
address space.
ClientRequest - Is a pointer to an opaque data structure
representing the client's request.
Return Values:
None.
--*/
{
//
// Fill in a pointer to the ClientRequest and zero the rest.
//
ClientBufferDesc->ClientRequest = ClientRequest;
ClientBufferDesc->UserBuffer = NULL;
ClientBufferDesc->MsvBuffer = NULL;
ClientBufferDesc->StringOffset = 0;
ClientBufferDesc->TotalSize = 0;
}
NTSTATUS
NlpAllocateClientBuffer(
IN OUT PCLIENT_BUFFER_DESC ClientBufferDesc,
IN ULONG FixedSize,
IN ULONG TotalSize
)
/*++
Routine Description:
This routine allocates a buffer in the clients address space.
It also allocates a mirror buffer in MSV's address space.
The data will be constructed in the MSV's address space then 'flushed'
into the client's address space.
Parameters:
ClientBufferDesc - Descriptor of a buffer allocated in the client's
address space.
FixedSize - The size in bytes of the fixed portion of the buffer.
TotalSize - The size in bytes of the entire buffer.
Return Values:
Status of the operation.
--*/
{
NTSTATUS Status = STATUS_SUCCESS;
//
// Allocate the Mirror buffer.
//
ASSERT( ClientBufferDesc->MsvBuffer == NULL );
ClientBufferDesc->MsvBuffer = RtlAllocateHeap( MspHeap, 0, TotalSize );
if ( ClientBufferDesc->MsvBuffer == NULL ) {
return STATUS_NO_MEMORY;
}
//
// Allocate the client's buffer
//
ASSERT( ClientBufferDesc->UserBuffer == NULL );
if ((ClientBufferDesc->ClientRequest == (PLSA_CLIENT_REQUEST) (-1)))
{
ClientBufferDesc->UserBuffer = (*(Lsa.AllocateLsaHeap))(TotalSize);
}
else
{
Status = (*Lsa.AllocateClientBuffer)(
ClientBufferDesc->ClientRequest,
TotalSize,
(PVOID *)&ClientBufferDesc->UserBuffer );
}
if ((ClientBufferDesc->ClientRequest == (PLSA_CLIENT_REQUEST) (-1)))
{
if (ClientBufferDesc->UserBuffer == NULL)
{
NlpFreeClientBuffer( ClientBufferDesc );
return STATUS_NO_MEMORY;
}
}
else
{
if ( !NT_SUCCESS( Status ) ) {
ClientBufferDesc->UserBuffer = NULL;
NlpFreeClientBuffer( ClientBufferDesc );
return Status;
}
}
//
// Return
//
ClientBufferDesc->StringOffset = FixedSize;
ClientBufferDesc->TotalSize = TotalSize;
return STATUS_SUCCESS;
}
NTSTATUS
NlpFlushClientBuffer(
IN OUT PCLIENT_BUFFER_DESC ClientBufferDesc,
OUT PVOID* UserBuffer
)
/*++
Routine Description:
Copy the Mirror Buffer into the Client's address space.
Parameters:
ClientBufferDesc - Descriptor of a buffer allocated in the client's
address space.
UserBuffer - If successful, returns a pointer to the user's buffer.
(The caller is now resposible for deallocating the buffer.)
Return Values:
Status of the operation.
--*/
{
NTSTATUS Status = STATUS_SUCCESS;
//
// Copy the data to the client's address space.
//
if ((ClientBufferDesc->ClientRequest == (PLSA_CLIENT_REQUEST) (-1)))
{
RtlCopyMemory(
ClientBufferDesc->UserBuffer,
ClientBufferDesc->MsvBuffer,
ClientBufferDesc->TotalSize);
}
else
{
Status = (*Lsa.CopyToClientBuffer)(
ClientBufferDesc->ClientRequest,
ClientBufferDesc->TotalSize,
ClientBufferDesc->UserBuffer,
ClientBufferDesc->MsvBuffer );
}
if ( !NT_SUCCESS( Status ) ) {
return Status;
}
//
// Mark that we're no longer responsible for the client's buffer.
//
*UserBuffer = (PVOID) ClientBufferDesc->UserBuffer;
ClientBufferDesc->UserBuffer = NULL;
//
// Free the mirror buffer
//
NlpFreeClientBuffer( ClientBufferDesc );
return STATUS_SUCCESS;
}
VOID
NlpFreeClientBuffer(
IN OUT PCLIENT_BUFFER_DESC ClientBufferDesc
)
/*++
Routine Description:
Free any Mirror Buffer or Client buffer.
Parameters:
ClientBufferDesc - Descriptor of a buffer allocated in the client's
address space.
Return Values:
None
--*/
{
//
// Free the mirror buffer.
//
if ( ClientBufferDesc->MsvBuffer != NULL ) {
RtlFreeHeap( MspHeap, 0, ClientBufferDesc->MsvBuffer );
ClientBufferDesc->MsvBuffer = NULL;
}
//
// Free the Client's buffer
//
if ((ClientBufferDesc->ClientRequest == (PLSA_CLIENT_REQUEST) (-1)))
{
if ( ClientBufferDesc->UserBuffer != NULL ) {
(*Lsa.FreeLsaHeap)(ClientBufferDesc->UserBuffer);
ClientBufferDesc->UserBuffer = NULL;
}
}
else
{
if ( ClientBufferDesc->UserBuffer != NULL ) {
(VOID) (*Lsa.FreeClientBuffer)( ClientBufferDesc->ClientRequest,
ClientBufferDesc->UserBuffer );
ClientBufferDesc->UserBuffer = NULL;
}
}
}
VOID
NlpPutClientString(
IN OUT PCLIENT_BUFFER_DESC ClientBufferDesc,
IN PUNICODE_STRING OutString,
IN PUNICODE_STRING InString
)
/*++
Routine Description:
This routine copies the InString string to the memory pointed to by
ClientBufferDesc->StringOffset, and fixes the OutString string to point
to that new copy.
Parameters:
ClientBufferDesc - Descriptor of a buffer allocated in the client's
address space.
InString - A pointer to an NT string to be copied
OutString - A pointer to a destination NT string. This string structure
is in the "Mirror" allocated buffer.
Return Status:
STATUS_SUCCESS - Indicates the service completed successfully.
--*/
{
//
// Ensure our caller passed good data.
//
ASSERT( OutString != NULL );
ASSERT( InString != NULL );
ASSERT( COUNT_IS_ALIGNED( ClientBufferDesc->StringOffset, sizeof(WCHAR)) );
ASSERT( (LPBYTE)OutString >= ClientBufferDesc->MsvBuffer );
ASSERT( (LPBYTE)OutString <
ClientBufferDesc->MsvBuffer + ClientBufferDesc->TotalSize - sizeof(UNICODE_STRING) );
ASSERT( ClientBufferDesc->StringOffset + InString->Length + sizeof(WCHAR) <=
ClientBufferDesc->TotalSize );
#ifdef notdef
KdPrint(("NlpPutClientString: %ld %Z\n", InString->Length, InString ));
KdPrint((" Orig: UserBuffer: %lx Offset: 0x%lx TotalSize: 0x%lx\n",
ClientBufferDesc->UserBuffer,
ClientBufferDesc->StringOffset,
ClientBufferDesc->TotalSize ));
#endif
//
// Build a string structure and copy the text to the Mirror buffer.
//
if ( InString->Length > 0 ) {
//
// Copy the string (Add a zero character)
//
RtlCopyMemory(
ClientBufferDesc->MsvBuffer + ClientBufferDesc->StringOffset,
InString->Buffer,
InString->Length );
// Do one byte at a time since some callers don't pass in an even
// InString->Length
*(ClientBufferDesc->MsvBuffer + ClientBufferDesc->StringOffset +
InString->Length) = '\0';
*(ClientBufferDesc->MsvBuffer + ClientBufferDesc->StringOffset +
InString->Length+1) = '\0';
//
// Build the string structure to point to the data in the client's
// address space.
//
OutString->Buffer = (PWSTR)(ClientBufferDesc->UserBuffer +
ClientBufferDesc->StringOffset);
OutString->Length = InString->Length;
OutString->MaximumLength = OutString->Length + sizeof(WCHAR);
//
// Adjust the offset to past the newly copied string.
//
ClientBufferDesc->StringOffset += OutString->MaximumLength;
} else {
RtlInitUnicodeString(OutString, NULL);
}
#ifdef notdef
KdPrint((" New: Offset: 0x%lx StringStart: %lx\n",
ClientBufferDesc->StringOffset,
OutString->Buffer ));
#endif
return;
}
VOID
NlpMakeRelativeString(
IN PUCHAR BaseAddress,
IN OUT PUNICODE_STRING String
)
/*++
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -