2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/cm/regobj.c
5 * PURPOSE: Registry object manipulation routines.
10 #include <internal/config.h>
11 #include <internal/ob.h>
14 #include <internal/pool.h>
15 #include <internal/registry.h>
18 #include <internal/debug.h>
22 extern POBJECT_TYPE CmiKeyType
;
23 extern KSPIN_LOCK CmiKeyListLock
;
26 CmiObjectParse(PVOID ParsedObject
,
28 PUNICODE_STRING FullPath
,
30 POBJECT_TYPE ObjectType
,
35 PKEY_OBJECT FoundObject
;
36 PKEY_OBJECT ParsedKey
=ParsedObject
;
37 PKEY_BLOCK SubKeyBlock
;
38 BLOCK_OFFSET BlockOffset
;
43 return STATUS_UNSUCCESSFUL
;
48 end
= wcschr((*Path
)+1, '\\');
51 wcstombs(cPath
,(*Path
)+1,wcslen((*Path
)+1));
52 cPath
[wcslen( (*Path
)+1)]=0;
56 end
= wcschr((*Path
), '\\');
59 wcstombs(cPath
,(*Path
),wcslen((*Path
)));
60 cPath
[wcslen( (*Path
))]=0;
63 FoundObject
= CmiScanKeyList(ParsedKey
,cPath
,Attributes
);
64 if (FoundObject
== NULL
)
66 Status
= CmiScanForSubKey(ParsedKey
->RegistryFile
,
73 if(!NT_SUCCESS(Status
) || SubKeyBlock
== NULL
)
79 return STATUS_UNSUCCESSFUL
;
81 /* Create new key object and put into linked list */
82 DPRINT("CmiObjectParse %s\n",cPath
);
83 Status
= ObCreateObject(NULL
,
84 STANDARD_RIGHTS_REQUIRED
,
87 (PVOID
*)&FoundObject
);
88 if (!NT_SUCCESS(Status
))
92 FoundObject
->Flags
= 0;
93 FoundObject
->Name
= SubKeyBlock
->Name
;
94 FoundObject
->NameSize
= SubKeyBlock
->NameSize
;
95 FoundObject
->KeyBlock
= SubKeyBlock
;
96 FoundObject
->BlockOffset
= BlockOffset
;
97 FoundObject
->RegistryFile
= ParsedKey
->RegistryFile
;
98 CmiAddKeyToList(ParsedKey
,FoundObject
);
101 ObReferenceObjectByPointer(FoundObject
,
102 STANDARD_RIGHTS_REQUIRED
,
105 DPRINT("CmiObjectParse %s\n",FoundObject
->Name
);
116 *NextObject
= FoundObject
;
118 return STATUS_SUCCESS
;
122 CmiObjectCreate(PVOID ObjectBody
,
125 struct _OBJECT_ATTRIBUTES
* ObjectAttributes
)
127 PKEY_OBJECT pKey
=ObjectBody
;
128 pKey
->ParentKey
= Parent
;
131 if(RemainingPath
[0]== L
'\\')
133 pKey
->Name
= (PCHAR
) (&RemainingPath
[1]);
134 pKey
->NameSize
= wcslen(RemainingPath
)-1;
138 pKey
->Name
= (PCHAR
) RemainingPath
;
139 pKey
->NameSize
= wcslen(RemainingPath
);
145 return STATUS_SUCCESS
;
149 CmiObjectDelete(PVOID DeletedObject
)
151 PKEY_OBJECT KeyObject
;
153 DPRINT("delete object key\n");
154 KeyObject
= (PKEY_OBJECT
) DeletedObject
;
155 if(!NT_SUCCESS(CmiRemoveKeyFromList(KeyObject
)))
157 DPRINT1("Key not found in parent list ???\n");
159 if (KeyObject
->Flags
& KO_MARKED_FOR_DELETE
)
161 DPRINT1("delete really key\n");
162 CmiDestroyBlock(KeyObject
->RegistryFile
,
164 KeyObject
->BlockOffset
);
168 CmiReleaseBlock(KeyObject
->RegistryFile
,
169 KeyObject
->KeyBlock
);
174 CmiAddKeyToList(PKEY_OBJECT ParentKey
,PKEY_OBJECT NewKey
)
178 KeAcquireSpinLock(&CmiKeyListLock
, &OldIrql
);
179 if (ParentKey
->SizeOfSubKeys
<= ParentKey
->NumberOfSubKeys
)
181 PKEY_OBJECT
*tmpSubKeys
= ExAllocatePool(PagedPool
182 , (ParentKey
->NumberOfSubKeys
+1) * sizeof(DWORD
));
183 if(ParentKey
->NumberOfSubKeys
> 0)
184 memcpy(tmpSubKeys
,ParentKey
->SubKeys
185 ,ParentKey
->NumberOfSubKeys
*sizeof(DWORD
));
186 if(ParentKey
->SubKeys
) ExFreePool(ParentKey
->SubKeys
);
187 ParentKey
->SubKeys
=tmpSubKeys
;
188 ParentKey
->SizeOfSubKeys
= ParentKey
->NumberOfSubKeys
+1;
190 /* FIXME : please maintain the list in alphabetic order */
191 /* to allow a dichotomic search */
192 ParentKey
->SubKeys
[ParentKey
->NumberOfSubKeys
++] = NewKey
;
193 ObReferenceObjectByPointer(ParentKey
,
194 STANDARD_RIGHTS_REQUIRED
,
197 NewKey
->ParentKey
= ParentKey
;
198 KeReleaseSpinLock(&CmiKeyListLock
, OldIrql
);
202 CmiRemoveKeyFromList(PKEY_OBJECT KeyToRemove
)
205 PKEY_OBJECT ParentKey
;
208 ParentKey
=KeyToRemove
->ParentKey
;
209 KeAcquireSpinLock(&CmiKeyListLock
, &OldIrql
);
210 /* FIXME : if list maintained in alphabetic order, use dichotomic search */
211 for (Index
=0; Index
< ParentKey
->NumberOfSubKeys
; Index
++)
213 if(ParentKey
->SubKeys
[Index
] == KeyToRemove
)
215 if (Index
< ParentKey
->NumberOfSubKeys
-1)
216 memmove(&ParentKey
->SubKeys
[Index
]
217 ,&ParentKey
->SubKeys
[Index
+1]
218 ,(ParentKey
->NumberOfSubKeys
-Index
-1)*sizeof(PKEY_OBJECT
));
219 ParentKey
->NumberOfSubKeys
--;
220 KeReleaseSpinLock(&CmiKeyListLock
, OldIrql
);
221 ObDereferenceObject(ParentKey
);
222 return STATUS_SUCCESS
;
225 KeReleaseSpinLock(&CmiKeyListLock
, OldIrql
);
226 return STATUS_UNSUCCESSFUL
;
230 CmiScanKeyList(PKEY_OBJECT Parent
,
238 NameSize
=strlen(KeyName
);
239 KeAcquireSpinLock(&CmiKeyListLock
, &OldIrql
);
240 /* FIXME : if list maintained in alphabetic order, use dichotomic search */
241 for (Index
=0; Index
< Parent
->NumberOfSubKeys
; Index
++)
243 CurKey
=Parent
->SubKeys
[Index
];
244 if (Attributes
& OBJ_CASE_INSENSITIVE
)
246 if( NameSize
== CurKey
->NameSize
247 && !_strnicmp(KeyName
,CurKey
->Name
,NameSize
))
249 KeReleaseSpinLock(&CmiKeyListLock
, OldIrql
);
255 if( NameSize
== CurKey
->NameSize
256 && !strncmp(KeyName
,CurKey
->Name
,NameSize
))
258 KeReleaseSpinLock(&CmiKeyListLock
, OldIrql
);
263 KeReleaseSpinLock(&CmiKeyListLock
, OldIrql
);