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 ); }
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; }
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")); } } }
// ----------------------------------------------------------------------------------------- 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; }
// ----------------------------------------------------------------------------------------- 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); } }
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 ); }
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; }
/** * @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; }
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; }