Sam Arun Raj Seeniraj:

[NTOSKRNL.EXE]
- Complemented existing stub routines ObpDeleteSymbolicLinkName() and ObpCreateSymbolicLinkName(). Now when symbolic links are created, they are checked for dos drive mapping and ObSystemDeviceMap is updated accordingly.
- Updates to ObpDeviceMapLock are protected by a guarded mutex (changed from fast mutex by Aleksey Bragin).
- Aleksey Bragin: Fix concurrent access issues in ObDereferenceDeviceMap. The DeviceMap read/write operation must be atomic (within the ObpDeviceMapLock region).

[SUBST.EXE]
- Removed hard coded strings and moved it to resource file.

[WIN32CSR.DLL]
- Added a workaround, when target path end with a trailing '\', the substituted drive fails to parse to the target, this is a bug in the object manager, but working around it in CsrDefineDosDevice() by stripping trailing '\'.

See issue #993 for more details.

svn path=/trunk/; revision=51452
This commit is contained in:
Aleksey Bragin 2011-04-25 16:08:00 +00:00
parent f34a5b0b2d
commit 3d60cef193
13 changed files with 399 additions and 58 deletions

View file

@ -0,0 +1,16 @@
#include "resource.h"
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
STRINGTABLE
BEGIN
IDS_INCORRECT_PARAMETER_COUNT "Incorrect number of parameters - %s\n"
IDS_INVALID_PARAMETER "Incorrect number of parameters - %s\n"
IDS_INVALID_PARAMETER2 "Invalid parameter - %s\n"
IDS_DRIVE_ALREAD_SUBSTED "Drive already SUBSTed\n"
IDS_FAILED_WITH_ERROCODE "Failed with error code 0x%x: %s\n"
IDS_USAGE "Associates a path with a drive letter.\n\nSUBST [drive1: [drive2:]path]\nSUBST drive1: /D\n\n drive1: \
Specifies a virtual drive to which you want to assign a path.\n \
[drive2:]path Specifies a physical drive and path you want to assign to\n \
a virtual drive.\n /D \
Deletes a substituted (virtual) drive.\n\nType SUBST with no parameters to display a list of current virtual drives.\n"
END

View file

@ -0,0 +1,11 @@
#define RC_STRING_MAX_SIZE 2048
/* Strings */
#define IDS_FAILED_WITH_ERROCODE 1001
#define IDS_USAGE 1002
#define IDS_INCORRECT_PARAMETER_COUNT 1003
#define IDS_INVALID_PARAMETER 1004
#define IDS_INVALID_PARAMETER2 1005
#define IDS_DRIVE_ALREAD_SUBSTED 1006
/* EOF */

View file

@ -0,0 +1,6 @@
#include <windows.h>
#include "resource.h"
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
#include "lang/en-US.rc"

View file

@ -14,11 +14,13 @@
#include <tchar.h>
#define NDEBUG
#include <debug.h>
#include "resource.h"
/* FUNCTIONS ****************************************************************/
void PrintError(DWORD ErrCode)
{
TCHAR szFmtString[RC_STRING_MAX_SIZE] = {0};
TCHAR *buffer = (TCHAR*) calloc(2048,
sizeof(TCHAR));
TCHAR *msg = NULL;
@ -32,9 +34,13 @@ void PrintError(DWORD ErrCode)
(TCHAR*)&msg,
0,
NULL);
LoadString(GetModuleHandle(NULL),
IDS_FAILED_WITH_ERROCODE,
szFmtString,
sizeof(szFmtString) / sizeof(szFmtString[0]));
_sntprintf(buffer,
2048,
_T("Failed with error code 0x%x: %s\n"),
szFmtString,
ErrCode,
msg);
_tprintf(_T("%s"),
@ -45,16 +51,15 @@ void PrintError(DWORD ErrCode)
}
}
void DisplaySubstUsage()
void DisplaySubstUsage(void)
{
_tprintf(_T("Associates a path with a drive letter.\n\n"));
_tprintf(_T("SUBST [drive1: [drive2:]path]\n"));
_tprintf(_T("SUBST drive1: /D\n\n"));
_tprintf(_T(" drive1: Specifies a virtual drive to which you want to assign a path.\n"));
_tprintf(_T(" [drive2:]path Specifies a physical drive and path you want to assign to\n"));
_tprintf(_T(" a virtual drive.\n"));
_tprintf(_T(" /D Deletes a substituted (virtual) drive.\n\n"));
_tprintf(_T("Type SUBST with no parameters to display a list of current virtual drives.\n"));
TCHAR szHelp[RC_STRING_MAX_SIZE] = {0};
LoadString(GetModuleHandle(NULL),
IDS_USAGE,
szHelp,
sizeof(szHelp) / sizeof(szHelp[0]));
_tprintf(_T("%s"), szHelp);
}
BOOLEAN IsSubstedDrive(TCHAR *Drive)
@ -103,7 +108,7 @@ BOOLEAN IsSubstedDrive(TCHAR *Drive)
return Result;
}
void DumpSubstedDrives()
void DumpSubstedDrives(void)
{
TCHAR Drive[3] = _T("A:");
LPTSTR lpTargetPath = NULL;
@ -161,17 +166,23 @@ void DumpSubstedDrives()
int DeleteSubst(TCHAR* Drive)
{
BOOL Result;
TCHAR szFmtString[RC_STRING_MAX_SIZE] = {0};
LoadString(GetModuleHandle(NULL),
IDS_INVALID_PARAMETER2,
szFmtString,
sizeof(szFmtString) / sizeof(szFmtString[0]));
if (_tcslen(Drive) > 2)
{
_tprintf(_T("Invalid parameter - %s\n"),
_tprintf(szFmtString,
Drive);
return 1;
}
if (! IsSubstedDrive(Drive))
{
_tprintf(_T("Invalid Parameter - %s\n"),
_tprintf(szFmtString,
Drive);
return 1;
}
@ -190,17 +201,33 @@ int DeleteSubst(TCHAR* Drive)
int AddSubst(TCHAR* Drive, TCHAR *Path)
{
BOOL Result;
TCHAR szFmtString[RC_STRING_MAX_SIZE] = {0};
if (_tcslen(Drive) > 2)
LoadString(GetModuleHandle(NULL),
IDS_INVALID_PARAMETER2,
szFmtString,
sizeof(szFmtString) / sizeof(szFmtString[0]));
if (_tcslen(Drive) != 2)
{
_tprintf(_T("Invalid parameter - %s\n"),
_tprintf(szFmtString,
Drive);
return 1;
}
if (Drive[1] != _T(':'))
{
_tprintf(szFmtString,
Drive);
return 1;
}
if (IsSubstedDrive(Drive))
{
_tprintf(_T("Drive already SUBSTed\n"));
LoadString(GetModuleHandle(NULL),
IDS_DRIVE_ALREAD_SUBSTED,
szFmtString,
sizeof(szFmtString) / sizeof(szFmtString[0]));
_tprintf(szFmtString);
return 1;
}
@ -218,6 +245,7 @@ int AddSubst(TCHAR* Drive, TCHAR *Path)
int _tmain(int argc, TCHAR* argv[])
{
INT i;
TCHAR szFmtString[RC_STRING_MAX_SIZE] = {0};
for (i = 0; i < argc; i++)
{
@ -232,7 +260,11 @@ int _tmain(int argc, TCHAR* argv[])
{
if (argc >= 2)
{
_tprintf(_T("Invalid parameter - %s\n"),
LoadString(GetModuleHandle(NULL),
IDS_INVALID_PARAMETER,
szFmtString,
sizeof(szFmtString) / sizeof(szFmtString[0]));
_tprintf(szFmtString,
argv[1]);
return 1;
}
@ -242,7 +274,11 @@ int _tmain(int argc, TCHAR* argv[])
if (argc > 3)
{
_tprintf(_T("Incorrect number of parameters - %s\n"),
LoadString(GetModuleHandle(NULL),
IDS_INCORRECT_PARAMETER_COUNT,
szFmtString,
sizeof(szFmtString) / sizeof(szFmtString[0]));
_tprintf(szFmtString,
argv[3]);
return 1;
}

View file

@ -1,9 +1,10 @@
<?xml version="1.0"?>
<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
<module name="subst" type="win32cui" installbase="system32" installname="subst.exe" >
<module name="subst" type="win32cui" installbase="system32" installname="subst.exe" unicode="yes">
<include base="ReactOS">include/reactos/wine</include>
<include base="subst">.</include>
<library>kernel32</library>
<library>user32</library>
<file>subst.c</file>
<file>subst.rc</file>
</module>

View file

@ -3,3 +3,5 @@
#define REACTOS_STR_INTERNAL_NAME "subst\0"
#define REACTOS_STR_ORIGINAL_FILENAME "subst.exe\0"
#include <reactos/version.rc>
#include "rsrc.rc"

View file

@ -64,17 +64,20 @@ HalpAssignDrive(IN PUNICODE_STRING PartitionName,
if ((DriveNumber != AUTO_DRIVE) && (DriveNumber < 26))
{
/* Force assignment */
KeAcquireGuardedMutex(&ObpDeviceMapLock);
if ((ObSystemDeviceMap->DriveMap & (1 << DriveNumber)) != 0)
{
DbgPrint("Drive letter already used!\n");
KeReleaseGuardedMutex(&ObpDeviceMapLock);
return FALSE;
}
KeReleaseGuardedMutex(&ObpDeviceMapLock);
}
else
{
/* Automatic assignment */
DriveNumber = AUTO_DRIVE;
KeAcquireGuardedMutex(&ObpDeviceMapLock);
for (i = 2; i < 26; i++)
{
if ((ObSystemDeviceMap->DriveMap & (1 << i)) == 0)
@ -83,6 +86,7 @@ HalpAssignDrive(IN PUNICODE_STRING PartitionName,
break;
}
}
KeReleaseGuardedMutex(&ObpDeviceMapLock);
if (DriveNumber == AUTO_DRIVE)
{
@ -93,10 +97,6 @@ HalpAssignDrive(IN PUNICODE_STRING PartitionName,
DPRINT("DriveNumber %d\n", DriveNumber);
/* Update the System Device Map */
ObSystemDeviceMap->DriveMap |= (1 << DriveNumber);
ObSystemDeviceMap->DriveType[DriveNumber] = DriveType;
/* Build drive name */
swprintf(DriveNameBuffer,
L"\\??\\%C:",

View file

@ -578,6 +578,7 @@ ObGetProcessHandleCount(
//
extern ULONG ObpTraceLevel;
extern KEVENT ObpDefaultObject;
extern KGUARDED_MUTEX ObpDeviceMapLock;
extern POBJECT_TYPE ObpTypeObjectType;
extern POBJECT_TYPE ObSymbolicLinkType;
extern POBJECT_TYPE ObpTypeObjectType;

View file

@ -169,6 +169,9 @@ ObInitSystem(VOID)
/* Initialize the Default Event */
KeInitializeEvent(&ObpDefaultObject, NotificationEvent, TRUE);
/* Initialize the Dos Device Map mutex */
KeInitializeGuardedMutex(&ObpDeviceMapLock);
/* Setup default access for the system process */
PsGetCurrentProcess()->GrantedAccess = PROCESS_ALL_ACCESS;
PsGetCurrentThread()->GrantedAccess = THREAD_ALL_ACCESS;

View file

@ -21,6 +21,7 @@ extern ULONG NtGlobalFlag;
POBJECT_TYPE ObpTypeObjectType = NULL;
KEVENT ObpDefaultObject;
KGUARDED_MUTEX ObpDeviceMapLock;
GENERAL_LOOKASIDE ObpNameBufferLookasideList, ObpCreateInfoLookasideList;
@ -107,7 +108,7 @@ ObpDeallocateObject(IN PVOID Object)
/* Add the SD charge too */
if (Header->Flags & OB_FLAG_SECURITY) PagedPoolCharge += 2048;
}
/* Return the quota */
DPRINT("FIXME: Should return quotas: %lx %lx\n", PagedPoolCharge, NonPagedPoolCharge);
#if 0
@ -115,7 +116,7 @@ ObpDeallocateObject(IN PVOID Object)
PagedPoolCharge,
NonPagedPoolCharge);
#endif
}
}
@ -1261,14 +1262,14 @@ ObpDeleteObjectType(IN PVOID Object)
{
ULONG i;
POBJECT_TYPE ObjectType = (PVOID)Object;
/* Loop our locks */
for (i = 0; i < 4; i++)
{
/* Delete each one */
ExDeleteResourceLite(&ObjectType->ObjectLocks[i]);
}
/* Delete our main mutex */
ExDeleteResourceLite(&ObjectType->Mutex);
}

View file

@ -23,8 +23,160 @@ VOID
NTAPI
ObpDeleteSymbolicLinkName(IN POBJECT_SYMBOLIC_LINK SymbolicLink)
{
/* FIXME: Device maps not supported yet */
POBJECT_HEADER ObjectHeader;
POBJECT_HEADER_NAME_INFO ObjectNameInfo;
/* FIXME: Need to support Device maps */
/* Get header data */
ObjectHeader = OBJECT_TO_OBJECT_HEADER(SymbolicLink);
ObjectNameInfo = ObpReferenceNameInfo(ObjectHeader);
/* Check if we are not actually in a directory with a device map */
if (!(ObjectNameInfo) ||
!(ObjectNameInfo->Directory) /*||
!(ObjectNameInfo->Directory->DeviceMap)*/)
{
ObpDereferenceNameInfo(ObjectNameInfo);
return;
}
/* Check if it's a DOS drive letter, and remove the entry from drive map if needed */
if (SymbolicLink->DosDeviceDriveIndex != 0 &&
ObjectNameInfo->Name.Length == 2 * sizeof(WCHAR) &&
ObjectNameInfo->Name.Buffer[1] == L':' &&
( (ObjectNameInfo->Name.Buffer[0] >= L'A' &&
ObjectNameInfo->Name.Buffer[0] <= L'Z') ||
(ObjectNameInfo->Name.Buffer[0] >= L'a' &&
ObjectNameInfo->Name.Buffer[0] <= L'z') ))
{
/* Remove the drive entry */
KeAcquireGuardedMutex(&ObpDeviceMapLock);
ObSystemDeviceMap->DriveType[SymbolicLink->DosDeviceDriveIndex-1] =
DOSDEVICE_DRIVE_UNKNOWN;
ObSystemDeviceMap->DriveMap &=
~(1 << (SymbolicLink->DosDeviceDriveIndex-1));
KeReleaseGuardedMutex(&ObpDeviceMapLock);
/* Reset the drive index, valid drive index starts from 1 */
SymbolicLink->DosDeviceDriveIndex = 0;
}
ObpDereferenceNameInfo(ObjectNameInfo);
}
NTSTATUS
NTAPI
ObpParseSymbolicLinkToIoDeviceObject(IN POBJECT_DIRECTORY SymbolicLinkDirectory,
IN OUT POBJECT_DIRECTORY *Directory,
IN OUT PUNICODE_STRING TargetPath,
IN OUT POBP_LOOKUP_CONTEXT Context,
OUT PVOID *Object)
{
UNICODE_STRING Name;
BOOLEAN ManualUnlock;
if (! TargetPath || ! Object || ! Context || ! Directory ||
! SymbolicLinkDirectory)
{
return STATUS_INVALID_PARAMETER;
}
/* FIXME: Need to support Device maps */
/* Try walking the target path and open each part of the path */
while (TargetPath->Length)
{
/* Strip '\' if present at the beginning of the target path */
if (TargetPath->Length >= sizeof(OBJ_NAME_PATH_SEPARATOR)&&
TargetPath->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
{
TargetPath->Buffer++;
TargetPath->Length -= sizeof(OBJ_NAME_PATH_SEPARATOR);
}
/* Remember the current component of the target path */
Name = *TargetPath;
/* Move forward to the next component of the target path */
while (TargetPath->Length >= sizeof(OBJ_NAME_PATH_SEPARATOR))
{
if (TargetPath->Buffer[0] != OBJ_NAME_PATH_SEPARATOR)
{
TargetPath->Buffer++;
TargetPath->Length -= sizeof(OBJ_NAME_PATH_SEPARATOR);
}
else
break;
}
Name.Length -= TargetPath->Length;
/* Finished processing the entire path, stop */
if (! Name.Length)
break;
/*
* Make sure a deadlock does not occur as an exclusive lock on a pushlock
* would have already taken one in ObpLookupObjectName() on the parent
* directory where the symlink is being created [ObInsertObject()].
* Prevent recursive locking by faking lock state in the lookup context
* when the current directory is same as the parent directory where
* the symlink is being created. If the lock state is not faked,
* ObpLookupEntryDirectory() will try to get a recursive lock on the
* pushlock and hang. For e.g. this happens when a substed drive is pointed to
* another substed drive.
*/
if (*Directory == SymbolicLinkDirectory && ! Context->DirectoryLocked)
{
/* Fake lock state so that ObpLookupEntryDirectory() doesn't attempt a lock */
ManualUnlock = TRUE;
Context->DirectoryLocked = TRUE;
}
else
ManualUnlock = FALSE;
*Object = ObpLookupEntryDirectory(*Directory,
&Name,
0,
FALSE,
Context);
/* Locking was faked, undo it now */
if (*Directory == SymbolicLinkDirectory && ManualUnlock)
Context->DirectoryLocked = FALSE;
/* Lookup failed, stop */
if (! *Object)
break;
if (OBJECT_TO_OBJECT_HEADER(*Object)->Type == ObDirectoryType)
{
/* Make this current directory, and continue search */
*Directory = (POBJECT_DIRECTORY)*Object;
}
else if (OBJECT_TO_OBJECT_HEADER(*Object)->Type == ObSymbolicLinkType &&
(((POBJECT_SYMBOLIC_LINK)*Object)->DosDeviceDriveIndex == 0))
{
/* Symlink points to another initialized symlink, ask caller to reparse */
*Directory = ObpRootDirectoryObject;
TargetPath = &((POBJECT_SYMBOLIC_LINK)*Object)->LinkTarget;
return STATUS_REPARSE_OBJECT;
}
else
{
/* Neither directory or symlink, stop */
break;
}
}
/* Return a valid object, only if object type is IoDeviceObject */
if (*Object &&
OBJECT_TO_OBJECT_HEADER(*Object)->Type != IoDeviceObjectType)
{
*Object = NULL;
}
return STATUS_SUCCESS;
}
VOID
@ -33,23 +185,124 @@ ObpCreateSymbolicLinkName(IN POBJECT_SYMBOLIC_LINK SymbolicLink)
{
POBJECT_HEADER ObjectHeader;
POBJECT_HEADER_NAME_INFO ObjectNameInfo;
PVOID Object = NULL;
POBJECT_DIRECTORY Directory;
UNICODE_STRING TargetPath;
NTSTATUS Status;
ULONG DriveType = DOSDEVICE_DRIVE_CALCULATE;
ULONG ReparseCnt;
const ULONG MaxReparseAttempts = 20;
OBP_LOOKUP_CONTEXT Context;
/* FIXME: Need to support Device maps */
/* Get header data */
ObjectHeader = OBJECT_TO_OBJECT_HEADER(SymbolicLink);
ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
ObjectNameInfo = ObpReferenceNameInfo(ObjectHeader);
/* Check if we are not actually in a directory with a device map */
if (!(ObjectNameInfo) ||
!(ObjectNameInfo->Directory) ||
!(ObjectNameInfo->Directory->DeviceMap))
!(ObjectNameInfo->Directory) /*||
!(ObjectNameInfo->Directory->DeviceMap)*/)
{
/* There's nothing to do, return */
ObpDereferenceNameInfo(ObjectNameInfo);
return;
}
/* FIXME: We don't support device maps yet */
DPRINT1("Unhandled path!\n");
ASSERT(FALSE);
/* Check if it's a DOS drive letter, and set the drive index accordingly */
if (ObjectNameInfo->Name.Length == 2 * sizeof(WCHAR) &&
ObjectNameInfo->Name.Buffer[1] == L':' &&
( (ObjectNameInfo->Name.Buffer[0] >= L'A' &&
ObjectNameInfo->Name.Buffer[0] <= L'Z') ||
(ObjectNameInfo->Name.Buffer[0] >= L'a' &&
ObjectNameInfo->Name.Buffer[0] <= L'z') ))
{
SymbolicLink->DosDeviceDriveIndex =
RtlUpcaseUnicodeChar(ObjectNameInfo->Name.Buffer[0]) - L'A';
/* The Drive index start from 1 */
SymbolicLink->DosDeviceDriveIndex++;
/* Initialize lookup context */
ObpInitializeLookupContext(&Context);
/* Start the search from the root */
Directory = ObpRootDirectoryObject;
TargetPath = SymbolicLink->LinkTarget;
/*
* Locate the IoDeviceObject if any this symbolic link points to.
* To prevent endless reparsing, setting an upper limit on the
* number of reparses.
*/
Status = STATUS_REPARSE_OBJECT;
ReparseCnt = 0;
while (Status == STATUS_REPARSE_OBJECT &&
ReparseCnt < MaxReparseAttempts)
{
Status =
ObpParseSymbolicLinkToIoDeviceObject(ObjectNameInfo->Directory,
&Directory,
&TargetPath,
&Context,
&Object);
if (Status == STATUS_REPARSE_OBJECT)
ReparseCnt++;
}
/* Cleanup lookup context */
ObpReleaseLookupContext(&Context);
/* Error, or max resparse attemtps exceeded */
if (! NT_SUCCESS(Status) || ReparseCnt >= MaxReparseAttempts)
{
/* Cleanup */
ObpDereferenceNameInfo(ObjectNameInfo);
return;
}
if (Object)
{
/* Calculate the drive type */
switch(((PDEVICE_OBJECT)Object)->DeviceType)
{
case FILE_DEVICE_VIRTUAL_DISK:
DriveType = DOSDEVICE_DRIVE_RAMDISK;
break;
case FILE_DEVICE_CD_ROM:
case FILE_DEVICE_CD_ROM_FILE_SYSTEM:
DriveType = DOSDEVICE_DRIVE_CDROM;
break;
case FILE_DEVICE_DISK:
case FILE_DEVICE_DISK_FILE_SYSTEM:
case FILE_DEVICE_FILE_SYSTEM:
if (((PDEVICE_OBJECT)Object)->Characteristics & FILE_REMOVABLE_MEDIA)
DriveType = DOSDEVICE_DRIVE_REMOVABLE;
else
DriveType = DOSDEVICE_DRIVE_FIXED;
break;
case FILE_DEVICE_NETWORK:
case FILE_DEVICE_NETWORK_FILE_SYSTEM:
DriveType = DOSDEVICE_DRIVE_REMOTE;
break;
default:
DPRINT1("Device Type %ld for %wZ is not known or unhandled\n",
((PDEVICE_OBJECT)Object)->DeviceType,
&SymbolicLink->LinkTarget);
DriveType = DOSDEVICE_DRIVE_UNKNOWN;
}
}
/* Add a new drive entry */
KeAcquireGuardedMutex(&ObpDeviceMapLock);
ObSystemDeviceMap->DriveType[SymbolicLink->DosDeviceDriveIndex-1] =
(UCHAR)DriveType;
ObSystemDeviceMap->DriveMap |=
1 << (SymbolicLink->DosDeviceDriveIndex-1);
KeReleaseGuardedMutex(&ObpDeviceMapLock);
}
/* Cleanup */
ObpDereferenceNameInfo(ObjectNameInfo);
}
/*++

View file

@ -113,24 +113,28 @@ VOID
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);
@ -138,8 +142,8 @@ ObDereferenceDeviceMap(IN PEPROCESS Process)
}
else
{
/* FIXME: Release the DeviceMap Spinlock */
// KeReleasepinLock(DeviceMap->Lock, OldIrql);
/* Release the devicemap lock */
KeReleaseGuardedMutex(&ObpDeviceMapLock);
}
}
}
@ -1144,15 +1148,12 @@ NTAPI
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;
@ -1160,8 +1161,7 @@ ObQueryDeviceMapInformation(IN PEPROCESS Process,
ObSystemDeviceMap->DriveType,
sizeof(ObSystemDeviceMap->DriveType));
/* FIXME: Release the DeviceMap Spinlock */
// KeReleasepinLock(DeviceMap->Lock, OldIrql);
KeReleaseGuardedMutex(&ObpDeviceMapLock);
}
/* EOF */

View file

@ -59,7 +59,7 @@ CSR_API(CsrDefineDosDevice)
DWORD dwFlags;
PWSTR lpBuffer;
DPRINT("CsrDefineDosDevice entered, Flags:%d, DeviceName:%wZ, TargetName:%wZ\n",
DPRINT("CsrDefineDosDevice entered, Flags:%d, DeviceName:%wZ, TargetName:%wZ\n",
Request->Data.DefineDosDeviceRequest.dwFlags,
&Request->Data.DefineDosDeviceRequest.DeviceName,
&Request->Data.DefineDosDeviceRequest.TargetName);
@ -98,6 +98,17 @@ CSR_API(CsrDefineDosDevice)
RequestLinkTarget =
&Request->Data.DefineDosDeviceRequest.TargetName;
/*
* Strip off any trailing '\', if we leave a trailing slash the drive remains non-accessible.
* So working around it for now.
* FIXME: Need to fix this in the object manager ObpLookupObjectName()??, and remove this when the its fixed.
*/
while (RequestLinkTarget->Length >= sizeof(WCHAR) &&
RequestLinkTarget->Buffer[(RequestLinkTarget->Length/sizeof(WCHAR)) - 1] == L'\\')
{
RequestLinkTarget->Length -= sizeof(WCHAR);
}
lpBuffer = (PWSTR) RtlAllocateHeap(Win32CsrApiHeap,
HEAP_ZERO_MEMORY,
RequestDeviceName.MaximumLength + 5 * sizeof(WCHAR));
@ -146,7 +157,7 @@ CSR_API(CsrDefineDosDevice)
&LinkTarget,
&Length);
}
if (! NT_SUCCESS(Status))
{
DPRINT1("NtQuerySymbolicLinkObject(%wZ) failed (Status %lx)\n",
@ -188,7 +199,7 @@ CSR_API(CsrDefineDosDevice)
CONTAINING_RECORD(Entry,
CSRSS_DOS_DEVICE_HISTORY_ENTRY,
Entry);
Matched =
Matched =
! RtlCompareUnicodeString(&RequestDeviceName,
&HistoryEntry->Device,
FALSE);
@ -459,7 +470,7 @@ CSR_API(CsrDefineDosDevice)
&DeviceName, Status);
}
}
_SEH2_FINALLY
_SEH2_FINALLY
{
(void) RtlLeaveCriticalSection(&Win32CsrDefineDosDeviceCritSec);
if (DeviceName.Buffer)
@ -504,13 +515,13 @@ CSR_API(CsrDefineDosDevice)
return Status;
}
void CsrCleanupDefineDosDevice()
void CsrCleanupDefineDosDevice(void)
{
PLIST_ENTRY Entry, ListHead;
PCSRSS_DOS_DEVICE_HISTORY_ENTRY HistoryEntry;
(void) RtlDeleteCriticalSection(&Win32CsrDefineDosDeviceCritSec);
ListHead = &DosDeviceHistory;
Entry = ListHead->Flink;
while (Entry != ListHead)