NTSTATUS
NTAPI
+INIT_FUNCTION
ObpCreateDosDevicesDirectory(VOID)
{
OBJECT_ATTRIBUTES ObjectAttributes;
NTAPI
ObDereferenceDeviceMap(IN PEPROCESS Process)
{
- //KIRQL OldIrql;
- PDEVICE_MAP DeviceMap = Process->DeviceMap;
+ PDEVICE_MAP DeviceMap;
- /* FIXME: We don't use Process Devicemaps yet */
+ /* Get the pointer to this process devicemap and reset it
+ holding devicemap lock */
+ KeAcquireGuardedMutex(&ObpDeviceMapLock);
+ DeviceMap = Process->DeviceMap;
+ Process->DeviceMap = NULL;
+ KeReleaseGuardedMutex(&ObpDeviceMapLock);
+
+ /* Continue only if there is a devicemap to dereference */
if (DeviceMap)
{
- /* FIXME: Acquire the DeviceMap Spinlock */
- // KeAcquireSpinLock(DeviceMap->Lock, &OldIrql);
+ KeAcquireGuardedMutex(&ObpDeviceMapLock);
/* Delete the device map link and dereference it */
- Process->DeviceMap = NULL;
if (--DeviceMap->ReferenceCount)
{
/* Nobody is referencing it anymore, unlink the DOS directory */
DeviceMap->DosDevicesDirectory->DeviceMap = NULL;
- /* FIXME: Release the DeviceMap Spinlock */
- // KeReleasepinLock(DeviceMap->Lock, OldIrql);
+ /* Release the devicemap lock */
+ KeReleaseGuardedMutex(&ObpDeviceMapLock);
/* Dereference the DOS Devices Directory and free the Device Map */
ObDereferenceObject(DeviceMap->DosDevicesDirectory);
}
else
{
- /* FIXME: Release the DeviceMap Spinlock */
- // KeReleasepinLock(DeviceMap->Lock, OldIrql);
+ /* Release the devicemap lock */
+ KeReleaseGuardedMutex(&ObpDeviceMapLock);
}
}
}
}
else if (!(ObjectName->Length) || !(ObjectName->Buffer))
{
- /* Just return the Root Directory if we didn't get a name*/
+ /* Just return the Root Directory if we didn't get a name */
Status = ObReferenceObjectByPointer(RootDirectory,
0,
ObjectType,
}
/* Reparse */
- while (Reparse)
+ while (Reparse && MaxReparse)
{
/* Get the name */
RemainingName = *ObjectName;
ObjectHeader)))
{
/* Either couldn't allocate the name, or insert failed */
- if (NewName) ExFreePool(NewName);
+ if (NewName) ExFreePoolWithTag(NewName, OB_NAME_TAG);
/* Fail due to memory reasons */
Status = STATUS_INSUFFICIENT_RESOURCES;
if (ObjectNameInfo->Name.Buffer)
{
/* Free it */
- ExFreePoolWithTag(ObjectNameInfo->Name.Buffer, OB_NAME_TAG );
+ ExFreePoolWithTag(ObjectNameInfo->Name.Buffer, OB_NAME_TAG);
}
/* Write new one */
{
/* Reparse again */
Reparse = TRUE;
+ --MaxReparse;
+ if (MaxReparse == 0)
+ {
+ Object = NULL;
+ break;
+ }
/* Start over from root if we got sent back there */
if ((Status == STATUS_REPARSE_OBJECT) ||
ULONG NameSize;
PWCH ObjectName;
BOOLEAN ObjectIsNamed;
+ NTSTATUS Status = STATUS_SUCCESS;
/* Get the Kernel Meta-Structures */
ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
/* Check if a Query Name Procedure is available */
if (ObjectHeader->Type->TypeInfo.QueryNameProcedure)
{
- /* Call the procedure */
+ /* Call the procedure inside SEH */
ObjectIsNamed = ((LocalInfo) && (LocalInfo->Name.Length > 0));
- return ObjectHeader->Type->TypeInfo.QueryNameProcedure(Object,
+
+ _SEH2_TRY
+ {
+ Status = ObjectHeader->Type->TypeInfo.QueryNameProcedure(Object,
ObjectIsNamed,
ObjectNameInfo,
Length,
ReturnLength,
KernelMode);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Return the exception code */
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ return Status;
}
/* Check if the object doesn't even have a name */
if (!(LocalInfo) || !(LocalInfo->Name.Buffer))
{
- /* We're returning the name structure */
- *ReturnLength = sizeof(OBJECT_NAME_INFORMATION);
+ Status = STATUS_SUCCESS;
- /* Check if we were given enough space */
- if (*ReturnLength > Length) return STATUS_INFO_LENGTH_MISMATCH;
+ _SEH2_TRY
+ {
+ /* We're returning the name structure */
+ *ReturnLength = sizeof(OBJECT_NAME_INFORMATION);
+
+ /* Check if we were given enough space */
+ if (*ReturnLength > Length)
+ {
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ }
+ else
+ {
+ /* Return an empty buffer */
+ RtlInitEmptyUnicodeString(&ObjectNameInfo->Name, NULL, 0);
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Return the exception code */
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
- /* Return an empty buffer */
- RtlInitEmptyUnicodeString(&ObjectNameInfo->Name, NULL, 0);
- return STATUS_SUCCESS;
+ return Status;
}
/*
* enough right at the beginning, not work our way through
* and find out at the end
*/
- if (Object == ObpRootDirectoryObject)
+ _SEH2_TRY
{
- /* Size of the '\' string */
- NameSize = sizeof(OBJ_NAME_PATH_SEPARATOR);
- }
- else
- {
- /* Get the Object Directory and add name of Object */
- ParentDirectory = LocalInfo->Directory;
- NameSize = sizeof(OBJ_NAME_PATH_SEPARATOR) + LocalInfo->Name.Length;
-
- /* Loop inside the directory to get the top-most one (meaning root) */
- while ((ParentDirectory != ObpRootDirectoryObject) && (ParentDirectory))
+ if (Object == ObpRootDirectoryObject)
{
- /* Get the Name Information */
- LocalInfo = OBJECT_HEADER_TO_NAME_INFO(
- OBJECT_TO_OBJECT_HEADER(ParentDirectory));
+ /* Size of the '\' string */
+ NameSize = sizeof(OBJ_NAME_PATH_SEPARATOR);
+ }
+ else
+ {
+ /* Get the Object Directory and add name of Object */
+ ParentDirectory = LocalInfo->Directory;
+ NameSize = sizeof(OBJ_NAME_PATH_SEPARATOR) + LocalInfo->Name.Length;
- /* Add the size of the Directory Name */
- if (LocalInfo && LocalInfo->Directory)
+ /* Loop inside the directory to get the top-most one (meaning root) */
+ while ((ParentDirectory != ObpRootDirectoryObject) && (ParentDirectory))
{
- /* Size of the '\' string + Directory Name */
- NameSize += sizeof(OBJ_NAME_PATH_SEPARATOR) +
- LocalInfo->Name.Length;
+ /* Get the Name Information */
+ LocalInfo = OBJECT_HEADER_TO_NAME_INFO(
+ OBJECT_TO_OBJECT_HEADER(ParentDirectory));
- /* Move to next parent Directory */
- ParentDirectory = LocalInfo->Directory;
- }
- else
- {
- /* Directory with no name. We append "...\" */
- NameSize += sizeof(L"...") + sizeof(OBJ_NAME_PATH_SEPARATOR);
- break;
+ /* Add the size of the Directory Name */
+ if (LocalInfo && LocalInfo->Directory)
+ {
+ /* Size of the '\' string + Directory Name */
+ NameSize += sizeof(OBJ_NAME_PATH_SEPARATOR) +
+ LocalInfo->Name.Length;
+
+ /* Move to next parent Directory */
+ ParentDirectory = LocalInfo->Directory;
+ }
+ else
+ {
+ /* Directory with no name. We append "...\" */
+ NameSize += sizeof(L"...") + sizeof(OBJ_NAME_PATH_SEPARATOR);
+ break;
+ }
}
}
- }
-
- /* Finally, add the name of the structure and the null char */
- *ReturnLength = NameSize +
- sizeof(OBJECT_NAME_INFORMATION) +
- sizeof(UNICODE_NULL);
- /* Check if we were given enough space */
- if (*ReturnLength > Length) return STATUS_INFO_LENGTH_MISMATCH;
-
- /*
- * Now we will actually create the name. We work backwards because
- * it's easier to start off from the Name we have and walk up the
- * parent directories. We use the same logic as Name Length calculation.
- */
- LocalInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
- ObjectName = (PWCH)((ULONG_PTR)ObjectNameInfo + *ReturnLength);
- *--ObjectName = UNICODE_NULL;
+ /* Finally, add the name of the structure and the null char */
+ *ReturnLength = NameSize +
+ sizeof(OBJECT_NAME_INFORMATION) +
+ sizeof(UNICODE_NULL);
- /* Check if the object is actually the Root directory */
- if (Object == ObpRootDirectoryObject)
- {
- /* This is already the Root Directory, return "\\" */
- *--ObjectName = OBJ_NAME_PATH_SEPARATOR;
- ObjectNameInfo->Name.Length = (USHORT)NameSize;
- ObjectNameInfo->Name.MaximumLength = (USHORT)(NameSize +
- sizeof(UNICODE_NULL));
- ObjectNameInfo->Name.Buffer = ObjectName;
- return STATUS_SUCCESS;
- }
- else
- {
- /* Start by adding the Object's Name */
- ObjectName = (PWCH)((ULONG_PTR)ObjectName -
- LocalInfo->Name.Length);
- RtlCopyMemory(ObjectName,
- LocalInfo->Name.Buffer,
- LocalInfo->Name.Length);
-
- /* Now parse the Parent directories until we reach the top */
- ParentDirectory = LocalInfo->Directory;
- while ((ParentDirectory != ObpRootDirectoryObject) && (ParentDirectory))
+ /* Check if we were given enough space */
+ if (*ReturnLength > Length) _SEH2_YIELD(return STATUS_INFO_LENGTH_MISMATCH);
+
+ /*
+ * Now we will actually create the name. We work backwards because
+ * it's easier to start off from the Name we have and walk up the
+ * parent directories. We use the same logic as Name Length calculation.
+ */
+ LocalInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
+ ObjectName = (PWCH)((ULONG_PTR)ObjectNameInfo + *ReturnLength);
+ *--ObjectName = UNICODE_NULL;
+
+ /* Check if the object is actually the Root directory */
+ if (Object == ObpRootDirectoryObject)
{
- /* Get the name information */
- LocalInfo = OBJECT_HEADER_TO_NAME_INFO(
- OBJECT_TO_OBJECT_HEADER(ParentDirectory));
+ /* This is already the Root Directory, return "\\" */
+ *--ObjectName = OBJ_NAME_PATH_SEPARATOR;
+ ObjectNameInfo->Name.Length = (USHORT)NameSize;
+ ObjectNameInfo->Name.MaximumLength = (USHORT)(NameSize +
+ sizeof(UNICODE_NULL));
+ ObjectNameInfo->Name.Buffer = ObjectName;
+ Status = STATUS_SUCCESS;
+ }
+ else
+ {
+ /* Start by adding the Object's Name */
+ ObjectName = (PWCH)((ULONG_PTR)ObjectName -
+ LocalInfo->Name.Length);
+ RtlCopyMemory(ObjectName,
+ LocalInfo->Name.Buffer,
+ LocalInfo->Name.Length);
+
+ /* Now parse the Parent directories until we reach the top */
+ ParentDirectory = LocalInfo->Directory;
+ while ((ParentDirectory != ObpRootDirectoryObject) && (ParentDirectory))
+ {
+ /* Get the name information */
+ LocalInfo = OBJECT_HEADER_TO_NAME_INFO(
+ OBJECT_TO_OBJECT_HEADER(ParentDirectory));
- /* Add the "\" */
- *(--ObjectName) = OBJ_NAME_PATH_SEPARATOR;
+ /* Add the "\" */
+ *(--ObjectName) = OBJ_NAME_PATH_SEPARATOR;
- /* Add the Parent Directory's Name */
- if (LocalInfo && LocalInfo->Name.Buffer)
- {
- /* Add the name */
- ObjectName = (PWCH)((ULONG_PTR)ObjectName -
- LocalInfo->Name.Length);
- RtlCopyMemory(ObjectName,
- LocalInfo->Name.Buffer,
- LocalInfo->Name.Length);
-
- /* Move to next parent */
- ParentDirectory = LocalInfo->Directory;
- }
- else
- {
- /* Directory without a name, we add "..." */
- ObjectName -= sizeof(L"...");
- ObjectName = L"...";
- break;
+ /* Add the Parent Directory's Name */
+ if (LocalInfo && LocalInfo->Name.Buffer)
+ {
+ /* Add the name */
+ ObjectName = (PWCH)((ULONG_PTR)ObjectName -
+ LocalInfo->Name.Length);
+ RtlCopyMemory(ObjectName,
+ LocalInfo->Name.Buffer,
+ LocalInfo->Name.Length);
+
+ /* Move to next parent */
+ ParentDirectory = LocalInfo->Directory;
+ }
+ else
+ {
+ /* Directory without a name, we add "..." */
+ ObjectName = (PWCH)((ULONG_PTR)ObjectName -
+ sizeof(L"...") +
+ sizeof(UNICODE_NULL));
+ RtlCopyMemory(ObjectName,
+ L"...",
+ sizeof(L"...") + sizeof(UNICODE_NULL));
+ break;
+ }
}
- }
- /* Add Root Directory Name */
- *(--ObjectName) = OBJ_NAME_PATH_SEPARATOR;
- ObjectNameInfo->Name.Length = (USHORT)NameSize;
- ObjectNameInfo->Name.MaximumLength = (USHORT)(NameSize +
- sizeof(UNICODE_NULL));
- ObjectNameInfo->Name.Buffer = ObjectName;
+ /* Add Root Directory Name */
+ *(--ObjectName) = OBJ_NAME_PATH_SEPARATOR;
+ ObjectNameInfo->Name.Length = (USHORT)NameSize;
+ ObjectNameInfo->Name.MaximumLength =
+ (USHORT)(NameSize + sizeof(UNICODE_NULL));
+ ObjectNameInfo->Name.Buffer = ObjectName;
+ }
}
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Return the exception code */
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
/* Return success */
- return STATUS_SUCCESS;
+ return Status;
}
VOID
ObQueryDeviceMapInformation(IN PEPROCESS Process,
IN PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo)
{
- //KIRQL OldIrql ;
-
/*
* FIXME: This is an ugly hack for now, to always return the System Device Map
* instead of returning the Process Device Map. Not important yet since we don't use it
*/
- /* FIXME: Acquire the DeviceMap Spinlock */
- // KeAcquireSpinLock(DeviceMap->Lock, &OldIrql);
+ KeAcquireGuardedMutex(&ObpDeviceMapLock);
/* Make a copy */
DeviceMapInfo->Query.DriveMap = ObSystemDeviceMap->DriveMap;
ObSystemDeviceMap->DriveType,
sizeof(ObSystemDeviceMap->DriveType));
- /* FIXME: Release the DeviceMap Spinlock */
- // KeReleasepinLock(DeviceMap->Lock, OldIrql);
+ KeReleaseGuardedMutex(&ObpDeviceMapLock);
+}
+
+NTSTATUS
+NTAPI
+ObIsDosDeviceLocallyMapped(
+ IN ULONG Index,
+ OUT PUCHAR DosDeviceState)
+{
+ /* check parameters */
+ if (Index < 1 || Index > 26)
+ {
+ /* invalid index */
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* acquire lock */
+ KeAcquireGuardedMutex(&ObpDeviceMapLock);
+
+ /* get drive mapping status */
+ *DosDeviceState = (ObSystemDeviceMap->DriveMap & (1 << Index)) != 0;
+
+ /* release lock */
+ KeReleaseGuardedMutex(&ObpDeviceMapLock);
+
+ /* done */
+ return STATUS_SUCCESS;
}
/* EOF */