Leaked source code of windows server 2003
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.
|
|
/*++
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; }
|