Author: turner
Date: Thu Jun 8 17:07:05 2006
New Revision: 22283
URL: http://svn.reactos.ru/svn/reactos?rev=22283&view=rev
Log:
If treat a backspace more like a normal char.
Modified:
trunk/reactos/subsystems/win32/csrss/win32csr/conio.c
Modified: trunk/reactos/subsystems/win32/csrss/win32csr/conio.c
URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/csrss/win3…
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/win32csr/conio.c (original)
+++ trunk/reactos/subsystems/win32/csrss/win32csr/conio.c Thu Jun 8 17:07:05 2006
@@ -613,13 +613,14 @@
i -= 2; /* if we already have something to return, just back it up by 2 */
}
else
- { /* otherwise, return STATUS_NOTIFY_CLEANUP to tell client to back up its buffer */
+ {
+ /* otherwise, we will treat the backspace just like any other char and let the client decide what to do */
Console->WaitingChars--;
ConioUnlockConsole(Console);
HeapFree(Win32CsrApiHeap, 0, Input);
- Request->Data.ReadConsoleRequest.NrCharactersRead = 0;
- Request->Status = STATUS_NOTIFY_CLEANUP;
- return STATUS_NOTIFY_CLEANUP;
+ Request->Data.ReadConsoleRequest.NrCharactersRead++;
+ Buffer[i] = Input->InputEvent.Event.KeyEvent.uChar.AsciiChar;
+ return Request->Status;
}
Request->Data.ReadConsoleRequest.nCharsCanBeDeleted--;
Input->Echoed = TRUE; /* mark as echoed so we don't echo it below */
Author: ion
Date: Thu Jun 8 10:17:46 2006
New Revision: 22280
URL: http://svn.reactos.ru/svn/reactos?rev=22280&view=rev
Log:
- ObFindObject should return the actual object being inserted, in the insert case (otherwise it always returns the root-directory instead...)
- Add check for optimized case for objects with no name and no security, but not implemented (ObpIncrementUnnamedHandleCount in Gl00my docs), since I need a better translation then babelfish's.
- Fix ObInsertObject to save the Security Descriptor in the Access State structure. Gl00my mentions this isn't absorbed by SeCreateAccessCheck and I just noticed that too.
- We only need to perform security checks for a new object, in ObInsertObject, not if the object already existed.
- Added proper backout+failure code in ObInsertObject if lookup failed, and also look out for mismatch/exists/collision cases (implemented using simple logic).
Modified:
trunk/reactos/ntoskrnl/ob/obhandle.c
trunk/reactos/ntoskrnl/ob/obname.c
Modified: trunk/reactos/ntoskrnl/ob/obhandle.c
URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/obhandle.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/ob/obhandle.c (original)
+++ trunk/reactos/ntoskrnl/ob/obhandle.c Thu Jun 8 10:17:46 2006
@@ -1175,6 +1175,7 @@
AUX_DATA AuxData;
BOOLEAN IsNamed = FALSE;
OB_OPEN_REASON OpenReason = ObCreateHandle;
+ static int LostOptimizations = 0;
PAGED_CODE();
/* Get the Header and Create Info */
@@ -1182,6 +1183,22 @@
ObjectCreateInfo = Header->ObjectCreateInfo;
ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(Header);
ObjectType = Header->Type;
+
+ /* Check if this is an named object */
+ if ((ObjectNameInfo) && (ObjectNameInfo->Name.Buffer)) IsNamed = TRUE;
+
+ /* Check if the object is unnamed and also doesn't have security */
+ if ((!ObjectType->TypeInfo.SecurityRequired) && !(IsNamed))
+ {
+ /*
+ * FIXME: TODO (Optimized path through ObpIncrement*UnNamed*HandleCount).
+ * Described in chapter 6 of Gl00my, but babelfish translation isn't fully
+ * clear, so waiting on Aleksey's translation. Currently just profiling.
+ * (about ~500 calls per boot - not critical atm).
+ */
+ ++LostOptimizations;
+ DPRINT("Optimized case could've be taken: %d times!\n", LostOptimizations);
+ }
/* Check if we didn't get an access state */
if (!PassedAccessState)
@@ -1200,8 +1217,9 @@
}
}
- /* Check if this is an named object */
- if ((ObjectNameInfo) && (ObjectNameInfo->Name.Buffer)) IsNamed = TRUE;
+ /* Save the security descriptor */
+ PassedAccessState->SecurityDescriptor =
+ ObjectCreateInfo->SecurityDescriptor;
/* Check if the object is named */
if (IsNamed)
@@ -1218,12 +1236,48 @@
ObjectCreateInfo->SecurityQos,
ObjectCreateInfo->ParseContext,
Object);
- if (!NT_SUCCESS(Status)) return Status;
-
- if (FoundObject)
- {
- DPRINT("Getting header: %x\n", FoundObject);
+ /* Check if we found an object that doesn't match the one requested */
+ if ((NT_SUCCESS(Status)) && (FoundObject) && (Object != FoundObject))
+ {
+ /* This means we're opening an object, not creating a new one */
FoundHeader = OBJECT_TO_OBJECT_HEADER(FoundObject);
+ OpenReason = ObOpenHandle;
+
+ /* Make sure the caller said it's OK to do this */
+ if (ObjectCreateInfo->Attributes & OBJ_OPENIF)
+ {
+ /* He did, but did he want this type? */
+ if (ObjectType != FoundHeader->Type)
+ {
+ /* Wrong type, so fail */
+ Status = STATUS_OBJECT_TYPE_MISMATCH;
+ }
+ else
+ {
+ /* Right type, so warn */
+ Status = STATUS_OBJECT_NAME_EXISTS;
+ }
+ }
+ else
+ {
+ /* Caller wanted to create a new object, fail */
+ Status = STATUS_OBJECT_NAME_COLLISION;
+ }
+ }
+
+ /* Check if anything until now failed */
+ if (!NT_SUCCESS(Status))
+ {
+ /* We failed, dereference the object and delete the access state */
+ ObDereferenceObject(Object);
+ if (PassedAccessState == &AccessState)
+ {
+ /* We used a local one; delete it */
+ SeDeleteAccessState(PassedAccessState);
+ }
+
+ /* Return failure code */
+ return Status;
}
}
else
@@ -1252,57 +1306,60 @@
}
}
- /* Check if it's named or forces security */
- if ((IsNamed) || (ObjectType->TypeInfo.SecurityRequired))
- {
- /* Make sure it's inserted into an object directory */
- if ((ObjectNameInfo) && (ObjectNameInfo->Directory))
- {
- /* Get the current descriptor */
- ObGetObjectSecurity(ObjectNameInfo->Directory,
- &DirectorySd,
- &SdAllocated);
- }
-
- /* Now assign it */
- Status = ObAssignSecurity(PassedAccessState,
- DirectorySd,
- Object,
- ObjectType);
-
- /* Check if we captured one */
- if (DirectorySd)
- {
- /* We did, release it */
- DPRINT1("Here\n");
- ObReleaseObjectSecurity(DirectorySd, SdAllocated);
- }
- else if (NT_SUCCESS(Status))
- {
- /* Other we didn't, but we were able to use the current SD */
- SeReleaseSecurityDescriptor(ObjectCreateInfo->SecurityDescriptor,
- ObjectCreateInfo->ProbeMode,
- TRUE);
-
- /* Clear the current one */
- PassedAccessState->SecurityDescriptor =
- ObjectCreateInfo->SecurityDescriptor = NULL;
- }
- }
-
- /* Check if anything until now failed */
- if (!NT_SUCCESS(Status))
- {
- /* We failed, dereference the object and delete the access state */
- ObDereferenceObject(Object);
- if (PassedAccessState == &AccessState)
- {
- /* We used a local one; delete it */
- SeDeleteAccessState(PassedAccessState);
- }
-
- /* Return failure code */
- return Status;
+ /* Now check if this object is being created */
+ if (FoundObject == Object)
+ {
+ /* Check if it's named or forces security */
+ if ((IsNamed) || (ObjectType->TypeInfo.SecurityRequired))
+ {
+ /* Make sure it's inserted into an object directory */
+ if ((ObjectNameInfo) && (ObjectNameInfo->Directory))
+ {
+ /* Get the current descriptor */
+ ObGetObjectSecurity(ObjectNameInfo->Directory,
+ &DirectorySd,
+ &SdAllocated);
+ }
+
+ /* Now assign it */
+ Status = ObAssignSecurity(PassedAccessState,
+ DirectorySd,
+ Object,
+ ObjectType);
+
+ /* Check if we captured one */
+ if (DirectorySd)
+ {
+ /* We did, release it */
+ ObReleaseObjectSecurity(DirectorySd, SdAllocated);
+ }
+ else if (NT_SUCCESS(Status))
+ {
+ /* Other we didn't, but we were able to use the current SD */
+ SeReleaseSecurityDescriptor(ObjectCreateInfo->SecurityDescriptor,
+ ObjectCreateInfo->ProbeMode,
+ TRUE);
+
+ /* Clear the current one */
+ PassedAccessState->SecurityDescriptor =
+ ObjectCreateInfo->SecurityDescriptor = NULL;
+ }
+ }
+
+ /* Check if anything until now failed */
+ if (!NT_SUCCESS(Status))
+ {
+ /* We failed, dereference the object and delete the access state */
+ ObDereferenceObject(Object);
+ if (PassedAccessState == &AccessState)
+ {
+ /* We used a local one; delete it */
+ SeDeleteAccessState(PassedAccessState);
+ }
+
+ /* Return failure code */
+ return Status;
+ }
}
/* HACKHACK: Because of ROS's incorrect startup, this can be called
Modified: trunk/reactos/ntoskrnl/ob/obname.c
URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/obname.c?rev=22…
==============================================================================
--- trunk/reactos/ntoskrnl/ob/obname.c (original)
+++ trunk/reactos/ntoskrnl/ob/obname.c Thu Jun 8 10:17:46 2006
@@ -310,6 +310,7 @@
}
}
RtlFreeUnicodeString(RemainingPath);
+ *ReturnedObject = Insert;
}
else
{
Author: ion
Date: Thu Jun 8 06:56:59 2006
New Revision: 22278
URL: http://svn.reactos.ru/svn/reactos?rev=22278&view=rev
Log:
- I just noticed that ObInsertObject never got updated to deal with the improvements in ObFindObject and ACCESS_STATE usage, so made the following fixes:
* Create the ACCESS_STATE structure much earlier.
* Actually send the access state and parse context to ObFindObject, when called from ObInsertObject (this should fix some hidden regressions, since they finally get an access state with access masks now).
* Remove some deprecated hacks.
* If inserting the handle failed, cleanup the name and remove it from the directory entry.
* Fix a memory leak because we weren't deleting the access state.
Modified:
trunk/reactos/ntoskrnl/ob/obhandle.c
Modified: trunk/reactos/ntoskrnl/ob/obhandle.c
URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/obhandle.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/ob/obhandle.c (original)
+++ trunk/reactos/ntoskrnl/ob/obhandle.c Thu Jun 8 06:56:59 2006
@@ -1152,8 +1152,8 @@
/*
* @implemented
*/
-NTSTATUS
-STDCALL
+NTSTATUS
+NTAPI
ObInsertObject(IN PVOID Object,
IN PACCESS_STATE PassedAccessState OPTIONAL,
IN ACCESS_MASK DesiredAccess,
@@ -1163,6 +1163,7 @@
{
POBJECT_CREATE_INFORMATION ObjectCreateInfo;
POBJECT_HEADER Header;
+ POBJECT_TYPE ObjectType;
PVOID FoundObject = NULL;
POBJECT_HEADER FoundHeader = NULL;
NTSTATUS Status = STATUS_SUCCESS;
@@ -1172,27 +1173,51 @@
POBJECT_HEADER_NAME_INFO ObjectNameInfo;
ACCESS_STATE AccessState;
AUX_DATA AuxData;
+ BOOLEAN IsNamed = FALSE;
+ OB_OPEN_REASON OpenReason = ObCreateHandle;
PAGED_CODE();
/* Get the Header and Create Info */
Header = OBJECT_TO_OBJECT_HEADER(Object);
ObjectCreateInfo = Header->ObjectCreateInfo;
ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(Header);
-
- /* First try to find the Object */
- if (ObjectNameInfo && ObjectNameInfo->Name.Buffer)
- {
+ ObjectType = Header->Type;
+
+ /* Check if we didn't get an access state */
+ if (!PassedAccessState)
+ {
+ /* Use our built-in access state */
+ PassedAccessState = &AccessState;
+ Status = SeCreateAccessState(&AccessState,
+ &AuxData,
+ DesiredAccess,
+ &ObjectType->TypeInfo.GenericMapping);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Fail */
+ ObDereferenceObject(Object);
+ return Status;
+ }
+ }
+
+ /* Check if this is an named object */
+ if ((ObjectNameInfo) && (ObjectNameInfo->Name.Buffer)) IsNamed = TRUE;
+
+ /* Check if the object is named */
+ if (IsNamed)
+ {
+ /* Look it up */
Status = ObFindObject(ObjectCreateInfo->RootDirectory,
- &ObjectNameInfo->Name,
- ObjectCreateInfo->Attributes,
- KernelMode,
- &FoundObject,
- Header->Type,
- &Context,
- NULL,
- ObjectCreateInfo->SecurityQos,
- NULL,
- Object);
+ &ObjectNameInfo->Name,
+ ObjectCreateInfo->Attributes,
+ KernelMode,
+ &FoundObject,
+ ObjectType,
+ &Context,
+ PassedAccessState,
+ ObjectCreateInfo->SecurityQos,
+ ObjectCreateInfo->ParseContext,
+ Object);
if (!NT_SUCCESS(Status)) return Status;
if (FoundObject)
@@ -1211,8 +1236,7 @@
* called ObFindObject which already has this code.
* We basically kill 3-4 hacks and add 2 new ones.
*/
- if ((Header->Type == IoFileObjectType) ||
- (Header->Type->TypeInfo.OpenProcedure != NULL))
+ if (Header->Type == IoFileObjectType)
{
DPRINT("About to call Open Routine\n");
if (Header->Type == IoFileObjectType)
@@ -1225,22 +1249,6 @@
NULL);
DPRINT("Called IopCreateFile: %x\n", Status);
}
- else if (Header->Type->TypeInfo.OpenProcedure)
- {
- DPRINT("Calling %x\n", Header->Type->TypeInfo.OpenProcedure);
- Status = Header->Type->TypeInfo.OpenProcedure(ObCreateHandle,
- NULL,
- &Header->Body,
- 0,
- 0);
- }
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Create Failed\n");
- if (FoundObject) ObDereferenceObject(FoundObject);
- return Status;
- }
}
}
@@ -1287,24 +1295,6 @@
DPRINT("Security Complete\n");
SeReleaseSubjectContext(&SubjectContext);
- /* Check if we didn't get an access state */
- if (!PassedAccessState)
- {
- /* Use our built-in access state */
- PassedAccessState = &AccessState;
- Status = SeCreateAccessState(&AccessState,
- &AuxData,
- DesiredAccess,
- &Header->Type->TypeInfo.GenericMapping);
- if (!NT_SUCCESS(Status))
- {
- /* Fail */
- ObDereferenceObject(Object);
- return Status;
- }
- }
-
- /* Create the Handle */
/* HACKHACK: Because of ROS's incorrect startup, this can be called
* without a valid Process until I finalize the startup patch,
* so don't create a handle if this is the case. We also don't create
@@ -1314,7 +1304,8 @@
DPRINT("Creating handle\n");
if (Handle != NULL)
{
- Status = ObpCreateHandle(ObCreateHandle,
+ /* Create the handle */
+ Status = ObpCreateHandle(OpenReason,
&Header->Body,
NULL,
PassedAccessState,
@@ -1329,6 +1320,24 @@
Header->ObjectCreateInfo = NULL;
ObpFreeAndReleaseCapturedAttributes(ObjectCreateInfo);
+ /* Check if creating the handle failed */
+ if (!NT_SUCCESS(Status))
+ {
+ /* If the object had a name, backout everything */
+ if (IsNamed) ObpDeleteNameCheck(Object);
+ }
+
+ /* Remove the extra keep-alive reference */
+ //ObDereferenceObject(Object); FIXME: Will require massive changes
+
+ /* Check if we created our own access state */
+ if (PassedAccessState == &AccessState)
+ {
+ /* We used a local one; delete it */
+ SeDeleteAccessState(PassedAccessState);
+ }
+
+ /* Return failure code */
DPRINT("Status %x\n", Status);
return Status;
}