Author: fireball
Date: Sat Jun 10 20:37:34 2006
New Revision: 22295
URL:
http://svn.reactos.ru/svn/reactos?rev=22295&view=rev
Log:
- Add create/insert object tests
- Add simple referencing tests (now disabled)
- All tests pass currently on Windows 2003
Modified:
trunk/reactos/drivers/test/kmtest/ntos_ob.c
Modified: trunk/reactos/drivers/test/kmtest/ntos_ob.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/drivers/test/kmtest/ntos_ob…
==============================================================================
--- trunk/reactos/drivers/test/kmtest/ntos_ob.c (original)
+++ trunk/reactos/drivers/test/kmtest/ntos_ob.c Sat Jun 10 20:37:34 2006
@@ -60,6 +60,9 @@
PVOID ObBody[NUM_OBTYPES];
PMY_OBJECT1 ObObject1;
PMY_OBJECT2 ObObject2;
+HANDLE ObHandle1[NUM_OBTYPES];
+HANDLE ObHandle2[NUM_OBTYPES];
+HANDLE DirectoryHandle;
/* PRIVATE FUNCTIONS **********************************************************/
@@ -70,30 +73,34 @@
DbgPrint("DumpProc() called\n");
}
+// prototype doesn't match Win2003! (causes BSOD)
VOID
OpenProc(IN OB_OPEN_REASON OpenReason,
- IN PEPROCESS Process,
+ IN PEPROCESS Process,
+ IN PVOID Object,
+ IN ACCESS_MASK GrantedAccess,
+ IN ULONG HandleCount)
+{
+ DbgPrint("OpenProc() called\n");
+ DbgBreakPoint();
+}
+
+// Tested in Win2k3
+VOID
+CloseProc(IN PEPROCESS Process,
IN PVOID Object,
IN ACCESS_MASK GrantedAccess,
- IN ULONG HandleCount)
-{
- DbgPrint("OpenProc() called\n");
-}
-
-VOID
-CloseProc(IN PEPROCESS Process,
- IN PVOID Object,
- IN ACCESS_MASK GrantedAccess,
- IN ULONG ProcessHandleCount,
- IN ULONG SystemHandleCount)
-{
- DbgPrint("CloseProc() called\n");
-}
-
+ IN ULONG ProcessHandleCount,
+ IN ULONG SystemHandleCount)
+{
+ DPRINT("CloseProc() called for Object=0x%p\n", Object);
+}
+
+// Tested in Win2k3
VOID
DeleteProc(IN PVOID Object)
{
- DbgPrint("DeleteProc()called\n");
+ DPRINT("DeleteProc() called for Object=0x%p\n", Object);
}
NTSTATUS
@@ -115,7 +122,7 @@
VOID
ObtCreateObjectTypes()
{
- UCHAR i;
+ USHORT i;
NTSTATUS Status;
for (i=0; i<NUM_OBTYPES; i++)
@@ -135,11 +142,19 @@
ObTypeInitializer[i].MaintainHandleCount = TRUE;
ObTypeInitializer[i].ValidAccessMask = OBJECT_TYPE_ALL_ACCESS;
+ // Test for invalid parameter
+ // FIXME: Make it more exact, to see which params Win2k3 checks
+ // existence of
+ Status = ObCreateObjectType(&ObTypeName[i], &ObTypeInitializer[i],
+ (PSECURITY_DESCRIPTOR)NULL, &ObTypes[i]);
+ ok(Status == STATUS_INVALID_PARAMETER,
+ "ObCreateObjectType returned 0x%lX", Status);
+
// Object procedures
ObTypeInitializer[i].CloseProcedure = (OB_CLOSE_METHOD)CloseProc;
ObTypeInitializer[i].DeleteProcedure = (OB_DELETE_METHOD)DeleteProc;
ObTypeInitializer[i].DumpProcedure = (OB_DUMP_METHOD)DumpProc;
- ObTypeInitializer[i].OpenProcedure = (OB_OPEN_METHOD)OpenProc;
+ //ObTypeInitializer[i].OpenProcedure = (OB_OPEN_METHOD)OpenProc;
ObTypeInitializer[i].ParseProcedure = (OB_PARSE_METHOD)ParseProc;
Status = ObCreateObjectType(&ObTypeName[i], &ObTypeInitializer[i],
@@ -153,7 +168,6 @@
ObtCreateDirectory()
{
NTSTATUS Status;
- HANDLE DirectoryHandle;
// Directory will have permanent and case insensitive flags
RtlInitUnicodeString(&ObDirectoryName, L"\\ObtDirectory");
@@ -163,17 +177,15 @@
Status = ZwCreateDirectoryObject(&DirectoryHandle, 0,
&ObDirectoryAttributes);
ok(Status == STATUS_SUCCESS,
"Failed to create directory object with status=0x%lX", Status);
-
- Status = ZwClose(DirectoryHandle);
- ok(Status == STATUS_SUCCESS,
- "Failed to close handle with status=0x%lX", Status);
}
VOID
ObtCreateObjects()
{
+ PVOID ObBody1[2];
NTSTATUS Status;
+ // Create two objects
RtlInitUnicodeString(&ObName[0], L"\\ObtDirectory\\MyObject1");
InitializeObjectAttributes(&ObAttributes[0], &ObName[0],
OBJ_CASE_INSENSITIVE, NULL, NULL);
@@ -187,20 +199,175 @@
(PVOID *)&ObBody[0]);
ok(Status == STATUS_SUCCESS,
"Failed to create object with status=0x%lX", Status);
- DPRINT("Created Object 0\n");
Status = ObCreateObject(KernelMode, ObTypes[1], &ObAttributes[1],
KernelMode, NULL, (ULONG)sizeof(MY_OBJECT2), 0L, 0L,
(PVOID *)&ObBody[1]);
ok(Status == STATUS_SUCCESS,
"Failed to create object with status=0x%lX", Status);
- DPRINT("Created Object 1\n");
+
+ // Insert them
+ Status = ObInsertObject(ObBody[0], NULL, STANDARD_RIGHTS_ALL, 0,
+ &ObBody[0], &ObHandle1[0]);
+ ok(Status == STATUS_SUCCESS,
+ "Failed to insert object 0 with status=0x%lX", Status);
+ ok(ObBody[0] != NULL, "Object body = NULL");
+ ok(ObHandle1[0] != NULL, "Handle = NULL");
+
+ Status = ObInsertObject(ObBody[1], NULL, GENERIC_ALL, 0,
+ &ObBody[1], &ObHandle1[1]);
+ ok(Status == STATUS_SUCCESS,
+ "Failed to insert object 1 with status=0x%lX", Status);
+ ok(ObBody[1] != NULL, "Object body = NULL");
+ ok(ObHandle1[1] != NULL, "Handle = NULL");
+
+ // Now create an object of type 0, of the same name and expect it to fail
+ // inserting, but success creation
+ RtlInitUnicodeString(&ObName[0], L"\\ObtDirectory\\MyObject1");
+ InitializeObjectAttributes(&ObAttributes[0], &ObName[0], OBJ_OPENIF,
+ NULL, NULL);
+
+ Status = ObCreateObject(KernelMode, ObTypes[0], &ObAttributes[0], KernelMode,
+ NULL, (ULONG)sizeof(MY_OBJECT1), 0L, 0L, (PVOID *)&ObBody1[0]);
+ ok(Status == STATUS_SUCCESS,
+ "Failed to create object with status=0x%lX", Status);
+
+ Status = ObInsertObject(ObBody1[0], NULL, GENERIC_ALL, 0,
+ &ObBody1[1], &ObHandle2[0]);
+ ok(Status == STATUS_OBJECT_NAME_EXISTS,
+ "Object insertion should have failed, but got 0x%lX", Status);
+ ok(ObBody[0] == ObBody1[1],
+ "Object bodies doesn't match, 0x%p != 0x%p", ObBody[0],
ObBody1[1]);
+ ok(ObHandle2[0] != NULL, "Bad handle returned 0x%lX",
(ULONG)ObHandle2[0]);
+
+ // Close its handle
+ Status = ZwClose(ObHandle2[0]);
+ ok(Status == STATUS_SUCCESS,
+ "Failed to close handle status=0x%lX", Status);
+
+ // Object referenced 2 times:
+ // 1) ObInsertObject
+ // 2) AdditionalReferences
+ ObDereferenceObject(ObBody1[1]);
}
VOID
ObtClose()
{
- // TODO: Close what we have opened and free what we allocated
+ PVOID DirObject;
+ NTSTATUS Status;
+ //PVOID TypeObject;
+ //USHORT i;
+ //UNICODE_STRING ObPathName[NUM_OBTYPES];
+
+ // Close what we have opened and free what we allocated
+ ZwClose(ObHandle1[0]);
+ ZwClose(ObHandle1[1]);
+ ZwClose(ObHandle2[0]);
+ ZwClose(ObHandle2[1]);
+
+ // Now we have to get rid of a directory object
+ // Since it is permanent, we have to firstly make it temporary
+ // and only then kill
+ // (this procedure is described in DDK)
+ Status = ObReferenceObjectByHandle(DirectoryHandle, 0L, NULL,
+ KernelMode, &DirObject, NULL);
+ ok(Status == STATUS_SUCCESS,
+ "Failed to reference object by handle with status=0x%lX", Status);
+
+ // Dereference 2 times - first for just previous referencing
+ // and 2nd time for creation of permanent object itself
+ ObDereferenceObject(DirObject);
+ ObDereferenceObject(DirObject);
+
+ Status = ZwMakeTemporaryObject(DirectoryHandle);
+ ok(Status == STATUS_SUCCESS,
+ "Failed to make temp object with status=0x%lX", Status);
+
+ // Close the handle now and we are done
+ Status = ZwClose(DirectoryHandle);
+ ok(Status == STATUS_SUCCESS,
+ "Failed to close handle with status=0x%lX", Status);
+
+ // Now delete the last piece - object types
+ // FIXME: How to do this correctly?
+ /*
+ for (i=0; i<NUM_OBTYPES; i++)
+ {
+ ObDereferenceObject(ObTypes[i]);
+ }*/
+ /*
+ RtlInitUnicodeString(&ObPathName[0], L"\\ObjectTypes\\MyObjectType1");
+ RtlInitUnicodeString(&ObPathName[1], L"\\ObjectTypes\\MyObjectType2");
+
+ for (i=0; i<NUM_OBTYPES; i++)
+ {
+ Status = ObReferenceObjectByName(&ObPathName[i],
+ OBJ_CASE_INSENSITIVE, NULL, 0L, NULL, KernelMode, NULL,
+ &TypeObject);
+
+ ObDereferenceObject(TypeObject);
+ ObDereferenceObject(TypeObject);
+ DPRINT("Reference Name %S = %p, ObTypes[%d] = %p\n",
+ ObPathName[i], TypeObject, i, ObTypes[i]);
+ }*/
+}
+
+VOID
+ObtReferenceTests()
+{
+ USHORT i;
+ NTSTATUS Status;
+ UNICODE_STRING ObPathName[NUM_OBTYPES];
+
+ // Reference them by handle
+ for (i=0; i<NUM_OBTYPES; i++)
+ {
+ Status = ObReferenceObjectByHandle(ObHandle1[i], 0L, ObTypes[i],
+ KernelMode, &ObBody[i], NULL);
+ ok(Status == STATUS_SUCCESS,
+ "Failed to reference object by handle, status=0x%lX", Status);
+ DPRINT("Ref by handle %lx = %p\n", ObHandle1[i], ObBody[i]);
+ }
+
+ // Reference them by pointer
+ for (i=0; i<NUM_OBTYPES; i++)
+ {
+ Status = ObReferenceObjectByPointer(ObBody[i], 0L, ObTypes[i], KernelMode);
+ ok(Status == STATUS_SUCCESS,
+ "Failed to reference object by pointer, status=0x%lX", Status);
+ }
+
+ // Reference them by name
+ RtlInitUnicodeString(&ObPathName[0], L"\\ObtDirectory\\MyObject1");
+ RtlInitUnicodeString(&ObPathName[1], L"\\ObtDirectory\\MyObject2");
+
+ for (i=0; i<NUM_OBTYPES; i++)
+ {
+ Status = ObReferenceObjectByName(&ObPathName[i],
+ OBJ_CASE_INSENSITIVE, NULL, 0L, ObTypes[i], KernelMode, NULL,
+ &ObBody[0]);
+
+ DPRINT("Ref by name %S = %p\n", ObPathName[i], ObBody[i]);
+ }
+
+ // Dereference now all of them
+
+ // For ObInsertObject, AdditionalReference
+ ObDereferenceObject(ObBody[0]);
+ ObDereferenceObject(ObBody[1]);
+
+ // For ByHandle
+ ObDereferenceObject(ObBody[0]);
+ ObDereferenceObject(ObBody[1]);
+
+ // For ByPointer
+ ObDereferenceObject(ObBody[0]);
+ ObDereferenceObject(ObBody[1]);
+
+ // For ByName
+ ObDereferenceObject(ObBody[0]);
+ ObDereferenceObject(ObBody[1]);
}
/* PUBLIC FUNCTIONS ***********************************************************/
@@ -223,7 +390,13 @@
ObtCreateObjects();
DPRINT("ObtCreateObjects() done\n");
+ // Reference them in a variety of ways
+ // FIXME: Disabled due to ParseProcedure call
+ //ObtReferenceTests();
+
// Clean up
+ // FIXME: Disabled to see results of creating objects in usermode
+ // and also due to problems with object types removal
ObtClose();
DPRINT("Cleanup done\n");