You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
140 lines
3.6 KiB
140 lines
3.6 KiB
/*++
|
|
|
|
Copyright (c) 1991 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
cmquery.c
|
|
|
|
Abstract:
|
|
|
|
This module contains the object name query method for the registry.
|
|
|
|
Author:
|
|
|
|
Bryan M. Willman (bryanwi) 8-Apr-1992
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "cmp.h"
|
|
|
|
#ifdef ALLOC_PRAGMA
|
|
#pragma alloc_text(PAGE,CmpQueryKeyName)
|
|
#endif
|
|
|
|
NTSTATUS
|
|
CmpQueryKeyName(
|
|
IN PVOID Object,
|
|
IN BOOLEAN HasObjectName,
|
|
OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
|
|
IN ULONG Length,
|
|
OUT PULONG ReturnLength,
|
|
IN KPROCESSOR_MODE Mode
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine interfaces to the NT Object Manager. It is invoked when
|
|
the object system wishes to discover the name of an object that
|
|
belongs to the registry.
|
|
|
|
Arguments:
|
|
|
|
Object - pointer to a Key, thus -> KEY_BODY.
|
|
|
|
HasObjectName - indicates whether the object manager knows about a name
|
|
for this object
|
|
|
|
ObjectNameInfo - place where we report the name
|
|
|
|
Length - maximum length they can deal with
|
|
|
|
ReturnLength - supplies variable to receive actual length
|
|
|
|
Mode - Processor mode of the caller
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS
|
|
|
|
STATUS_INFO_LENGTH_MISMATCH
|
|
|
|
--*/
|
|
|
|
{
|
|
PUNICODE_STRING Name;
|
|
PWCHAR t;
|
|
PWCHAR s;
|
|
ULONG l;
|
|
NTSTATUS status;
|
|
|
|
UNREFERENCED_PARAMETER(HasObjectName);
|
|
UNREFERENCED_PARAMETER(Mode);
|
|
|
|
CmKdPrintEx((DPFLTR_CONFIG_ID,CML_PARSE,"CmpQueryKeyName:\n"));
|
|
|
|
CmpLockRegistry();
|
|
|
|
if ( ((PCM_KEY_BODY)Object)->KeyControlBlock->Delete) {
|
|
CmpUnlockRegistry();
|
|
return STATUS_KEY_DELETED;
|
|
}
|
|
Name = CmpConstructName(((PCM_KEY_BODY)Object)->KeyControlBlock);
|
|
if (Name == NULL) {
|
|
status = STATUS_INSUFFICIENT_RESOURCES;
|
|
CmpUnlockRegistry();
|
|
return status;
|
|
}
|
|
|
|
if (Length <= sizeof(OBJECT_NAME_INFORMATION)) {
|
|
*ReturnLength = Name->Length + sizeof(WCHAR) + sizeof(OBJECT_NAME_INFORMATION);
|
|
ExFreePoolWithTag(Name, CM_NAME_TAG | PROTECTED_POOL);
|
|
CmpUnlockRegistry();
|
|
return STATUS_INFO_LENGTH_MISMATCH; // they can't even handle null
|
|
}
|
|
|
|
t = (PWCHAR)(ObjectNameInfo + 1);
|
|
s = Name->Buffer;
|
|
l = Name->Length;
|
|
l += sizeof(WCHAR); // account for null
|
|
|
|
|
|
*ReturnLength = l + sizeof(OBJECT_NAME_INFORMATION);
|
|
if (l > Length - sizeof(OBJECT_NAME_INFORMATION)) {
|
|
l = Length - sizeof(OBJECT_NAME_INFORMATION);
|
|
status = STATUS_INFO_LENGTH_MISMATCH;
|
|
if( l < sizeof(WCHAR) ) {
|
|
ExFreePoolWithTag(Name, CM_NAME_TAG | PROTECTED_POOL);
|
|
CmpUnlockRegistry();
|
|
return status; // they can't even handle null
|
|
}
|
|
} else {
|
|
status = STATUS_SUCCESS;
|
|
}
|
|
|
|
l -= sizeof(WCHAR);
|
|
|
|
//
|
|
// The ObjectNameInfo buffer is a usermode buffer, so make sure we have an
|
|
// exception handler in case a malicious app changes the protection out from
|
|
// under us.
|
|
//
|
|
// Note the object manager is responsible for probing the buffer and ensuring
|
|
// that a top-level exception handler returns the correct error code. We just
|
|
// need to make sure we drop our lock.
|
|
//
|
|
try {
|
|
RtlCopyMemory(t, s, l);
|
|
t[l/sizeof(WCHAR)] = UNICODE_NULL;
|
|
ObjectNameInfo->Name.Length = (USHORT)l;
|
|
ObjectNameInfo->Name.MaximumLength = ObjectNameInfo->Name.Length;
|
|
ObjectNameInfo->Name.Buffer = t;
|
|
} finally {
|
|
ExFreePoolWithTag(Name, CM_NAME_TAG | PROTECTED_POOL);
|
|
CmpUnlockRegistry();
|
|
}
|
|
return status;
|
|
}
|