Author: fireball
Date: Mon Apr 25 16:08:00 2011
New Revision: 51452
URL:
http://svn.reactos.org/svn/reactos?rev=51452&view=rev
Log:
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.
Added:
trunk/reactos/base/system/subst/lang/ (with props)
trunk/reactos/base/system/subst/lang/en-US.rc (with props)
trunk/reactos/base/system/subst/resource.h (with props)
trunk/reactos/base/system/subst/rsrc.rc (with props)
Modified:
trunk/reactos/base/system/subst/subst.c
trunk/reactos/base/system/subst/subst.rbuild
trunk/reactos/base/system/subst/subst.rc
trunk/reactos/ntoskrnl/fstub/disksup.c
trunk/reactos/ntoskrnl/include/internal/ob.h
trunk/reactos/ntoskrnl/ob/obinit.c
trunk/reactos/ntoskrnl/ob/oblife.c
trunk/reactos/ntoskrnl/ob/oblink.c
trunk/reactos/ntoskrnl/ob/obname.c
trunk/reactos/subsystems/win32/csrss/win32csr/file.c
Propchange: trunk/reactos/base/system/subst/lang/
------------------------------------------------------------------------------
--- bugtraq:logregex (added)
+++ bugtraq:logregex Mon Apr 25 16:08:00 2011
@@ -1,0 +1,2 @@
+([Ii]ssue|[Bb]ug)s? #?(\d+)(,? ?#?(\d+))*(,? ?(and |or )?#?(\d+))?
+(\d+)
Propchange: trunk/reactos/base/system/subst/lang/
------------------------------------------------------------------------------
bugtraq:message = See issue #%BUGID% for more details.
Propchange: trunk/reactos/base/system/subst/lang/
------------------------------------------------------------------------------
bugtraq:url =
http://www.reactos.org/bugzilla/show_bug.cgi?id=%BUGID%
Propchange: trunk/reactos/base/system/subst/lang/
------------------------------------------------------------------------------
tsvn:logminsize = 10
Added: trunk/reactos/base/system/subst/lang/en-US.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/subst/lang/en-…
==============================================================================
--- trunk/reactos/base/system/subst/lang/en-US.rc (added)
+++ trunk/reactos/base/system/subst/lang/en-US.rc [iso-8859-1] Mon Apr 25 16:08:00 2011
@@ -1,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
Propchange: trunk/reactos/base/system/subst/lang/en-US.rc
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/base/system/subst/resource.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/subst/resource…
==============================================================================
--- trunk/reactos/base/system/subst/resource.h (added)
+++ trunk/reactos/base/system/subst/resource.h [iso-8859-1] Mon Apr 25 16:08:00 2011
@@ -1,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 */
Propchange: trunk/reactos/base/system/subst/resource.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/base/system/subst/rsrc.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/subst/rsrc.rc?…
==============================================================================
--- trunk/reactos/base/system/subst/rsrc.rc (added)
+++ trunk/reactos/base/system/subst/rsrc.rc [iso-8859-1] Mon Apr 25 16:08:00 2011
@@ -1,0 +1,6 @@
+#include <windows.h>
+#include "resource.h"
+
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+
+#include "lang/en-US.rc"
Propchange: trunk/reactos/base/system/subst/rsrc.rc
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/base/system/subst/subst.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/subst/subst.c?…
==============================================================================
--- trunk/reactos/base/system/subst/subst.c [iso-8859-1] (original)
+++ trunk/reactos/base/system/subst/subst.c [iso-8859-1] Mon Apr 25 16:08:00 2011
@@ -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 @@
(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 DisplaySubstUsage()
-{
- _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"));
+void DisplaySubstUsage(void)
+{
+ 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 @@
return Result;
}
-void DumpSubstedDrives()
+void DumpSubstedDrives(void)
{
TCHAR Drive[3] = _T("A:");
LPTSTR lpTargetPath = NULL;
@@ -161,17 +166,23 @@
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 AddSubst(TCHAR* Drive, TCHAR *Path)
{
BOOL Result;
-
- if (_tcslen(Drive) > 2)
- {
- _tprintf(_T("Invalid parameter - %s\n"),
+ TCHAR szFmtString[RC_STRING_MAX_SIZE] = {0};
+
+ LoadString(GetModuleHandle(NULL),
+ IDS_INVALID_PARAMETER2,
+ szFmtString,
+ sizeof(szFmtString) / sizeof(szFmtString[0]));
+ if (_tcslen(Drive) != 2)
+ {
+ _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 _tmain(int argc, TCHAR* argv[])
{
INT i;
+ TCHAR szFmtString[RC_STRING_MAX_SIZE] = {0};
for (i = 0; i < argc; i++)
{
@@ -232,7 +260,11 @@
{
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 @@
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;
}
Modified: trunk/reactos/base/system/subst/subst.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/subst/subst.rb…
==============================================================================
--- trunk/reactos/base/system/subst/subst.rbuild [iso-8859-1] (original)
+++ trunk/reactos/base/system/subst/subst.rbuild [iso-8859-1] Mon Apr 25 16:08:00 2011
@@ -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>
Modified: trunk/reactos/base/system/subst/subst.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/subst/subst.rc…
==============================================================================
--- trunk/reactos/base/system/subst/subst.rc [iso-8859-1] (original)
+++ trunk/reactos/base/system/subst/subst.rc [iso-8859-1] Mon Apr 25 16:08:00 2011
@@ -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"
Modified: trunk/reactos/ntoskrnl/fstub/disksup.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/fstub/disksup.c?r…
==============================================================================
--- trunk/reactos/ntoskrnl/fstub/disksup.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/fstub/disksup.c [iso-8859-1] Mon Apr 25 16:08:00 2011
@@ -64,17 +64,20 @@
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 @@
break;
}
}
+ KeReleaseGuardedMutex(&ObpDeviceMapLock);
if (DriveNumber == AUTO_DRIVE)
{
@@ -92,10 +96,6 @@
}
DPRINT("DriveNumber %d\n", DriveNumber);
-
- /* Update the System Device Map */
- ObSystemDeviceMap->DriveMap |= (1 << DriveNumber);
- ObSystemDeviceMap->DriveType[DriveNumber] = DriveType;
/* Build drive name */
swprintf(DriveNameBuffer,
Modified: trunk/reactos/ntoskrnl/include/internal/ob.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ob.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/ob.h [iso-8859-1] Mon Apr 25 16:08:00 2011
@@ -578,6 +578,7 @@
//
extern ULONG ObpTraceLevel;
extern KEVENT ObpDefaultObject;
+extern KGUARDED_MUTEX ObpDeviceMapLock;
extern POBJECT_TYPE ObpTypeObjectType;
extern POBJECT_TYPE ObSymbolicLinkType;
extern POBJECT_TYPE ObpTypeObjectType;
Modified: trunk/reactos/ntoskrnl/ob/obinit.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/obinit.c?rev=5…
==============================================================================
--- trunk/reactos/ntoskrnl/ob/obinit.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ob/obinit.c [iso-8859-1] Mon Apr 25 16:08:00 2011
@@ -168,6 +168,9 @@
/* 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;
Modified: trunk/reactos/ntoskrnl/ob/oblife.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/oblife.c?rev=5…
==============================================================================
--- trunk/reactos/ntoskrnl/ob/oblife.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ob/oblife.c [iso-8859-1] Mon Apr 25 16:08:00 2011
@@ -21,6 +21,7 @@
POBJECT_TYPE ObpTypeObjectType = NULL;
KEVENT ObpDefaultObject;
+KGUARDED_MUTEX ObpDeviceMapLock;
GENERAL_LOOKASIDE ObpNameBufferLookasideList, ObpCreateInfoLookasideList;
@@ -107,7 +108,7 @@
/* 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 @@
PagedPoolCharge,
NonPagedPoolCharge);
#endif
-
+
}
}
@@ -1261,14 +1262,14 @@
{
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);
}
Modified: trunk/reactos/ntoskrnl/ob/oblink.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/oblink.c?rev=5…
==============================================================================
--- trunk/reactos/ntoskrnl/ob/oblink.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ob/oblink.c [iso-8859-1] Mon Apr 25 16:08:00 2011
@@ -23,8 +23,160 @@
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 @@
{
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))
- {
- /* There's nothing to do, return */
+ !(ObjectNameInfo->Directory) /*||
+ !(ObjectNameInfo->Directory->DeviceMap)*/)
+ {
+ 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);
}
/*++
Modified: trunk/reactos/ntoskrnl/ob/obname.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/obname.c?rev=5…
==============================================================================
--- trunk/reactos/ntoskrnl/ob/obname.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ob/obname.c [iso-8859-1] Mon Apr 25 16:08:00 2011
@@ -113,24 +113,28 @@
NTAPI
ObDereferenceDeviceMap(IN PEPROCESS Process)
{
- //KIRQL OldIrql;
- PDEVICE_MAP DeviceMap = Process->DeviceMap;
-
- /* FIXME: We don't use Process Devicemaps yet */
+ PDEVICE_MAP DeviceMap;
+
+ /* 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 @@
}
else
{
- /* FIXME: Release the DeviceMap Spinlock */
- // KeReleasepinLock(DeviceMap->Lock, OldIrql);
+ /* Release the devicemap lock */
+ KeReleaseGuardedMutex(&ObpDeviceMapLock);
}
}
}
@@ -1144,15 +1148,12 @@
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 @@
ObSystemDeviceMap->DriveType,
sizeof(ObSystemDeviceMap->DriveType));
- /* FIXME: Release the DeviceMap Spinlock */
- // KeReleasepinLock(DeviceMap->Lock, OldIrql);
+ KeReleaseGuardedMutex(&ObpDeviceMapLock);
}
/* EOF */
Modified: trunk/reactos/subsystems/win32/csrss/win32csr/file.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win…
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/win32csr/file.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/csrss/win32csr/file.c [iso-8859-1] Mon Apr 25 16:08:00
2011
@@ -59,7 +59,7 @@
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 @@
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 @@
&LinkTarget,
&Length);
}
-
+
if (! NT_SUCCESS(Status))
{
DPRINT1("NtQuerySymbolicLinkObject(%wZ) failed (Status
%lx)\n",
@@ -188,7 +199,7 @@
CONTAINING_RECORD(Entry,
CSRSS_DOS_DEVICE_HISTORY_ENTRY,
Entry);
- Matched =
+ Matched =
! RtlCompareUnicodeString(&RequestDeviceName,
&HistoryEntry->Device,
FALSE);
@@ -459,7 +470,7 @@
&DeviceName, Status);
}
}
- _SEH2_FINALLY
+ _SEH2_FINALLY
{
(void) RtlLeaveCriticalSection(&Win32CsrDefineDosDeviceCritSec);
if (DeviceName.Buffer)
@@ -504,13 +515,13 @@
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)