Example #1
0
NTSTATUS
ParseAProc(
    IN PVOID ParseObject,
    IN ULONG DesiredAccess,
    IN KPROCESSOR_MODE AccessMode,
    IN ULONG Attributes,
    IN OUT PSTRING CompleteName,
    IN OUT PSTRING RemainingName,
    IN OUT PVOID Context OPTIONAL,
    OUT PVOID *Object
    )
{
    DbgPrint( "ParseAProc: %lx\n", ParseObject );
    DbgPrint( "    CompleteName:  %.*s\n", CompleteName->Length,
                                         CompleteName->Buffer );
    DbgPrint( "    RemainingName: %.*s\n", RemainingName->Length,
                                         RemainingName->Buffer );
    ObReferenceObjectByPointer(
        ParseObject,
        DesiredAccess,
        ObjectTypeA,
        AccessMode
        );

    *Object = ParseObject;
    return( STATUS_SUCCESS );
}
Example #2
0
PDEVICE_OBJECT
Disk_GetDeviceByName(PWCHAR DriveName)
{
	PDEVICE_OBJECT pDevice = NULL;
	PFILE_OBJECT pFileObject;
	NTSTATUS ntStatus;

	UNICODE_STRING ObjectName;

	RtlInitUnicodeString(&ObjectName, DriveName);
	
	if (ObjectName.Length == sizeof(WCHAR))
		return Disk_GetDeviceObjectByLetter(*DriveName);
	else
	{
		HANDLE DeviceHandle;
		OBJECT_ATTRIBUTES ObjAttr;
		IO_STATUS_BLOCK ioStatus;

		InitializeObjectAttributes(&ObjAttr, &ObjectName, OBJ_CASE_INSENSITIVE, NULL, NULL);

		ntStatus = ZwCreateFile(&DeviceHandle, SYNCHRONIZE | FILE_ANY_ACCESS, &ObjAttr, &ioStatus, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
		if(NT_SUCCESS(ntStatus))
		{
			ntStatus = ObReferenceObjectByHandle(DeviceHandle, STANDARD_RIGHTS_REQUIRED, NULL, KernelMode, (VOID**)&pFileObject, NULL);
			if(NT_SUCCESS(ntStatus))
			{
				if (pFileObject->DeviceObject != NULL)
				{
					pDevice = pFileObject->DeviceObject;
					
					if (pDevice->Vpb != NULL)
					{
						if (pDevice->Vpb->RealDevice != NULL)
							pDevice = pDevice->Vpb->RealDevice;
					}
					
					if (pDevice->Flags & DO_DEVICE_INITIALIZING)
						pDevice = NULL;
					else
					{
						if(pDevice->DeviceType == FILE_DEVICE_DISK || pDevice->DeviceType == FILE_DEVICE_CD_ROM || pDevice->DeviceType == FILE_DEVICE_DVD)
						{
							if (!NT_SUCCESS(ObReferenceObjectByPointer(pDevice, STANDARD_RIGHTS_REQUIRED, *IoDeviceObjectType, KernelMode)))
								pDevice = NULL;
						}
						else
							pDevice = NULL;
					}
				}
				
				ObDereferenceObject(pFileObject);
			}
			
			ZwClose(DeviceHandle);
		}
	}

	return pDevice;
}
Example #3
0
VOID FindDiskDev(PDRIVER_OBJECT pDrv, PVOID pUserValue)
{
PDEVICE_OBJECT		pDev,tmp;
NTSTATUS					refStatus;
PDISK_DEV_LIST		NewDevEntry;
ULONG							i;
BOOLEAN						Disk;
	pDev=pDrv->DeviceObject;
	Disk=FALSE;
	while(pDev) {
		refStatus=ObReferenceObjectByPointer(pDev,STANDARD_RIGHTS_REQUIRED,NULL,KernelMode);
		if(!NT_SUCCESS(refStatus)){
			DbPrint(DC_DISK,DL_ERROR, ("FindDiskDev ObReferenceObjectByPointer 0x%x failed, status 0x%x\n",pDev, refStatus));
		}
		if(pDev->DeviceType==FILE_DEVICE_DISK) {//!! probably FILE_DEVICE_CD_ROM && FILE_DEVICE_DVD & somthing else
			Disk=TRUE;
			DbPrint(DC_DISK,DL_INFO, ("Drv=0x%x Device=0x%x Type=%s \n",pDrv, pDev, DbgGetDevTypeName(pDev->DeviceType)));
		}
		tmp=pDev;
		pDev=pDev->NextDevice;
		if(NT_SUCCESS(refStatus)){
			ObDereferenceObject(tmp);
		}
	}
	if(Disk) {
		NewDevEntry=ExAllocatePoolWithTag(NonPagedPool,sizeof(DISK_DEV_LIST),'dSeB');
		if(NewDevEntry) {
			NewDevEntry->DiskDevDispArray=ExAllocatePoolWithTag(NonPagedPool,sizeof(PDRIVER_DISPATCH)*(IRP_MJ_MAXIMUM_FUNCTION+1),'dSeB');
			if(NewDevEntry->DiskDevDispArray) {
				memcpy(NewDevEntry->DiskDevDispArray,pDrv->MajorFunction,sizeof(PDRIVER_DISPATCH)*(IRP_MJ_MAXIMUM_FUNCTION+1));
				NewDevEntry->Drv=pDrv;
				for(i=0;i<=IRP_MJ_MAXIMUM_FUNCTION;i++) {
					if(pDrv->MajorFunction[i]) {
						pDrv->MajorFunction[i]=DiskDevDispatch;
					} else {
						DbPrint(DC_DISK,DL_WARNING, ("Disk Drv 0x%x Empty func %s\n",pDrv,NTMajorFunctionName[i]));
					}
				}
				DbPrint(DC_DISK,DL_INFO, ("Disk Drv 0x%x hooked\n",pDrv));
				ExAcquireFastMutex(&DiskDevListMutex);
				NewDevEntry->Next=DiskDevList;
				DiskDevList=NewDevEntry;
				ExReleaseFastMutex(&DiskDevListMutex);
			} else {
				ExFreePool(NewDevEntry);
				DbPrint(DC_DISK,DL_ERROR, ("No memory for IRP_MJ_ Table for disk device\n"));
			}
		} else {
			DbPrint(DC_DISK,DL_ERROR, ("No memory for NewDiskDevEntry\n"));
		}
	}
}
Example #4
0
// -----------------------------------------------------------------------------------------
PDEVICE_OBJECT
Disk_GetDeviceObjectByLetter(WCHAR DriveLetter)
{
	PDEVICE_OBJECT		pDevice = NULL;
	NTSTATUS			ntStatus;
	
	HANDLE				hDir;
	UNICODE_STRING		us;
	OBJECT_ATTRIBUTES	ObjAttr;
	
	HANDLE				hLink;
	WCHAR				targetNameBuffer[260];
	UNICODE_STRING      targetNameUnicodeString;
	
	PFILE_OBJECT		fileObject;
	IO_STATUS_BLOCK		ioStatus;

	WCHAR				cDrive[3] = L"A:";

	RtlInitUnicodeString(&us, (PWCHAR)L"\\??");
	InitializeObjectAttributes(&ObjAttr, &us, OBJ_CASE_INSENSITIVE, NULL, NULL);
	ntStatus = ZwOpenDirectoryObject(&hDir, DIRECTORY_QUERY,&ObjAttr);
	if(!NT_SUCCESS(ntStatus))
	{
		DbPrint(DC_LLDISKIO, DL_ERROR, ("ZwOpenDirectoryObject %S failed, status %x\n",us.Buffer, ntStatus));
		return NULL;
	}

	cDrive[0] = DriveLetter;
	RtlInitUnicodeString(&us,cDrive);

	InitializeObjectAttributes(&ObjAttr, &us, OBJ_CASE_INSENSITIVE, hDir, NULL);
	ntStatus = ZwOpenSymbolicLinkObject(&hLink, SYMBOLIC_LINK_QUERY, &ObjAttr);
	if(NT_SUCCESS(ntStatus))
	{
		RtlZeroMemory(targetNameBuffer, sizeof(targetNameBuffer));
		targetNameUnicodeString.Buffer = targetNameBuffer;
		targetNameUnicodeString.MaximumLength = sizeof(targetNameBuffer);
		ntStatus = ZwQuerySymbolicLinkObject(hLink, &targetNameUnicodeString, NULL);
		if(NT_SUCCESS(ntStatus))
		{
			if(!wcsncmp(targetNameBuffer,L"\\Device",7))
			{
				HANDLE hFile;
				ntStatus = ZwCreateFile(&hFile, SYNCHRONIZE | FILE_ANY_ACCESS, &ObjAttr, &ioStatus, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
				if(NT_SUCCESS(ntStatus))
				{
					//!FILE_DEVICE_MASS_STORAGE or FILE_DEVICE_TAPE
					ntStatus = ObReferenceObjectByHandle(hFile, FILE_READ_DATA, NULL, KernelMode, (PVOID*) &fileObject, NULL);
					if(NT_SUCCESS(ntStatus))
					{
						pDevice = fileObject->DeviceObject;
						if (pDevice->Vpb != NULL)
						{
							if (pDevice->Vpb->RealDevice != NULL)
								pDevice = pDevice->Vpb->RealDevice;
						}
						if(pDevice->DeviceType == FILE_DEVICE_DISK || pDevice->DeviceType == FILE_DEVICE_CD_ROM || pDevice->DeviceType == FILE_DEVICE_DVD)
						{
							if(!NT_SUCCESS(ObReferenceObjectByPointer(pDevice, STANDARD_RIGHTS_REQUIRED, *IoDeviceObjectType, KernelMode)))	//dereference will be in caller proc
								pDevice = NULL;
						}
						else
							pDevice = NULL;

						ObDereferenceObject(fileObject);
					}

					ZwClose(hFile);
				}
			}
		}
		ZwClose(hLink);
	}
					
	ZwClose(hDir);

	return pDevice;
}
Example #5
0
// -----------------------------------------------------------------------------------------
VOID Disk_FindDiskDev(PDRIVER_OBJECT pDrv, PVOID pUserValue)
{
	PDEVICE_OBJECT		pDev, tmp;
	NTSTATUS			refStatus;
	ULONG				i;
	BOOLEAN				Disk;
	PWCHAR				pDeviceName;

	PDISKQUERYNAMES		pQueryName = (PDISKQUERYNAMES) pUserValue;
	ULONG				Key;

	BOOLEAN bOverBuf;
	
	pDev = pDrv->DeviceObject;
	Disk = FALSE;
	while(pDev && NT_SUCCESS(pQueryName->m_RetStatus))
	{
		refStatus = ObReferenceObjectByPointer(pDev,STANDARD_RIGHTS_REQUIRED,NULL,KernelMode);
		if(!NT_SUCCESS(refStatus))
		{
			DbPrint(DC_LLDISKIO, DL_ERROR, ("FindDiskDev ObReferenceObjectByPointer 0x%x failed, status 0x%x\n",
				pDev, refStatus));
		}
		
		if(pDev->DeviceType == FILE_DEVICE_DISK || pDev->DeviceType == FILE_DEVICE_CD_ROM || 
			pDev->DeviceType == FILE_DEVICE_DVD)
		{
			if (pDev->Flags & DO_DEVICE_HAS_NAME)
			{
				Disk = TRUE;
				if ((pDev->AttachedDevice != NULL) && (pDev->AttachedDevice->Flags & DO_DEVICE_HAS_NAME))
				{
					// skip this device because attached has name
				}
				else
				{
					pDeviceName = ExAllocatePoolWithTag(NonPagedPool, MAXPATHLEN * sizeof(WCHAR), 'WboS');
					if (pDeviceName != NULL)
					{
						if (GetDeviceName(pDev, pDeviceName, MAXPATHLEN * sizeof(WCHAR)) != NULL)
						{
							ULONG NameLen;
							NameLen = wcslen(pDeviceName);
							if (NameLen == 0) 
							{
								//DbPrint(DC_LLDISKIO, DL_WARNING, ("Drv=0x%x Device=0x%x Type=%s has DO_HASNNAME flag but GetDeviceName return name with len == 0\n",pDrv,pDev,
								//(pDev->DeviceType<sizeof(FileDevTypeName)/sizeof(CHAR*))?FileDevTypeName[pDev->DeviceType]:NullStr));
							}
							else
							{
								//DbPrint(DC_LLDISKIO, DL_NOTIFY, ("Drv=0x%x Device=0x%x Type=%s name %S\n",pDrv,pDev,	
								//(pDev->DeviceType < sizeof(FileDevTypeName) / sizeof(CHAR*)) ? FileDevTypeName[pDev->DeviceType] : NullStr, pDeviceName));
								NameLen++;
								NameLen *= sizeof(WCHAR);
								
								Key = CalcCacheID(NameLen, (BYTE*) pDeviceName, 0);
								bOverBuf = FALSE;
								if (NameCacheGet(pQueryName->m_pNameCache, Key, NULL, 0, &bOverBuf))
								{
									// name already exist
									DbPrint(DC_SYS, DL_WARNING, ("NameCacheTruncating - buffer too small in Disk_FindDiskDev\n"));
									DbgBreakPoint();
								}
								else
								{
									if ((pQueryName->m_Bufferlength + sizeof(WCHAR)) < (pQueryName->m_CurrentDataSize + NameLen))
									{
										DbPrint(DC_LLDISKIO, DL_NOTIFY, ("Disk_FindDiskDev - to small buffer\n"));
										pQueryName->m_RetStatus = STATUS_BUFFER_TOO_SMALL;
									}
									else
									{
										NameCacheStore(pQueryName->m_pNameCache, Key, pDeviceName, NameLen, 
											FALSE, 'DboS');
										
										if (pQueryName->m_pBuffer != NULL)
										{
											RtlCopyMemory(pQueryName->m_pBuffer + pQueryName->m_CurrentDataSize, 
												pDeviceName, NameLen);
										}

										pQueryName->m_CurrentDataSize += NameLen;
									}
								}
							}
						}
						
						ExFreePool(pDeviceName);
					}
				}
			}
		}
		
		tmp = pDev;
		pDev = pDev->NextDevice;

		if(NT_SUCCESS(refStatus))
			ObDereferenceObject(tmp);
	}
}
Example #6
0
BOOLEAN
obtest( void )
{
    ULONG i;
    HANDLE Handles[ 2 ];
    NTSTATUS Status;
    OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    RtlInitString( &ObjectTypeAName, "ObjectTypeA" );
    RtlInitString( &ObjectTypeBName, "ObjectTypeB" );

    RtlZeroMemory( &ObjectTypeInitializer, sizeof( ObjectTypeInitializer ) );
    ObjectTypeInitializer.Length = sizeof( ObjectTypeInitializer );
    ObjectTypeInitializer.ValidAccessMask = -1;

    ObjectTypeInitializer.PoolType = NonPagedPool;
    ObjectTypeInitializer.MaintainHandleCount = TRUE;
    ObjectTypeInitializer.DumpProcedure = DumpAProc;
    ObjectTypeInitializer.OpenProcedure = OpenAProc;
    ObjectTypeInitializer.CloseProcedure = CloseAProc;
    ObjectTypeInitializer.DeleteProcedure = DeleteAProc;
    ObjectTypeInitializer.ParseProcedure = ParseAProc;
    ObCreateObjectType(
        &ObjectTypeAName,
        &ObjectTypeInitializer,
        (PSECURITY_DESCRIPTOR)NULL,
        &ObjectTypeA
        );

    ObjectTypeInitializer.PoolType = NonPagedPool;
    ObjectTypeInitializer.MaintainHandleCount = FALSE;
    ObjectTypeInitializer.GenericMapping = MyGenericMapping;
    ObjectTypeInitializer.DumpProcedure = DumpBProc;
    ObjectTypeInitializer.OpenProcedure = NULL;
    ObjectTypeInitializer.CloseProcedure = NULL;
    ObjectTypeInitializer.DeleteProcedure = DeleteBProc;
    ObjectTypeInitializer.ParseProcedure = NULL;
    ObCreateObjectType(
        &ObjectTypeBName,
        &ObjectTypeInitializer,
        (PSECURITY_DESCRIPTOR)NULL,
        &ObjectTypeB
        );

    ObpDumpTypes( NULL );

    RtlInitString( &DirectoryName, "\\MyObjects" );
    InitializeObjectAttributes( &DirectoryObjA,
                                &DirectoryName,
                                OBJ_PERMANENT |
                                OBJ_CASE_INSENSITIVE,
                                NULL,
                                NULL
                              );
    NtCreateDirectoryObject( &DirectoryHandle,
                             0,
                             &DirectoryObjA
                           );
    NtClose( DirectoryHandle );

    RtlInitString( &ObjectAName, "\\myobjects\\ObjectA" );
    InitializeObjectAttributes( &ObjectAObjA,
                                &ObjectAName,
                                OBJ_CASE_INSENSITIVE,
                                NULL,
                                NULL
                              );

    RtlInitString( &ObjectBName, "\\myobjects\\ObjectB" );
    InitializeObjectAttributes( &ObjectBObjA,
                                &ObjectBName,
                                OBJ_CASE_INSENSITIVE,
                                NULL,
                                NULL
                              );

    Status = ObCreateObject(
        KernelMode,
        ObjectTypeA,
        &ObjectAObjA,
        KernelMode,
        NULL,
        (ULONG)sizeof( OBJECTTYPEA ),
        0L,
        0L,
        (PVOID *)&ObjectBodyA
        );

    ObjectA = (POBJECTTYPEA)ObjectBodyA;
    ObjectA->TypeALength = sizeof( *ObjectA );
    for (i=0; i<4; i++) {
        ObjectA->Stuff[i] = i+1;
        }
    KeInitializeEvent( &ObjectA->Event, NotificationEvent, TRUE );

    Status = ObCreateObject(
        KernelMode,
        ObjectTypeB,
        &ObjectBObjA,
        KernelMode,
        NULL,
        (ULONG)sizeof( OBJECTTYPEB ),
        0L,
        0L,
        (PVOID *)&ObjectBodyB
        );

    ObjectB = (POBJECTTYPEB)ObjectBodyB;
    ObjectB->TypeBLength = sizeof( *ObjectB );
    for (i=0; i<16; i++) {
        ObjectB->Stuff[i] = i+1;
        }
    KeInitializeSemaphore ( &ObjectB->Semaphore, 2L, 2L );

    Status = ObInsertObject(
        ObjectBodyA,
        SYNCHRONIZE | 0x3,
        NULL,
        1,
        &ObjectBodyA,
        &ObjectHandleA1
        );

    DbgPrint( "Status: %lx  ObjectBodyA: %lx  ObjectHandleA1: %lx\n",
             Status, ObjectBodyA, ObjectHandleA1
           );

    Status = ObInsertObject(
        ObjectBodyB,
        SYNCHRONIZE | 0x1,
        NULL,
        1,
        &ObjectBodyB,
        &ObjectHandleB1
        );

    DbgPrint( "Status: %lx  ObjectBodyB: %lx  ObjectHandleB1: %lx\n",
             Status, ObjectBodyB, ObjectHandleB1
           );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    RtlInitString( &ObjectAName, "\\MyObjects\\ObjectA" );
    InitializeObjectAttributes( &ObjectAObjA,
                                &ObjectAName,
                                OBJ_OPENIF,
                                NULL,
                                NULL
                              );

    Status = ObCreateObject(
        KernelMode,
        ObjectTypeA,
        &ObjectAObjA,
        KernelMode,
        NULL,
        (ULONG)sizeof( OBJECTTYPEA ),
        0L,
        0L,
        (PVOID *)&ObjectBodyA1
        );


    Status = ObInsertObject(
        ObjectBodyA1,
        SYNCHRONIZE | 0x3,
        NULL,
        1,
        &ObjectBodyA2,
        &ObjectHandleA2
        );

    DbgPrint( "Status: %lx  ObjectBodyA1: %lx  ObjectBodyA2: %lx  ObjectHandleA2: %lx\n",
             Status, ObjectBodyA1, ObjectBodyA2, ObjectHandleA2
           );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );
    NtClose( ObjectHandleA2 );
    ObDereferenceObject( ObjectBodyA2 );    // ObInsertObject,ObjectPointerBias

    NtWaitForSingleObject( ObjectHandleB1, TRUE, NULL );
    Handles[ 0 ] = ObjectHandleA1;
    Handles[ 1 ] = ObjectHandleB1;
    NtWaitForMultipleObjects( 2, Handles, WaitAny, TRUE, NULL );

    ObReferenceObjectByHandle(
        ObjectHandleA1,
        0L,
        ObjectTypeA,
        KernelMode,
        &ObjectBodyA,
        NULL
        );

    ObReferenceObjectByHandle(
        ObjectHandleB1,
        0L,
        ObjectTypeB,
        KernelMode,
        &ObjectBodyB,
        NULL
        );
    DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleA1, ObjectBodyA );

    DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleB1, ObjectBodyB );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    ObReferenceObjectByPointer(
        ObjectBodyA,
        0L,
        ObjectTypeA,
        KernelMode
        );

    ObReferenceObjectByPointer(
        ObjectBodyB,
        0L,
        ObjectTypeB,
        KernelMode
        );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    RtlInitString( &ObjectAPathName, "\\MyObjects\\ObjectA" );
    RtlInitString( &ObjectBPathName, "\\MyObjects\\ObjectB" );
    ObReferenceObjectByName(
        &ObjectAPathName,
        OBJ_CASE_INSENSITIVE,
        0L,
        ObjectTypeA,
        KernelMode,
        NULL,
        &ObjectBodyA
        );

    ObReferenceObjectByName(
        &ObjectBPathName,
        OBJ_CASE_INSENSITIVE,
        0L,
        ObjectTypeB,
        KernelMode,
        NULL,
        &ObjectBodyB
        );

    DbgPrint( "Reference Name %s = %lx\n", ObjectAPathName.Buffer,
            ObjectBodyA );

    DbgPrint( "Reference Name %s = %lx\n", ObjectBPathName.Buffer,
            ObjectBodyB );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    ObDereferenceObject( ObjectBodyA );     // ObInsertObject,ObjectPointerBias
    ObDereferenceObject( ObjectBodyB );

    ObDereferenceObject( ObjectBodyA );     // ObReferenceObjectByHandle
    ObDereferenceObject( ObjectBodyB );

    ObDereferenceObject( ObjectBodyA );     // ObReferenceObjectByPointer
    ObDereferenceObject( ObjectBodyB );

    ObDereferenceObject( ObjectBodyA );     // ObReferenceObjectByName
    ObDereferenceObject( ObjectBodyB );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    InitializeObjectAttributes( &ObjectAObjA,
                                &ObjectAPathName,
                                OBJ_CASE_INSENSITIVE,
                                NULL,
                                NULL
                              );
    ObOpenObjectByName(
        &ObjectAObjA,
        0L,
        NULL,
        ObjectTypeA,
        KernelMode,
        NULL,
        &ObjectHandleA2
        );

    InitializeObjectAttributes( &ObjectBObjA,
                                &ObjectBPathName,
                                OBJ_CASE_INSENSITIVE,
                                NULL,
                                NULL
                              );
    ObOpenObjectByName(
        &ObjectBObjA,
        0L,
        NULL,
        ObjectTypeB,
        KernelMode,
        NULL,
        &ObjectHandleB2
        );

    DbgPrint( "Open Object Name %s = %lx\n", ObjectAPathName.Buffer,
            ObjectHandleA2 );

    DbgPrint( "Open Object Name %s = %lx\n", ObjectBPathName.Buffer,
            ObjectHandleB2 );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    NtClose( ObjectHandleA1 );
    NtClose( ObjectHandleB1 );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    ObReferenceObjectByHandle(
        ObjectHandleA2,
        0L,
        ObjectTypeA,
        KernelMode,
        &ObjectBodyA,
        NULL
        );

    ObReferenceObjectByHandle(
        ObjectHandleB2,
        0L,
        ObjectTypeB,
        KernelMode,
        &ObjectBodyB,
        NULL
        );
    DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleA2, ObjectBodyA );

    DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleB2, ObjectBodyB );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    ObOpenObjectByPointer(
        ObjectBodyA,
        OBJ_CASE_INSENSITIVE,
        0L,
        NULL,
        ObjectTypeA,
        KernelMode,
        &ObjectHandleA1
        );

    ObOpenObjectByPointer(
        ObjectBodyB,
        OBJ_CASE_INSENSITIVE,
        0L,
        NULL,
        ObjectTypeB,
        KernelMode,
        &ObjectHandleB1
        );

    DbgPrint( "Open Object Pointer %lx = %lx\n", ObjectBodyA,
            ObjectHandleA1 );

    DbgPrint( "Open Object Pointer %lx = %lx\n", ObjectBodyB,
            ObjectHandleB1 );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    ObReferenceObjectByHandle(
        ObjectHandleA1,
        0L,
        ObjectTypeA,
        KernelMode,
        &ObjectBodyA,
        NULL
        );

    ObReferenceObjectByHandle(
        ObjectHandleB1,
        0L,
        ObjectTypeB,
        KernelMode,
        &ObjectBodyB,
        NULL
        );
    DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleA1, ObjectBodyA );

    DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleB1, ObjectBodyB );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    ObDereferenceObject( ObjectBodyA );     // ObReferenceObjectByHandle
    ObDereferenceObject( ObjectBodyB );

    ObDereferenceObject( ObjectBodyA );     // ObReferenceObjectByHandle
    ObDereferenceObject( ObjectBodyB );

    NtClose( ObjectHandleA1 );
    NtClose( ObjectHandleB1 );

    NtClose( ObjectHandleA2 );
    NtClose( ObjectHandleB2 );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    TestFunction = NULL;

    return( TRUE );
}
Example #7
0
PPROVIDER_DEF
ReplLookupProvider(
    ULONG ProviderId
) {
    NTSTATUS Status;
    PPROVIDER_DEF pProv;
    HANDLE   hProvider = NULL;
    OBJECT_ATTRIBUTES objectAttributes;
    IO_STATUS_BLOCK ioStatusBlock;
    OBJECT_HANDLE_INFORMATION handleInformation;
    PFILE_OBJECT    fileObject;
    int i;

    DfsDbgTrace(+1, Dbg, "ReplLookupProvider Entered: id = %x\n", ProviderId);

    for (pProv = DfsData.pProvider, i=0; i<DfsData.cProvider; pProv++, i++) {

        if (ProviderId == pProv->eProviderId) {

            if (pProv->FileObject == NULL) {

                DfsDbgTrace(0, Dbg, "Provider device not been referenced yet\n", 0);

                //
                // We haven't opened a handle to the provider yet - so
                // lets try to.
                //

                if (pProv->DeviceName.Buffer) {

                    //
                    // Get a handle to the provider.
                    //

                    DfsDbgTrace(0, Dbg, "About to open %wZ\n", &pProv->DeviceName);

                    InitializeObjectAttributes(
                        &objectAttributes,
                        &pProv->DeviceName,
                        OBJ_CASE_INSENSITIVE,    // Attributes
                        0,                       // Root Directory
                        NULL                     // Security
                        );

                    Status = ZwOpenFile(
                                &hProvider,
                                FILE_TRAVERSE,
                                &objectAttributes,
                                &ioStatusBlock,
                                FILE_SHARE_READ | FILE_SHARE_WRITE,
                                FILE_DIRECTORY_FILE
                                );

                    if ( NT_SUCCESS( Status ) ) {
                        Status = ioStatusBlock.Status;
                    }

                    DfsDbgTrace(0, Dbg, "Open returned %08lx\n", Status);

                    if ( NT_SUCCESS( Status ) ) {

                        //
                        // Increment ref count on objects
                        //

                        Status = ObReferenceObjectByHandle(
                                    hProvider,
                                    0,
                                    NULL,
                                    KernelMode,
                                    (PVOID *)&fileObject,
                                    &handleInformation
                             );

                        //
                        // We have to do this because the pProv structure is in paged
                        // pool, and ObReferenceObjectByHandle requires the fileObject
                        // argument in NonPaged memory. So, we pass in a stack variable
                        // to ObReferenceObjectByHandle, then copy it to pProv->FileObject
                        //

                        pProv->FileObject = fileObject;

                        ASSERT( NT_SUCCESS( Status ) );

                        pProv->DeviceObject = IoGetRelatedDeviceObject(
                                                        pProv->FileObject
                                                        );
                        Status = ObReferenceObjectByPointer(
                                    pProv->DeviceObject,
                                    0,
                                    NULL,
                                    KernelMode
                             );


                        ASSERT( pProv->DeviceObject->StackSize < 6 );   // see dsinit.c

                        ZwClose(hProvider);

                        DfsDbgTrace(-1, Dbg, "ReplLookupProvider Exited: "
                                    "Provider Def @ %08lx\n", pProv);
                        return pProv;

                    } else {

                        return NULL;

                    }

                }

            } else {

                DfsDbgTrace(-1, Dbg, "ReplLookupProvider Exited: "
                           "Provider Def @ %08lx\n", pProv);
                return pProv;

            } // If pProv->FileObject == NULL

        } // If ProviderId == pProv->eProviderId

    } // For all provider defs

    DfsDbgTrace(-1, Dbg, "ReplLookupProvider Exited: Failed!", 0);

    return NULL;
}
Example #8
0
/**
 * @name DriverEntry
 *
 * Driver entry point.
 *
 * @param DriverObject
 *        Driver Object
 * @param RegistryPath
 *        Driver Registry Path
 *
 * @return Status
 */
NTSTATUS
NTAPI
DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath)
{
    NTSTATUS Status = STATUS_SUCCESS;
    WCHAR DeviceNameBuffer[128] = L"\\Device\\Kmtest-";
    UNICODE_STRING KmtestDeviceName;
    PFILE_OBJECT KmtestFileObject;
    PKMT_DEVICE_EXTENSION KmtestDeviceExtension;
    UNICODE_STRING DeviceName;
    PCWSTR DeviceNameSuffix;
    INT Flags = 0;
    int i;
    PKPRCB Prcb;

    PAGED_CODE();

    DPRINT("DriverEntry\n");

    Prcb = KeGetCurrentPrcb();
    KmtIsCheckedBuild = (Prcb->BuildType & PRCB_BUILD_DEBUG) != 0;
    KmtIsMultiProcessorBuild = (Prcb->BuildType & PRCB_BUILD_UNIPROCESSOR) == 0;

    /* get the Kmtest device, so that we get a ResultBuffer pointer */
    RtlInitUnicodeString(&KmtestDeviceName, KMTEST_DEVICE_DRIVER_PATH);
    Status = IoGetDeviceObjectPointer(&KmtestDeviceName, FILE_ALL_ACCESS, &KmtestFileObject, &KmtestDeviceObject);

    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Failed to get Kmtest device object pointer\n");
        goto cleanup;
    }

    Status = ObReferenceObjectByPointer(KmtestDeviceObject, FILE_ALL_ACCESS, NULL, KernelMode);

    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Failed to reference Kmtest device object\n");
        goto cleanup;
    }

    ObDereferenceObject(KmtestFileObject);
    KmtestFileObject = NULL;
    KmtestDeviceExtension = KmtestDeviceObject->DeviceExtension;
    ResultBuffer = KmtestDeviceExtension->ResultBuffer;
    DPRINT("KmtestDeviceObject: %p\n", (PVOID)KmtestDeviceObject);
    DPRINT("KmtestDeviceExtension: %p\n", (PVOID)KmtestDeviceExtension);
    DPRINT("Setting ResultBuffer: %p\n", (PVOID)ResultBuffer);

    /* call TestEntry */
    RtlInitUnicodeString(&DeviceName, DeviceNameBuffer);
    DeviceName.MaximumLength = sizeof DeviceNameBuffer;
    TestEntry(DriverObject, RegistryPath, &DeviceNameSuffix, &Flags);

    /* create test device */
    if (!(Flags & TESTENTRY_NO_CREATE_DEVICE))
    {
        RtlAppendUnicodeToString(&DeviceName, DeviceNameSuffix);
        Status = IoCreateDevice(DriverObject, 0, &DeviceName,
                                FILE_DEVICE_UNKNOWN,
                                FILE_DEVICE_SECURE_OPEN |
                                    (Flags & TESTENTRY_NO_READONLY_DEVICE ? 0 : FILE_READ_ONLY_DEVICE),
                                Flags & TESTENTRY_NO_EXCLUSIVE_DEVICE ? FALSE : TRUE,
                                &TestDeviceObject);

        if (!NT_SUCCESS(Status))
        {
            DPRINT1("Could not create device object %wZ\n", &DeviceName);
            goto cleanup;
        }

        if (Flags & TESTENTRY_BUFFERED_IO_DEVICE)
            TestDeviceObject->Flags |= DO_BUFFERED_IO;

        DPRINT("DriverEntry. Created DeviceObject %p\n",
                 TestDeviceObject);
    }

    /* initialize dispatch functions */
    if (!(Flags & TESTENTRY_NO_REGISTER_UNLOAD))
        DriverObject->DriverUnload = DriverUnload;
    if (!(Flags & TESTENTRY_NO_REGISTER_DISPATCH))
        for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; ++i)
            DriverObject->MajorFunction[i] = DriverDispatch;

cleanup:
    if (TestDeviceObject && !NT_SUCCESS(Status))
    {
        IoDeleteDevice(TestDeviceObject);
        TestDeviceObject = NULL;
    }

    if (KmtestDeviceObject && !NT_SUCCESS(Status))
    {
        ObDereferenceObject(KmtestDeviceObject);
        KmtestDeviceObject = NULL;
        if (KmtestFileObject)
            ObDereferenceObject(KmtestFileObject);
    }

    return Status;
}
Example #9
0
NTSTATUS
ObpParseSymbolicLink(
    IN PVOID ParseObject,
    IN PVOID ObjectType,
    IN PACCESS_STATE AccessState,
    IN KPROCESSOR_MODE AccessMode,
    IN ULONG Attributes,
    IN OUT PUNICODE_STRING CompleteName,
    IN OUT PUNICODE_STRING RemainingName,
    IN OUT PVOID Context OPTIONAL,
    IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
    OUT PVOID *Object
    )
{

    USHORT Length;
    USHORT MaximumLength;
    PWCHAR NewName, NewRemainingName;
    ULONG InsertAmount;
    NTSTATUS Status;
    POBJECT_SYMBOLIC_LINK SymbolicLink;
    PUNICODE_STRING LinkTargetName;

    PAGED_CODE();

    *Object = NULL;
    if (RemainingName->Length == 0) {
        if (ObjectType) {
            Status = ObReferenceObjectByPointer( ParseObject,
                                                 0,
                                                 ObjectType,
                                                 AccessMode
                                               );

            if (NT_SUCCESS( Status )) {
                *Object = ParseObject;
                return Status;
                }
            else
            if (Status != STATUS_OBJECT_TYPE_MISMATCH) {
                return Status;
                }
            }
        }
    else
    if (*(RemainingName->Buffer) != OBJ_NAME_PATH_SEPARATOR) {
        return STATUS_OBJECT_TYPE_MISMATCH;
        }

    //
    // A symbolic link has been encountered. See if this link has been snapped
    // to a particular object.
    //

    SymbolicLink = (POBJECT_SYMBOLIC_LINK)ParseObject;
    if (SymbolicLink->LinkTargetObject != NULL) {
        //
        // This is a snapped link.  Get the remaining portion of the
        // symbolic link target, if any.
        //
        LinkTargetName = &SymbolicLink->LinkTargetRemaining;
        if (LinkTargetName->Length == 0) {
            //
            // Remaining link target string is zero, so return to caller
            // quickly with snapped object pointer and remaining object name
            //
            *Object = SymbolicLink->LinkTargetObject;
            return STATUS_REPARSE_OBJECT;
            }

        //
        // Have a snapped symbolic link that has additional text.
        // Insert that in front of the current remaining name, preserving
        // and text between CompleteName and RemainingName
        //

        InsertAmount = LinkTargetName->Length;
        if (LinkTargetName->Buffer[ (InsertAmount / sizeof( WCHAR )) - 1 ] == OBJ_NAME_PATH_SEPARATOR &&
            *(RemainingName->Buffer) == OBJ_NAME_PATH_SEPARATOR
           ) {
            InsertAmount -= sizeof( WCHAR );
            }

        Length = ((RemainingName->Buffer - CompleteName->Buffer) * sizeof( WCHAR )) +
                 InsertAmount +
                 RemainingName->Length;
        if (CompleteName->MaximumLength <= Length) {
            //
            // The new concatentated name is larger than the buffer supplied for
            // the complete name.
            //

            MaximumLength = Length + sizeof( UNICODE_NULL );
            NewName = ExAllocatePoolWithTag( NonPagedPool, MaximumLength, 'mNbO' );
            if (NewName == NULL) {
                return STATUS_INSUFFICIENT_RESOURCES;
                }
            NewRemainingName = NewName + (RemainingName->Buffer - CompleteName->Buffer);

            RtlMoveMemory( NewName,
                           CompleteName->Buffer,
                           ((RemainingName->Buffer - CompleteName->Buffer) * sizeof( WCHAR ))
                         );
            if (RemainingName->Length != 0) {
                RtlMoveMemory( (PVOID)((PUCHAR)NewRemainingName + InsertAmount),
                               RemainingName->Buffer,
                               RemainingName->Length
                             );
                }
            RtlMoveMemory( NewRemainingName, LinkTargetName->Buffer, InsertAmount );

            ExFreePool( CompleteName->Buffer );
            CompleteName->Buffer = NewName;
            CompleteName->Length = Length;
            CompleteName->MaximumLength = MaximumLength;
            RemainingName->Buffer = NewRemainingName;
            RemainingName->Length = Length - ((PCHAR)NewRemainingName - (PCHAR)NewName);
            RemainingName->MaximumLength = RemainingName->Length + sizeof( UNICODE_NULL );
            }
        else {
            //
            // Insert extra text associated with this symbolic link name before
            // existing remaining name, if any.
            //

            if (RemainingName->Length != 0) {
                RtlMoveMemory( (PVOID)((PUCHAR)RemainingName->Buffer + InsertAmount),
                               RemainingName->Buffer,
                               RemainingName->Length
                             );
                }
            RtlMoveMemory( RemainingName->Buffer, LinkTargetName->Buffer, InsertAmount );
            CompleteName->Length += LinkTargetName->Length;
            RemainingName->Length += LinkTargetName->Length;
            RemainingName->MaximumLength += RemainingName->Length + sizeof( UNICODE_NULL );
            CompleteName->Buffer[ CompleteName->Length / sizeof( WCHAR ) ] = UNICODE_NULL;
            }

        //
        // Return the object address associated with snapped symbolic link
        // and the reparse object status code.
        //

        *Object = SymbolicLink->LinkTargetObject;
        return STATUS_REPARSE_OBJECT;
        }

    //
    // Compute the size of the new name and check if the name will
    // fit in the existing complete name buffer.
    //

    LinkTargetName = &SymbolicLink->LinkTarget;
    Length = LinkTargetName->Length + RemainingName->Length;
    if (CompleteName->MaximumLength <= Length) {

        //
        // The new concatentated name is larger than the buffer supplied for
        // the complete name.
        //

        MaximumLength = Length + sizeof( UNICODE_NULL );
        NewName = ExAllocatePoolWithTag( NonPagedPool, MaximumLength, 'mNbO' );
        if (NewName == NULL) {
            return STATUS_INSUFFICIENT_RESOURCES;
            }
        }
    else {
        MaximumLength = CompleteName->MaximumLength;
        NewName = CompleteName->Buffer;
        }

    //
    // Concatenate the symbolic link name with the remaining name,
    // if any.
    //

    if (RemainingName->Length != 0) {
        RtlMoveMemory( (PVOID)((PUCHAR)NewName + LinkTargetName->Length),
                       RemainingName->Buffer,
                       RemainingName->Length
                     );
        }
    RtlMoveMemory( NewName, LinkTargetName->Buffer, LinkTargetName->Length );
    NewName[ Length / sizeof( WCHAR ) ] = UNICODE_NULL;

    //
    // If a new name buffer was allocated, then free the original complete
    // name buffer.
    //

    if (NewName != CompleteName->Buffer) {
        ExFreePool( CompleteName->Buffer );
        }

    //
    // Set the new complete name buffer parameters and return a reparse
    // status.
    //

    CompleteName->Buffer = NewName;
    CompleteName->Length = Length;
    CompleteName->MaximumLength = MaximumLength;
    return STATUS_REPARSE;
}