mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 12:23:31 +00:00
- Add create/insert object tests
- Add simple referencing tests (now disabled) - All tests pass currently on Windows 2003 svn path=/trunk/; revision=22295
This commit is contained in:
@@ -60,6 +60,9 @@ OBJECT_ATTRIBUTES ObAttributes[NUM_OBTYPES];
|
||||
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 @@ DumpProc(IN PVOID Object,
|
||||
DbgPrint("DumpProc() called\n");
|
||||
}
|
||||
|
||||
// prototype doesn't match Win2003! (causes BSOD)
|
||||
VOID
|
||||
OpenProc(IN OB_OPEN_REASON OpenReason,
|
||||
IN PEPROCESS Process,
|
||||
IN PVOID Object,
|
||||
IN ACCESS_MASK GrantedAccess,
|
||||
IN ULONG HandleCount)
|
||||
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 ProcessHandleCount,
|
||||
IN ULONG SystemHandleCount)
|
||||
IN PVOID Object,
|
||||
IN ACCESS_MASK GrantedAccess,
|
||||
IN ULONG ProcessHandleCount,
|
||||
IN ULONG SystemHandleCount)
|
||||
{
|
||||
DbgPrint("CloseProc() called\n");
|
||||
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 @@ ParseProc(IN PVOID ParseObject,
|
||||
VOID
|
||||
ObtCreateObjectTypes()
|
||||
{
|
||||
UCHAR i;
|
||||
USHORT i;
|
||||
NTSTATUS Status;
|
||||
|
||||
for (i=0; i<NUM_OBTYPES; i++)
|
||||
@@ -135,11 +142,19 @@ ObtCreateObjectTypes()
|
||||
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 @@ VOID
|
||||
ObtCreateDirectory()
|
||||
{
|
||||
NTSTATUS Status;
|
||||
HANDLE DirectoryHandle;
|
||||
|
||||
// Directory will have permanent and case insensitive flags
|
||||
RtlInitUnicodeString(&ObDirectoryName, L"\\ObtDirectory");
|
||||
@@ -163,17 +177,15 @@ ObtCreateDirectory()
|
||||
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 @@ ObtCreateObjects()
|
||||
(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 @@ NtoskrnlObTest()
|
||||
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");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user