PUNICODE_STRING TargetPath);
/* FUNCTONS *****************************************************************/
+NTSTATUS
+NTAPI
+CmFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
+ PUNICODE_STRING ObjectName,
+ PVOID* ReturnedObject,
+ PUNICODE_STRING RemainingPath,
+ POBJECT_TYPE ObjectType,
+ IN PACCESS_STATE AccessState,
+ IN PVOID ParseContext)
+{
+ PVOID NextObject;
+ PVOID CurrentObject;
+ PVOID RootObject;
+ POBJECT_HEADER CurrentHeader;
+ NTSTATUS Status;
+ PWSTR current;
+ UNICODE_STRING PathString;
+ ULONG Attributes;
+ UNICODE_STRING CurrentUs;
+ OBP_LOOKUP_CONTEXT Context;
+
+ PAGED_CODE();
+
+ DPRINT("CmindObject(ObjectCreateInfo %x, ReturnedObject %x, "
+ "RemainingPath %x)\n",ObjectCreateInfo,ReturnedObject,RemainingPath);
+
+ RtlInitUnicodeString (RemainingPath, NULL);
+
+ if (ObjectCreateInfo->RootDirectory == NULL)
+ {
+ ObReferenceObjectByPointer(NameSpaceRoot,
+ DIRECTORY_TRAVERSE,
+ NULL,
+ ObjectCreateInfo->ProbeMode);
+ CurrentObject = NameSpaceRoot;
+ }
+ else
+ {
+ Status = ObReferenceObjectByHandle(ObjectCreateInfo->RootDirectory,
+ 0,
+ NULL,
+ ObjectCreateInfo->ProbeMode,
+ &CurrentObject,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ }
+
+ if (ObjectName->Length == 0 ||
+ ObjectName->Buffer[0] == UNICODE_NULL)
+ {
+ *ReturnedObject = CurrentObject;
+ return STATUS_SUCCESS;
+ }
+ if (ObjectCreateInfo->RootDirectory == NULL &&
+ ObjectName->Buffer[0] != L'\\')
+ {
+ ObDereferenceObject (CurrentObject);
+ DPRINT1("failed\n");
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /* Create a zero-terminated copy of the object name */
+ PathString.Length = ObjectName->Length;
+ PathString.MaximumLength = ObjectName->Length + sizeof(WCHAR);
+ PathString.Buffer = ExAllocatePool (NonPagedPool,
+ PathString.MaximumLength);
+ if (PathString.Buffer == NULL)
+ {
+ ObDereferenceObject (CurrentObject);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ RtlCopyMemory (PathString.Buffer,
+ ObjectName->Buffer,
+ ObjectName->Length);
+ PathString.Buffer[PathString.Length / sizeof(WCHAR)] = UNICODE_NULL;
+
+ current = PathString.Buffer;
+
+ RootObject = CurrentObject;
+ Attributes = ObjectCreateInfo->Attributes;
+ if (ObjectType == ObSymbolicLinkType)
+ Attributes |= OBJ_OPENLINK;
+
+ while (TRUE)
+ {
+ CurrentHeader = OBJECT_TO_OBJECT_HEADER(CurrentObject);
+
+ /* Loop as long as we're dealing with a directory */
+ while (CurrentHeader->Type == ObDirectoryType)
+ {
+ PWSTR Start, End;
+ PVOID FoundObject;
+ UNICODE_STRING StartUs;
+ NextObject = NULL;
+
+ if (!current) goto Next;
+
+ Start = current;
+ if (*Start == L'\\') Start++;
+
+ End = wcschr(Start, L'\\');
+ if (End != NULL) *End = 0;
+
+ RtlInitUnicodeString(&StartUs, Start);
+ Context.DirectoryLocked = TRUE;
+ Context.Directory = CurrentObject;
+ FoundObject = ObpLookupEntryDirectory(CurrentObject, &StartUs, Attributes, FALSE, &Context);
+ if (FoundObject == NULL)
+ {
+ if (End != NULL)
+ {
+ *End = L'\\';
+ }
+ goto Next;
+ }
+
+ ObReferenceObjectByPointer(FoundObject,
+ STANDARD_RIGHTS_REQUIRED,
+ NULL,
+ UserMode);
+ if (End != NULL)
+ {
+ *End = L'\\';
+ current = End;
+ }
+ else
+ {
+ current = NULL;
+ }
+
+ NextObject = FoundObject;
+
+Next:
+ if (NextObject == NULL)
+ {
+ break;
+ }
+ ObDereferenceObject(CurrentObject);
+ CurrentObject = NextObject;
+ CurrentHeader = OBJECT_TO_OBJECT_HEADER(CurrentObject);
+ }
+
+ if (CurrentHeader->Type->TypeInfo.ParseProcedure == NULL)
+ {
+ DPRINT("Current object can't parse\n");
+ break;
+ }
+
+ RtlInitUnicodeString(&CurrentUs, current);
+ Status = CurrentHeader->Type->TypeInfo.ParseProcedure(CurrentObject,
+ CurrentHeader->Type,
+ AccessState,
+ ExGetPreviousMode(), // fixme: should be a parameter, since caller decides.
+ Attributes,
+ &PathString,
+ &CurrentUs,
+ ParseContext,
+ NULL, // fixme: where do we get this from? captured OBP?
+ &NextObject);
+ current = CurrentUs.Buffer;
+ if (Status == STATUS_REPARSE)
+ {
+ /* reparse the object path */
+ NextObject = NameSpaceRoot;
+ current = PathString.Buffer;
+
+ ObReferenceObjectByPointer(NextObject,
+ DIRECTORY_TRAVERSE,
+ NULL,
+ ObjectCreateInfo->ProbeMode);
+ }
+
+
+ if (NextObject == NULL)
+ {
+ break;
+ }
+ ObDereferenceObject(CurrentObject);
+ CurrentObject = NextObject;
+ }
+
+ if (current)
+ {
+ RtlpCreateUnicodeString (RemainingPath, current, NonPagedPool);
+ }
+
+ RtlFreeUnicodeString (&PathString);
+ *ReturnedObject = CurrentObject;
+
+ return STATUS_SUCCESS;
+}
NTSTATUS STDCALL
CmiObjectParse(IN PVOID ParsedObject,