mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 16:32:59 +00:00
- Fix definition of OBJECT_DIRECTORY_INFORMATION
- Implement most of NtQueryDirectoryObject. It lacks the last step of converting the absolute buffer to a relative one. I have no idea why the old code was re-implemented in a recent commit when I clearly said I would fix this tonight. svn path=/trunk/; revision=23112
This commit is contained in:
parent
8baa71bb63
commit
96722f7c02
9 changed files with 158 additions and 215 deletions
|
@ -257,11 +257,11 @@ ListDirectory (
|
||||||
CHAR TypeNameA [MAX_PATH];
|
CHAR TypeNameA [MAX_PATH];
|
||||||
CHAR TargetNameA [MAX_PATH];
|
CHAR TargetNameA [MAX_PATH];
|
||||||
|
|
||||||
if (0 == wcscmp (L"SymbolicLink", pDirectoryEntry->ObjectTypeName.Buffer))
|
if (0 == wcscmp (L"SymbolicLink", pDirectoryEntry->TypeName.Buffer))
|
||||||
{
|
{
|
||||||
if (TRUE == ExpandSymbolicLink (
|
if (TRUE == ExpandSymbolicLink (
|
||||||
DirectoryNameW,
|
DirectoryNameW,
|
||||||
& pDirectoryEntry->ObjectName,
|
& pDirectoryEntry->Name,
|
||||||
& TargetObjectName
|
& TargetObjectName
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -269,8 +269,8 @@ ListDirectory (
|
||||||
|
|
||||||
printf (
|
printf (
|
||||||
"%-16s %s -> %s\n",
|
"%-16s %s -> %s\n",
|
||||||
RawUszAsz (pDirectoryEntry->ObjectTypeName.Buffer, TypeNameA),
|
RawUszAsz (pDirectoryEntry->TypeName.Buffer, TypeNameA),
|
||||||
RawUszAsz (pDirectoryEntry->ObjectName.Buffer, ObjectNameA),
|
RawUszAsz (pDirectoryEntry->Name.Buffer, ObjectNameA),
|
||||||
RawUszAsz (TargetObjectName.Buffer, TargetNameA)
|
RawUszAsz (TargetObjectName.Buffer, TargetNameA)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -278,8 +278,8 @@ ListDirectory (
|
||||||
{
|
{
|
||||||
printf (
|
printf (
|
||||||
"%-16s %s -> (error!)\n",
|
"%-16s %s -> (error!)\n",
|
||||||
RawUszAsz (pDirectoryEntry->ObjectTypeName.Buffer, TypeNameA),
|
RawUszAsz (pDirectoryEntry->TypeName.Buffer, TypeNameA),
|
||||||
RawUszAsz (pDirectoryEntry->ObjectName.Buffer, ObjectNameA)
|
RawUszAsz (pDirectoryEntry->Name.Buffer, ObjectNameA)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -287,8 +287,8 @@ ListDirectory (
|
||||||
{
|
{
|
||||||
printf (
|
printf (
|
||||||
"%-16s %s\n",
|
"%-16s %s\n",
|
||||||
RawUszAsz (pDirectoryEntry->ObjectTypeName.Buffer, TypeNameA),
|
RawUszAsz (pDirectoryEntry->TypeName.Buffer, TypeNameA),
|
||||||
RawUszAsz (pDirectoryEntry->ObjectName.Buffer, ObjectNameA)
|
RawUszAsz (pDirectoryEntry->Name.Buffer, ObjectNameA)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
++ pDirectoryEntry;
|
++ pDirectoryEntry;
|
||||||
|
@ -306,9 +306,9 @@ ListDirectory (
|
||||||
if (FALSE != Recurse)
|
if (FALSE != Recurse)
|
||||||
{
|
{
|
||||||
pDirectoryEntry = (POBJECT_DIRECTORY_INFORMATION) DirectoryEntry;
|
pDirectoryEntry = (POBJECT_DIRECTORY_INFORMATION) DirectoryEntry;
|
||||||
while (0 != pDirectoryEntry->ObjectTypeName.Length)
|
while (0 != pDirectoryEntry->TypeName.Length)
|
||||||
{
|
{
|
||||||
if (0 == wcscmp (L"Directory", pDirectoryEntry->ObjectTypeName.Buffer))
|
if (0 == wcscmp (L"Directory", pDirectoryEntry->TypeName.Buffer))
|
||||||
{
|
{
|
||||||
WCHAR CurrentName [MAX_PATH];
|
WCHAR CurrentName [MAX_PATH];
|
||||||
UNICODE_STRING CurrentDirectory;
|
UNICODE_STRING CurrentDirectory;
|
||||||
|
@ -319,7 +319,7 @@ ListDirectory (
|
||||||
{
|
{
|
||||||
wcscat (CurrentName, L"\\");
|
wcscat (CurrentName, L"\\");
|
||||||
}
|
}
|
||||||
wcscat (CurrentName, pDirectoryEntry->ObjectName.Buffer);
|
wcscat (CurrentName, pDirectoryEntry->Name.Buffer);
|
||||||
RtlInitUnicodeString (& CurrentDirectory, CurrentName);
|
RtlInitUnicodeString (& CurrentDirectory, CurrentName);
|
||||||
ListDirectory (& CurrentDirectory, Recurse);
|
ListDirectory (& CurrentDirectory, Recurse);
|
||||||
}
|
}
|
||||||
|
|
|
@ -470,12 +470,12 @@ ScmCheckDriver(PSERVICE Service)
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
DPRINT("Comparing: '%S' '%wZ'\n", Service->lpServiceName, &DirInfo->ObjectName);
|
DPRINT("Comparing: '%S' '%wZ'\n", Service->lpServiceName, &DirInfo->Name);
|
||||||
|
|
||||||
if (_wcsicmp(Service->lpServiceName, DirInfo->ObjectName.Buffer) == 0)
|
if (_wcsicmp(Service->lpServiceName, DirInfo->Name.Buffer) == 0)
|
||||||
{
|
{
|
||||||
DPRINT("Found: '%S' '%wZ'\n",
|
DPRINT("Found: '%S' '%wZ'\n",
|
||||||
Service->lpServiceName, &DirInfo->ObjectName);
|
Service->lpServiceName, &DirInfo->Name);
|
||||||
|
|
||||||
/* Mark service as 'running' */
|
/* Mark service as 'running' */
|
||||||
Service->Status.dwCurrentState = SERVICE_RUNNING;
|
Service->Status.dwCurrentState = SERVICE_RUNNING;
|
||||||
|
|
|
@ -140,12 +140,12 @@ ScmGetDriverStatus(PSERVICE lpService,
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
DPRINT("Comparing: '%S' '%wZ'\n", lpService->lpServiceName, &DirInfo->ObjectName);
|
DPRINT("Comparing: '%S' '%wZ'\n", lpService->lpServiceName, &DirInfo->Name);
|
||||||
|
|
||||||
if (_wcsicmp(lpService->lpServiceName, DirInfo->ObjectName.Buffer) == 0)
|
if (_wcsicmp(lpService->lpServiceName, DirInfo->Name.Buffer) == 0)
|
||||||
{
|
{
|
||||||
DPRINT1("Found: '%S' '%wZ'\n",
|
DPRINT1("Found: '%S' '%wZ'\n",
|
||||||
lpService->lpServiceName, &DirInfo->ObjectName);
|
lpService->lpServiceName, &DirInfo->Name);
|
||||||
bFound = TRUE;
|
bFound = TRUE;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -298,11 +298,11 @@ QueryDosDeviceW(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!wcscmp (DirInfo->ObjectTypeName.Buffer, L"SymbolicLink"))
|
if (!wcscmp (DirInfo->TypeName.Buffer, L"SymbolicLink"))
|
||||||
{
|
{
|
||||||
DPRINT ("Name: '%wZ'\n", &DirInfo->ObjectName);
|
DPRINT ("Name: '%wZ'\n", &DirInfo->Name);
|
||||||
|
|
||||||
NameLength = DirInfo->ObjectName.Length / sizeof(WCHAR);
|
NameLength = DirInfo->Name.Length / sizeof(WCHAR);
|
||||||
if (Length + NameLength + 1 >= ucchMax)
|
if (Length + NameLength + 1 >= ucchMax)
|
||||||
{
|
{
|
||||||
Length = 0;
|
Length = 0;
|
||||||
|
@ -311,8 +311,8 @@ QueryDosDeviceW(
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy (Ptr,
|
memcpy (Ptr,
|
||||||
DirInfo->ObjectName.Buffer,
|
DirInfo->Name.Buffer,
|
||||||
DirInfo->ObjectName.Length);
|
DirInfo->Name.Length);
|
||||||
Ptr += NameLength;
|
Ptr += NameLength;
|
||||||
Length += NameLength;
|
Length += NameLength;
|
||||||
*Ptr = UNICODE_NULL;
|
*Ptr = UNICODE_NULL;
|
||||||
|
|
|
@ -261,8 +261,8 @@ typedef struct _OBJECT_HANDLE_ATTRIBUTE_INFORMATION
|
||||||
|
|
||||||
typedef struct _OBJECT_DIRECTORY_INFORMATION
|
typedef struct _OBJECT_DIRECTORY_INFORMATION
|
||||||
{
|
{
|
||||||
UNICODE_STRING ObjectName;
|
UNICODE_STRING Name;
|
||||||
UNICODE_STRING ObjectTypeName;
|
UNICODE_STRING TypeName;
|
||||||
} OBJECT_DIRECTORY_INFORMATION, *POBJECT_DIRECTORY_INFORMATION;
|
} OBJECT_DIRECTORY_INFORMATION, *POBJECT_DIRECTORY_INFORMATION;
|
||||||
|
|
||||||
#ifndef NTOS_MODE_USER
|
#ifndef NTOS_MODE_USER
|
||||||
|
|
|
@ -513,12 +513,12 @@ xHalpGetRDiskCount(VOID)
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
Count = 0;
|
Count = 0;
|
||||||
while (DirectoryInfo[Count].ObjectName.Buffer)
|
while (DirectoryInfo[Count].Name.Buffer)
|
||||||
{
|
{
|
||||||
DPRINT("Count %x\n", Count);
|
DPRINT("Count %x\n", Count);
|
||||||
DirectoryInfo[Count].ObjectName.Buffer[DirectoryInfo[Count].ObjectName.Length / sizeof(WCHAR)] = 0;
|
DirectoryInfo[Count].Name.Buffer[DirectoryInfo[Count].Name.Length / sizeof(WCHAR)] = 0;
|
||||||
ArcNameBuffer = DirectoryInfo[Count].ObjectName.Buffer;
|
ArcNameBuffer = DirectoryInfo[Count].Name.Buffer;
|
||||||
if (DirectoryInfo[Count].ObjectName.Length >= sizeof(L"multi(0)disk(0)rdisk(0)") - sizeof(WCHAR) &&
|
if (DirectoryInfo[Count].Name.Length >= sizeof(L"multi(0)disk(0)rdisk(0)") - sizeof(WCHAR) &&
|
||||||
!_wcsnicmp(ArcNameBuffer, L"multi(0)disk(0)rdisk(", (sizeof(L"multi(0)disk(0)rdisk(") - sizeof(WCHAR)) / sizeof(WCHAR)))
|
!_wcsnicmp(ArcNameBuffer, L"multi(0)disk(0)rdisk(", (sizeof(L"multi(0)disk(0)rdisk(") - sizeof(WCHAR)) / sizeof(WCHAR)))
|
||||||
{
|
{
|
||||||
DPRINT("%S\n", ArcNameBuffer);
|
DPRINT("%S\n", ArcNameBuffer);
|
||||||
|
|
|
@ -414,6 +414,15 @@ NtQueryDirectoryObject(IN HANDLE DirectoryHandle,
|
||||||
ULONG NextEntry = 0;
|
ULONG NextEntry = 0;
|
||||||
ULONG CopyBytes = 0;
|
ULONG CopyBytes = 0;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
PVOID LocalBuffer;
|
||||||
|
POBJECT_DIRECTORY_INFORMATION DirectoryInfo;
|
||||||
|
ULONG Length, TotalLength;
|
||||||
|
ULONG Count, CurrentEntry;
|
||||||
|
ULONG Hash;
|
||||||
|
POBJECT_DIRECTORY_ENTRY Entry;
|
||||||
|
POBJECT_HEADER ObjectHeader;
|
||||||
|
POBJECT_HEADER_NAME_INFO ObjectNameInfo;
|
||||||
|
UNICODE_STRING Name;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
/* Check if we need to do any probing */
|
/* Check if we need to do any probing */
|
||||||
|
@ -447,6 +456,14 @@ NtQueryDirectoryObject(IN HANDLE DirectoryHandle,
|
||||||
SkipEntries = *Context;
|
SkipEntries = *Context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Allocate a buffer */
|
||||||
|
LocalBuffer = ExAllocatePoolWithTag(PagedPool,
|
||||||
|
sizeof(OBJECT_DIRECTORY_INFORMATION) +
|
||||||
|
BufferLength,
|
||||||
|
OB_NAME_TAG);
|
||||||
|
if (!LocalBuffer) return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
RtlZeroMemory(LocalBuffer, BufferLength);
|
||||||
|
|
||||||
/* Get a reference to directory */
|
/* Get a reference to directory */
|
||||||
Status = ObReferenceObjectByHandle(DirectoryHandle,
|
Status = ObReferenceObjectByHandle(DirectoryHandle,
|
||||||
DIRECTORY_QUERY,
|
DIRECTORY_QUERY,
|
||||||
|
@ -454,199 +471,125 @@ NtQueryDirectoryObject(IN HANDLE DirectoryHandle,
|
||||||
PreviousMode,
|
PreviousMode,
|
||||||
(PVOID*)&Directory,
|
(PVOID*)&Directory,
|
||||||
NULL);
|
NULL);
|
||||||
if (NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
PVOID TemporaryBuffer = ExAllocatePool(NonPagedPool,
|
/* Free the buffer and fail */
|
||||||
BufferLength);
|
ExFreePool(LocalBuffer);
|
||||||
if(TemporaryBuffer != NULL)
|
return Status;
|
||||||
{
|
}
|
||||||
POBJECT_HEADER EntryHeader;
|
|
||||||
ULONG RequiredSize = sizeof(OBJECT_DIRECTORY_INFORMATION);
|
|
||||||
ULONG nDirectories = 0;
|
|
||||||
POBJECT_DIRECTORY_INFORMATION DirInfo = (POBJECT_DIRECTORY_INFORMATION)TemporaryBuffer;
|
|
||||||
POBJECT_DIRECTORY_ENTRY DirectoryEntry;
|
|
||||||
ULONG i;
|
|
||||||
BOOLEAN StopIt = FALSE;
|
|
||||||
|
|
||||||
|
/* Start at position 0 */
|
||||||
|
DirectoryInfo = (POBJECT_DIRECTORY_INFORMATION)LocalBuffer;
|
||||||
|
TotalLength = sizeof(OBJECT_DIRECTORY_INFORMATION);
|
||||||
|
|
||||||
|
/* Start with 0 entries */
|
||||||
|
Count = 0;
|
||||||
|
CurrentEntry = 0;
|
||||||
|
|
||||||
|
/* Set default status and start looping */
|
||||||
Status = STATUS_NO_MORE_ENTRIES;
|
Status = STATUS_NO_MORE_ENTRIES;
|
||||||
|
for (Hash = 0; Hash < 37; Hash++)
|
||||||
KeEnterCriticalRegion();
|
|
||||||
ExAcquireResourceSharedLite(&Directory->Lock, TRUE);
|
|
||||||
|
|
||||||
for (i = 0; i < NUMBER_HASH_BUCKETS && !StopIt; i++)
|
|
||||||
{
|
{
|
||||||
DirectoryEntry = Directory->HashBuckets[i];
|
/* Get this entry and loop all of them */
|
||||||
while (DirectoryEntry)
|
Entry = Directory->HashBuckets[Hash];
|
||||||
|
while (Entry)
|
||||||
{
|
{
|
||||||
NextEntry++;
|
/* Check if we should process this entry */
|
||||||
if (SkipEntries == 0)
|
if (SkipEntries == CurrentEntry++)
|
||||||
{
|
{
|
||||||
PUNICODE_STRING Name, Type;
|
/* Get the header data */
|
||||||
ULONG EntrySize;
|
ObjectHeader = OBJECT_TO_OBJECT_HEADER(Entry->Object);
|
||||||
|
ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
|
||||||
|
|
||||||
EntryHeader = OBJECT_TO_OBJECT_HEADER(DirectoryEntry->Object);
|
/* Get the object name */
|
||||||
|
if (ObjectNameInfo)
|
||||||
/* Calculate the size of the required buffer space for this entry */
|
|
||||||
Name = (OBJECT_HEADER_TO_NAME_INFO(EntryHeader)->Name.Length != 0 ? &OBJECT_HEADER_TO_NAME_INFO(EntryHeader)->Name : NULL);
|
|
||||||
Type = &EntryHeader->Type->Name;
|
|
||||||
EntrySize = sizeof(OBJECT_DIRECTORY_INFORMATION) +
|
|
||||||
((Name != NULL) ? ((ULONG)Name->Length + sizeof(WCHAR)) : 0) +
|
|
||||||
(ULONG)EntryHeader->Type->Name.Length + sizeof(WCHAR);
|
|
||||||
|
|
||||||
if (RequiredSize + EntrySize <= BufferLength)
|
|
||||||
{
|
{
|
||||||
/* The buffer is large enough to receive this entry. It would've
|
/* Use the one we have */
|
||||||
been much easier if the strings were directly appended to the
|
Name = ObjectNameInfo->Name;
|
||||||
OBJECT_DIRECTORY_INFORMATION structured written into the buffer */
|
|
||||||
if (Name != NULL && Name->Length > 0)
|
|
||||||
DirInfo->ObjectName = *Name;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DirInfo->ObjectName.Length = DirInfo->ObjectName.MaximumLength = 0;
|
|
||||||
DirInfo->ObjectName.Buffer = NULL;
|
|
||||||
}
|
|
||||||
DirInfo->ObjectTypeName = *Type;
|
|
||||||
|
|
||||||
nDirectories++;
|
|
||||||
RequiredSize += EntrySize;
|
|
||||||
|
|
||||||
Status = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
if (ReturnSingleEntry)
|
|
||||||
{
|
|
||||||
/* We're only supposed to query one entry, so bail and copy the
|
|
||||||
strings to the buffer */
|
|
||||||
StopIt = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
DirInfo++;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* Otherwise, use an empty one */
|
||||||
|
RtlInitEmptyUnicodeString(&Name, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate the length for this entry */
|
||||||
|
Length = sizeof(OBJECT_DIRECTORY_INFORMATION) +
|
||||||
|
Name.Length + sizeof(UNICODE_NULL) +
|
||||||
|
ObjectHeader->Type->Name.Length + sizeof(UNICODE_NULL);
|
||||||
|
|
||||||
|
/* Make sure this entry won't overflow */
|
||||||
|
if ((TotalLength + Length) > BufferLength)
|
||||||
|
{
|
||||||
|
/* Check if the caller wanted only an entry */
|
||||||
if (ReturnSingleEntry)
|
if (ReturnSingleEntry)
|
||||||
{
|
{
|
||||||
/* The buffer is too small, so return the number of bytes that
|
/* Then we'll fail and ask for more buffer */
|
||||||
would've been required for this query */
|
TotalLength += Length;
|
||||||
RequiredSize += EntrySize;
|
|
||||||
Status = STATUS_BUFFER_TOO_SMALL;
|
Status = STATUS_BUFFER_TOO_SMALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We couldn't query this entry, so leave the index that will be stored
|
|
||||||
in Context to this entry so the caller can query it the next time
|
|
||||||
he queries (hopefully with a buffer that is large enough then...) */
|
|
||||||
NextEntry--;
|
|
||||||
|
|
||||||
/* Just copy the entries that fit into the buffer */
|
|
||||||
StopIt = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Skip the entry */
|
/* Otherwise, we'll say we're done for now */
|
||||||
SkipEntries--;
|
|
||||||
}
|
|
||||||
DirectoryEntry = DirectoryEntry->ChainLink;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ReturnSingleEntry)
|
|
||||||
{
|
|
||||||
/* Check if there are more entries to enumerate but the buffer is already
|
|
||||||
full. Only tell this to the user if he queries multiple entries */
|
|
||||||
if (DirectoryEntry)
|
|
||||||
Status = STATUS_MORE_ENTRIES;
|
Status = STATUS_MORE_ENTRIES;
|
||||||
else
|
}
|
||||||
for (; i < NUMBER_HASH_BUCKETS; i++)
|
|
||||||
if (Directory->HashBuckets[i])
|
/* Decrease the entry since we didn't process */
|
||||||
{
|
CurrentEntry--;
|
||||||
Status = STATUS_MORE_ENTRIES;
|
goto Quickie;
|
||||||
break;
|
}
|
||||||
|
|
||||||
|
/* Now fill in the buffer */
|
||||||
|
DirectoryInfo->Name.Length = Name.Length;
|
||||||
|
DirectoryInfo->Name.MaximumLength = Name.Length +
|
||||||
|
sizeof(UNICODE_NULL);
|
||||||
|
DirectoryInfo->Name.Buffer = Name.Buffer;
|
||||||
|
DirectoryInfo->TypeName.Length = ObjectHeader->
|
||||||
|
Type->Name.Length;
|
||||||
|
DirectoryInfo->TypeName.MaximumLength = ObjectHeader->
|
||||||
|
Type->Name.Length +
|
||||||
|
sizeof(UNICODE_NULL);
|
||||||
|
DirectoryInfo->TypeName.Buffer = ObjectHeader->
|
||||||
|
Type->Name.Buffer;
|
||||||
|
|
||||||
|
/* Increase statistics */
|
||||||
|
TotalLength += Length;
|
||||||
|
DirectoryInfo++;
|
||||||
|
Count++;
|
||||||
|
|
||||||
|
/* If the caller only wanted an entry, bail out */
|
||||||
|
if (ReturnSingleEntry) goto Quickie;
|
||||||
|
|
||||||
|
/* Increase the key by one */
|
||||||
|
SkipEntries++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NT_SUCCESS(Status) && nDirectories > 0)
|
/* Move to the next directory */
|
||||||
{
|
Entry = Entry->ChainLink;
|
||||||
PWSTR strbuf = (PWSTR)((POBJECT_DIRECTORY_INFORMATION)TemporaryBuffer + nDirectories + 1);
|
|
||||||
PWSTR deststrbuf = (PWSTR)((POBJECT_DIRECTORY_INFORMATION)Buffer + nDirectories + 1);
|
|
||||||
memset((POBJECT_DIRECTORY_INFORMATION)TemporaryBuffer + nDirectories, 0, sizeof(OBJECT_DIRECTORY_INFORMATION));
|
|
||||||
|
|
||||||
CopyBytes = (nDirectories + 1) * sizeof(OBJECT_DIRECTORY_INFORMATION);
|
|
||||||
|
|
||||||
/* Copy the names from the objects and append them to the list of the
|
|
||||||
objects. copy to the temporary buffer only because the directory
|
|
||||||
lock can't be released and the buffer might be pagable memory! */
|
|
||||||
for (DirInfo = (POBJECT_DIRECTORY_INFORMATION)TemporaryBuffer;
|
|
||||||
nDirectories > 0;
|
|
||||||
nDirectories--, DirInfo++)
|
|
||||||
{
|
|
||||||
ULONG NameLength;
|
|
||||||
|
|
||||||
if (DirInfo->ObjectName.Length > 0)
|
|
||||||
{
|
|
||||||
RtlCopyMemory(strbuf,
|
|
||||||
DirInfo->ObjectName.Buffer,
|
|
||||||
DirInfo->ObjectName.Length);
|
|
||||||
/* Change the buffer pointer to the buffer */
|
|
||||||
DirInfo->ObjectName.Buffer = deststrbuf;
|
|
||||||
NameLength = DirInfo->ObjectName.Length / sizeof(WCHAR);
|
|
||||||
/* NULL-terminate the string */
|
|
||||||
strbuf[NameLength] = L'\0';
|
|
||||||
strbuf += NameLength + 1;
|
|
||||||
deststrbuf += NameLength + 1;
|
|
||||||
|
|
||||||
CopyBytes += (NameLength + 1) * sizeof(WCHAR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlCopyMemory(strbuf,
|
Quickie:
|
||||||
DirInfo->ObjectTypeName.Buffer,
|
/* Make sure we got success */
|
||||||
DirInfo->ObjectTypeName.Length);
|
if (NT_SUCCESS(Status))
|
||||||
/* Change the buffer pointer to the buffer */
|
|
||||||
DirInfo->ObjectTypeName.Buffer = deststrbuf;
|
|
||||||
NameLength = DirInfo->ObjectTypeName.Length / sizeof(WCHAR);
|
|
||||||
/* NULL-terminate the string */
|
|
||||||
strbuf[NameLength] = L'\0';
|
|
||||||
strbuf += NameLength + 1;
|
|
||||||
deststrbuf += NameLength + 1;
|
|
||||||
|
|
||||||
CopyBytes += (NameLength + 1) * sizeof(WCHAR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ExReleaseResourceLite(&Directory->Lock);
|
|
||||||
KeLeaveCriticalRegion();
|
|
||||||
ObDereferenceObject(Directory);
|
|
||||||
|
|
||||||
if (NT_SUCCESS(Status) || ReturnSingleEntry)
|
|
||||||
{
|
|
||||||
_SEH_TRY
|
|
||||||
{
|
|
||||||
if (CopyBytes != 0)
|
|
||||||
{
|
|
||||||
RtlCopyMemory(Buffer,
|
|
||||||
TemporaryBuffer,
|
|
||||||
CopyBytes);
|
|
||||||
}
|
|
||||||
*Context = NextEntry;
|
|
||||||
if(ReturnLength != NULL)
|
|
||||||
{
|
|
||||||
*ReturnLength = RequiredSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_SEH_HANDLE
|
|
||||||
{
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
}
|
|
||||||
_SEH_END;
|
|
||||||
}
|
|
||||||
|
|
||||||
ExFreePool(TemporaryBuffer);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
/* We need to parse all the entries and convert absolute to relative */
|
||||||
|
DPRINT1("NOT FULLY IMPLEMENTED\n");
|
||||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
/* Copy the buffer */
|
||||||
|
RtlMoveMemory(Buffer,
|
||||||
|
LocalBuffer,
|
||||||
|
(TotalLength <= BufferLength) ?
|
||||||
|
TotalLength : BufferLength);
|
||||||
|
|
||||||
|
/* Check if the caller requested the return length and return it*/
|
||||||
|
if (ReturnLength) *ReturnLength = TotalLength;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/* Dereference the directory and free our buffer */
|
||||||
|
ObDereferenceObject(Directory);
|
||||||
|
ExFreePool(LocalBuffer);
|
||||||
|
|
||||||
/* Return status to caller */
|
/* Return status to caller */
|
||||||
return Status;
|
return Status;
|
||||||
|
|
|
@ -94,14 +94,14 @@ CsrPopulateDosDevicesDirectory(IN HANDLE hDosDevicesDirectory,
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* Make sure it has a name */
|
/* Make sure it has a name */
|
||||||
if (!QueryBuffer->ObjectName.Buffer[0]) continue;
|
if (!QueryBuffer->Name.Buffer[0]) continue;
|
||||||
|
|
||||||
/* Check if it's actually a symbolic link */
|
/* Check if it's actually a symbolic link */
|
||||||
if (wcscmp(QueryBuffer->ObjectTypeName.Buffer, SYMLINK_NAME))
|
if (wcscmp(QueryBuffer->TypeName.Buffer, SYMLINK_NAME))
|
||||||
{
|
{
|
||||||
/* It is, open it */
|
/* It is, open it */
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
&QueryBuffer->ObjectName,
|
&QueryBuffer->Name,
|
||||||
OBJ_CASE_INSENSITIVE,
|
OBJ_CASE_INSENSITIVE,
|
||||||
NULL,
|
NULL,
|
||||||
hDirectory);
|
hDirectory);
|
||||||
|
|
|
@ -1235,10 +1235,10 @@ BuildWindowStationNameList(
|
||||||
*/
|
*/
|
||||||
ReturnLength = sizeof(DWORD);
|
ReturnLength = sizeof(DWORD);
|
||||||
EntryCount = 0;
|
EntryCount = 0;
|
||||||
for (DirEntry = (POBJECT_DIRECTORY_INFORMATION) Buffer; 0 != DirEntry->ObjectName.Length;
|
for (DirEntry = (POBJECT_DIRECTORY_INFORMATION) Buffer; 0 != DirEntry->Name.Length;
|
||||||
DirEntry++)
|
DirEntry++)
|
||||||
{
|
{
|
||||||
ReturnLength += DirEntry->ObjectName.Length + sizeof(WCHAR);
|
ReturnLength += DirEntry->Name.Length + sizeof(WCHAR);
|
||||||
EntryCount++;
|
EntryCount++;
|
||||||
}
|
}
|
||||||
DPRINT("Required size: %d Entry count: %d\n", ReturnLength, EntryCount);
|
DPRINT("Required size: %d Entry count: %d\n", ReturnLength, EntryCount);
|
||||||
|
@ -1282,10 +1282,10 @@ BuildWindowStationNameList(
|
||||||
lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(DWORD));
|
lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(DWORD));
|
||||||
|
|
||||||
NullWchar = L'\0';
|
NullWchar = L'\0';
|
||||||
for (DirEntry = (POBJECT_DIRECTORY_INFORMATION) Buffer; 0 != DirEntry->ObjectName.Length;
|
for (DirEntry = (POBJECT_DIRECTORY_INFORMATION) Buffer; 0 != DirEntry->Name.Length;
|
||||||
DirEntry++)
|
DirEntry++)
|
||||||
{
|
{
|
||||||
Status = MmCopyToCaller(lpBuffer, DirEntry->ObjectName.Buffer, DirEntry->ObjectName.Length);
|
Status = MmCopyToCaller(lpBuffer, DirEntry->Name.Buffer, DirEntry->Name.Length);
|
||||||
if (! NT_SUCCESS(Status))
|
if (! NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
if (Buffer != InitialBuffer)
|
if (Buffer != InitialBuffer)
|
||||||
|
@ -1294,7 +1294,7 @@ BuildWindowStationNameList(
|
||||||
}
|
}
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
lpBuffer = (PVOID) ((PCHAR) lpBuffer + DirEntry->ObjectName.Length);
|
lpBuffer = (PVOID) ((PCHAR) lpBuffer + DirEntry->Name.Length);
|
||||||
Status = MmCopyToCaller(lpBuffer, &NullWchar, sizeof(WCHAR));
|
Status = MmCopyToCaller(lpBuffer, &NullWchar, sizeof(WCHAR));
|
||||||
if (! NT_SUCCESS(Status))
|
if (! NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue