Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

cmquery.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1991 Microsoft Corporation 00004 00005 Module Name: 00006 00007 cmquery.c 00008 00009 Abstract: 00010 00011 This module contains the object name query method for the registry. 00012 00013 Author: 00014 00015 Bryan M. Willman (bryanwi) 8-Apr-1992 00016 00017 Revision History: 00018 00019 --*/ 00020 00021 #include "cmp.h" 00022 00023 #ifdef ALLOC_PRAGMA 00024 #pragma alloc_text(PAGE,CmpQueryKeyName) 00025 #endif 00026 00027 NTSTATUS 00028 CmpQueryKeyName( 00029 IN PVOID Object, 00030 IN BOOLEAN HasObjectName, 00031 OUT POBJECT_NAME_INFORMATION ObjectNameInfo, 00032 IN ULONG Length, 00033 OUT PULONG ReturnLength 00034 ) 00035 /*++ 00036 00037 Routine Description: 00038 00039 This routine interfaces to the NT Object Manager. It is invoked when 00040 the object system wishes to discover the name of an object that 00041 belongs to the registry. 00042 00043 Arguments: 00044 00045 Object - pointer to a Key, thus -> KEY_BODY. 00046 00047 HasObjectName - indicates whether the object manager knows about a name 00048 for this object 00049 00050 ObjectNameInfo - place where we report the name 00051 00052 Length - maximum length they can deal with 00053 00054 ReturnLength - supplies variable to receive actual length 00055 00056 Return Value: 00057 00058 STATUS_SUCCESS 00059 00060 STATUS_INFO_LENGTH_MISMATCH 00061 00062 --*/ 00063 00064 { 00065 PUNICODE_STRING Name; 00066 PWCHAR t; 00067 PWCHAR s; 00068 ULONG l; 00069 NTSTATUS status; 00070 00071 UNREFERENCED_PARAMETER(HasObjectName); 00072 00073 CMLOG(CML_MINOR, CMS_PARSE) { 00074 KdPrint(("CmpQueryKeyName:\n")); 00075 } 00076 00077 CmpLockRegistry(); 00078 00079 if ( ((PCM_KEY_BODY)Object)->KeyControlBlock->Delete) { 00080 CmpUnlockRegistry(); 00081 return STATUS_KEY_DELETED; 00082 } 00083 Name = CmpConstructName(((PCM_KEY_BODY)Object)->KeyControlBlock); 00084 if (Name == NULL) { 00085 status = STATUS_INSUFFICIENT_RESOURCES; 00086 CmpUnlockRegistry(); 00087 return status; 00088 } 00089 00090 if (Length <= sizeof(OBJECT_NAME_INFORMATION)) { 00091 *ReturnLength = Name->Length + sizeof(WCHAR) + sizeof(OBJECT_NAME_INFORMATION); 00092 ExFreePoolWithTag(Name, CM_NAME_TAG | PROTECTED_POOL); 00093 CmpUnlockRegistry(); 00094 return STATUS_INFO_LENGTH_MISMATCH; // they can't even handle null 00095 } 00096 00097 t = (PWCHAR)(ObjectNameInfo + 1); 00098 s = Name->Buffer; 00099 l = Name->Length; 00100 l += sizeof(WCHAR); // account for null 00101 00102 00103 *ReturnLength = l + sizeof(OBJECT_NAME_INFORMATION); 00104 if (l > Length - sizeof(OBJECT_NAME_INFORMATION)) { 00105 l = Length - sizeof(OBJECT_NAME_INFORMATION); 00106 status = STATUS_INFO_LENGTH_MISMATCH; 00107 } else { 00108 status = STATUS_SUCCESS; 00109 } 00110 l -= sizeof(WCHAR); 00111 00112 // 00113 // The ObjectNameInfo buffer is a usermode buffer, so make sure we have an 00114 // exception handler in case a malicious app changes the protection out from 00115 // under us. 00116 // 00117 // Note the object manager is responsible for probing the buffer and ensuring 00118 // that a top-level exception handler returns the correct error code. We just 00119 // need to make sure we drop our lock. 00120 // 00121 try { 00122 RtlMoveMemory(t, s, l); 00123 t[l/sizeof(WCHAR)] = UNICODE_NULL; 00124 ObjectNameInfo->Name.Length = (USHORT)l; 00125 ObjectNameInfo->Name.MaximumLength = ObjectNameInfo->Name.Length; 00126 ObjectNameInfo->Name.Buffer = t; 00127 } finally { 00128 ExFreePoolWithTag(Name, CM_NAME_TAG | PROTECTED_POOL); 00129 CmpUnlockRegistry(); 00130 } 00131 return status; 00132 }

Generated on Sat May 15 19:39:28 2004 for test by doxygen 1.3.7