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-U... ============================================================================== --- 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?r... ============================================================================== --- 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?r... ============================================================================== --- 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.rbu... ============================================================================== --- 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?re... ============================================================================== --- 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/o... ============================================================================== --- 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=51... ============================================================================== --- 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=51... ============================================================================== --- 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=51... ============================================================================== --- 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=51... ============================================================================== --- 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/win3... ============================================================================== --- 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)