- }
- else
- {
- current_entry = dir->head.Flink;
- i = 0;
- }
-
- /*
- * Check if we have reached the end of the directory
- */
- if (current_entry != &dir->head)
- {
- *DataWritten = 0;
- return(STATUS_NO_MORE_ENTRIES);
- }
-
- /*
- * Read the current entry into the buffer
- */
- FirstFree = sizeof(OBJDIR_INFORMATION);
-
- current = CONTAINING_RECORD(current_entry, OBJECT_HEADER, Entry);
-
- SpaceRequired = (wcslen(current->Name.Buffer) + 1) * 2;
- SpaceRequired = SpaceRequired +
- ((wcslen(current->ObjectType->TypeName.Buffer) + 1) * 2);
- SpaceRequired = SpaceRequired + sizeof(OBJDIR_INFORMATION);
-
- if (SpaceRequired <= BufferLength)
- {
-
- DirObjInformation->ObjectName.Length =
- current->Name.Length;
- DirObjInformation->ObjectName.MaximumLength =
- current->Name.Length;
- DirObjInformation->ObjectName.Buffer =
- (((PVOID)DirObjInformation) + FirstFree);
- FirstFree = FirstFree + (wcslen(current->Name.Buffer + 1) * 2);
- wcscpy(DirObjInformation->ObjectName.Buffer,
- current->Name.Buffer);
-
- DirObjInformation->ObjectTypeName.Length =
- current->ObjectType->TypeName.Length;
- DirObjInformation->ObjectTypeName.MaximumLength =
- current->ObjectType->TypeName.Length;
- DirObjInformation->ObjectName.Buffer =
- (((PVOID)DirObjInformation) + FirstFree);
- FirstFree = FirstFree +
- (wcslen(current->ObjectType->TypeName.Buffer + 1) * 2);
- wcscpy(DirObjInformation->ObjectTypeName.Buffer,
- current->ObjectType->TypeName.Buffer);
-
- *DataWritten = SpaceRequired;
- Status = STATUS_SUCCESS;
- }
- else
- {
- Status = STATUS_BUFFER_TOO_SMALL;
- }
-
- /*
- * Store into ObjectIndex
- */
- if (GetNextIndex)
- {
- *ObjectIndex = i + 1;
- }
- else
- {
- i = 0;
- current_entry = dir->head.Flink;
- while (current_entry != (&dir->head))
- {
- current_entry = current_entry->Flink;
- i++;
- }
- *ObjectIndex = i;
- }
-
- return(STATUS_SUCCESS);
+ }
+ /*
+ * Initialize the array of OBJDIR_INFORMATION.
+ */
+ RtlZeroMemory (FirstFree, DirectorySize);
+ /*
+ * Move FirstFree to point to the Unicode strings area
+ */
+ FirstFree += DirectorySize;
+ /*
+ * Compute how much space is left after allocating the
+ * array in the user buffer.
+ */
+ SpaceLeft -= DirectorySize;
+ /* Scan the directory */
+ do {
+ /*
+ * Check if we reached the end of the directory.
+ */
+ if (current_entry == & dir->head)
+ {
+ /* Any data? */
+ if (i) break; /* DONE */
+ /* FIXME: better error handling here! */
+ return (STATUS_NO_MORE_ENTRIES);
+ }
+ /*
+ * Compute the current OBJECT_HEADER memory
+ * object's address.
+ */
+ current = CONTAINING_RECORD(current_entry, OBJECT_HEADER, Entry);
+ /*
+ * Compute the space required in the user buffer to copy
+ * the data from the current object:
+ *
+ * Name (WCHAR) 0 TypeName (WCHAR) 0
+ */
+ NameLength = (wcslen (current->Name.Buffer) * sizeof (WCHAR));
+ TypeNameLength = (wcslen (current->ObjectType->TypeName.Buffer) * sizeof (WCHAR));
+ SpaceRequired =
+ (NameLength + sizeof (WCHAR))
+ + (TypeNameLength + sizeof (WCHAR));
+ /*
+ * Check for free space in the user buffer.
+ */
+ if (SpaceRequired >= SpaceLeft)
+ {
+ return (STATUS_BUFFER_TOO_SMALL);
+ }
+ /*
+ * Copy the current directory entry's data into the buffer
+ * and update the OBJDIR_INFORMATION entry in the array.
+ */
+ /* --- Object's name --- */
+ current_odi->ObjectName.Length = NameLength;
+ current_odi->ObjectName.MaximumLength = (NameLength + sizeof (WCHAR));
+ current_odi->ObjectName.Buffer = (PWCHAR) FirstFree;
+ wcscpy ((PWCHAR) FirstFree, current->Name.Buffer);
+ FirstFree += (current_odi->ObjectName.MaximumLength);
+ /* --- Object type's name --- */
+ current_odi->ObjectTypeName.Length = TypeNameLength;
+ current_odi->ObjectTypeName.MaximumLength = (TypeNameLength + sizeof (WCHAR));
+ current_odi->ObjectTypeName.Buffer = (PWCHAR) FirstFree;
+ wcscpy ((PWCHAR) FirstFree, current->ObjectType->TypeName.Buffer);
+ FirstFree += (current_odi->ObjectTypeName.MaximumLength);
+ /* Next entry in the array */
+ ++ current_odi;
+ /* Decrease the space left count */
+ SpaceLeft -= SpaceRequired;
+ /* Increase the object index number */
+ ++ i;
+ /* Next object in the directory */
+ current_entry = current_entry->Flink;
+
+ } while (FALSE == ReturnSingleEntry);
+ /*
+ * Store current index in ObjectIndex
+ */
+ *ObjectIndex = i;
+ /*
+ * Report to the caller how much bytes
+ * we wrote in the user buffer.
+ */
+ if (NULL != DataWritten)
+ {
+ *DataWritten = (BufferLength - SpaceLeft);
+ }
+ return (STATUS_SUCCESS);