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");