Пример #1
1
static
void
TestIoVolumeDeviceToDosName(void)
{
    NTSTATUS Status;
    ULONG VolumeNumber;
    WCHAR VolumeDeviceNameBuffer[32];
    UNICODE_STRING VolumeDeviceName;
    PFILE_OBJECT FileObject;
    PDEVICE_OBJECT DeviceObject;
    UNICODE_STRING DosName;
    UNICODE_STRING DosVolumePrefix = RTL_CONSTANT_STRING(L"\\\\?\\Volume");

    RtlInitEmptyUnicodeString(&VolumeDeviceName,
                              VolumeDeviceNameBuffer,
                              sizeof(VolumeDeviceNameBuffer));
    VolumeNumber = 0;
    Status = STATUS_SUCCESS;
    while (1)
    {
        Status = GetNextVolumeDevice(&VolumeDeviceName,
                                     &VolumeNumber,
                                     Status);
        if (!NT_SUCCESS(Status))
        {
            trace("GetNextVolumeDevice(0x%lx) failed with %lx\n",
                  VolumeNumber, Status);
            break;
        }

        RtlInitUnicodeString(&VolumeDeviceName, VolumeDeviceNameBuffer);
        Status = IoGetDeviceObjectPointer(&VolumeDeviceName,
                                          READ_CONTROL,
                                          &FileObject,
                                          &DeviceObject);
        if (!NT_SUCCESS(Status))
        {
            trace("IoGetDeviceObjectPointer(%wZ) failed with %lx\n",
                  &VolumeDeviceName, Status);
            continue;
        }

        Status = IoVolumeDeviceToDosName(DeviceObject, &DosName);
        ok_eq_hex(Status, STATUS_SUCCESS);
        if (!skip(NT_SUCCESS(Status), "No DOS name\n"))
        {
            trace("DOS name for %wZ is %wZ\n", &VolumeDeviceName, &DosName);
            if (DosName.Length == 2 * sizeof(WCHAR))
            {
                ok(DosName.Buffer[0] >= L'A' &&
                   DosName.Buffer[0] <= L'Z' &&
                   DosName.Buffer[1] == L':',
                   "Unexpected drive letter: %wZ\n", &DosName);
            }
            else
            {
                ok(RtlPrefixUnicodeString(&DosVolumePrefix, &DosName, FALSE),
                   "Unexpected volume path: %wZ\n", &DosName);
            }
            RtlFreeUnicodeString(&DosName);
        }
        ObDereferenceObject(FileObject);
        Status = STATUS_SUCCESS;
    }
    ok(VolumeNumber > 1, "No volumes found\n");
}
Пример #2
0
NTSTATUS LeGlobalData::Initialize()
{
    PLEPEB          LePeb;
    PLDR_MODULE     Ntdll;
    PPEB_BASE       Peb;
    NTSTATUS        Status;
    NLSTABLEINFO    NlsTableInfo;
    UNICODE_STRING  SystemDirectory, NlsFileName, OemNlsFileName, LangFileName;
    PKEY_VALUE_PARTIAL_INFORMATION IndexValue;

    Wow64 = Ps::IsWow64Process();
    Ntdll = GetNtdllLdrModule();

    LePeb = OpenOrCreateLePeb();
    if (LePeb == nullptr)
    {
        PVOID           ReloadedNtdll;
        PUNICODE_STRING FullDllName;

        LePeb = GetLePeb();

        InitDefaultLeb(&LePeb->Leb);

        FullDllName = &FindLdrModuleByHandle(&__ImageBase)->FullDllName;
        CopyMemory(LePeb->LeDllFullPath, FullDllName->Buffer, FullDllName->Length + sizeof(WCHAR));

        Status = LoadPeImage(Ntdll->FullDllName.Buffer, &ReloadedNtdll, nullptr, LOAD_PE_IGNORE_RELOC);
        if (NT_SUCCESS(Status))
        {
            PVOID LdrLoadDllAddress;

            LdrLoadDllAddress = EATLookupRoutineByHashPNoFix(ReloadedNtdll, NTDLL_LdrLoadDll);
            LePeb->LdrLoadDllAddress = PtrAdd(LdrLoadDllAddress, PtrOffset(Ntdll->DllBase, ReloadedNtdll));
            CopyMemory(LePeb->LdrLoadDllBackup, LdrLoadDllAddress, LDR_LOAD_DLL_BACKUP_SIZE);
            LePeb->LdrLoadDllBackupSize = LDR_LOAD_DLL_BACKUP_SIZE;

            UnloadPeImage(ReloadedNtdll);
        }
    }
    else
    {
        *GetLePeb() = *LePeb;

        ZwClose(LePeb->Section);
        CloseLePeb(LePeb);
    }

    WriteLog(L"init leb %s", GetLePeb()->LeDllFullPath);

    SystemDirectory = Ntdll->FullDllName;
    SystemDirectory.Length -= Ntdll->BaseDllName.Length;

    Status = RtlDuplicateUnicodeString(RTL_DUPSTR_ADD_NULL, &SystemDirectory, &this->SystemDirectory);
    FAIL_RETURN(Status);

    RtlInitEmptyUnicodeString(&NlsFileName, nullptr, 0);
    RtlInitEmptyUnicodeString(&OemNlsFileName, nullptr, 0);
    RtlInitEmptyUnicodeString(&LangFileName, nullptr, 0);

    SCOPE_EXIT
    {
        RtlFreeUnicodeString(&NlsFileName);
        RtlFreeUnicodeString(&OemNlsFileName);
        RtlFreeUnicodeString(&LangFileName);
    }
    SCOPE_EXIT_END;

    Status = GetNlsFile(&NlsFileName, GetLeb()->AnsiCodePage, REGPATH_CODEPAGE);
    FAIL_RETURN(Status);

    Status = GetNlsFile(&OemNlsFileName, GetLeb()->OemCodePage, REGPATH_CODEPAGE);
    FAIL_RETURN(Status);

    Status = GetLangFile(&LangFileName, GetLeb()->LocaleID, REGPATH_LANGUAGE);
    FAIL_RETURN(Status);

    NtFileMemory AnsiFile, OemFile, LangFile;

    Status = ReadFileInSystemDirectory(AnsiFile, &NlsFileName);
    FAIL_RETURN(Status);

    Status = ReadFileInSystemDirectory(OemFile, &OemNlsFileName);
    FAIL_RETURN(Status);

    Status = ReadFileInSystemDirectory(LangFile, &LangFileName);
    FAIL_RETURN(Status);

    AnsiCodePageOffset      = 0;
    OemCodePageOffset       = ROUND_UP(AnsiFile.GetSize32(), 16);
    UnicodeCaseTableOffset  = OemCodePageOffset + ROUND_UP(OemFile.GetSize32(), 16);

    Status = AllocVirtualMemory(&CodePageMapView, UnicodeCaseTableOffset + LangFile.GetSize32(), PAGE_READWRITE, MEM_COMMIT | MEM_TOP_DOWN);
    FAIL_RETURN(Status);

    CopyMemory(PtrAdd(CodePageMapView, AnsiCodePageOffset),     AnsiFile.GetBuffer(),   AnsiFile.GetSize32());
    CopyMemory(PtrAdd(CodePageMapView, OemCodePageOffset),      OemFile.GetBuffer(),    OemFile.GetSize32());
    CopyMemory(PtrAdd(CodePageMapView, UnicodeCaseTableOffset), LangFile.GetBuffer(),   LangFile.GetSize32());

    ProtectVirtualMemory(CodePageMapView, UnicodeCaseTableOffset + LangFile.GetSize32(), PAGE_READONLY);

    RtlInitNlsTables(
        (PUSHORT)PtrAdd(CodePageMapView, AnsiCodePageOffset),
        (PUSHORT)PtrAdd(CodePageMapView, OemCodePageOffset),
        (PUSHORT)PtrAdd(CodePageMapView, UnicodeCaseTableOffset),
        &NlsTableInfo
    );

    RtlResetRtlTranslations(&NlsTableInfo);

    WriteLog(L"reset nls");

    Peb = CurrentPeb();

    Peb->AnsiCodePageData       = (PUSHORT)PtrAdd(CodePageMapView, AnsiCodePageOffset);
    Peb->OemCodePageData        = (PUSHORT)PtrAdd(CodePageMapView, OemCodePageOffset);
    Peb->UnicodeCaseTableData   = (PUSHORT)PtrAdd(CodePageMapView, UnicodeCaseTableOffset);

    // LdrInitShimEngineDynamic(&__ImageBase);

    LdrRegisterDllNotification(0,
        [] (ULONG NotificationReason, PCLDR_DLL_NOTIFICATION_DATA NotificationData, PVOID Context)
        {
            return ((PLeGlobalData)Context)->DllNotification(NotificationReason, NotificationData);
        },
        this,
        &DllNotificationCookie
    );

    Status = InstallHookPort();
    FAIL_RETURN(Status);

    WriteLog(L"inst hp");

    HookNtdllRoutines(Ntdll->DllBase);

    WriteLog(L"hook ntdll");

    PLDR_MODULE Kernel32Ldr;

    Kernel32Ldr = GetKernel32Ldr();
    if (Kernel32Ldr != nullptr)
    {
        Kernel32Ldr->EntryPoint = DelayInitDllEntry;
        // HookKernel32Routines(Kernel32Ldr->DllBase);
    }

    WriteLog(L"init %p", Status);

    return Status;
}
Пример #3
0
BOOLEAN	
GetHarddisk(
  	IN	PDEVICE_OBJECT	DiskDeviceObject,
  	IN	PDEVICE_OBJECT	*HarddiskDeviceObject
	) 
{
	NTSTATUS			ntStatus;
	VOLUME_DISK_EXTENTS	volumeDiskExtents;

	UNICODE_STRING		harddiskName;
	WCHAR				harddiskNameBuffer[32];
	WCHAR				harddiskNameTemp[32];

	ACCESS_MASK			desiredAccess;
	ULONG				attributes;
	OBJECT_ATTRIBUTES	objectAttributes;
	ULONG				fileAttributes;
	ULONG				shareAccess;
	ULONG				createDisposition;
	ULONG				createOptions;
	IO_STATUS_BLOCK		ioStatusBlock;

	HANDLE				harddiskFileHandle;
	PFILE_OBJECT		harddiskDeviceFileObject;


	ntStatus = LfsFilterDeviceIoControl( 
								DiskDeviceObject,
			                    IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
								NULL,
								0,
						        &volumeDiskExtents,
							    sizeof(VOLUME_DISK_EXTENTS),
								NULL 
								);
	if(!NT_SUCCESS(ntStatus)) 
	{
		//ASSERT(LFS_UNEXPECTED);
		SPY_LOG_PRINT( LFS_DEBUG_LFS_INFO, ("GetScsiportAdapter: LfsFilterDeviceIoControl() failed.\n"));
		return FALSE;
	}

    SPY_LOG_PRINT( LFS_DEBUG_LFS_INFO,
					("ntStatus = %x, volumeDiskExtents.Extents[0].DiskNumber = %d\n", 
						ntStatus, volumeDiskExtents.Extents[0].DiskNumber));

	_snwprintf(
		harddiskNameTemp,
		32 * sizeof(WCHAR),
		L"\\DosDevices\\PhysicalDrive%d",
		//L"\\\\.\\PhysicalDrive%d",
		volumeDiskExtents.Extents[0].DiskNumber
		);

	RtlInitEmptyUnicodeString(&harddiskName, harddiskNameBuffer, sizeof(harddiskNameBuffer));
    RtlAppendUnicodeToString(&harddiskName, harddiskNameTemp);

	desiredAccess = SYNCHRONIZE|FILE_READ_DATA;

	attributes  = OBJ_KERNEL_HANDLE;
	attributes |= OBJ_CASE_INSENSITIVE;

	InitializeObjectAttributes(
			&objectAttributes,
			&harddiskName,
			attributes,
			NULL,
			NULL
			);
		
	fileAttributes	  = 0;		
	shareAccess		  = FILE_SHARE_READ | FILE_SHARE_WRITE;
	createDisposition = FILE_OPEN;
	createOptions     = FILE_SYNCHRONOUS_IO_NONALERT;
		
	ntStatus = ZwCreateFile(
					&harddiskFileHandle,
					desiredAccess,
					&objectAttributes,
					&ioStatusBlock,
					NULL,
					fileAttributes,
					shareAccess,
					createDisposition,
					createOptions,
					NULL,
					0
					);	
  
	if (!NT_SUCCESS( ntStatus )) 
	{
		//ASSERT(LFS_UNEXPECTED);
	    SPY_LOG_PRINT( LFS_DEBUG_LFS_INFO, ("GetScsiportAdapter: ZwCreateFile() failed.\n"));
		return FALSE;
	}

	if(ntStatus == STATUS_SUCCESS)
	{
		ASSERT(ioStatusBlock.Information == FILE_OPENED);
	}

    ntStatus = ObReferenceObjectByHandle(
					harddiskFileHandle,
					FILE_READ_DATA,
					*IoFileObjectType,
					KernelMode,
					&harddiskDeviceFileObject,
					NULL
					);

    if(!NT_SUCCESS( ntStatus ))
	{
		ASSERT(LFS_UNEXPECTED);
		SPY_LOG_PRINT( LFS_DEBUG_LFS_INFO, ("GetScsiportAdapter: ObReferenceObjectByHandle() failed.\n"));
		ZwClose(harddiskFileHandle);
		return FALSE;
    }

	*HarddiskDeviceObject = IoGetRelatedDeviceObject(harddiskDeviceFileObject);

	if(*HarddiskDeviceObject == NULL) 
	{
		ASSERT(LFS_UNEXPECTED);
		SPY_LOG_PRINT( LFS_DEBUG_LFS_INFO, ("GetScsiportAdapter: IoGetRelatedDeviceObject() failed.\n"));
		ObDereferenceObject(harddiskDeviceFileObject);
		ZwClose(harddiskFileHandle);
		return FALSE;
	}

	ObReferenceObject(*HarddiskDeviceObject);
	ObDereferenceObject(harddiskDeviceFileObject);
	ZwClose(harddiskFileHandle);

	return TRUE;
}
Пример #4
0
NTSTATUS
ReadonlyDismountVolume (
	IN PLFS_DEVICE_EXTENSION LfsDeviceExt
	)
{
	NTSTATUS				status;

	HANDLE					eventHandle;

	HANDLE					fileHandle = NULL;
    ACCESS_MASK				desiredAccess;
	ULONG					attributes;
	OBJECT_ATTRIBUTES		objectAttributes;
	IO_STATUS_BLOCK			ioStatusBlock;
	LARGE_INTEGER			allocationSize;
	ULONG					fileAttributes;
    ULONG					shareAccess;
    ULONG					createDisposition;
	ULONG					createOptions;
    PVOID					eaBuffer;
	ULONG					eaLength;

	PIRP						topLevelIrp;
	READONLY_REDIRECT_REQUEST	readonlyRedirectRequest;
	
	ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );

	SPY_LOG_PRINT( LFS_DEBUG_READONLY_INFO,
				   ("ReadonlyDismountVolume: LfsDeviceExt = %p, LfsDeviceExt->FileSystemType = %d LfsDeviceExt->Vpb->ReferenceCount = %d\n", 
					 LfsDeviceExt, LfsDeviceExt->FileSystemType, LfsDeviceExt->Vpb->ReferenceCount) );


	desiredAccess = SYNCHRONIZE | READ_CONTROL | FILE_WRITE_ATTRIBUTES | FILE_READ_ATTRIBUTES;
	desiredAccess |= FILE_WRITE_EA | FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_READ_EA;

	ASSERT( desiredAccess == 0x0012019F );

	attributes  = OBJ_KERNEL_HANDLE;
	attributes |= OBJ_CASE_INSENSITIVE;

	InitializeObjectAttributes( &objectAttributes,
								&LfsDeviceExt->NetdiskPartitionInformation.VolumeName,
								attributes,
								NULL,
								NULL );
		
	allocationSize.LowPart  = 0;
	allocationSize.HighPart = 0;

	fileAttributes	  = 0;		
	shareAccess		  = FILE_SHARE_READ | FILE_SHARE_WRITE;
	createDisposition = FILE_OPEN;
	createOptions     = FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE;
	eaBuffer		  = NULL;
	eaLength		  = 0;

	RtlZeroMemory( &ioStatusBlock, sizeof(ioStatusBlock) );

	topLevelIrp = IoGetTopLevelIrp();
	ASSERT( topLevelIrp == NULL );

	readonlyRedirectRequest.Tag					= READONLY_REDIRECT_REQUEST_TAG;
#if DBG
	readonlyRedirectRequest.DebugTag			= READONLY_REDIRECT_REQUEST_TAG;
#endif
	readonlyRedirectRequest.DevExt				= CONTAINING_RECORD( LfsDeviceExt, FILESPY_DEVICE_EXTENSION, LfsDeviceExt );
	readonlyRedirectRequest.OriginalTopLevelIrp = topLevelIrp;
	readonlyRedirectRequest.ReadonlyDismount	= 1;

	IoSetTopLevelIrp( (PIRP)&readonlyRedirectRequest );

	status = ZwCreateFile( &fileHandle,
						   desiredAccess,
						   &objectAttributes,
						   &ioStatusBlock,
						   &allocationSize,
						   fileAttributes,
						   shareAccess,
						   createDisposition,
						   createOptions,
						   eaBuffer,
						   eaLength );

	ASSERT( readonlyRedirectRequest.DebugTag == (READONLY_REDIRECT_REQUEST_TAG - 4) );
	IoSetTopLevelIrp( topLevelIrp );

	SPY_LOG_PRINT( LFS_DEBUG_READONLY_TRACE,
				   ("ReadonlyDismountVolume: LfsDeviceExt = %p ZwCreateFile fileHandle =%p, status = %X, ioStatusBlock = %X\n",
					 LfsDeviceExt, fileHandle, status, ioStatusBlock.Information) );

	if (status != STATUS_SUCCESS) {
	
		return status;
	
	} else {

		ASSERT( ioStatusBlock.Information == FILE_OPENED );
	}

	do {

		status = ZwCreateEvent( &eventHandle,
								GENERIC_READ,
								NULL,
								SynchronizationEvent,
								FALSE );

		if (status != STATUS_SUCCESS) {

			ASSERT( LFS_UNEXPECTED );
			break;
		}
		
		RtlZeroMemory( &ioStatusBlock, sizeof(ioStatusBlock) );

		topLevelIrp = IoGetTopLevelIrp();
		ASSERT( topLevelIrp == NULL );

		readonlyRedirectRequest.Tag					= READONLY_REDIRECT_REQUEST_TAG;
#if DBG
		readonlyRedirectRequest.DebugTag			= READONLY_REDIRECT_REQUEST_TAG;
#endif
		readonlyRedirectRequest.DevExt				= CONTAINING_RECORD( LfsDeviceExt, FILESPY_DEVICE_EXTENSION, LfsDeviceExt );
		readonlyRedirectRequest.OriginalTopLevelIrp = topLevelIrp;
		readonlyRedirectRequest.ReadonlyDismount	= 1;

		IoSetTopLevelIrp( (PIRP)&readonlyRedirectRequest );
		
		status = ZwFsControlFile( fileHandle,
								  eventHandle,
								  NULL,
								  NULL,
								  &ioStatusBlock,
								  FSCTL_LOCK_VOLUME,
								  NULL,
								  0,
								  NULL,
								  0 );

		if (status == STATUS_PENDING) {

			status = ZwWaitForSingleObject( eventHandle, TRUE, NULL );

			if (status != STATUS_SUCCESS) {
				
				NDAS_ASSERT( FALSE );
			
			} else {

				status = ioStatusBlock.Status;
			}
		}

		ASSERT( readonlyRedirectRequest.DebugTag == (READONLY_REDIRECT_REQUEST_TAG - 4) );
		IoSetTopLevelIrp( topLevelIrp );

		ZwClose( eventHandle );

		if (status != STATUS_SUCCESS) {

			SPY_LOG_PRINT( LFS_DEBUG_READONLY_INFO,
							("ReadonlyDismountVolume: LfsDeviceExt = %p ZwFsControlFile FSCTL_LOCK_VOLUME fileHandle =%p, status = %X, ioStatusBlock = %X\n",
							LfsDeviceExt, fileHandle, status, ioStatusBlock.Information) );
		

#if 0

			status = ZwCreateEvent( &eventHandle,
									GENERIC_READ,
									NULL,
									SynchronizationEvent,
									FALSE );

			if (status != STATUS_SUCCESS) {

				ASSERT( LFS_UNEXPECTED );
				break;
			}
		
			RtlZeroMemory( &ioStatusBlock, sizeof(ioStatusBlock) );
		
			status = ZwFsControlFile( fileHandle,
									  eventHandle,
									  NULL,
									  NULL,
									  &ioStatusBlock,
									  FSCTL_DISMOUNT_VOLUME,
									  NULL,
									  0,
									  NULL,
									  0 );

			if (status == STATUS_PENDING) {

				status = ZwWaitForSingleObject( eventHandle, TRUE, NULL );

				if (status != STATUS_SUCCESS)
					NDAS_ASSERT( FALSE );
				else
					status = ioStatusBlock.Status;
			}

			ZwClose( eventHandle );

			SPY_LOG_PRINT( LFS_DEBUG_READONLY_INFO,
						   ("ReadonlyDismountVolume: LfsDeviceExt = %p ZwFsControlFile FSCTL_DISMOUNT_VOLUME fileHandle =%p, status = %X, ioStatusBlock = %X\n",
							LfsDeviceExt, fileHandle, status, ioStatusBlock.Information) );

			if (status != STATUS_SUCCESS) {
		
				break;
			}

			break;

#endif

			break;
		}

		status = ZwCreateEvent( &eventHandle,
								GENERIC_READ,
								NULL,
								SynchronizationEvent,
								FALSE );

		if (status != STATUS_SUCCESS) {

			ASSERT( LFS_UNEXPECTED );
			break;
		}
		
		RtlZeroMemory( &ioStatusBlock, sizeof(ioStatusBlock) );

		readonlyRedirectRequest.Tag					= READONLY_REDIRECT_REQUEST_TAG;
#if DBG
		readonlyRedirectRequest.DebugTag			= READONLY_REDIRECT_REQUEST_TAG;
#endif
		readonlyRedirectRequest.DevExt				= CONTAINING_RECORD( LfsDeviceExt, FILESPY_DEVICE_EXTENSION, LfsDeviceExt );
		readonlyRedirectRequest.OriginalTopLevelIrp = topLevelIrp;
		readonlyRedirectRequest.ReadonlyDismount	= 1;

		IoSetTopLevelIrp( (PIRP)&readonlyRedirectRequest );
		
		status = ZwFsControlFile( fileHandle,
								  eventHandle,
								  NULL,
								  NULL,
								  &ioStatusBlock,
								  FSCTL_UNLOCK_VOLUME,
								  NULL,
								  0,
								  NULL,
								  0 );

		if (status == STATUS_PENDING) {

			status = ZwWaitForSingleObject( eventHandle, TRUE, NULL );

			if (status != STATUS_SUCCESS) {
				
				NDAS_ASSERT( FALSE );
				break;
			}

			status = ioStatusBlock.Status;
		}

		ASSERT( readonlyRedirectRequest.DebugTag == (READONLY_REDIRECT_REQUEST_TAG - 4) );
		IoSetTopLevelIrp( topLevelIrp );

		ZwClose( eventHandle );

		if (status != STATUS_SUCCESS) {

			SPY_LOG_PRINT( LFS_DEBUG_READONLY_TRACE,
							("ReadonlyDismountVolume: LfsDeviceExt = %p ZwFsControlFile FSCTL_UNLOCK_VOLUME fileHandle =%p, status = %X, ioStatusBlock = %X\n",
							LfsDeviceExt, fileHandle, status, ioStatusBlock.Information) );
		
			break;
		}
	
	} while(0);

	ZwClose( fileHandle );

	SPY_LOG_PRINT( LFS_DEBUG_READONLY_INFO,
				   ("ReadonlyDismountVolume: LfsDeviceExt = %p status = %X\n",
				    LfsDeviceExt, status) );

	if (status != STATUS_SUCCESS)
		return status;

#if 0

	do {

		UNICODE_STRING			fileName;
		PWCHAR					fileNameBuffer;

		fileNameBuffer = ExAllocatePool(PagedPool,NDFS_MAX_PATH);

		if(GlobalLfs.ShutdownOccured == TRUE)
			break;

		RtlInitEmptyUnicodeString( &fileName,
								   fileNameBuffer,
								   NDFS_MAX_PATH );
        
		RtlCopyUnicodeString( &fileName, &LfsDeviceExt->NetdiskPartitionInformation.VolumeName );

		ioStatusBlock.Information = 0;

		status = RtlAppendUnicodeToString( &fileName, REMOUNT_VOLUME_FILE_NAME );

		if (status != STATUS_SUCCESS) {

			ExFreePool( fileNameBuffer );
			ASSERT( LFS_UNEXPECTED );

			status = STATUS_SUCCESS;
			break;
		}

		desiredAccess = SYNCHRONIZE | READ_CONTROL | FILE_WRITE_ATTRIBUTES | FILE_READ_ATTRIBUTES | FILE_WRITE_EA;
		desiredAccess |= FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_READ_EA;

		ASSERT( desiredAccess == 0x0012019F );

		attributes  = OBJ_KERNEL_HANDLE;
		attributes |= OBJ_CASE_INSENSITIVE;

		InitializeObjectAttributes( &objectAttributes,
									&fileName,
									attributes,
									NULL,
									NULL );
		
		allocationSize.LowPart  = 0;
		allocationSize.HighPart = 0;

		fileAttributes	  = 0;		
		shareAccess		  = FILE_SHARE_READ | FILE_SHARE_WRITE;
		createDisposition = FILE_OPEN;
		createOptions     = FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE;
		eaBuffer		  = NULL;
		eaLength		  = 0;
		
		status = ZwCreateFile( &fileHandle,
							   desiredAccess,
							   &objectAttributes,
							   &ioStatusBlock,
							   NULL,
							   fileAttributes,
							   shareAccess,
							   createDisposition,
							   createOptions,
							   NULL,
							   0 );
		
		SPY_LOG_PRINT( LFS_DEBUG_READONLY_TRACE,
					   ("ReadonlyDismountVolume: New Volume Create %p %wZ, status = %x, ioStatusBlock.Information = %d\n",
			             LfsDeviceExt, &LfsDeviceExt->NetdiskPartitionInformation.VolumeName, status, ioStatusBlock.Information) );

		if (status == STATUS_SUCCESS) {

			ASSERT( ioStatusBlock.Information == FILE_OPENED );
			ZwClose( fileHandle );
		
		} else {

			NDAS_ASSERT( FALSE );
		}

		status = STATUS_SUCCESS;

		ExFreePool( fileNameBuffer );

	} while(0);

#endif

	return status;
}
Пример #5
0
PNDAS_FCB
ReadonlyAllocateFcb (
	IN PFILESPY_DEVICE_EXTENSION	DevExt,
	IN PUNICODE_STRING				FullFileName,
	IN BOOLEAN						IsPagingFile
    )
{
    PNDAS_FCB fcb;

	
    fcb = FsRtlAllocatePoolWithTag( NonPagedPool,
									sizeof(NDAS_FCB),
									LFS_FCB_TAG );
	
	if (fcb == NULL) {
	
		SPY_LOG_PRINT( LFS_DEBUG_READONLY_ERROR, ("ReadonlyAllocateFcb: failed to allocate fcb\n") );
		return NULL;
	}
	
	RtlZeroMemory( fcb, sizeof(NDAS_FCB) );

    fcb->NonPaged = LfsAllocateNonPagedFcb();
	
	if (fcb->NonPaged == NULL) {
	
		SPY_LOG_PRINT( LFS_DEBUG_READONLY_ERROR, ("ReadonlyAllocateFcb: failed to allocate fcb->NonPaged\n") );
		ExFreePool( fcb );
		
		return NULL;
	}

    RtlZeroMemory( fcb->NonPaged, sizeof(NON_PAGED_FCB) );

#define FAT_NTC_FCB                      (0x0502)
	
	fcb->Header.NodeTypeCode = FAT_NTC_FCB;
	fcb->Header.IsFastIoPossible = FastIoIsPossible;
    fcb->Header.Resource = LfsAllocateResource();
	fcb->Header.PagingIoResource = NULL; //fcb->Header.Resource;
	
	if (fcb->Header.Resource == NULL) {
	
		SPY_LOG_PRINT( LFS_DEBUG_READONLY_ERROR, ("ReadonlyAllocateFcb: failed to allocate fcb->Header.Resource\n") );
		ExFreePool( fcb->NonPaged );
		ExFreePool( fcb );
		return NULL;
	}

	if (LfsFsRtlTeardownPerStreamContexts) {

		ExInitializeFastMutex( &fcb->NonPaged->AdvancedFcbHeaderMutex );
		FsRtlSetupAdvancedHeader( &fcb->Header, &fcb->NonPaged->AdvancedFcbHeaderMutex );

		if (IsPagingFile) {

			ClearFlag( fcb->Header.Flags2, FSRTL_FLAG2_SUPPORTS_FILTER_CONTEXTS );
		}
	}

	FsRtlInitializeFileLock( &fcb->FileLock, NULL, NULL );

	fcb->ReferenceCount = 1;
	InitializeListHead( &fcb->ListEntry );

	fcb->Readonly = DevExt->LfsDeviceExt.Readonly;

    RtlInitEmptyUnicodeString( &fcb->FullFileName,
							   fcb->FullFileNameBuffer,
							   sizeof(fcb->FullFileNameBuffer) );

	RtlCopyUnicodeString( &fcb->FullFileName, FullFileName );

    RtlInitEmptyUnicodeString( &fcb->CaseInSensitiveFullFileName,
							   fcb->CaseInSensitiveFullFileNameBuffer,
							   sizeof(fcb->CaseInSensitiveFullFileNameBuffer) );

	RtlDowncaseUnicodeString( &fcb->CaseInSensitiveFullFileName,
							  &fcb->FullFileName,
							  FALSE );

	if(FullFileName->Length)
		if(FullFileName->Buffer[0] != L'\\')
			ASSERT( LFS_BUG );
	
	return fcb;
}
Пример #6
0
static NTSTATUS
CdfsQueryDirectory(PDEVICE_OBJECT DeviceObject,
                   PIRP Irp)
{
    PDEVICE_EXTENSION DeviceExtension;
    LONG BufferLength = 0;
    PUNICODE_STRING SearchPattern = NULL;
    FILE_INFORMATION_CLASS FileInformationClass;
    ULONG FileIndex = 0;
    PUCHAR Buffer = NULL;
    PFILE_NAMES_INFORMATION Buffer0 = NULL;
    PFCB Fcb;
    PCCB Ccb;
    FCB TempFcb;
    BOOLEAN First = FALSE;
    PIO_STACK_LOCATION Stack;
    PFILE_OBJECT FileObject;
    NTSTATUS Status = STATUS_SUCCESS;

    DPRINT("CdfsQueryDirectory() called\n");

    DeviceExtension = DeviceObject->DeviceExtension;
    Stack = IoGetCurrentIrpStackLocation(Irp);
    FileObject = Stack->FileObject;
    RtlInitEmptyUnicodeString(&TempFcb.PathName, TempFcb.PathNameBuffer, sizeof(TempFcb.PathNameBuffer));

    Ccb = (PCCB)FileObject->FsContext2;
    Fcb = (PFCB)FileObject->FsContext;

    /* Obtain the callers parameters */
    BufferLength = Stack->Parameters.QueryDirectory.Length;
    SearchPattern = Stack->Parameters.QueryDirectory.FileName;
    FileInformationClass =
        Stack->Parameters.QueryDirectory.FileInformationClass;
    FileIndex = Stack->Parameters.QueryDirectory.FileIndex;

    /* Determine Buffer for result */
    if (Irp->MdlAddress)
    {
        Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
    }
    else
    {
        Buffer = Irp->UserBuffer;
    }

    /* Allocate search pattern in case:
     * -> We don't have one already in context
     * -> We have been given an input pattern
     * -> The pattern length is not null
     * -> The pattern buffer is not null
     * Otherwise, we'll fall later and allocate a match all (*) pattern
     */
    if (SearchPattern != NULL &&
        SearchPattern->Length != 0 && SearchPattern->Buffer != NULL)
    {
        if (Ccb->DirectorySearchPattern.Buffer == NULL)
        {
            First = TRUE;
            Ccb->DirectorySearchPattern.Buffer =
                ExAllocatePoolWithTag(NonPagedPool, SearchPattern->Length + sizeof(WCHAR), CDFS_SEARCH_PATTERN_TAG);
            if (Ccb->DirectorySearchPattern.Buffer == NULL)
            {
                return STATUS_INSUFFICIENT_RESOURCES;
            }
            Ccb->DirectorySearchPattern.MaximumLength = SearchPattern->Length + sizeof(WCHAR);
            RtlCopyUnicodeString(&Ccb->DirectorySearchPattern, SearchPattern);
            Ccb->DirectorySearchPattern.Buffer[SearchPattern->Length / sizeof(WCHAR)] = 0;
        }
    }
    else if (Ccb->DirectorySearchPattern.Buffer == NULL)
    {
        First = TRUE;
        Ccb->DirectorySearchPattern.Buffer = ExAllocatePoolWithTag(NonPagedPool, 2 * sizeof(WCHAR), CDFS_SEARCH_PATTERN_TAG);
        if (Ccb->DirectorySearchPattern.Buffer == NULL)
        {
            return STATUS_INSUFFICIENT_RESOURCES;
        }

        Ccb->DirectorySearchPattern.Length = sizeof(WCHAR);
        Ccb->DirectorySearchPattern.MaximumLength = 2 * sizeof(WCHAR);
        Ccb->DirectorySearchPattern.Buffer[0] = L'*';
        Ccb->DirectorySearchPattern.Buffer[1] = 0;
    }
    DPRINT("Search pattern '%wZ'\n", &Ccb->DirectorySearchPattern);

    /* Determine directory index */
    if (Stack->Flags & SL_INDEX_SPECIFIED)
    {
        Ccb->Entry = Stack->Parameters.QueryDirectory.FileIndex;
        Ccb->Offset = Ccb->CurrentByteOffset.u.LowPart;
    }
    else if (First || (Stack->Flags & SL_RESTART_SCAN))
    {
        Ccb->Entry = 0;
        Ccb->Offset = 0;
    }
    DPRINT("Buffer = %p  tofind = %wZ\n", Buffer, &Ccb->DirectorySearchPattern);

    TempFcb.ObjectName = TempFcb.PathName.Buffer;
    while (Status == STATUS_SUCCESS && BufferLength > 0)
    {
        Status = CdfsFindFile(DeviceExtension,
            &TempFcb,
            Fcb,
            &Ccb->DirectorySearchPattern,
            &Ccb->Entry,
            &Ccb->Offset);
        DPRINT("Found %S, Status=%x, entry %x\n", TempFcb.ObjectName, Status, Ccb->Entry);

        if (NT_SUCCESS(Status))
        {
            switch (FileInformationClass)
            {
            case FileNameInformation:
                Status = CdfsGetNameInformation(&TempFcb,
                    DeviceExtension,
                    (PFILE_NAMES_INFORMATION)Buffer,
                    BufferLength);
                break;

            case FileDirectoryInformation:
                Status = CdfsGetDirectoryInformation(&TempFcb,
                    DeviceExtension,
                    (PFILE_DIRECTORY_INFORMATION)Buffer,
                    BufferLength);
                break;

            case FileFullDirectoryInformation:
                Status = CdfsGetFullDirectoryInformation(&TempFcb,
                    DeviceExtension,
                    (PFILE_FULL_DIR_INFORMATION)Buffer,
                    BufferLength);
                break;

            case FileBothDirectoryInformation:
                Status = CdfsGetBothDirectoryInformation(&TempFcb,
                    DeviceExtension,
                    (PFILE_BOTH_DIR_INFORMATION)Buffer,
                    BufferLength);
                break;

            default:
                Status = STATUS_INVALID_INFO_CLASS;
            }

            if (Status == STATUS_BUFFER_OVERFLOW)
            {
                if (Buffer0)
                {
                    Buffer0->NextEntryOffset = 0;
                }
                break;
            }
        }
        else
        {
            if (Buffer0)
            {
                Buffer0->NextEntryOffset = 0;
            }

            if (First)
            {
                Status = STATUS_NO_SUCH_FILE;
            }
            else
            {
                Status = STATUS_NO_MORE_FILES;
            }
            break;
        }

        Buffer0 = (PFILE_NAMES_INFORMATION)Buffer;
        Buffer0->FileIndex = FileIndex++;
        Ccb->Entry++;

        if (Stack->Flags & SL_RETURN_SINGLE_ENTRY)
        {
            break;
        }
        BufferLength -= Buffer0->NextEntryOffset;
        Buffer += Buffer0->NextEntryOffset;
    }

    if (Buffer0)
    {
        Buffer0->NextEntryOffset = 0;
    }

    if (FileIndex > 0)
    {
        Status = STATUS_SUCCESS;
    }

    return(Status);
}
Пример #7
0
LONG
APIENTRY
NtUserChangeDisplaySettings(
    PUNICODE_STRING pustrDevice,
    LPDEVMODEW lpDevMode,
    DWORD dwflags,
    LPVOID lParam)
{
    WCHAR awcDevice[CCHDEVICENAME];
    UNICODE_STRING ustrDevice;
    DEVMODEW dmLocal;
    LONG lRet;

    /* Check arguments */
    if ((dwflags != CDS_VIDEOPARAMETERS) && (lParam != NULL))
    {
        EngSetLastError(ERROR_INVALID_PARAMETER);
        return DISP_CHANGE_BADPARAM;
    }

    /* Check flags */
    if ((dwflags & (CDS_GLOBAL|CDS_NORESET)) && !(dwflags & CDS_UPDATEREGISTRY))
    {
        return DISP_CHANGE_BADFLAGS;
    }

    /* Copy the device name */
    if (pustrDevice)
    {
        /* Initialize destination string */
        RtlInitEmptyUnicodeString(&ustrDevice, awcDevice, sizeof(awcDevice));

        _SEH2_TRY
        {
            /* Probe the UNICODE_STRING and the buffer */
            ProbeForRead(pustrDevice, sizeof(UNICODE_STRING), 1);
            ProbeForRead(pustrDevice->Buffer, pustrDevice->Length, 1);

            /* Copy the string */
            RtlCopyUnicodeString(&ustrDevice, pustrDevice);
        }
        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
        {
            /* Set and return error */
            SetLastNtError(_SEH2_GetExceptionCode());
            _SEH2_YIELD(return DISP_CHANGE_BADPARAM);
        }
        _SEH2_END

        pustrDevice = &ustrDevice;
   }

    /* Copy devmode */
    if (lpDevMode)
    {
        _SEH2_TRY
        {
            /* Probe the size field of the structure */
            ProbeForRead(lpDevMode, sizeof(dmLocal.dmSize), 1);

            /* Calculate usable size */
            dmLocal.dmSize = min(sizeof(dmLocal), lpDevMode->dmSize);

            /* Probe and copy the full DEVMODE */
            ProbeForRead(lpDevMode, dmLocal.dmSize, 1);
            RtlCopyMemory(&dmLocal, lpDevMode, dmLocal.dmSize);
        }
        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
        {
            /* Set and return error */
            SetLastNtError(_SEH2_GetExceptionCode());
            _SEH2_YIELD(return DISP_CHANGE_BADPARAM);
        }
        _SEH2_END

        /* Check for extra parameters */
        if (dmLocal.dmDriverExtra > 0)
        {
            /* FIXME: TODO */
            ERR("lpDevMode->dmDriverExtra is IGNORED!\n");
            dmLocal.dmDriverExtra = 0;
        }

        /* Use the local structure */
        lpDevMode = &dmLocal;
    }

    // FIXME: Copy videoparameters

    /* Acquire global USER lock */
    UserEnterExclusive();

    /* Call internal function */
    lRet = UserChangeDisplaySettings(pustrDevice, lpDevMode, dwflags, NULL);

    /* Release lock */
    UserLeave();

    return lRet;
}
Пример #8
0
//NTSTATUS
BOOL
NTAPI
NtUserEnumDisplayDevices(
    PUNICODE_STRING pustrDevice,
    DWORD iDevNum,
    PDISPLAY_DEVICEW pDisplayDevice,
    DWORD dwFlags)
{
    UNICODE_STRING ustrDevice;
    WCHAR awcDevice[CCHDEVICENAME];
    DISPLAY_DEVICEW dispdev;
    NTSTATUS Status;

    TRACE("Enter NtUserEnumDisplayDevices(%wZ, %lu)\n",
          pustrDevice, iDevNum);

    dispdev.cb = sizeof(dispdev);

    if (pustrDevice)
    {
        /* Initialize destination string */
        RtlInitEmptyUnicodeString(&ustrDevice, awcDevice, sizeof(awcDevice));

        _SEH2_TRY
        {
            /* Probe the UNICODE_STRING and the buffer */
            ProbeForRead(pustrDevice, sizeof(UNICODE_STRING), 1);
            ProbeForRead(pustrDevice->Buffer, pustrDevice->Length, 1);

            /* Copy the string */
            RtlCopyUnicodeString(&ustrDevice, pustrDevice);
        }
        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
        {
//            _SEH2_YIELD(return _SEH2_GetExceptionCode());
            _SEH2_YIELD(return NT_SUCCESS(_SEH2_GetExceptionCode()));
        }
        _SEH2_END

        if (ustrDevice.Length > 0)
            pustrDevice = &ustrDevice;
        else
            pustrDevice = NULL;
   }

    /* If name is given only iDevNum==0 gives results */
    if (pustrDevice && iDevNum != 0)
        return FALSE;

    /* Acquire global USER lock */
    UserEnterShared();

    /* Call the internal function */
    Status = UserEnumDisplayDevices(pustrDevice, iDevNum, &dispdev, dwFlags);

    /* Release lock */
    UserLeave();

    /* On success copy data to caller */
    if (NT_SUCCESS(Status))
    {
        /* Enter SEH */
        _SEH2_TRY
        {
            /* First probe the cb field */
            ProbeForWrite(&pDisplayDevice->cb, sizeof(DWORD), 1);

            /* Check the buffer size */
            if (pDisplayDevice->cb)
            {
                /* Probe the output buffer */
                pDisplayDevice->cb = min(pDisplayDevice->cb, sizeof(dispdev));
                ProbeForWrite(pDisplayDevice, pDisplayDevice->cb, 1);

                /* Copy as much as the given buffer allows */
                RtlCopyMemory(pDisplayDevice, &dispdev, pDisplayDevice->cb);
            }
        }
        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
        {
            Status = _SEH2_GetExceptionCode();
        }
        _SEH2_END
    }

    TRACE("Leave NtUserEnumDisplayDevices, Status = 0x%lx\n", Status);
    /* Return the result */
//    return Status;
    return NT_SUCCESS(Status); // FIXME
}
Пример #9
0
NTSTATUS
NTAPI
CmpInitializeHive(OUT PCMHIVE *RegistryHive,
                  IN ULONG OperationType,
                  IN ULONG HiveFlags,
                  IN ULONG FileType,
                  IN PVOID HiveData OPTIONAL,
                  IN HANDLE Primary,
                  IN HANDLE Log,
                  IN HANDLE External,
                  IN PCUNICODE_STRING FileName OPTIONAL,
                  IN ULONG CheckFlags)
{
    PCMHIVE Hive;
    FILE_STANDARD_INFORMATION FileInformation;
    IO_STATUS_BLOCK IoStatusBlock;
    FILE_FS_SIZE_INFORMATION FileSizeInformation;
    NTSTATUS Status;
    ULONG Cluster;

    /* Assume failure */
    *RegistryHive = NULL;

    /*
     * The following are invalid:
     * An external hive that is also internal.
     * A log hive that's not a primary hive too.
     * A volatile hive that's linked to permanent storage.
     * An in-memory initialization without hive data.
     * A log hive that's not linked to a correct file type.
     */
    if (((External) && ((Primary) || (Log))) ||
        ((Log) && !(Primary)) ||
        ((HiveFlags & HIVE_VOLATILE) && ((Primary) || (External) || (Log))) ||
        ((OperationType == HINIT_MEMORY) && (!HiveData)) ||
        ((Log) && (FileType != HFILE_TYPE_LOG)))
    {
        /* Fail the request */
        return STATUS_INVALID_PARAMETER;
    }

    /* Check if this is a primary hive */
    if (Primary)
    {
        /* Get the cluster size */
        Status = ZwQueryVolumeInformationFile(Primary,
                                              &IoStatusBlock,
                                              &FileSizeInformation,
                                              sizeof(FILE_FS_SIZE_INFORMATION),
                                              FileFsSizeInformation);
        if (!NT_SUCCESS(Status)) return Status;

        /* Make sure it's not larger then the block size */
        if (FileSizeInformation.BytesPerSector > HBLOCK_SIZE)
        {
            /* Fail */
            return STATUS_REGISTRY_IO_FAILED;
        }

        /* Otherwise, calculate the cluster */
        Cluster = FileSizeInformation.BytesPerSector / HSECTOR_SIZE;
        Cluster = max(1, Cluster);
    }
    else
    {
        /* Otherwise use cluster 1 */
        Cluster = 1;
    }

    /* Allocate the hive */
    Hive = ExAllocatePoolWithTag(NonPagedPool, sizeof(CMHIVE), TAG_CM);
    if (!Hive) return STATUS_INSUFFICIENT_RESOURCES;

    /* Setup null fields */
    Hive->UnloadEvent = NULL;
    Hive->RootKcb = NULL;
    Hive->Frozen = FALSE;
    Hive->UnloadWorkItem = NULL;
    Hive->GrowOnlyMode = FALSE;
    Hive->GrowOffset = 0;
    Hive->CellRemapArray = NULL;
    Hive->UseCountLog.Next = 0;
    Hive->LockHiveLog.Next = 0;
    Hive->FileObject = NULL;
    Hive->NotifyList.Flink = NULL;
    Hive->NotifyList.Blink = NULL;

    /* Set loading flag */
    Hive->HiveIsLoading = TRUE;

    /* Set the current thread as creator */
    Hive->CreatorOwner = KeGetCurrentThread();

    /* Initialize lists */
    InitializeListHead(&Hive->KcbConvertListHead);
    InitializeListHead(&Hive->KnodeConvertListHead);
    InitializeListHead(&Hive->TrustClassEntry);

    /* Allocate the view log */
    Hive->ViewLock = ExAllocatePoolWithTag(NonPagedPool,
                                           sizeof(KGUARDED_MUTEX),
                                           TAG_CM);
    if (!Hive->ViewLock)
    {
        /* Cleanup allocation and fail */
        ExFreePoolWithTag(Hive, TAG_CM);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    /* Allocate the flush lock */
    Hive->FlusherLock = ExAllocatePoolWithTag(NonPagedPool,
                                              sizeof(ERESOURCE),
                                              TAG_CM);
    if (!Hive->FlusherLock)
    {
        /* Cleanup allocations and fail */
        ExFreePoolWithTag(Hive->ViewLock, TAG_CM);
        ExFreePoolWithTag(Hive, TAG_CM);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    /* Setup the handles */
    Hive->FileHandles[HFILE_TYPE_PRIMARY] = Primary;
    Hive->FileHandles[HFILE_TYPE_LOG] = Log;
    Hive->FileHandles[HFILE_TYPE_EXTERNAL] = External;

    /* Initailize the guarded mutex */
    KeInitializeGuardedMutex(Hive->ViewLock);
    Hive->ViewLockOwner = NULL;

    /* Initialize the flush lock */
    ExInitializeResourceLite(Hive->FlusherLock);

    /* Setup hive locks */
    ExInitializePushLock(&Hive->HiveLock);
    Hive->HiveLockOwner = NULL;
    ExInitializePushLock(&Hive->WriterLock);
    Hive->WriterLockOwner = NULL;
    ExInitializePushLock(&Hive->SecurityLock);
    Hive->HiveSecurityLockOwner = NULL;

    /* Clear file names */
    RtlInitEmptyUnicodeString(&Hive->FileUserName, NULL, 0);
    RtlInitEmptyUnicodeString(&Hive->FileFullPath, NULL, 0);

    /* Initialize the view list */
    CmpInitHiveViewList(Hive);

    /* Initailize the security cache */
    CmpInitSecurityCache(Hive);

    /* Setup flags */
    Hive->Flags = 0;
    Hive->FlushCount = 0;

    /* Set flags */
    Hive->Flags = HiveFlags;

    /* Check if this is a primary */
    if (Primary)
    {
        /* Check how large the file is */
        ZwQueryInformationFile(Primary,
                               &IoStatusBlock,
                               &FileInformation,
                               sizeof(FileInformation),
                               FileStandardInformation);
        Cluster = FileInformation.EndOfFile.LowPart;
    }

    /* Initialize it */
    Status = HvInitialize(&Hive->Hive,
                          OperationType,
                          FileType,
                          HiveFlags,
                          HiveData,
                          CmpAllocate,
                          CmpFree,
                          CmpFileSetSize,
                          CmpFileWrite,
                          CmpFileRead,
                          CmpFileFlush,
                          Cluster,
                          FileName);
    if (!NT_SUCCESS(Status))
    {
        /* Cleanup allocations and fail */
        ExDeleteResourceLite(Hive->FlusherLock);
        ExFreePoolWithTag(Hive->FlusherLock, TAG_CM);
        ExFreePoolWithTag(Hive->ViewLock, TAG_CM);
        ExFreePoolWithTag(Hive, TAG_CM);
        return Status;
    }

    /* Check if we should verify the registry */
    if ((OperationType == HINIT_FILE) ||
        (OperationType == HINIT_MEMORY) ||
        (OperationType == HINIT_MEMORY_INPLACE) ||
        (OperationType == HINIT_MAPFILE))
    {
        /* Verify integrity */
        ULONG CheckStatus = CmCheckRegistry(Hive, CheckFlags);
        if (CheckStatus != 0)
        {
            /* Cleanup allocations and fail */
            ExDeleteResourceLite(Hive->FlusherLock);
            ExFreePoolWithTag(Hive->FlusherLock, TAG_CM);
            ExFreePoolWithTag(Hive->ViewLock, TAG_CM);
            ExFreePoolWithTag(Hive, TAG_CM);
            return STATUS_REGISTRY_CORRUPT;
        }
    }

    /* Lock the hive list */
    ExAcquirePushLockExclusive(&CmpHiveListHeadLock);

    /* Insert this hive */
    InsertHeadList(&CmpHiveListHead, &Hive->HiveList);

    /* Release the lock */
    ExReleasePushLock(&CmpHiveListHeadLock);

    /* Return the hive and success */
    *RegistryHive = (PCMHIVE)Hive;
    return STATUS_SUCCESS;
}
Пример #10
0
VOID
NTAPI
IopLogWorker(IN PVOID Parameter)
{
#define IO_ERROR_OBJECT_NAMES_LENGTH    100

    NTSTATUS Status;
    PELF_API_MSG Message;
    PIO_ERROR_LOG_MESSAGE ErrorMessage;
    PLIST_ENTRY ListEntry;
    PERROR_LOG_ENTRY LogEntry;
    PIO_ERROR_LOG_PACKET Packet;
    PCHAR StringBuffer;
    ULONG RemainingLength;
    PDRIVER_OBJECT DriverObject;
    PWCHAR NameString;
    ULONG DriverNameLength, DeviceNameLength;
    UCHAR Buffer[sizeof(OBJECT_NAME_INFORMATION) + IO_ERROR_OBJECT_NAMES_LENGTH];
    POBJECT_NAME_INFORMATION ObjectNameInfo = (POBJECT_NAME_INFORMATION)&Buffer;
    POBJECT_NAME_INFORMATION PoolObjectNameInfo;
    ULONG ReturnedLength, MessageLength;
    ULONG ExtraStringLength;
    PWCHAR p;

    PAGED_CODE();

    UNREFERENCED_PARAMETER(Parameter);

    /* Connect to the port */
    if (!IopConnectLogPort()) return;

    /* Allocate the message */
    Message = ExAllocatePoolWithTag(PagedPool, IO_ERROR_LOG_MESSAGE_LENGTH, TAG_IO);
    if (!Message)
    {
        /* Couldn't allocate, try again */
        IopRestartLogWorker();
        return;
    }

    /* Zero out the message and get the actual I/O structure */
    RtlZeroMemory(Message, sizeof(*Message));
    ErrorMessage = &Message->IoErrorMessage;

    /* Start loop */
    while (TRUE)
    {
        /* Get an entry */
        ListEntry = IopGetErrorLogEntry();
        if (!ListEntry) break;
        LogEntry = CONTAINING_RECORD(ListEntry, ERROR_LOG_ENTRY, ListEntry);

        /* Get pointer to the log packet */
        Packet = (PIO_ERROR_LOG_PACKET)((ULONG_PTR)LogEntry +
                                        sizeof(ERROR_LOG_ENTRY));

        /* Calculate the total length of the message only */
        MessageLength = sizeof(IO_ERROR_LOG_MESSAGE) -
                        sizeof(ERROR_LOG_ENTRY) -
                        sizeof(IO_ERROR_LOG_PACKET) +
                        LogEntry->Size;

        /* Copy the packet */
        RtlCopyMemory(&ErrorMessage->EntryData,
                      Packet,
                      LogEntry->Size - sizeof(ERROR_LOG_ENTRY));

        /* Set the timestamp and time */
        ErrorMessage->TimeStamp = LogEntry->TimeStamp;
        ErrorMessage->Type = IO_TYPE_ERROR_MESSAGE;

        /* Check if this message has any strings */
        if (Packet->NumberOfStrings)
        {
            /* String buffer is after the current strings */
            StringBuffer = (PCHAR)&ErrorMessage->EntryData +
                            Packet->StringOffset;
        }
        else
        {
            /* Otherwise, string buffer is at the end */
            StringBuffer = (PCHAR)ErrorMessage + MessageLength;
        }

        /* Align the buffer */
        StringBuffer = ALIGN_UP_POINTER(StringBuffer, WCHAR);

        /* Set the offset for the driver's name to the current buffer */
        ErrorMessage->DriverNameOffset = (ULONG)(StringBuffer -
                                                (PCHAR)ErrorMessage);

        /* Check how much space we have left for the device string */
        RemainingLength = (ULONG)((ULONG_PTR)Message +
                                  IO_ERROR_LOG_MESSAGE_LENGTH -
                                  (ULONG_PTR)StringBuffer);

        NameString = NULL;
        DriverNameLength = 0; DeviceNameLength = 0;
        PoolObjectNameInfo = NULL;
        ObjectNameInfo = (POBJECT_NAME_INFORMATION)&Buffer;

        /* Now check if there is a driver object */
        DriverObject = LogEntry->DriverObject;
        if (DriverObject)
        {
            /* Check if the driver has a name, and use it if so */
            if (DriverObject->DriverName.Buffer)
            {
                NameString = DriverObject->DriverName.Buffer;
                DriverNameLength = DriverObject->DriverName.Length;
            }
            else
            {
                NameString = NULL;
                DriverNameLength = 0;
            }

            /* Check if there isn't a valid name */
            if (!DriverNameLength)
            {
                /* Query the name directly */
                Status = ObQueryNameString(DriverObject,
                                           ObjectNameInfo,
                                           sizeof(Buffer),
                                           &ReturnedLength);
                if (!NT_SUCCESS(Status) || (ObjectNameInfo->Name.Length == 0))
                {
                    /* We don't have a name */
                    DriverNameLength = 0;
                }
                else
                {
                    NameString = ObjectNameInfo->Name.Buffer;
                    DriverNameLength = ObjectNameInfo->Name.Length;
                }
            }
        }
        else
        {
            /* Use default name */
            NameString = L"Application Popup";
            DriverNameLength = (ULONG)wcslen(NameString) * sizeof(WCHAR);
        }

        /* Check if we have a driver name */
        if (DriverNameLength)
        {
            /* Skip to the end of the driver's name */
            p = &NameString[DriverNameLength / sizeof(WCHAR)];

            /* Now we'll walk backwards and assume the minimum size */
            DriverNameLength = sizeof(WCHAR);
            p--;
            while ((*p != L'\\') && (p != NameString))
            {
                /* No backslash found, keep going */
                p--;
                DriverNameLength += sizeof(WCHAR);
            }

            /* Now we probably hit the backslash itself, skip past it */
            if (*p == L'\\')
            {
                p++;
                DriverNameLength -= sizeof(WCHAR);
            }

            /*
             * Now make sure that the driver name fits in the buffer, minus
             * 3 NULL chars (driver name, device name, and remaining strings),
             * and copy the driver name in the string buffer.
             */
            DriverNameLength = min(DriverNameLength,
                                   RemainingLength - 3 * sizeof(UNICODE_NULL));
            RtlCopyMemory(StringBuffer, p, DriverNameLength);
        }

        /* Null-terminate the driver name */
        *((PWSTR)(StringBuffer + DriverNameLength)) = UNICODE_NULL;
        DriverNameLength += sizeof(WCHAR);

        /* Go to the next string buffer position */
        StringBuffer += DriverNameLength;
        RemainingLength -= DriverNameLength;

        /* Update the string offset */
        ErrorMessage->EntryData.StringOffset =
            (USHORT)((ULONG_PTR)StringBuffer - (ULONG_PTR)ErrorMessage);

        /* Check if we have a device object */
        if (LogEntry->DeviceObject)
        {
            /* We do, query its name */
            Status = ObQueryNameString(LogEntry->DeviceObject,
                                       ObjectNameInfo,
                                       sizeof(Buffer) - DriverNameLength,
                                       &ReturnedLength);
            if (!NT_SUCCESS(Status) || (ObjectNameInfo->Name.Length == 0))
            {
                /* Setup an empty name */
                RtlInitEmptyUnicodeString(&ObjectNameInfo->Name, L"", 0);

                /* Check if we failed because our buffer wasn't large enough */
                if (Status == STATUS_INFO_LENGTH_MISMATCH)
                {
                    /* Then we'll allocate one... we really want this name! */
                    PoolObjectNameInfo = ExAllocatePoolWithTag(PagedPool,
                                                               ReturnedLength,
                                                               TAG_IO);
                    if (PoolObjectNameInfo)
                    {
                        /* Query it again */
                        ObjectNameInfo = PoolObjectNameInfo;
                        Status = ObQueryNameString(LogEntry->DeviceObject,
                                                   ObjectNameInfo,
                                                   ReturnedLength,
                                                   &ReturnedLength);
                        if (NT_SUCCESS(Status))
                        {
                            /* Success, update the information */
                            ObjectNameInfo->Name.Length =
                                IO_ERROR_OBJECT_NAMES_LENGTH - (USHORT)DriverNameLength;
                        }
                    }
                }
            }

            NameString = ObjectNameInfo->Name.Buffer;
            DeviceNameLength = ObjectNameInfo->Name.Length;
        }
        else
        {
            /* No device object, setup an empty name */
            NameString = L"";
            DeviceNameLength = 0;
        }

        /*
         * Now make sure that the device name fits in the buffer, minus
         * 2 NULL chars (device name, and remaining strings), and copy
         * the device name in the string buffer.
         */
        DeviceNameLength = min(DeviceNameLength,
                               RemainingLength - 2 * sizeof(UNICODE_NULL));
        RtlCopyMemory(StringBuffer, NameString, DeviceNameLength);

        /* Null-terminate the device name */
        *((PWSTR)(StringBuffer + DeviceNameLength)) = UNICODE_NULL;
        DeviceNameLength += sizeof(WCHAR);

        /* Free the buffer if we had one */
        if (PoolObjectNameInfo)
        {
            ExFreePoolWithTag(PoolObjectNameInfo, TAG_IO);
            PoolObjectNameInfo = NULL;
        }

        /* Go to the next string buffer position */
        ErrorMessage->EntryData.NumberOfStrings++;
        StringBuffer += DeviceNameLength;
        RemainingLength -= DeviceNameLength;

        /* Check if we have any extra strings */
        if (Packet->NumberOfStrings)
        {
            /* Find out the size of the extra strings */
            ExtraStringLength = LogEntry->Size -
                                sizeof(ERROR_LOG_ENTRY) -
                                Packet->StringOffset;

            /* Round up the length */
            ExtraStringLength = ROUND_UP(ExtraStringLength, sizeof(WCHAR));

            /* Make sure that the extra strings fit in our buffer */
            if (ExtraStringLength > (RemainingLength - sizeof(UNICODE_NULL)))
            {
                /* They wouldn't, so set normalize the length */
                MessageLength -= ExtraStringLength - RemainingLength;
                ExtraStringLength = RemainingLength - sizeof(UNICODE_NULL);
            }

            /* Now copy the extra strings */
            RtlCopyMemory(StringBuffer,
                          (PCHAR)Packet + Packet->StringOffset,
                          ExtraStringLength);

            /* Null-terminate them */
            *((PWSTR)(StringBuffer + ExtraStringLength)) = UNICODE_NULL;
        }

        /* Set the driver name length */
        ErrorMessage->DriverNameLength = (USHORT)DriverNameLength;

        /* Update the message length to include the driver and device names */
        MessageLength += DriverNameLength + DeviceNameLength;
        ErrorMessage->Size = (USHORT)MessageLength;

        /* Now update it again for the size of the actual LPC */
        MessageLength += (FIELD_OFFSET(ELF_API_MSG, IoErrorMessage) -
                          FIELD_OFFSET(ELF_API_MSG, Unknown[0]));

        /* Set the total and data lengths */
        Message->Header.u1.s1.TotalLength =
            (USHORT)(sizeof(PORT_MESSAGE) + MessageLength);
        Message->Header.u1.s1.DataLength = (USHORT)MessageLength;

        /* Send the message */
        Status = ZwRequestPort(IopLogPort, &Message->Header);
        if (!NT_SUCCESS(Status))
        {
            /*
             * An error happened while sending the message on the port.
             * Close the port, requeue the log message on top of the list
             * and restart the worker.
             */
            ZwClose(IopLogPort);
            IopLogPortConnected = FALSE;

            ExInterlockedInsertHeadList(&IopErrorLogListHead,
                                        &LogEntry->ListEntry,
                                        &IopLogListLock);

            IopRestartLogWorker();
            break;
        }

        /* NOTE: The following is basically 'IoFreeErrorLogEntry(Packet)' */

        /* Dereference both objects */
        if (LogEntry->DeviceObject) ObDereferenceObject(LogEntry->DeviceObject);
        if (LogEntry->DriverObject) ObDereferenceObject(LogEntry->DriverObject);

        /* Decrease the total allocation size and free the entry */
        InterlockedExchangeAdd(&IopTotalLogSize, -(LONG)LogEntry->Size);
        ExFreePoolWithTag(LogEntry, TAG_ERROR_LOG);
    }

    /* Free the LPC Message */
    ExFreePoolWithTag(Message, TAG_IO);
}
Пример #11
0
NTSTATUS
SampleDrvEvtDeviceD0Entry (
    _In_ WDFDEVICE Device,
    _In_ WDF_POWER_DEVICE_STATE PreviousPowerState
    )

/*++

Routine Description:

    This routine is invoked by the framework to program the device to goto
    D0, which is the working state. The framework invokes callback every
    time the hardware needs to be (re-)initialized.  This includes after
    IRP_MN_START_DEVICE, IRP_MN_CANCEL_STOP_DEVICE, IRP_MN_CANCEL_REMOVE_DEVICE,
    and IRP_MN_SET_POWER-D0.

    N.B. This function is not marked pageable because this function is in
         the device power up path. When a function is marked pagable and the
         code section is paged out, it will generate a page fault which could
         impact the fast resume behavior because the client driver will have
         to wait until the system drivers can service this page fault.

Arguments:

    Device - Supplies a handle to the framework device object.

    PreviousPowerState - WDF_POWER_DEVICE_STATE-typed enumerator that identifies
        the device power state that the device was in before this transition
        to D0.

Return Value:

    NTSTATUS code. A failure here will indicate a fatal error and cause the
    framework to tear down the stack.

--*/

{

    BYTE Data;
    NTSTATUS Status;
    WDFIOTARGET ReadTarget;
    WDFIOTARGET WriteTarget;
    PSAMPLE_DRV_DEVICE_EXTENSION SampleDrvExtension;
    UNICODE_STRING ReadString;
    WCHAR ReadStringBuffer[100];
    UNICODE_STRING WriteString;
    WCHAR WriteStringBuffer[100];

    UNREFERENCED_PARAMETER(PreviousPowerState);

    ReadTarget = NULL;
    WriteTarget = NULL;

    SampleDrvExtension = SampleDrvGetDeviceExtension(Device);

    //
    //  For demonstration purporses, the sample device consumes two IO resources,
    //  the first of which will be used for input, and the second for output.
    //

    RtlInitEmptyUnicodeString(&ReadString,
                              ReadStringBuffer,
                              sizeof(ReadStringBuffer));

    RtlInitEmptyUnicodeString(&WriteString,
                              WriteStringBuffer,
                              sizeof(WriteStringBuffer));


    //
    //  Construct full-path string for GPIO read operation
    //

    Status = RESOURCE_HUB_CREATE_PATH_FROM_ID(&ReadString,
                                              SampleDrvExtension->ConnectionIds[0].LowPart,
                                              SampleDrvExtension->ConnectionIds[0].HighPart);

    if (!NT_SUCCESS(Status)) {
        goto Cleanup;
    }

    //
    //  Construct full-path string for GPIO write operation
    //

    Status = RESOURCE_HUB_CREATE_PATH_FROM_ID(&WriteString,
                                              SampleDrvExtension->ConnectionIds[1].LowPart,
                                              SampleDrvExtension->ConnectionIds[1].HighPart);

    if (!NT_SUCCESS(Status)) {
        goto Cleanup;
    }

    //
    // Perform the read operation
    //

    Data = 0x0;
    Status = TestReadWrite(Device, &ReadString, TRUE, &Data, sizeof(Data), &ReadTarget);
    if (!NT_SUCCESS(Status)) {
        goto Cleanup;
    }

    //
    //  Perform the write operation
    //

    Status = TestReadWrite(Device, &WriteString, FALSE, &Data, sizeof(Data), &WriteTarget);
    if (!NT_SUCCESS(Status)) {
        goto Cleanup;
    }

Cleanup:

    if (ReadTarget != NULL) {
        WdfIoTargetClose(ReadTarget);
        WdfObjectDelete(ReadTarget);
    }

    if (WriteTarget != NULL) {
        WdfIoTargetClose(WriteTarget);
        WdfObjectDelete(WriteTarget);
    }

    return Status;
}
Пример #12
0
NTSTATUS
NcStreamHandleContextEnumSetup (
    _Inout_ PNC_DIR_QRY_CONTEXT DirContext,
    _In_ PNC_INSTANCE_CONTEXT InstanceContext,
    _In_ PDIRECTORY_CONTROL_OFFSETS Offsets,
    _In_ PFLT_CALLBACK_DATA Data,
    _In_ PCFLT_RELATED_OBJECTS FltObjects,
    _In_ NC_PATH_OVERLAP UserMappingOverlap,
    _Out_ PBOOLEAN FirstUsage
    )
/*++

Routine Description:

    Acquires the stream handle context and initializes it for a directory
    enumeration.

Arguments:

    DirContext - Pointer to the directory context.

    InstanceContext - Pointer to this instance's context.

    Offsets - Offsets structure for this enumeration class.

    Data - Callback data for this operation.

    FltObjects - FltObjects structure for this operation.

    UserMappingOverlap - The overlap between the user mapping and this file
        object.

    FirstUsage - Weather or not this is the first usage of this handle in a
        directory enumeration.

Return Value:

    The return value is the Status of the operation.

--*/
{
    NTSTATUS Status = STATUS_SUCCESS;

    PUNICODE_STRING SearchString = Data->Iopb->Parameters.DirectoryControl.QueryDirectory.FileName;
    FILE_INFORMATION_CLASS InformationClass = Data->Iopb->Parameters.DirectoryControl.QueryDirectory.FileInformationClass;
    BOOLEAN ResetSearch = BooleanFlagOn( Data->Iopb->OperationFlags, SL_RESTART_SCAN );
    BOOLEAN IgnoreCase = !BooleanFlagOn( FltObjects->FileObject->Flags,
                                         FO_OPENED_CASE_SENSITIVE );

    PAGED_CODE();

    //
    //  This context could be in its first use. If it is, then we need to 
    //  setup the search string and information class. 
    //
    
    if (DirContext->InUse == FALSE) {

        //
        //  This was the first usage of the context.
        //  We should set up the search string.
        //

        if (SearchString != NULL) {

            DirContext->SearchString.Buffer = ExAllocatePoolWithTag( PagedPool,
                                                                     SearchString->Length,
                                                                     NC_DIR_QRY_SEARCH_STRING );

            if (DirContext->SearchString.Buffer == NULL) {

                Status = STATUS_INSUFFICIENT_RESOURCES;
                goto NcStreamHandleContextEnumSetupCleanup;
            }
            
            DirContext->SearchString.MaximumLength = SearchString->Length;

            if (IgnoreCase) {

                RtlUpcaseUnicodeString( &DirContext->SearchString, SearchString, FALSE );

            } else {

                RtlCopyUnicodeString( &DirContext->SearchString, SearchString );
            }

            DirContext->SearchString.Length = SearchString->Length;

        } else {

            RtlInitEmptyUnicodeString( &DirContext->SearchString,
                                       NULL,
                                       0 );
        }

        DirContext->InformationClass = InformationClass;

        //
        //  We should write back to the caller so they know its the first usage.
        //

        *FirstUsage = TRUE;

    } else {

        //
        //  This is not the fist usage, so write back to user.
        //

        *FirstUsage = FALSE;

        //
        //  This is not the first query. Lets make sure that our data 
        //  is consistent. If the information classes don't line up
        //  then our cache might be inconsistant. We should fail this
        //  operation.
        //
        //  TODO: Is this correct?
        //

        if (DirContext->InformationClass != InformationClass) {

            Status = STATUS_INVALID_PARAMETER;
            goto NcStreamHandleContextEnumSetupCleanup;
        }
    }

    if (!DirContext->InUse || ResetSearch) {

        //
        //  Either this is the first use of the context,
        //  or they are reseting the enumeration. We 
        //  should clear the cache either way.
        //

        if (DirContext->Cache.Buffer != NULL) {
            
            ExFreePoolWithTag( DirContext->Cache.Buffer, NC_TAG );
            DirContext->Cache.Buffer = NULL;
            DirContext->Cache.CurrentOffset = 0;
        }

        if (DirContext->InjectionEntry.Buffer != NULL) {

            ExFreePoolWithTag( DirContext->InjectionEntry.Buffer, NC_TAG );
            DirContext->InjectionEntry.Buffer = NULL;
            DirContext->InjectionEntry.CurrentOffset = 0;
        }

        //
        //  Now that the cache is clear we can set up the injection entry.
        //  The injection entry is the user mapping itself. Thus it only needs
        //  to be injected if the directory being enumerated is the parent of
        //  the user mapping.
        //

        if (UserMappingOverlap.Parent) {

            Status = NcEnumerateDirectorySetupInjection( DirContext,
                                                         FltObjects,
                                                         InstanceContext,
                                                         Offsets,
                                                         InformationClass ); 
            if (!NT_SUCCESS( Status )) {
                
                goto NcStreamHandleContextEnumSetupCleanup;
            }
        }
    }

    // 
    //  Now we know that the entry is setup.
    //  Mark it as in use.
    //
    
    DirContext->InUse = TRUE;
    Status = STATUS_SUCCESS;

NcStreamHandleContextEnumSetupCleanup:

    if (!NT_SUCCESS( Status )) {

        if (!DirContext->InUse) {

            //
            //  We failed to set up the context for first use.
            //  We should free our buffer we allocated.
            //

            if (DirContext->SearchString.Buffer != NULL) {

                ExFreePoolWithTag( DirContext->SearchString.Buffer, NC_TAG );
                DirContext->SearchString.Buffer = NULL;
                DirContext->SearchString.Length = 0;
                DirContext->SearchString.MaximumLength = 0;
            }
        }
    }

    return Status;
}
Пример #13
0
/*
 * NtUserLoadKeyboardLayoutEx
 *
 * Loads keyboard layout with given locale id
 */
HKL
APIENTRY
NtUserLoadKeyboardLayoutEx(
    IN HANDLE Handle, // hFile (See downloads.securityfocus.com/vulnerabilities/exploits/43774.c)
    IN DWORD offTable, // Offset to KbdTables
    IN PUNICODE_STRING puszKeyboardName, // Not used?
    IN HKL hklUnload,
    IN PUNICODE_STRING pustrKLID,
    IN DWORD hkl,
    IN UINT Flags)
{
    HKL hklRet = NULL;
    PKL pKl = NULL, pklLast;
    WCHAR Buffer[9];
    UNICODE_STRING ustrSafeKLID;

    if (Flags & ~(KLF_ACTIVATE|KLF_NOTELLSHELL|KLF_REORDER|KLF_REPLACELANG|
                  KLF_SUBSTITUTE_OK|KLF_SETFORPROCESS|KLF_UNLOADPREVIOUS|
                  KLF_RESET|KLF_SETFORPROCESS|KLF_SHIFTLOCK))
    {
        ERR("Invalid flags: %x\n", Flags);
        EngSetLastError(ERROR_INVALID_FLAGS);
        return NULL;
    }

    /* FIXME: It seems KLF_RESET is only supported for WINLOGON */

    RtlInitEmptyUnicodeString(&ustrSafeKLID, Buffer, sizeof(Buffer));
    _SEH2_TRY
    {
        ProbeForRead(pustrKLID, sizeof(*pustrKLID), 1);
        ProbeForRead(pustrKLID->Buffer, sizeof(pustrKLID->Length), 1);
        RtlCopyUnicodeString(&ustrSafeKLID, pustrKLID);
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        SetLastNtError(_SEH2_GetExceptionCode());
        _SEH2_YIELD(return NULL);
    }
    _SEH2_END;

    UserEnterExclusive();

    /* If hklUnload is specified, unload it and load new layput as default */
    if (hklUnload && hklUnload != (HKL)hkl)
    {
        pKl = UserHklToKbl(hklUnload);
        if (pKl)
            UserUnloadKbl(pKl);
    }

    /* Let's see if layout was already loaded. */
    pKl = UserHklToKbl((HKL)hkl);
    if (!pKl)
    {
        /* It wasn't, so load it. */
        pKl = UserLoadKbdLayout(&ustrSafeKLID, (HKL)hkl);
        if (!pKl)
            goto cleanup;

        if (gspklBaseLayout)
        {
            /* Find last not unloaded layout */
            pklLast = gspklBaseLayout->pklPrev;
            while (pklLast != gspklBaseLayout && pklLast->dwKL_Flags & KLF_UNLOAD)
                pklLast = pklLast->pklPrev;

            /* Add new layout to the list */
            pKl->pklNext = pklLast->pklNext;
            pKl->pklPrev = pklLast;
            pKl->pklNext->pklPrev = pKl;
            pKl->pklPrev->pklNext = pKl;
        }
        else
        {
            /* This is the first layout */
            pKl->pklNext = pKl;
            pKl->pklPrev = pKl;
            gspklBaseLayout = pKl;
        }
    }

    /* If this layout was prepared to unload, undo it */
    pKl->dwKL_Flags &= ~KLF_UNLOAD;

    /* Activate this layout in current thread */
    if (Flags & KLF_ACTIVATE)
        co_UserActivateKbl(PsGetCurrentThreadWin32Thread(), pKl, Flags);

    /* Send shell message */
    if (!(Flags & KLF_NOTELLSHELL))
        co_IntShellHookNotify(HSHELL_LANGUAGE, 0, (LPARAM)hkl);

    /* Return hkl on success */
    hklRet = (HKL)hkl;

    /* FIXME: KLF_REPLACELANG
              KLF_REORDER */

cleanup:
    UserLeave();
    return hklRet;
}
Пример #14
0
VOID
SpySetName (
    __inout PRECORD_LIST RecordList,
    __in PDEVICE_OBJECT DeviceObject,
    __in_opt PFILE_OBJECT FileObject,
    __in ULONG LookupFlags,
    __in_opt PVOID Context
)
/*++

Routine Description:

    This routine looks up the FileObject in the hash table.  If the FileObject
    is found in the hash table, copy the associated file name to RecordList.
    Otherwise, calls NLGetFullPathName to try to get the name of the FileObject.
    If successful, copy the file name to the RecordList and insert into hash
    table.

Arguments:

    RecordList - RecordList to copy name to.
    FileObject - the FileObject to look up.
    LookInFileObject - see routine description
    DeviceExtension - contains the volume name (e.g., "c:") and
        the next device object which may be needed.

Return Value:

    None.

--*/
{
    PFILESPY_DEVICE_EXTENSION devExt = DeviceObject->DeviceExtension;
    UINT_PTR hashIndex;
    KIRQL oldIrql;
    PHASH_ENTRY pHash;
    PHASH_ENTRY newHash;
    PLIST_ENTRY listHead;
    PNAME_CONTROL newName = NULL;
    PCHAR buffer = NULL;
    NTSTATUS status;
    BOOLEAN cacheName;

    UNREFERENCED_PARAMETER( Context );

    try {

        if (FileObject == NULL) {

            SpyCopyFileNameToLogRecord( &RecordList->LogRecord, &gEmptyUnicode );
            leave;
        }

        hashIndex = HASH_FUNC(FileObject);

        INC_STATS(TotalContextSearches);

        listHead = &gHashTable[hashIndex];

        //
        //  Don't bother checking the hash if we are in create, we must always
        //  generate a name.
        //

        if (!FlagOn(LookupFlags, NLFL_IN_CREATE)) {

            //
            //  Acquire the hash lock
            //

            KeAcquireSpinLock( &gHashLockTable[hashIndex], &oldIrql );

            pHash = SpyHashBucketLookup( &gHashTable[hashIndex], FileObject );

            if (pHash != NULL) {

                //
                //  Copy the found file name to the LogRecord
                //

                SpyCopyFileNameToLogRecord( &RecordList->LogRecord, &pHash->Name );

                KeReleaseSpinLock( &gHashLockTable[hashIndex], oldIrql );

                INC_STATS( TotalContextFound );

                leave;
            }

            KeReleaseSpinLock( &gHashLockTable[hashIndex], oldIrql );
        }

#if WINVER >= 0x0501
        //
        //  We can not allocate paged pool if this is a paging file.  If it is
        //  a paging file set a default name and return
        //

#if __NDAS_FS__

        NDASFS_ASSERT( FALSE );

#else

        if (FsRtlIsPagingFile( FileObject )) {

            SpyCopyFileNameToLogRecord( &RecordList->LogRecord, &PagingFile );
            leave;
        }

#endif

#endif

        //
        //  We did not find the name in the hash.  Allocate name control buffer
        //  (for getting name) and a buffer for inserting this name into the
        //  hash.
        //

        buffer = SpyAllocateBuffer( &gNamesAllocated, gMaxNamesToAllocate, NULL );

        status = NLAllocateNameControl( &newName, &gFileSpyNameBufferLookasideList );

        if ((buffer != NULL) && NT_SUCCESS(status)) {

            //
            //  Init the new hash entry in case we need to use it
            //

            newHash = (PHASH_ENTRY)buffer;
            RtlInitEmptyUnicodeString( &newHash->Name,
                                       (PWCHAR)(buffer + sizeof(HASH_ENTRY)),
                                       RECORD_SIZE - sizeof(HASH_ENTRY) );

            //
            //  Retrieve the name
            //

            status = NLGetFullPathName( FileObject,
                                        newName,
                                        &devExt->NLExtHeader,
                                        LookupFlags | NLFL_USE_DOS_DEVICE_NAME,
                                        &gFileSpyNameBufferLookasideList,
                                        &cacheName );

            if (NT_SUCCESS( status ) && cacheName) {

                //
                //  We got a name and the name should be cached, save it in the
                //  log record and the hash buffer.
                //

                SpyCopyFileNameToLogRecord( &RecordList->LogRecord, &newName->Name );

                RtlCopyUnicodeString( &newHash->Name, &newName->Name );
                newHash->FileObject = FileObject;

                //
                //  Acquire the hash lock
                //

                KeAcquireSpinLock( &gHashLockTable[hashIndex], &oldIrql );

                //
                //  Search again because it may have been stored in the hash table
                //  since we did our last search and dropped the lock.
                //

                pHash = SpyHashBucketLookup( &gHashTable[hashIndex], FileObject );

                if (pHash != NULL) {

                    //
                    //  We found it in the hash table this time, don't need to
                    //  cache it again.
                    //

                    KeReleaseSpinLock( &gHashLockTable[hashIndex], oldIrql );

                    leave;
                }

                //
                //  It not found in the hash, add the new entry.
                //

                InsertHeadList( listHead, &newHash->List );

                gHashCurrentCounters[hashIndex]++;

                if (gHashCurrentCounters[hashIndex] > gHashMaxCounters[hashIndex]) {

                    gHashMaxCounters[hashIndex] = gHashCurrentCounters[hashIndex];
                }

                //
                //  Since we inserted the new hash entry, mark the buffer as empty
                //  so we won't try and free it
                //

                buffer = NULL;

                KeReleaseSpinLock( &gHashLockTable[hashIndex], oldIrql );

            } else {

                //
                //  Either the name should not be cached or we couldn't get a
                //  name, return whatever name they gave us
                //

                SpyCopyFileNameToLogRecord( &RecordList->LogRecord, &newName->Name );

                INC_STATS( TotalContextTemporary );
            }

        } else {

            //
            //  Set a default string even if there is no buffer.
            //

            SpyCopyFileNameToLogRecord( &RecordList->LogRecord, &OutOfBuffers );
        }

    }
    finally {

        //
        //  Free memory
        //

        if (buffer != NULL) {

            SpyFreeBuffer( buffer, &gNamesAllocated );
        }

        if (newName != NULL) {

            NLFreeNameControl( newName, &gFileSpyNameBufferLookasideList );
        }
    }
}
Пример #15
0
NTSTATUS
NdasPortFdoGetExtendedInterface(
	CONST GUID* ExternalTypeGuid,
	PFILE_OBJECT* ExternalFileObject,
	PDEVICE_OBJECT* ExternalDeviceObject,
	PNDAS_LU_QUERY_NDAS_LOGICALUNIT_INTERFACE* LogicalUnitInterface)
{
	NTSTATUS status;
	UNICODE_STRING externalDeviceTypeGuidString;
	WCHAR externalDeviceNameBuffer[64];
	UNICODE_STRING externalDeviceName;
	PIRP irp;
	KEVENT event;
	IO_STATUS_BLOCK ioStatus;
	NDASPORT_EXTERNAL_TYPE_GET_INTERFACE externalTypeGetInterface;

	PAGED_CODE();

	*ExternalFileObject = NULL;
	*ExternalDeviceObject = NULL;

	RtlInitEmptyUnicodeString(
		&externalDeviceName,
		externalDeviceNameBuffer,
		sizeof(externalDeviceNameBuffer));

	status = RtlStringFromGUID(
		ExternalTypeGuid,
		&externalDeviceTypeGuidString);

	if (!NT_SUCCESS(status))
	{
		return status;
	}

	status = RtlUnicodeStringCopyString(
		&externalDeviceName,
		L"\\Device\\NdasPort_");

	ASSERT(NT_SUCCESS(status));
	if (!NT_SUCCESS(status))
	{
		return status;
	}

	status = RtlUnicodeStringCat(
		&externalDeviceName,
		&externalDeviceTypeGuidString);

	RtlFreeUnicodeString(&externalDeviceTypeGuidString);

	ASSERT(NT_SUCCESS(status));
	if (!NT_SUCCESS(status))
	{
		return status;
	}

	status = IoGetDeviceObjectPointer(
		&externalDeviceName,
		FILE_ALL_ACCESS,
		ExternalFileObject,
		ExternalDeviceObject);

	if (!NT_SUCCESS(status))
	{
		return status;
	}

	KeInitializeEvent(&event, NotificationEvent, FALSE);

	externalTypeGetInterface.Size = sizeof(NDASPORT_EXTERNAL_TYPE_GET_INTERFACE);
	externalTypeGetInterface.Version = NDASPORT_EXTERNAL_TYPE_GET_INTERFACE_VERSION;
	externalTypeGetInterface.ExternalTypeGuid = *ExternalTypeGuid;
	externalTypeGetInterface.GetInterfaceFunction = NULL;
	
	irp = IoBuildDeviceIoControlRequest(
		NDASPORTEXT_IOCTL_GET_LOGICALUNIT_INTERFACE,
		*ExternalDeviceObject,
		&externalTypeGetInterface, sizeof(NDASPORT_EXTERNAL_TYPE_GET_INTERFACE),
		&externalTypeGetInterface, sizeof(NDASPORT_EXTERNAL_TYPE_GET_INTERFACE),
		TRUE,
		&event,
		&ioStatus);

	if (NULL == irp)
	{
		status = STATUS_INSUFFICIENT_RESOURCES;
		goto error1;
	}

	status = IoCallDriver(*ExternalDeviceObject, irp);

	if (!NT_SUCCESS(status))
	{
		goto error2;
	}

	KeWaitForSingleObject(
		&event, 
		Executive, 
		KernelMode, 
		FALSE, 
		NULL);

	status = ioStatus.Status;

	if (!NT_SUCCESS(status))
	{
		goto error3;
	}
	
	*LogicalUnitInterface = externalTypeGetInterface.GetInterfaceFunction;

	return status;

error3:
error2:
error1:

	ObDereferenceObject(*ExternalFileObject);
	*ExternalDeviceObject = NULL;
	*ExternalFileObject = NULL;

	return status;
}
Пример #16
0
NTSTATUS
NTAPI
CmpOpenHiveFiles(IN PCUNICODE_STRING BaseName,
                 IN PCWSTR Extension OPTIONAL,
                 OUT PHANDLE Primary,
                 OUT PHANDLE Log,
                 OUT PULONG PrimaryDisposition,
                 OUT PULONG LogDisposition,
                 IN BOOLEAN CreateAllowed,
                 IN BOOLEAN MarkAsSystemHive,
                 IN BOOLEAN NoBuffering,
                 OUT PULONG ClusterSize OPTIONAL)
{
    HANDLE EventHandle;
    PKEVENT Event;
    NTSTATUS Status;
    UNICODE_STRING FullName, ExtensionName;
    PWCHAR NameBuffer;
    USHORT Length;
    OBJECT_ATTRIBUTES ObjectAttributes;
    IO_STATUS_BLOCK IoStatusBlock;
    ULONG AttributeFlags, ShareMode, DesiredAccess, CreateDisposition, IoFlags;
    USHORT CompressionState;
    FILE_STANDARD_INFORMATION FileInformation;
    FILE_FS_SIZE_INFORMATION FsSizeInformation;

    /* Create event */
    Status = CmpCreateEvent(NotificationEvent, &EventHandle, &Event);
    if (!NT_SUCCESS(Status)) return Status;

    /* Initialize the full name */
    RtlInitEmptyUnicodeString(&FullName, NULL, 0);
    Length = BaseName->Length;

    /* Check if we have an extension */
    if (Extension)
    {
        /* Update the name length */
        Length += (USHORT)wcslen(Extension) * sizeof(WCHAR) + sizeof(UNICODE_NULL);

        /* Allocate the buffer for the full name */
        NameBuffer = ExAllocatePoolWithTag(PagedPool, Length, TAG_CM);
        if (!NameBuffer)
        {
            /* Fail */
            ObDereferenceObject(Event);
            ZwClose(EventHandle);
            return STATUS_NO_MEMORY;
        }

        /* Build the full name */
        FullName.Buffer = NameBuffer;
        FullName.MaximumLength = Length;
        RtlAppendUnicodeStringToString(&FullName, BaseName);
    }
    else
    {
        /* The base name is the full name */
        FullName = *BaseName;
        NameBuffer = NULL;
    }

    /* Initialize the attributes */
    InitializeObjectAttributes(&ObjectAttributes,
                               &FullName,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               NULL,
                               NULL);

    /* Check if we can create the hive */
    if ((CreateAllowed) && !(CmpShareSystemHives))
    {
        /* Open only or create */
        CreateDisposition = FILE_OPEN_IF;
    }
    else
    {
        /* Open only */
        CreateDisposition = FILE_OPEN;
    }

    /* Setup the flags */
    // FIXME : FILE_OPEN_FOR_BACKUP_INTENT is unimplemented and breaks 3rd stage boot
    IoFlags = //FILE_OPEN_FOR_BACKUP_INTENT |
              FILE_NO_COMPRESSION |
              FILE_RANDOM_ACCESS |
              (NoBuffering ? FILE_NO_INTERMEDIATE_BUFFERING : 0);

    /* Set share and access modes */
    if ((CmpMiniNTBoot) && (CmpShareSystemHives))
    {
        /* We're on Live CD or otherwise sharing */
        DesiredAccess = FILE_READ_DATA;
        ShareMode = FILE_SHARE_READ;
    }
    else
    {
        /* We want to write exclusively */
        ShareMode = 0;
        DesiredAccess = FILE_READ_DATA | FILE_WRITE_DATA;
    }

    /* Default attributes */
    AttributeFlags = FILE_ATTRIBUTE_NORMAL;

    /* Now create the file */
    Status = ZwCreateFile(Primary,
                          DesiredAccess | SYNCHRONIZE,
                          &ObjectAttributes,
                          &IoStatusBlock,
                          NULL,
                          AttributeFlags,
                          ShareMode,
                          CreateDisposition,
                          FILE_SYNCHRONOUS_IO_NONALERT | IoFlags,
                          NULL,
                          0);
    /* Check if anything failed until now */
    if (!NT_SUCCESS(Status))
    {
        /* Close handles and free buffers */
        if (NameBuffer) ExFreePoolWithTag(NameBuffer, TAG_CM);
        ObDereferenceObject(Event);
        ZwClose(EventHandle);
        DPRINT1("ZwCreateFile failed : %lx.\n", Status);
        *Primary = NULL;
        return Status;
    }
                          
    if (MarkAsSystemHive)
    {
        /* We opened it, mark it as a system hive */
        Status = ZwFsControlFile(*Primary,
                                 EventHandle,
                                 NULL,
                                 NULL,
                                 &IoStatusBlock,
                                 FSCTL_MARK_AS_SYSTEM_HIVE,
                                 NULL,
                                 0,
                                 NULL,
                                 0);
        if (Status == STATUS_PENDING)
        {
            /* Wait for completion */
            KeWaitForSingleObject(Event,
                                  Executive,
                                  KernelMode,
                                  FALSE,
                                  NULL);
            Status = IoStatusBlock.Status;
        }

        /* If we don't support it, ignore the failure */
        if (Status == STATUS_INVALID_DEVICE_REQUEST) Status = STATUS_SUCCESS;

        if (!NT_SUCCESS(Status))
        {
            /* Close handles and free buffers */
            if (NameBuffer) ExFreePoolWithTag(NameBuffer, TAG_CM);
            ObDereferenceObject(Event);
            ZwClose(EventHandle);
            ZwClose(*Primary);
            *Primary = NULL;
            return Status;
        }
    }

    /* Disable compression */
    CompressionState = 0;
    Status = ZwFsControlFile(*Primary,
                             EventHandle,
                             NULL,
                             NULL,
                             &IoStatusBlock,
                             FSCTL_SET_COMPRESSION,
                             &CompressionState,
                             sizeof(CompressionState),
                             NULL,
                             0);
    if (Status == STATUS_PENDING)
    {
        /* Wait for completion */
        KeWaitForSingleObject(Event,
                              Executive,
                              KernelMode,
                              FALSE,
                              NULL);
    }

    /* Get the disposition */
    *PrimaryDisposition = (ULONG)IoStatusBlock.Information;
    if (IoStatusBlock.Information != FILE_CREATED)
    {
        /* Check how large the file is */
        Status = ZwQueryInformationFile(*Primary,
                                        &IoStatusBlock,
                                        &FileInformation,
                                        sizeof(FileInformation),
                                        FileStandardInformation);
        if (NT_SUCCESS(Status))
        {
            /* Check if it's 0 bytes */
            if (!FileInformation.EndOfFile.QuadPart)
            {
                /* Assume it's a new file */
                *PrimaryDisposition = FILE_CREATED;
            }
        }
    }

    /* Check if the caller wants cluster size returned */
    if (ClusterSize)
    {
        /* Query it */
        Status = ZwQueryVolumeInformationFile(*Primary,
                                              &IoStatusBlock,
                                              &FsSizeInformation,
                                              sizeof(FsSizeInformation),
                                              FileFsSizeInformation);
        if (!NT_SUCCESS(Status))
        {
            /* Close handles and free buffers */
            if (NameBuffer) ExFreePoolWithTag(NameBuffer, TAG_CM);
            ObDereferenceObject(Event);
            ZwClose(EventHandle);
            return Status;
        }

        /* Check if the sector size is invalid */
        if (FsSizeInformation.BytesPerSector > HBLOCK_SIZE)
        {
            /* Close handles and free buffers */
            if (NameBuffer) ExFreePoolWithTag(NameBuffer, TAG_CM);
            ObDereferenceObject(Event);
            ZwClose(EventHandle);
            return STATUS_CANNOT_LOAD_REGISTRY_FILE;
        }

        /* Return cluster size */
        *ClusterSize = max(1, FsSizeInformation.BytesPerSector / HSECTOR_SIZE);
    }

    /* Check if we don't need to create a log file */
    if (!Extension)
    {
        /* We're done, close handles */
        ObDereferenceObject(Event);
        ZwClose(EventHandle);
        return STATUS_SUCCESS;
    }

    /* Check if we can create the hive */
    CreateDisposition = CmpShareSystemHives ? FILE_OPEN : FILE_OPEN_IF;
    if (*PrimaryDisposition == FILE_CREATED)
    {
        /* Over-write the existing log file, since this is a new hive */
        CreateDisposition = FILE_SUPERSEDE;
    }

    /* Setup the name */
    RtlInitUnicodeString(&ExtensionName, Extension);
    RtlAppendUnicodeStringToString(&FullName, &ExtensionName);

    /* Initialize the attributes */
    InitializeObjectAttributes(&ObjectAttributes,
                               &FullName,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               NULL,
                               NULL);

    /* Setup the flags */
    IoFlags = FILE_NO_COMPRESSION | FILE_NO_INTERMEDIATE_BUFFERING;

    /* Check if this is a log file */
    if (!_wcsnicmp(Extension, L".log", 4))
    {
        /* Hide log files */
        AttributeFlags |= FILE_ATTRIBUTE_HIDDEN;
    }

    /* Now create the file */
    Status = ZwCreateFile(Log,
                          DesiredAccess,
                          &ObjectAttributes,
                          &IoStatusBlock,
                          NULL,
                          AttributeFlags,
                          ShareMode,
                          CreateDisposition,
                          IoFlags,
                          NULL,
                          0);
    if ((NT_SUCCESS(Status)) && (MarkAsSystemHive))
    {
        /* We opened it, mark it as a system hive */
        Status = ZwFsControlFile(*Log,
                                 EventHandle,
                                 NULL,
                                 NULL,
                                 &IoStatusBlock,
                                 FSCTL_MARK_AS_SYSTEM_HIVE,
                                 NULL,
                                 0,
                                 NULL,
                                 0);
        if (Status == STATUS_PENDING)
        {
            /* Wait for completion */
            KeWaitForSingleObject(Event,
                                  Executive,
                                  KernelMode,
                                  FALSE,
                                  NULL);
            Status = IoStatusBlock.Status;
        }

        /* If we don't support it, ignore the failure */
        if (Status == STATUS_INVALID_DEVICE_REQUEST) Status = STATUS_SUCCESS;

        /* If we failed, close the handle */
        if (!NT_SUCCESS(Status)) ZwClose(*Log);
    }

    /* Check if anything failed until now */
    if (!NT_SUCCESS(Status))
    {
        /* Clear the handle */
        *Log = NULL;
    }
    else
    {
        /* Disable compression */
        Status = ZwFsControlFile(*Log,
                                 EventHandle,
                                 NULL,
                                 NULL,
                                 &IoStatusBlock,
                                 FSCTL_SET_COMPRESSION,
                                 &CompressionState,
                                 sizeof(CompressionState),
                                 NULL,
                                 0);
        if (Status == STATUS_PENDING)
        {
            /* Wait for completion */
            KeWaitForSingleObject(Event,
                                  Executive,
                                  KernelMode,
                                  FALSE,
                                  NULL);
        }

        /* Return the disposition */
        *LogDisposition = (ULONG)IoStatusBlock.Information;
    }

    /* We're done, close handles and free buffers */
    if (NameBuffer) ExFreePoolWithTag(NameBuffer, TAG_CM);
    ObDereferenceObject(Event);
    ZwClose(EventHandle);
    return STATUS_SUCCESS;
}
Пример #17
0
NTSTATUS
NdasPortFdoRegDeleteLogicalUnit(
	__in PNDASPORT_FDO_EXTENSION FdoExtension,
	__in NDAS_LOGICALUNIT_ADDRESS LogicalUnitAddress)
{
	NTSTATUS status, status2;
	HANDLE keyHandle;
	WCHAR valueNameBuffer[32];
	UNICODE_STRING valueName;

	PAGED_CODE();

	keyHandle = NULL;
	status = NdasPortFdoOpenRegistryKey(
		FdoExtension,
		NDASPORT_FDO_REGKEY_LOGICALUNIT_LIST,
		KEY_WRITE,
		&keyHandle);

	if (!NT_SUCCESS(status))
	{
		NdasPortTrace(NDASPORT_FDO_IOCTL, TRACE_LEVEL_ERROR,
			"IoOpenDeviceRegistryKey failed, status=%X, fdo=%p\n", 
			status,
			FdoExtension->DeviceObject);
		return status;
	}

	RtlInitEmptyUnicodeString(
		&valueName, 
		valueNameBuffer, 
		sizeof(valueNameBuffer));

	status2 = RtlUnicodeStringPrintf(
		&valueName, 
		L"LU%08X",
		LogicalUnitAddress);

	ASSERT(NT_SUCCESS(status2));

	status = ZwDeleteValueKey(
		keyHandle,
		&valueName);

	if (!NT_SUCCESS(status))
	{
		NdasPortTrace(NDASPORT_FDO_IOCTL, TRACE_LEVEL_ERROR,
			"ZwDeleteValueKey failed, keyHandle=%p, value=%wZ, status=%X\n", 
			keyHandle, &valueName, status);
		goto ret;
	}

	status = STATUS_SUCCESS;

	goto ret;

ret:
	status2 = ZwClose(keyHandle);

	ASSERT(NT_SUCCESS(status2));
	if (!NT_SUCCESS(status2))
	{
		NdasPortTrace(NDASPORT_FDO_IOCTL, TRACE_LEVEL_WARNING,
			"ZwClose failed, keyHandle=%p, status=%X\n", 
			keyHandle, status2);
	}

	return status;
}
Пример #18
0
/* Move a file handle to recycle bin
 * The pathname must be a valid NT file name generated using filename_to_nt_pathname()
 */
static NTSTATUS move_to_recycle_bin(HANDLE handle, WCHAR *pathname)
{
	IO_STATUS_BLOCK status_block;
	NTSTATUS status;

	/* TODO: Handle the case when recycle bin does not exist (according to cygwin) */
	/* TODO: Handle when the file is inside recycle bin */
	WCHAR recyclepath[512];
	UNICODE_STRING recycle;
	RtlInitEmptyUnicodeString(&recycle, recyclepath, sizeof(recyclepath));
	/* Root directory, should look like "\??\C:\", 7 characters */
	UNICODE_STRING root;
	RtlInitCountedUnicodeString(&root, pathname, sizeof(WCHAR) * 7);
	RtlAppendUnicodeStringToString(&recycle, &root);
	RtlAppendUnicodeToString(&recycle, L"$Recycle.Bin\\");

	WCHAR renamepath[512];
	UNICODE_STRING rename;
	RtlInitEmptyUnicodeString(&rename, renamepath, sizeof(renamepath));
	RtlAppendUnicodeStringToString(&rename, &recycle);
	/* Append user sid */
	{
		WCHAR buf[256];
		UNICODE_STRING sid;
		RtlInitEmptyUnicodeString(&sid, buf, sizeof(buf));
		RtlConvertSidToUnicodeString(&sid, get_user_sid(), FALSE);
		RtlAppendUnicodeStringToString(&rename, &sid);
		RtlAppendUnicodeToString(&rename, L"\\");
	}
	/* Generate an unique file name by append file id and a hash of the pathname,
	 * To allow unlinking multiple hard links of the same file
	 */
	RtlAppendUnicodeToString(&rename, L".flinux");
	/* Append file id */
	{
		FILE_INTERNAL_INFORMATION info;
		status = NtQueryInformationFile(handle, &status_block, &info, sizeof(info), FileInternalInformation);
		if (!NT_SUCCESS(status))
		{
			log_error("NtQueryInformationFile(FileInternalInformation) failed, status: %x", status);
			return status;
		}
		RtlAppendInt64ToString(info.IndexNumber.QuadPart, 16, &rename);
		RtlAppendUnicodeToString(&rename, L"_");
	}
	/* Append file path hash */
	{
		UNICODE_STRING path;
		RtlInitUnicodeString(&path, pathname);
		ULONG hash;
		RtlHashUnicodeString(&path, FALSE, HASH_STRING_ALGORITHM_DEFAULT, &hash);
		RtlAppendIntegerToString(hash, 16, &rename);
	}
	/* Rename file */
	char buf[512];
	FILE_RENAME_INFORMATION *info = (FILE_RENAME_INFORMATION *)buf;
	info->ReplaceIfExists = FALSE;
	info->RootDirectory = NULL;
	info->FileNameLength = rename.Length;
	memcpy(info->FileName, rename.Buffer, rename.Length);
	status = NtSetInformationFile(handle, &status_block, info, sizeof(*info) + info->FileNameLength, FileRenameInformation);
	if (!NT_SUCCESS(status))
	{
		log_error("NtSetInformationFile(FileRenameInformation) failed, status: %x", status);
		return status;
	}
	return STATUS_SUCCESS;
}
Пример #19
0
NTSTATUS
APIENTRY
NtUserEnumDisplaySettings(
    IN PUNICODE_STRING pustrDevice,
    IN DWORD iModeNum,
    OUT LPDEVMODEW lpDevMode,
    IN DWORD dwFlags)
{
    UNICODE_STRING ustrDevice;
    WCHAR awcDevice[CCHDEVICENAME];
    NTSTATUS Status;
    ULONG cbSize, cbExtra;
    DEVMODEW dmReg, *pdm;

    TRACE("Enter NtUserEnumDisplaySettings(%wZ, %lu, %p, 0x%lx)\n",
          pustrDevice, iModeNum, lpDevMode, dwFlags);

    if (pustrDevice)
    {
        /* Initialize destination string */
        RtlInitEmptyUnicodeString(&ustrDevice, awcDevice, sizeof(awcDevice));

        _SEH2_TRY
        {
            /* Probe the UNICODE_STRING and the buffer */
            ProbeForRead(pustrDevice, sizeof(UNICODE_STRING), 1);
            ProbeForRead(pustrDevice->Buffer, pustrDevice->Length, 1);

            /* Copy the string */
            RtlCopyUnicodeString(&ustrDevice, pustrDevice);
        }
        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
        {
            _SEH2_YIELD(return _SEH2_GetExceptionCode());
        }
        _SEH2_END

        pustrDevice = &ustrDevice;
   }

    /* Acquire global USER lock */
    UserEnterShared();

    if (iModeNum == ENUM_REGISTRY_SETTINGS)
    {
        /* Get the registry settings */
        Status = UserEnumRegistryDisplaySettings(pustrDevice, &dmReg);
        pdm = &dmReg;
        pdm->dmSize = sizeof(DEVMODEW);
    }
    else if (iModeNum == ENUM_CURRENT_SETTINGS)
    {
        /* Get the current settings */
        Status = UserEnumCurrentDisplaySettings(pustrDevice, &pdm);
    }
    else
    {
        /* Get specified settings */
        Status = UserEnumDisplaySettings(pustrDevice, iModeNum, &pdm, dwFlags);
    }

    /* Release lock */
    UserLeave();

    /* Did we succeed? */
    if (NT_SUCCESS(Status))
    {
        /* Copy some information back */
        _SEH2_TRY
        {
            ProbeForRead(lpDevMode, sizeof(DEVMODEW), 1);
            cbSize = lpDevMode->dmSize;
            cbExtra = lpDevMode->dmDriverExtra;

            ProbeForWrite(lpDevMode, cbSize + cbExtra, 1);
            /* Output what we got */
            RtlCopyMemory(lpDevMode, pdm, min(cbSize, pdm->dmSize));

            /* Output private/extra driver data */
            if (cbExtra > 0 && pdm->dmDriverExtra > 0)
            {
                RtlCopyMemory((PCHAR)lpDevMode + cbSize,
                              (PCHAR)pdm + pdm->dmSize,
                              min(cbExtra, pdm->dmDriverExtra));
            }
        }
        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
        {
            Status = _SEH2_GetExceptionCode();
        }
        _SEH2_END;
    }

    return Status;
}
Пример #20
0
NTSTATUS NTAPI
LsaApLogonUserEx (PLSA_CLIENT_REQUEST request, SECURITY_LOGON_TYPE logon_type,
		  PVOID auth, PVOID client_auth_base, ULONG auth_len,
		  PVOID *pbuf, PULONG pbuf_len, PLUID logon_id,
		  PNTSTATUS sub_stat, PLSA_TOKEN_INFORMATION_TYPE tok_type,
		  PVOID *tok, PUNICODE_STRING *account,
		  PUNICODE_STRING *authority, PUNICODE_STRING *machine)
{
  DWORD checksum, i;
  PDWORD csp, csp_end;
  NTSTATUS stat;
  SECPKG_CLIENT_INFO clinf;
  PLSA_TOKEN_INFORMATION_V2 tokinf;

  cyglsa_t *authinf = (cyglsa_t *) auth;

  /* Check if the caller has the SeTcbPrivilege, otherwise refuse service. */
  stat = funcs->GetClientInfo (&clinf);
  if (stat != STATUS_SUCCESS)
    {
      cyglsa_printf ("GetClientInfo failed: 0x%08lx\n", stat);
      return stat;
    }
  if (!clinf.HasTcbPrivilege)
    {
      cyglsa_printf ("Client has no TCB privilege.  Access denied.\n");
      return STATUS_ACCESS_DENIED;
    }

  /* Make a couple of validity checks. */
  if (auth_len < sizeof *authinf
      || authinf->magic != CYG_LSA_MAGIC
      || !authinf->username[0]
      || !authinf->domain[0])
    {
      cyglsa_printf ("Invalid authentication parameter.\n");
      return STATUS_INVALID_PARAMETER;
    }
  checksum = CYG_LSA_MAGIC;
  csp = (PDWORD) &authinf->username;
  csp_end = (PDWORD) ((PBYTE) authinf + auth_len);
  while (csp < csp_end)
    checksum += *csp++;
  if (authinf->checksum != checksum)
    {
      cyglsa_printf ("Invalid checksum.\n");
      return STATUS_INVALID_PARAMETER_3;
    }

  /* Set account to username and authority to domain resp. machine name.
     The name of the logon account name as returned by LookupAccountSid
     is created from here as "authority\account". */
  authinf->username[UNLEN] = '\0';
  authinf->domain[MAX_DOMAIN_NAME_LEN] = '\0';
  if (account && !(*account = uni_alloc (authinf->username,
  					 wcslen (authinf->username))))
    {
      cyglsa_printf ("No memory trying to create account.\n");
      return STATUS_NO_MEMORY;
    }
  if (authority && !(*authority = uni_alloc (authinf->domain,
					     wcslen (authinf->domain))))
    {
      cyglsa_printf ("No memory trying to create authority.\n");
      return STATUS_NO_MEMORY;
    }
  if (machine)
    {
      WCHAR mach[MAX_COMPUTERNAME_LENGTH + 1];
      DWORD msize = MAX_COMPUTERNAME_LENGTH + 1;
      if (!GetComputerNameW (mach, &msize))
        wcscpy (mach, L"UNKNOWN");
      if (!(*machine = uni_alloc (mach, wcslen (mach))))
	{
	  cyglsa_printf ("No memory trying to create machine.\n");
	  return STATUS_NO_MEMORY;
	}
    }
  /* Create a fake buffer in pbuf which is free'd again in the client.
     Windows 2000 tends to crash when setting this pointer to NULL. */
  if (pbuf)
    {
#ifdef JUST_ANOTHER_NONWORKING_SOLUTION
      cygprf_t prf;
      WCHAR sam_username[MAX_DOMAIN_NAME_LEN + UNLEN + 2];
      SECURITY_STRING sam_user, prefix;
      PUCHAR user_auth;
      ULONG user_auth_size;
      WCHAR flatname[UNLEN + 1];
      UNICODE_STRING flatnm;
      TOKEN_SOURCE ts;
      HANDLE token;
#endif /* JUST_ANOTHER_NONWORKING_SOLUTION */

      stat = funcs->AllocateClientBuffer (request, 64UL, pbuf);
      if (!LSA_SUCCESS (stat))
	{
	  cyglsa_printf ("AllocateClientBuffer failed: 0x%08lx\n", stat);
	  return stat;
	}
#ifdef JUST_ANOTHER_NONWORKING_SOLUTION
      prf.magic_pre = MAGIC_PRE;
      prf.token = NULL;
      prf.magic_post = MAGIC_POST;

#if 0
      /* That's how it was supposed to work according to MSDN... */
      wcscpy (sam_username, authinf->domain);
      wcscat (sam_username, L"\\");
      wcscat (sam_username, authinf->username);
#else
      /* That's the only solution which worked, and then it only worked
         for machine local accounts.  No domain authentication possible.
	 STATUS_NO_SUCH_USER galore! */
      wcscpy (sam_username, authinf->username);
#endif
      RtlInitUnicodeString (&sam_user, sam_username);
      RtlInitUnicodeString (&prefix, L"");
      RtlInitEmptyUnicodeString (&flatnm, flatname,
				 (UNLEN + 1) * sizeof (WCHAR));

      stat = funcs->GetAuthDataForUser (&sam_user, SecNameSamCompatible,
					NULL, &user_auth,
					&user_auth_size, &flatnm);
      if (!NT_SUCCESS (stat))
	{
	  char sam_u[MAX_DOMAIN_NAME_LEN + UNLEN + 2];
	  wcstombs (sam_u, sam_user.Buffer, sizeof (sam_u));
	  cyglsa_printf ("GetAuthDataForUser (%u,%u,%s) failed: 0x%08lx\n",
		  sam_user.Length, sam_user.MaximumLength, sam_u, stat);
	  return stat;
	}

      memcpy (ts.SourceName, "MSYS.2", 6);
      ts.SourceIdentifier.HighPart = 0;
      ts.SourceIdentifier.LowPart = 0x0104;
      RtlInitEmptyUnicodeString (&flatnm, flatname,
				 (UNLEN + 1) * sizeof (WCHAR));
      stat = funcs->ConvertAuthDataToToken (user_auth, user_auth_size,
					    SecurityDelegation, &ts,
					    Interactive, *authority,
					    &token, logon_id, &flatnm,
					    sub_stat);
      if (!NT_SUCCESS (stat))
	{
	  cyglsa_printf ("ConvertAuthDataToToken failed: 0x%08lx\n", stat);
	  return stat;
	}

      stat = funcs->DuplicateHandle (token, &prf.token);
      if (!NT_SUCCESS (stat))
	{
	  cyglsa_printf ("DuplicateHandle failed: 0x%08lx\n", stat);
	  return stat;
	}
      
      stat = funcs->CopyToClientBuffer (request, sizeof prf, *pbuf, &prf);
      if (!NT_SUCCESS (stat))
	{
	  cyglsa_printf ("CopyToClientBuffer failed: 0x%08lx\n", stat);
	  return stat;
	}
      funcs->FreeLsaHeap (user_auth);
#endif /* JUST_ANOTHER_NONWORKING_SOLUTION */
    }
  if (pbuf_len)
    *pbuf_len = 64UL;

  /* A PLSA_TOKEN_INFORMATION_V2 is allocated in one piece, so... */
#if defined (__x86_64__) || defined (_M_AMD64)
    {
      /* ...on 64 bit systems we have to convert the incoming 32 bit offsets
	 into 64 bit pointers.  That requires to re-evaluate the size of the
	 outgoing tokinf structure and a somewhat awkward procedure to copy
	 the information over. */
      LONG_PTR base;
      PBYTE tptr;
      DWORD size, newsize;
      PSID src_sid;
      PCYG_TOKEN_GROUPS src_grps;
      PTOKEN_GROUPS grps;
      PTOKEN_PRIVILEGES src_privs;
      PACL src_acl;

      base = (LONG_PTR) &authinf->inf;

      newsize = authinf->inf_size;
      newsize += sizeof (TOKEN_USER) - sizeof (CYG_TOKEN_USER); /* User SID */
      newsize += sizeof (PTOKEN_GROUPS) - sizeof (OFFSET); /* Groups */
      src_grps = (PCYG_TOKEN_GROUPS) (base + authinf->inf.Groups);
      newsize += src_grps->GroupCount		  /* Group SIDs */
      		 * (sizeof (SID_AND_ATTRIBUTES)
		    - sizeof (CYG_SID_AND_ATTRIBUTES));
      newsize += sizeof (PSID) - sizeof (OFFSET); /* Primary Group SID */
      newsize += sizeof (PTOKEN_PRIVILEGES) - sizeof (OFFSET); /* Privileges */
      newsize += 0; /* Owner SID */
      newsize += sizeof (PACL) - sizeof (OFFSET); /* Default DACL */

      if (!(tokinf = funcs->AllocateLsaHeap (newsize)))
	return STATUS_NO_MEMORY;
      tptr = (PBYTE)(tokinf + 1);

      tokinf->ExpirationTime = authinf->inf.ExpirationTime;
      /* User SID */
      src_sid = (PSID) (base + authinf->inf.User.User.Sid);
      size = GetLengthSid (src_sid);
      CopySid (size, (PSID) tptr, src_sid);
      tokinf->User.User.Sid = (PSID) tptr;
      tptr += size;
      tokinf->User.User.Attributes = authinf->inf.User.User.Attributes;
      /* Groups */
      grps = (PTOKEN_GROUPS) tptr;
      tokinf->Groups = grps;
      grps->GroupCount = src_grps->GroupCount;
      tptr += sizeof grps->GroupCount
	      + grps->GroupCount * sizeof (SID_AND_ATTRIBUTES);
      /* Group SIDs */
      for (i = 0; i < src_grps->GroupCount; ++i)
	{
	  src_sid = (PSID) (base + src_grps->Groups[i].Sid);
	  size = GetLengthSid (src_sid);
	  CopySid (size, (PSID) tptr, src_sid);
	  tokinf->Groups->Groups[i].Sid = (PSID) tptr;
	  tptr += size;
	  tokinf->Groups->Groups[i].Attributes = src_grps->Groups[i].Attributes;
	}
      /* Primary Group SID */
      src_sid = (PSID) (base + authinf->inf.PrimaryGroup.PrimaryGroup);
      size = GetLengthSid (src_sid);
      CopySid (size, (PSID) tptr, src_sid);
      tokinf->PrimaryGroup.PrimaryGroup = (PSID) tptr;
      tptr += size;
      /* Privileges */
      src_privs = (PTOKEN_PRIVILEGES) (base + authinf->inf.Privileges);
      size = sizeof src_privs->PrivilegeCount
	     + src_privs->PrivilegeCount * sizeof (LUID_AND_ATTRIBUTES);
      memcpy (tptr, src_privs, size);
      tokinf->Privileges = (PTOKEN_PRIVILEGES) tptr;
      tptr += size;
      /* Owner */
      tokinf->Owner.Owner = NULL;
      /* Default DACL */
      src_acl = (PACL) (base + authinf->inf.DefaultDacl.DefaultDacl);
      size = src_acl->AclSize;
      memcpy (tptr, src_acl, size);
      tokinf->DefaultDacl.DefaultDacl = (PACL) tptr;
    }
#else
    {
      /* ...on 32 bit systems we just allocate tokinf with the same size as
         we get, copy the whole structure and convert offsets into pointers. */

      /* Allocate LUID for usage in the logon SID on Windows 2000.  This is
	 not done in the 64 bit code above for hopefully obvious reasons... */
      LUID logon_sid_id;

      if (must_create_logon_sid && !AllocateLocallyUniqueId (&logon_sid_id))
	return STATUS_INSUFFICIENT_RESOURCES;

      if (!(tokinf = funcs->AllocateLsaHeap (authinf->inf_size)))
	return STATUS_NO_MEMORY;
      memcpy (tokinf, &authinf->inf, authinf->inf_size);

      /* User SID */
      tokinf->User.User.Sid = (PSID)
	      ((PBYTE) tokinf + (LONG_PTR) tokinf->User.User.Sid);
      /* Groups */
      tokinf->Groups = (PTOKEN_GROUPS)
	      ((PBYTE) tokinf + (LONG_PTR) tokinf->Groups);
      /* Group SIDs */
      for (i = 0; i < tokinf->Groups->GroupCount; ++i)
	{
	  tokinf->Groups->Groups[i].Sid = (PSID)
		((PBYTE) tokinf + (LONG_PTR) tokinf->Groups->Groups[i].Sid);
	  if (must_create_logon_sid
	      && tokinf->Groups->Groups[i].Attributes & SE_GROUP_LOGON_ID
	      && *GetSidSubAuthorityCount (tokinf->Groups->Groups[i].Sid) == 3
	      && *GetSidSubAuthority (tokinf->Groups->Groups[i].Sid, 0)
		 == SECURITY_LOGON_IDS_RID)
	    {
	      *GetSidSubAuthority (tokinf->Groups->Groups[i].Sid, 1)
	      = logon_sid_id.HighPart;
	      *GetSidSubAuthority (tokinf->Groups->Groups[i].Sid, 2)
	      = logon_sid_id.LowPart;
	    }
	}

      /* Primary Group SID */
      tokinf->PrimaryGroup.PrimaryGroup = (PSID)
	      ((PBYTE) tokinf + (LONG_PTR) tokinf->PrimaryGroup.PrimaryGroup);
      /* Privileges */
      tokinf->Privileges = (PTOKEN_PRIVILEGES)
	      ((PBYTE) tokinf + (LONG_PTR) tokinf->Privileges);
      /* Owner SID */
      tokinf->Owner.Owner = NULL;
      /* Default DACL */
      tokinf->DefaultDacl.DefaultDacl = (PACL)
	      ((PBYTE) tokinf + (LONG_PTR) tokinf->DefaultDacl.DefaultDacl);

    }
#endif

  *tok = (PVOID) tokinf;
  *tok_type = LsaTokenInformationV2;

  print_tokinf (tokinf, authinf->inf_size, authinf, &authinf->inf,
		(PVOID)((LONG_PTR) &authinf->inf + authinf->inf_size));

  /* Create logon session. */
  if (!AllocateLocallyUniqueId (logon_id))
    {
      funcs->FreeLsaHeap (*tok);
      *tok = NULL;
      cyglsa_printf ("AllocateLocallyUniqueId failed: Win32 error %lu\n",
		     GetLastError ());
      return STATUS_INSUFFICIENT_RESOURCES;
    }
  stat = funcs->CreateLogonSession (logon_id);
  if (stat != STATUS_SUCCESS)
    {
      funcs->FreeLsaHeap (*tok);
      *tok = NULL;
      cyglsa_printf ("CreateLogonSession failed: 0x%08lx\n", stat);
      return stat;
    }

  cyglsa_printf ("BINGO!!!\n", stat);
  return STATUS_SUCCESS;
}
Пример #21
0
/*
* FUNCTION: Find a file
*/
static NTSTATUS
CdfsFindFile(PDEVICE_EXTENSION DeviceExt,
             PFCB Fcb,
             PFCB Parent,
             PUNICODE_STRING FileToFind,
             PULONG pDirIndex,
             PULONG pOffset)
{
    WCHAR name[256];
    WCHAR ShortNameBuffer[13];
    UNICODE_STRING TempString;
    UNICODE_STRING ShortName;
    UNICODE_STRING LongName;
    UNICODE_STRING FileToFindUpcase;
    PVOID Block;
    NTSTATUS Status;
    ULONG len;
    ULONG DirIndex;
    ULONG Offset = 0;
    BOOLEAN IsRoot;
    PVOID Context = NULL;
    ULONG DirSize;
    PDIR_RECORD Record;
    LARGE_INTEGER StreamOffset, OffsetOfEntry;

    DPRINT("FindFile(Parent %p, FileToFind '%wZ', DirIndex: %u)\n",
        Parent, FileToFind, pDirIndex ? *pDirIndex : 0);
    DPRINT("FindFile: old Pathname %p, old Objectname %p)\n",
        Fcb->PathName, Fcb->ObjectName);

    IsRoot = FALSE;
    DirIndex = 0;

    if (FileToFind == NULL || FileToFind->Length == 0)
    {
        RtlInitUnicodeString(&TempString, L".");
        FileToFind = &TempString;
    }

    if (Parent)
    {
        if (Parent->Entry.ExtentLocationL == DeviceExt->CdInfo.RootStart)
        {
            IsRoot = TRUE;
        }
    }
    else
    {
        IsRoot = TRUE;
    }

    if (IsRoot == TRUE)
    {
        StreamOffset.QuadPart = (LONGLONG)DeviceExt->CdInfo.RootStart * (LONGLONG)BLOCKSIZE;
        DirSize = DeviceExt->CdInfo.RootSize;


        if (FileToFind->Buffer[0] == 0 ||
            (FileToFind->Buffer[0] == '\\' && FileToFind->Buffer[1] == 0) ||
            (FileToFind->Buffer[0] == '.' && FileToFind->Buffer[1] == 0))
        {
            /* it's root : complete essentials fields then return ok */
            RtlZeroMemory(Fcb, sizeof(FCB));
            RtlInitEmptyUnicodeString(&Fcb->PathName, Fcb->PathNameBuffer, sizeof(Fcb->PathNameBuffer));

            Fcb->PathNameBuffer[0] = '\\';
            Fcb->PathName.Length = sizeof(WCHAR);
            Fcb->ObjectName = &Fcb->PathNameBuffer[1];
            Fcb->Entry.ExtentLocationL = DeviceExt->CdInfo.RootStart;
            Fcb->Entry.DataLengthL = DeviceExt->CdInfo.RootSize;
            Fcb->Entry.FileFlags = 0x02; //FILE_ATTRIBUTE_DIRECTORY;

            if (pDirIndex)
                *pDirIndex = 0;
            if (pOffset)
                *pOffset = 0;
            DPRINT("CdfsFindFile: new Pathname %wZ, new Objectname %S)\n",&Fcb->PathName, Fcb->ObjectName);
            return STATUS_SUCCESS;
        }
    }
    else
    {
        StreamOffset.QuadPart = (LONGLONG)Parent->Entry.ExtentLocationL * (LONGLONG)BLOCKSIZE;
        DirSize = Parent->Entry.DataLengthL;
    }

    DPRINT("StreamOffset %I64d  DirSize %u\n", StreamOffset.QuadPart, DirSize);

    if (pDirIndex && (*pDirIndex))
        DirIndex = *pDirIndex;

    if (pOffset && (*pOffset))
    {
        Offset = *pOffset;
        StreamOffset.QuadPart += ROUND_DOWN(Offset, BLOCKSIZE);
    }

    if (!CcMapData(DeviceExt->StreamFileObject, &StreamOffset,
        BLOCKSIZE, TRUE, &Context, &Block))
    {
        DPRINT("CcMapData() failed\n");
        return STATUS_UNSUCCESSFUL;
    }

    Record = (PDIR_RECORD) ((ULONG_PTR)Block + Offset % BLOCKSIZE);
    if (Offset)
    {
        Offset += Record->RecordLength;
        Record = (PDIR_RECORD)((ULONG_PTR)Record + Record->RecordLength);
    }

    /* Upper case the expression for FsRtlIsNameInExpression */
    Status = RtlUpcaseUnicodeString(&FileToFindUpcase, FileToFind, TRUE);
    if (!NT_SUCCESS(Status))
    {
        return Status;
    }

    while(TRUE)
    {
        DPRINT("RecordLength %u  ExtAttrRecordLength %u  NameLength %u\n",
            Record->RecordLength, Record->ExtAttrRecordLength, Record->FileIdLength);

        Status = CdfsGetEntryName
            (DeviceExt, &Context, &Block, &StreamOffset,
            DirSize, (PVOID*)&Record, name, &DirIndex, &Offset);

        if (Status == STATUS_NO_MORE_ENTRIES)
        {
            break;
        }
        else if (Status == STATUS_UNSUCCESSFUL || Status == STATUS_DISK_CORRUPT_ERROR)
        {
            /* Note: the directory cache has already been unpinned */
            RtlFreeUnicodeString(&FileToFindUpcase);
            return Status;
        }

        DPRINT("Name '%S'\n", name);

        RtlInitUnicodeString(&LongName, name);

        ShortName.Length = 0;
        ShortName.MaximumLength = 26;
        ShortName.Buffer = ShortNameBuffer;

        OffsetOfEntry.QuadPart = StreamOffset.QuadPart + Offset;
        CdfsShortNameCacheGet(Parent, &OffsetOfEntry, &LongName, &ShortName);

        DPRINT("ShortName '%wZ'\n", &ShortName);

        if (FsRtlIsNameInExpression(&FileToFindUpcase, &LongName, TRUE, NULL) ||
            FsRtlIsNameInExpression(&FileToFindUpcase, &ShortName, TRUE, NULL))
        {
            if (Parent->PathName.Buffer[0])
            {
                RtlCopyUnicodeString(&Fcb->PathName, &Parent->PathName);
                len = Parent->PathName.Length / sizeof(WCHAR);
                Fcb->ObjectName=&Fcb->PathName.Buffer[len];
                if (len != 1 || Fcb->PathName.Buffer[0] != '\\')
                {
                    Fcb->ObjectName[0] = '\\';
                    Fcb->ObjectName = &Fcb->ObjectName[1];
                }
            }
            else
            {
                Fcb->ObjectName=Fcb->PathName.Buffer;
                Fcb->ObjectName[0]='\\';
                Fcb->ObjectName=&Fcb->ObjectName[1];
            }

            DPRINT("PathName '%wZ'  ObjectName '%S'\n", &Fcb->PathName, Fcb->ObjectName);

            memcpy(&Fcb->Entry, Record, sizeof(DIR_RECORD));
            wcsncpy(Fcb->ObjectName, name, min(wcslen(name) + 1,
                MAX_PATH - (Fcb->PathName.Length / sizeof(WCHAR)) + wcslen(Fcb->ObjectName)));

            /* Copy short name */
            Fcb->ShortNameU.Length = ShortName.Length;
            Fcb->ShortNameU.MaximumLength = ShortName.Length;
            Fcb->ShortNameU.Buffer = Fcb->ShortNameBuffer;
            memcpy(Fcb->ShortNameBuffer, ShortName.Buffer, ShortName.Length);

            if (pDirIndex)
                *pDirIndex = DirIndex;
            if (pOffset)
                *pOffset = Offset;

            DPRINT("FindFile: new Pathname %wZ, new Objectname %S, DirIndex %u\n",
                &Fcb->PathName, Fcb->ObjectName, DirIndex);

            RtlFreeUnicodeString(&FileToFindUpcase);
            CcUnpinData(Context);

            return STATUS_SUCCESS;
        }

        Offset += Record->RecordLength;
        Record = (PDIR_RECORD)((ULONG_PTR)Record + Record->RecordLength);
        DirIndex++;
    }

    RtlFreeUnicodeString(&FileToFindUpcase);
    CcUnpinData(Context);

    if (pDirIndex)
        *pDirIndex = DirIndex;

    if (pOffset)
        *pOffset = Offset;

    return STATUS_UNSUCCESSFUL;
}
Пример #22
0
VOID
NTAPI
BaseInitializeStaticServerData(IN PCSR_SERVER_DLL LoadedServerDll)
{
    NTSTATUS Status;
    BOOLEAN Success;
    WCHAR Buffer[MAX_PATH];
    PWCHAR HeapBuffer;
    UNICODE_STRING SystemRootString;
    UNICODE_STRING UnexpandedSystemRootString = RTL_CONSTANT_STRING(L"%SystemRoot%");
    UNICODE_STRING BaseSrvCSDString;
    UNICODE_STRING BaseSrvWindowsDirectory;
    UNICODE_STRING BaseSrvWindowsSystemDirectory;
    UNICODE_STRING BnoString;
    OBJECT_ATTRIBUTES ObjectAttributes;
    ULONG SessionId;
    HANDLE BaseSrvNamedObjectDirectory;
    HANDLE BaseSrvRestrictedObjectDirectory;
    PACL BnoDacl, BnoRestrictedDacl;
    PSECURITY_DESCRIPTOR BnoSd;
    HANDLE SymHandle;
    UNICODE_STRING DirectoryName, SymlinkName;
    ULONG LuidEnabled;
    RTL_QUERY_REGISTRY_TABLE BaseServerRegistryConfigurationTable[2] =
    {
        {
            NULL,
            RTL_QUERY_REGISTRY_DIRECT,
            L"CSDVersion",
            &BaseSrvCSDString,
            REG_NONE, NULL, 0
        },

        {0}
    };

    /* Initialize the memory */
    BaseSrvHeap = RtlGetProcessHeap();                  // Initialize our own heap.
    BaseSrvSharedHeap = LoadedServerDll->SharedSection; // Get the CSR shared heap.

    /* Get the session ID */
    SessionId = NtCurrentPeb()->SessionId;

    /* Get the Windows directory */
    RtlInitEmptyUnicodeString(&SystemRootString, Buffer, sizeof(Buffer));
    Status = RtlExpandEnvironmentStrings_U(NULL,
                                           &UnexpandedSystemRootString,
                                           &SystemRootString,
                                           NULL);
    ASSERT(NT_SUCCESS(Status));

    /* Create the base directory */
    Buffer[SystemRootString.Length / sizeof(WCHAR)] = UNICODE_NULL;
    Success = RtlCreateUnicodeString(&BaseSrvWindowsDirectory,
                                     SystemRootString.Buffer);
    ASSERT(Success);

    /* Create the system directory */
    wcscat(SystemRootString.Buffer, L"\\System32");
    Success = RtlCreateUnicodeString(&BaseSrvWindowsSystemDirectory,
                                     SystemRootString.Buffer);
    ASSERT(Success);

    /* Create the kernel32 path */
    wcscat(SystemRootString.Buffer, L"\\kernel32.dll");
    Success = RtlCreateUnicodeString(&BaseSrvKernel32DllPath,
                                     SystemRootString.Buffer);
    ASSERT(Success);

    /* FIXME: Check Session ID */
    wcscpy(Buffer, L"\\BaseNamedObjects");
    RtlInitUnicodeString(&BnoString, Buffer);

    /* Allocate the server data */
    BaseStaticServerData = RtlAllocateHeap(BaseSrvSharedHeap,
                                           HEAP_ZERO_MEMORY,
                                           sizeof(BASE_STATIC_SERVER_DATA));
    ASSERT(BaseStaticServerData != NULL);

    /* Process timezone information */
    BaseStaticServerData->TermsrvClientTimeZoneId = TIME_ZONE_ID_INVALID;
    BaseStaticServerData->TermsrvClientTimeZoneChangeNum = 0;
    Status = NtQuerySystemInformation(SystemTimeOfDayInformation,
                                      &BaseStaticServerData->TimeOfDay,
                                      sizeof(BaseStaticServerData->TimeOfDay),
                                      NULL);
    ASSERT(NT_SUCCESS(Status));

    /* Make a shared heap copy of the Windows directory */
    BaseStaticServerData->WindowsDirectory = BaseSrvWindowsDirectory;
    HeapBuffer = RtlAllocateHeap(BaseSrvSharedHeap,
                                 0,
                                 BaseSrvWindowsDirectory.MaximumLength);
    ASSERT(HeapBuffer);
    RtlCopyMemory(HeapBuffer,
                  BaseStaticServerData->WindowsDirectory.Buffer,
                  BaseSrvWindowsDirectory.MaximumLength);
    BaseStaticServerData->WindowsDirectory.Buffer = HeapBuffer;

    /* Make a shared heap copy of the System directory */
    BaseStaticServerData->WindowsSystemDirectory = BaseSrvWindowsSystemDirectory;
    HeapBuffer = RtlAllocateHeap(BaseSrvSharedHeap,
                                 0,
                                 BaseSrvWindowsSystemDirectory.MaximumLength);
    ASSERT(HeapBuffer);
    RtlCopyMemory(HeapBuffer,
                  BaseStaticServerData->WindowsSystemDirectory.Buffer,
                  BaseSrvWindowsSystemDirectory.MaximumLength);
    BaseStaticServerData->WindowsSystemDirectory.Buffer = HeapBuffer;

    /* This string is not used */
    RtlInitEmptyUnicodeString(&BaseStaticServerData->WindowsSys32x86Directory,
                              NULL,
                              0);

    /* Make a shared heap copy of the BNO directory */
    BaseStaticServerData->NamedObjectDirectory = BnoString;
    BaseStaticServerData->NamedObjectDirectory.MaximumLength = BnoString.Length +
                                                               sizeof(UNICODE_NULL);
    HeapBuffer = RtlAllocateHeap(BaseSrvSharedHeap,
                                 0,
                                 BaseStaticServerData->NamedObjectDirectory.MaximumLength);
    ASSERT(HeapBuffer);
    RtlCopyMemory(HeapBuffer,
                  BaseStaticServerData->NamedObjectDirectory.Buffer,
                  BaseStaticServerData->NamedObjectDirectory.MaximumLength);
    BaseStaticServerData->NamedObjectDirectory.Buffer = HeapBuffer;

    /*
     * Confirmed that in Windows, CSDNumber and RCNumber are actually Length
     * and MaximumLength of the CSD String, since the same UNICODE_STRING is
     * being queried twice, the first time as a ULONG!
     *
     * Somehow, in Windows this doesn't cause a buffer overflow, but it might
     * in ReactOS, so this code is disabled until someone figures out WTF.
     */
    BaseStaticServerData->CSDNumber = 0;
    BaseStaticServerData->RCNumber = 0;

    /* Initialize the CSD string and query its value from the registry */
    RtlInitEmptyUnicodeString(&BaseSrvCSDString, Buffer, sizeof(Buffer));
    Status = RtlQueryRegistryValues(RTL_REGISTRY_WINDOWS_NT,
                                    L"",
                                    BaseServerRegistryConfigurationTable,
                                    NULL,
                                    NULL);
    if (NT_SUCCESS(Status))
    {
        /* Copy into the shared buffer */
        wcsncpy(BaseStaticServerData->CSDVersion,
                BaseSrvCSDString.Buffer,
                BaseSrvCSDString.Length / sizeof(WCHAR));
    }
    else
    {
        /* NULL-terminate to indicate nothing is there */
        BaseStaticServerData->CSDVersion[0] = UNICODE_NULL;
    }

    /* Cache the system information */
    Status = NtQuerySystemInformation(SystemBasicInformation,
                                      &BaseStaticServerData->SysInfo,
                                      sizeof(BaseStaticServerData->SysInfo),
                                      NULL);
    ASSERT(NT_SUCCESS(Status));

    /* Setup the ini file mappings */
    Status = BaseSrvInitializeIniFileMappings(BaseStaticServerData);
    ASSERT(NT_SUCCESS(Status));

    /* FIXME: Should query the registry for these */
    BaseStaticServerData->DefaultSeparateVDM = FALSE;
    BaseStaticServerData->IsWowTaskReady = FALSE;

    /* Allocate a security descriptor and create it */
    BnoSd = RtlAllocateHeap(BaseSrvHeap, 0, 1024);
    ASSERT(BnoSd);
    Status = RtlCreateSecurityDescriptor(BnoSd, SECURITY_DESCRIPTOR_REVISION);
    ASSERT(NT_SUCCESS(Status));

    /* Create the BNO and \Restricted DACLs */
    Status = CreateBaseAcls(&BnoDacl, &BnoRestrictedDacl);
    ASSERT(NT_SUCCESS(Status));

    /* Set the BNO DACL as active for now */
    Status = RtlSetDaclSecurityDescriptor(BnoSd, TRUE, BnoDacl, FALSE);
    ASSERT(NT_SUCCESS(Status));

    /* Create the BNO directory */
    RtlInitUnicodeString(&BnoString, L"\\BaseNamedObjects");
    InitializeObjectAttributes(&ObjectAttributes,
                               &BnoString,
                               OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
                               NULL,
                               BnoSd);
    Status = NtCreateDirectoryObject(&BaseSrvNamedObjectDirectory,
                                     DIRECTORY_ALL_ACCESS,
                                     &ObjectAttributes);
    ASSERT(NT_SUCCESS(Status));

    /* Check if we are session 0 */
    if (SessionId == 0)
    {
        /* Mark this as a session 0 directory */
        Status = NtSetInformationObject(BaseSrvNamedObjectDirectory,
                                        ObjectSessionInformation,
                                        NULL,
                                        0);
        ASSERT(NT_SUCCESS(Status));
    }

    /* Check if LUID device maps are enabled */
    Status = NtQueryInformationProcess(NtCurrentProcess(),
                                       ProcessLUIDDeviceMapsEnabled,
                                       &LuidEnabled,
                                       sizeof(LuidEnabled),
                                       NULL);
    ASSERT(NT_SUCCESS(Status));
    BaseStaticServerData->LUIDDeviceMapsEnabled = (BOOLEAN)LuidEnabled;
    if (!BaseStaticServerData->LUIDDeviceMapsEnabled)
    {
        /* Make Global point back to BNO */
        RtlInitUnicodeString(&DirectoryName, L"Global");
        RtlInitUnicodeString(&SymlinkName, L"\\BaseNamedObjects");
        InitializeObjectAttributes(&ObjectAttributes,
                                   &DirectoryName,
                                   OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
                                   BaseSrvNamedObjectDirectory,
                                   BnoSd);
        Status = NtCreateSymbolicLinkObject(&SymHandle,
                                            SYMBOLIC_LINK_ALL_ACCESS,
                                            &ObjectAttributes,
                                            &SymlinkName);
        if ((NT_SUCCESS(Status)) && SessionId == 0) NtClose(SymHandle);

        /* Make local point back to \Sessions\x\BNO */
        RtlInitUnicodeString(&DirectoryName, L"Local");
        ASSERT(SessionId == 0);
        InitializeObjectAttributes(&ObjectAttributes,
                                   &DirectoryName,
                                   OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
                                   BaseSrvNamedObjectDirectory,
                                   BnoSd);
        Status = NtCreateSymbolicLinkObject(&SymHandle,
                                            SYMBOLIC_LINK_ALL_ACCESS,
                                            &ObjectAttributes,
                                            &SymlinkName);
        if ((NT_SUCCESS(Status)) && SessionId == 0) NtClose(SymHandle);

        /* Make Session point back to BNOLINKS */
        RtlInitUnicodeString(&DirectoryName, L"Session");
        RtlInitUnicodeString(&SymlinkName, L"\\Sessions\\BNOLINKS");
        InitializeObjectAttributes(&ObjectAttributes,
                                   &DirectoryName,
                                   OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
                                   BaseSrvNamedObjectDirectory,
                                   BnoSd);
        Status = NtCreateSymbolicLinkObject(&SymHandle,
                                            SYMBOLIC_LINK_ALL_ACCESS,
                                            &ObjectAttributes,
                                            &SymlinkName);
        if ((NT_SUCCESS(Status)) && SessionId == 0) NtClose(SymHandle);

        /* Create the BNO\Restricted directory and set the restricted DACL */
        RtlInitUnicodeString(&DirectoryName, L"Restricted");
        Status = RtlSetDaclSecurityDescriptor(BnoSd, TRUE, BnoRestrictedDacl, FALSE);
        ASSERT(NT_SUCCESS(Status));
        InitializeObjectAttributes(&ObjectAttributes,
                                   &DirectoryName,
                                   OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
                                   BaseSrvNamedObjectDirectory,
                                   BnoSd);
        Status = NtCreateDirectoryObject(&BaseSrvRestrictedObjectDirectory,
                                         DIRECTORY_ALL_ACCESS,
                                         &ObjectAttributes);
        ASSERT(NT_SUCCESS(Status));
    }

    /* Initialize NLS */
    BaseSrvNLSInit(BaseStaticServerData);

    /* Finally, set the pointer */
    LoadedServerDll->SharedSection = BaseStaticServerData;
}
Пример #23
0
NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )

/*++

Routine Description:

    This is the initialization routine for the Fat file system
    device driver.  This routine creates the device object for the FileSystem
    device and performs all other driver initialization.

Arguments:

    DriverObject - Pointer to driver object created by the system.

Return Value:

    NTSTATUS - The function value is the final status from the initialization
        operation.

--*/

{
    USHORT MaxDepth;
    NTSTATUS Status;
    UNICODE_STRING UnicodeString;
    FS_FILTER_CALLBACKS FilterCallbacks;
    UNICODE_STRING ValueName;
    ULONG Value;

#if __NDAS_FAT__
	UNICODE_STRING	linkString;
	UNICODE_STRING	functionName;
	UNICODE_STRING	tempUnicode;
#endif

#if DBG
	DbgPrint( "NdasFat DriverEntry %s %s\n", __DATE__, __TIME__ );
#endif

#if __NDAS_FAT_DBG__

	FatDebugTraceLevel |= DEBUG_TRACE_ERROR;
	FatDebugTraceLevel |= DEBUG_TRACE_CLEANUP;
	FatDebugTraceLevel |= DEBUG_TRACE_CLOSE;
	FatDebugTraceLevel |= DEBUG_TRACE_CREATE;
	FatDebugTraceLevel |= DEBUG_TRACE_DIRCTRL;
	FatDebugTraceLevel |= DEBUG_TRACE_EA;
	FatDebugTraceLevel |= DEBUG_TRACE_FILEINFO;
	FatDebugTraceLevel |= DEBUG_TRACE_FSCTRL;
	FatDebugTraceLevel |= DEBUG_TRACE_LOCKCTRL;
	FatDebugTraceLevel |= DEBUG_TRACE_READ;
	FatDebugTraceLevel |= DEBUG_TRACE_VOLINFO;
	FatDebugTraceLevel |= DEBUG_TRACE_WRITE;
	FatDebugTraceLevel |= DEBUG_TRACE_DEVCTRL;
	FatDebugTraceLevel |= DEBUG_TRACE_FLUSH;
	FatDebugTraceLevel |= DEBUG_TRACE_PNP;
	FatDebugTraceLevel |= DEBUG_TRACE_SHUTDOWN;
	

	//FatDebugTraceLevel |= DEBUG_TRACE_FSCTRL;
	//FatDebugTraceLevel |= DEBUG_INFO_DEVCTRL;
	//FatDebugTraceLevel |= DEBUG_INFO_PRIMARY;
	//FatDebugTraceLevel |= DEBUG_TRACE_WRITE;
	//FatDebugTraceLevel = 0xFFFFFFFFFFFFFFFF;
	//FatDebugTraceLevel |= DEBUG_TRACE_STRUCSUP;
	//FatDebugTraceLevel |= DEBUG_TRACE_FILEINFO;

	FatDebugTraceLevel = 0x00000009;

	FatDebugTraceLevel |= DEBUG_INFO_FSCTRL;
	FatDebugTraceLevel |= DEBUG_INFO_READ;
	FatDebugTraceLevel |= DEBUG_INFO_SECONDARY;
	FatDebugTraceLevel |= DEBUG_INFO_FILOBSUP;
	FatDebugTraceLevel |= DEBUG_TRACE_PNP;
	FatDebugTraceLevel |= DEBUG_TRACE_SHUTDOWN;
	FatDebugTraceLevel |= DEBUG_INFO_FILEINFO;
	FatDebugTraceLevel |= DEBUG_INFO_CREATE;
	FatDebugTraceLevel |= DEBUG_INFO_STRUCSUP;
	FatDebugTraceLevel |= DEBUG_INFO_CLEANUP;
	FatDebugTraceLevel |= DEBUG_INFO_CLOSE;
	FatDebugTraceLevel |= DEBUG_INFO_ALL;
	FatDebugTraceLevel |= DEBUG_INFO_WRITE;
	FatDebugTraceLevel &= ~DEBUG_TRACE_UNWIND;
	FatDebugTraceLevel |= DEBUG_INFO_FILEINFO;

	DebugTrace2( 0, DEBUG_INFO_ALL, ("sizeof(NDFS_WINXP_REPLY_HEADER) = %d\n", sizeof(NDFS_WINXP_REPLY_HEADER)) );

#endif

#if __NDAS_FAT_WIN2K_SUPPORT__

	PsGetVersion( &gOsMajorVersion,
                  &gOsMinorVersion,
                  NULL,
                  NULL );

	RtlInitUnicodeString( &functionName, L"SeFilterToken" );
	NdasFatSeFilterToken = MmGetSystemRoutineAddress( &functionName );

	if (IS_WINDOWSXP_OR_LATER()) {

		// to prevent incomprehensible error

		RtlInitUnicodeString( &functionName, L"CcMdlWriteAbort" ); 
		NdasFatCcMdlWriteAbort = MmGetSystemRoutineAddress( &functionName );
	}

	RtlInitUnicodeString( &functionName, L"KeAreApcsDisabled" );
	NdasFatKeAreApcsDisabled = MmGetSystemRoutineAddress( &functionName );

	RtlInitUnicodeString( &functionName, L"KeAreAllApcsDisabled" );
	NdasFatKeAreAllApcsDisabled = MmGetSystemRoutineAddress( &functionName );

	RtlInitUnicodeString( &functionName, L"FsRtlRegisterFileSystemFilterCallbacks" );
	NdasFatFsRtlRegisterFileSystemFilterCallbacks = MmGetSystemRoutineAddress( &functionName );

	RtlInitUnicodeString( &functionName, L"FsRtlAreVolumeStartupApplicationsComplete" );
	NdasFatFsRtlAreVolumeStartupApplicationsComplete = MmGetSystemRoutineAddress( &functionName );
	
	RtlInitUnicodeString( &functionName, L"MmDoesFileHaveUserWritableReferences" );
	NdasFatMmDoesFileHaveUserWritableReferences = MmGetSystemRoutineAddress( &functionName );

#endif

#if __NDAS_FAT__
	
    RtlInitUnicodeString( &UnicodeString, NDAS_FAT_CONTROL_DEVICE_NAME );

    Status = IoCreateDevice( DriverObject,
                             0,                 //  has no device extension
                             &UnicodeString,
                             FILE_DEVICE_NULL,
                             0,
                             FALSE,
                             &FatControlDeviceObject );

	if (!NT_SUCCESS(Status)) {

		return Status;
	}

    RtlInitUnicodeString( &linkString, NDAS_FAT_CONTROL_LINK_NAME );
    Status = IoCreateSymbolicLink( &linkString, &UnicodeString );

    if (!NT_SUCCESS(Status)) {
		
        IoDeleteDevice( FatControlDeviceObject );
	    return Status;
    }

#endif

#if __NDAS_FAT__

    RtlInitUnicodeString( &UnicodeString, NDAS_FAT_DEVICE_NAME );

    Status = IoCreateDevice( DriverObject,
                             sizeof(VOLUME_DEVICE_OBJECT) - sizeof(DEVICE_OBJECT),
                             &UnicodeString,
                             FILE_DEVICE_DISK_FILE_SYSTEM,
                             0,
                             FALSE,
                             &FatDiskFileSystemDeviceObject );

	if (!NT_SUCCESS(Status)) {
		
        IoDeleteSymbolicLink( &linkString );
        IoDeleteDevice( FatControlDeviceObject );
	    return Status;
    }

	RtlZeroMemory( (PUCHAR)FatDiskFileSystemDeviceObject+sizeof(DEVICE_OBJECT), 
				   sizeof(VOLUME_DEVICE_OBJECT)-sizeof(DEVICE_OBJECT) );

#else

    //
    // Create the device object for disks.  To avoid problems with filters who
    // know this name, we must keep it.
    //

    RtlInitUnicodeString( &UnicodeString, L"\\Fat" );
    Status = IoCreateDevice( DriverObject,
                             0,
                             &UnicodeString,
                             FILE_DEVICE_DISK_FILE_SYSTEM,
                             0,
                             FALSE,
                             &FatDiskFileSystemDeviceObject );

    if (!NT_SUCCESS( Status )) {
        return Status;
    }

#endif

#if !__NDAS_FAT__

    //
    // Create the device object for "cdroms".
    //

    RtlInitUnicodeString( &UnicodeString, L"\\FatCdrom" );
    Status = IoCreateDevice( DriverObject,
                             0,
                             &UnicodeString,
                             FILE_DEVICE_CD_ROM_FILE_SYSTEM,
                             0,
                             FALSE,
                             &FatCdromFileSystemDeviceObject );

    if (!NT_SUCCESS( Status )) {
        IoDeleteDevice( FatDiskFileSystemDeviceObject);
        return Status;
    }

#endif

    DriverObject->DriverUnload = FatUnload;

    //
    //  Note that because of the way data caching is done, we set neither
    //  the Direct I/O or Buffered I/O bit in DeviceObject->Flags.  If
    //  data is not in the cache, or the request is not buffered, we may,
    //  set up for Direct I/O by hand.
    //

    //
    // Initialize the driver object with this driver's entry points.
    //

    DriverObject->MajorFunction[IRP_MJ_CREATE]                   = (PDRIVER_DISPATCH)FatFsdCreate;
    DriverObject->MajorFunction[IRP_MJ_CLOSE]                    = (PDRIVER_DISPATCH)FatFsdClose;
    DriverObject->MajorFunction[IRP_MJ_READ]                     = (PDRIVER_DISPATCH)FatFsdRead;
    DriverObject->MajorFunction[IRP_MJ_WRITE]                    = (PDRIVER_DISPATCH)FatFsdWrite;
    DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION]        = (PDRIVER_DISPATCH)FatFsdQueryInformation;
    DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION]          = (PDRIVER_DISPATCH)FatFsdSetInformation;
    DriverObject->MajorFunction[IRP_MJ_QUERY_EA]                 = (PDRIVER_DISPATCH)FatFsdQueryEa;
    DriverObject->MajorFunction[IRP_MJ_SET_EA]                   = (PDRIVER_DISPATCH)FatFsdSetEa;
    DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS]            = (PDRIVER_DISPATCH)FatFsdFlushBuffers;
    DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = (PDRIVER_DISPATCH)FatFsdQueryVolumeInformation;
    DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION]   = (PDRIVER_DISPATCH)FatFsdSetVolumeInformation;
    DriverObject->MajorFunction[IRP_MJ_CLEANUP]                  = (PDRIVER_DISPATCH)FatFsdCleanup;
    DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL]        = (PDRIVER_DISPATCH)FatFsdDirectoryControl;
    DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL]      = (PDRIVER_DISPATCH)FatFsdFileSystemControl;
    DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL]             = (PDRIVER_DISPATCH)FatFsdLockControl;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]           = (PDRIVER_DISPATCH)FatFsdDeviceControl;
    DriverObject->MajorFunction[IRP_MJ_SHUTDOWN]                 = (PDRIVER_DISPATCH)FatFsdShutdown;
    DriverObject->MajorFunction[IRP_MJ_PNP]                      = (PDRIVER_DISPATCH)FatFsdPnp;

    DriverObject->FastIoDispatch = &FatFastIoDispatch;

    RtlZeroMemory(&FatFastIoDispatch, sizeof(FatFastIoDispatch));

    FatFastIoDispatch.SizeOfFastIoDispatch =    sizeof(FAST_IO_DISPATCH);
    FatFastIoDispatch.FastIoCheckIfPossible =   FatFastIoCheckIfPossible;  //  CheckForFastIo
    FatFastIoDispatch.FastIoRead =              FsRtlCopyRead;             //  Read
    FatFastIoDispatch.FastIoWrite =             FsRtlCopyWrite;            //  Write
    FatFastIoDispatch.FastIoQueryBasicInfo =    FatFastQueryBasicInfo;     //  QueryBasicInfo
    FatFastIoDispatch.FastIoQueryStandardInfo = FatFastQueryStdInfo;       //  QueryStandardInfo
    FatFastIoDispatch.FastIoLock =              FatFastLock;               //  Lock
    FatFastIoDispatch.FastIoUnlockSingle =      FatFastUnlockSingle;       //  UnlockSingle
    FatFastIoDispatch.FastIoUnlockAll =         FatFastUnlockAll;          //  UnlockAll
    FatFastIoDispatch.FastIoUnlockAllByKey =    FatFastUnlockAllByKey;     //  UnlockAllByKey
    FatFastIoDispatch.FastIoQueryNetworkOpenInfo = FatFastQueryNetworkOpenInfo;
    FatFastIoDispatch.AcquireForCcFlush =       FatAcquireForCcFlush;
    FatFastIoDispatch.ReleaseForCcFlush =       FatReleaseForCcFlush;
    FatFastIoDispatch.MdlRead =                 FsRtlMdlReadDev;
    FatFastIoDispatch.MdlReadComplete =         FsRtlMdlReadCompleteDev;
    FatFastIoDispatch.PrepareMdlWrite =         FsRtlPrepareMdlWriteDev;
    FatFastIoDispatch.MdlWriteComplete =        FsRtlMdlWriteCompleteDev;
    
#if __NDAS_FAT_SECONDARY__

	RtlZeroMemory(&FatFastIoDispatch, sizeof(FAST_IO_DISPATCH));
	FatFastIoDispatch.SizeOfFastIoDispatch			 =	sizeof(FAST_IO_DISPATCH);

	//FatFastIoDispatch.FastIoCheckIfPossible			=  FatFastIoCheckIfPossible;  //  CheckForFastIo
	//FatFastIoDispatch.AcquireForModWrite				=  FatAcquireFileForModWrite;
	//FatFastIoDispatch.AcquireFileForNtCreateSection	=  FatAcquireForCreateSection;
	//FatFastIoDispatch.ReleaseFileForNtCreateSection	=  FatReleaseForCreateSection;

	FatFastIoDispatch.AcquireForCcFlush				=  FatAcquireForCcFlush;
	FatFastIoDispatch.ReleaseForCcFlush				=  FatReleaseForCcFlush;

#endif

    //
    //  Initialize the filter callbacks we use.
    //

#if __NDAS_FAT__

	if (IS_WINDOWSVISTA_OR_LATER()) {

#if __NDAS_FAT_WIN2K_SUPPORT__

	if (NdasFatFsRtlRegisterFileSystemFilterCallbacks) {

		RtlZeroMemory( &FilterCallbacks,
		               sizeof(FS_FILTER_CALLBACKS) );

		FilterCallbacks.SizeOfFsFilterCallbacks = sizeof(FS_FILTER_CALLBACKS);

		FilterCallbacks.PreAcquireForSectionSynchronization = FatFilterCallbackAcquireForCreateSection;

	    Status = NdasFatFsRtlRegisterFileSystemFilterCallbacks( DriverObject,
															  &FilterCallbacks );

	    if (!NT_SUCCESS( Status )) {

		    IoDeleteDevice( FatDiskFileSystemDeviceObject );
			IoDeleteDevice( FatCdromFileSystemDeviceObject );
			return Status;
		}
	}

#else

    RtlZeroMemory( &FilterCallbacks,
                   sizeof(FS_FILTER_CALLBACKS) );

    FilterCallbacks.SizeOfFsFilterCallbacks = sizeof(FS_FILTER_CALLBACKS);
    FilterCallbacks.PreAcquireForSectionSynchronization = FatFilterCallbackAcquireForCreateSection;

    Status = FsRtlRegisterFileSystemFilterCallbacks( DriverObject,
                                                     &FilterCallbacks );

    if (!NT_SUCCESS( Status )) {

        IoDeleteDevice( FatDiskFileSystemDeviceObject );
        IoDeleteDevice( FatCdromFileSystemDeviceObject );
        return Status;
    }

#endif

	}

#endif

    //
    //  Initialize the global data structures
    //

    //
    //  The FatData record
    //

    RtlZeroMemory( &FatData, sizeof(FAT_DATA));

    FatData.NodeTypeCode = FAT_NTC_DATA_HEADER;
    FatData.NodeByteSize = sizeof(FAT_DATA);

    InitializeListHead(&FatData.VcbQueue);

    FatData.DriverObject = DriverObject;
    FatData.DiskFileSystemDeviceObject = FatDiskFileSystemDeviceObject;
    FatData.CdromFileSystemDeviceObject = FatCdromFileSystemDeviceObject;

    //
    //  This list head keeps track of closes yet to be done.
    //

    InitializeListHead( &FatData.AsyncCloseList );
    InitializeListHead( &FatData.DelayedCloseList );
    
    FatData.FatCloseItem = IoAllocateWorkItem( FatDiskFileSystemDeviceObject);

    if (FatData.FatCloseItem == NULL) {
        IoDeleteDevice (FatDiskFileSystemDeviceObject);

#if __NDAS_FAT__
		if (FatCdromFileSystemDeviceObject)
#endif
        IoDeleteDevice (FatCdromFileSystemDeviceObject);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    //
    //  Now initialize our general purpose spinlock (gag) and figure out how
    //  deep and wide we want our delayed lists (along with fooling ourselves
    //  about the lookaside depths).
    //

    KeInitializeSpinLock( &FatData.GeneralSpinLock );

    switch ( MmQuerySystemSize() ) {

    case MmSmallSystem:

        MaxDepth = 4;
        FatMaxDelayedCloseCount = FAT_MAX_DELAYED_CLOSES;
        break;

    case MmMediumSystem:

        MaxDepth = 8;
        FatMaxDelayedCloseCount = 4 * FAT_MAX_DELAYED_CLOSES;
        break;

    case MmLargeSystem:

        MaxDepth = 16;
        FatMaxDelayedCloseCount = 16 * FAT_MAX_DELAYED_CLOSES;
        break;
    }


    //
    //  Initialize the cache manager callback routines
    //

    FatData.CacheManagerCallbacks.AcquireForLazyWrite  = &FatAcquireFcbForLazyWrite;
    FatData.CacheManagerCallbacks.ReleaseFromLazyWrite = &FatReleaseFcbFromLazyWrite;
    FatData.CacheManagerCallbacks.AcquireForReadAhead  = &FatAcquireFcbForReadAhead;
    FatData.CacheManagerCallbacks.ReleaseFromReadAhead = &FatReleaseFcbFromReadAhead;

    FatData.CacheManagerNoOpCallbacks.AcquireForLazyWrite  = &FatNoOpAcquire;
    FatData.CacheManagerNoOpCallbacks.ReleaseFromLazyWrite = &FatNoOpRelease;
    FatData.CacheManagerNoOpCallbacks.AcquireForReadAhead  = &FatNoOpAcquire;
    FatData.CacheManagerNoOpCallbacks.ReleaseFromReadAhead = &FatNoOpRelease;

    //
    //  Set up global pointer to our process.
    //

    FatData.OurProcess = PsGetCurrentProcess();

    //
    //  Read the registry to determine if we are in ChicagoMode.
    //

    ValueName.Buffer = COMPATIBILITY_MODE_VALUE_NAME;
    ValueName.Length = sizeof(COMPATIBILITY_MODE_VALUE_NAME) - sizeof(WCHAR);
    ValueName.MaximumLength = sizeof(COMPATIBILITY_MODE_VALUE_NAME);

    Status = FatGetCompatibilityModeValue( &ValueName, &Value );

    if (NT_SUCCESS(Status) && FlagOn(Value, 1)) {

        FatData.ChicagoMode = FALSE;

    } else {

        FatData.ChicagoMode = TRUE;
    }

    //
    //  Read the registry to determine if we are going to generate LFNs
    //  for valid 8.3 names with extended characters.
    //

    ValueName.Buffer = CODE_PAGE_INVARIANCE_VALUE_NAME;
    ValueName.Length = sizeof(CODE_PAGE_INVARIANCE_VALUE_NAME) - sizeof(WCHAR);
    ValueName.MaximumLength = sizeof(CODE_PAGE_INVARIANCE_VALUE_NAME);

    Status = FatGetCompatibilityModeValue( &ValueName, &Value );

    if (NT_SUCCESS(Status) && FlagOn(Value, 1)) {

        FatData.CodePageInvariant = FALSE;

    } else {

        FatData.CodePageInvariant = TRUE;
    }

    //
    //  Initialize our global resource and fire up the lookaside lists.
    //

    ExInitializeResourceLite( &FatData.Resource );

    ExInitializeNPagedLookasideList( &FatIrpContextLookasideList,
                                     NULL,
                                     NULL,
                                     POOL_RAISE_IF_ALLOCATION_FAILURE,
                                     sizeof(IRP_CONTEXT),
                                     TAG_IRP_CONTEXT,
                                     MaxDepth );

    ExInitializeNPagedLookasideList( &FatNonPagedFcbLookasideList,
                                     NULL,
                                     NULL,
                                     POOL_RAISE_IF_ALLOCATION_FAILURE,
                                     sizeof(NON_PAGED_FCB),
                                     TAG_FCB_NONPAGED,
                                     MaxDepth );

    ExInitializeNPagedLookasideList( &FatEResourceLookasideList,
                                     NULL,
                                     NULL,
                                     POOL_RAISE_IF_ALLOCATION_FAILURE,
                                     sizeof(ERESOURCE),
                                     TAG_ERESOURCE,
                                     MaxDepth );

    ExInitializeSListHead( &FatCloseContextSList );
    ExInitializeFastMutex( &FatCloseQueueMutex );
    KeInitializeEvent( &FatReserveEvent, SynchronizationEvent, TRUE );

    //
    //  Register the file system with the I/O system
    //

    IoRegisterFileSystem(FatDiskFileSystemDeviceObject);
    ObReferenceObject (FatDiskFileSystemDeviceObject);
#if __NDAS_FAT__
	if (FatCdromFileSystemDeviceObject) {

		IoRegisterFileSystem(FatCdromFileSystemDeviceObject);
		ObReferenceObject (FatCdromFileSystemDeviceObject);
	}
#else
    IoRegisterFileSystem(FatCdromFileSystemDeviceObject);
    ObReferenceObject (FatCdromFileSystemDeviceObject);
#endif

#if __NDAS_FAT__

	FatData.FileSystemRegistered = TRUE;

	RtlInitEmptyUnicodeString( &FatData.Root, 
							   FatData.RootBuffer,
							   sizeof(FatData.RootBuffer) );

	RtlInitUnicodeString( &tempUnicode, L"\\" );
	RtlCopyUnicodeString( &FatData.Root, &tempUnicode );

	RtlInitEmptyUnicodeString( &FatData.MountMgrRemoteDatabase, 
							   FatData.MountMgrRemoteDatabaseBuffer,
							   sizeof(FatData.MountMgrRemoteDatabaseBuffer) );

	RtlInitUnicodeString( &tempUnicode, L"\\:$MountMgrRemoteDatabase" );
	RtlCopyUnicodeString( &FatData.MountMgrRemoteDatabase, &tempUnicode );

	RtlInitEmptyUnicodeString( &FatData.ExtendReparse, 
							   FatData.ExtendReparseBuffer,
							   sizeof(FatData.ExtendReparseBuffer) );

	RtlInitUnicodeString( &tempUnicode, L"\\$Extend\\$Reparse:$R:$INDEX_ALLOCATION" );
	RtlCopyUnicodeString( &FatData.ExtendReparse, &tempUnicode );

	RtlInitEmptyUnicodeString( &FatData.MountPointManagerRemoteDatabase, 
							   FatData.MountPointManagerRemoteDatabaseBuffer,
							   sizeof(FatData.MountPointManagerRemoteDatabaseBuffer) );

	RtlInitUnicodeString( &tempUnicode, L"\\System Volume Information\\MountPointManagerRemoteDatabase" );
	RtlCopyUnicodeString( &FatData.MountPointManagerRemoteDatabase, &tempUnicode );

#endif

    //
    //  Find out if we are running an a FujitsuFMR machine.
    //

    FatData.FujitsuFMR = FatIsFujitsuFMR();

#if __NDAS_FAT__

    //
    //  Check to see if new kernel is present to decide if we want
    //  to support advance fcb headers
    //

    RtlInitUnicodeString( &UnicodeString, L"FsRtlTeardownPerStreamContexts" );
    FatFsRtlTeardownPerStreamContexts = MmGetSystemRoutineAddress( &UnicodeString );

#endif

    //
    //  And return to our caller
    //

    return( STATUS_SUCCESS );
}
Пример #24
0
static
VOID
Test_IoSetDeviceInterface(VOID)
{
    NTSTATUS Status;
    UNICODE_STRING SymbolicLinkName;
    PWCHAR Buffer;
    ULONG BufferSize;

    /* Invalid prefix or GUID */
    KmtStartSeh()
        Status = IoSetDeviceInterfaceState(NULL, TRUE);
    KmtEndSeh(STATUS_SUCCESS)
    ok_eq_hex(Status, STATUS_INVALID_PARAMETER);

    RtlInitEmptyUnicodeString(&SymbolicLinkName, NULL, 0);
    KmtStartSeh()
        Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE);
    KmtEndSeh(STATUS_SUCCESS)
    ok_eq_hex(Status, STATUS_INVALID_PARAMETER);

    RtlInitUnicodeString(&SymbolicLinkName, L"\\??");
    KmtStartSeh()
        Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE);
    KmtEndSeh(STATUS_SUCCESS)
    ok_eq_hex(Status, STATUS_INVALID_PARAMETER);

    RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\");
    KmtStartSeh()
        Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE);
    KmtEndSeh(STATUS_SUCCESS)
    ok_eq_hex(Status, STATUS_INVALID_PARAMETER);

    RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\\\");
    KmtStartSeh()
        Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE);
    KmtEndSeh(STATUS_SUCCESS)
    ok_eq_hex(Status, STATUS_INVALID_PARAMETER);

    RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}");
    KmtStartSeh()
        Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE);
    KmtEndSeh(STATUS_SUCCESS)
    ok_eq_hex(Status, STATUS_INVALID_PARAMETER);

    /* Valid prefix & GUID, invalid device node */
    RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\X{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}");
    KmtStartSeh()
        Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE);
    KmtEndSeh(STATUS_SUCCESS)
    ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND);

    RtlInitUnicodeString(&SymbolicLinkName, L"\\\\?\\X{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}");
    KmtStartSeh()
        Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE);
    KmtEndSeh(STATUS_SUCCESS)
    ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND);

    RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\X{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}\\");
    KmtStartSeh()
        Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE);
    KmtEndSeh(STATUS_SUCCESS)
    ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND);

    RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\#{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}");
    KmtStartSeh()
        Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE);
    KmtEndSeh(STATUS_SUCCESS)
    ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND);

    /* Must not read past the buffer */
    RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\#{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}");
    BufferSize = SymbolicLinkName.Length;
    Buffer = KmtAllocateGuarded(BufferSize);
    if (!skip(Buffer != NULL, "Failed to allocate %lu bytes\n", BufferSize))
    {
        RtlCopyMemory(Buffer, SymbolicLinkName.Buffer, BufferSize);
        SymbolicLinkName.Buffer = Buffer;
        SymbolicLinkName.MaximumLength = BufferSize;
        KmtStartSeh()
            Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE);
        KmtEndSeh(STATUS_SUCCESS)
        ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND);
        KmtFreeGuarded(Buffer);
    }

    RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\#aaaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}");
    BufferSize = SymbolicLinkName.Length;
    Buffer = KmtAllocateGuarded(BufferSize);
    if (!skip(Buffer != NULL, "Failed to allocate %lu bytes\n", BufferSize))
    {
        RtlCopyMemory(Buffer, SymbolicLinkName.Buffer, BufferSize);
        SymbolicLinkName.Buffer = Buffer;
        SymbolicLinkName.MaximumLength = BufferSize;
        KmtStartSeh()
            Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE);
        KmtEndSeh(STATUS_SUCCESS)
        ok_eq_hex(Status, STATUS_INVALID_PARAMETER);
        KmtFreeGuarded(Buffer);
    }
}
Пример #25
0
PNDAS_FCB
ReadonlyLookUpFcb (
	IN PFILESPY_DEVICE_EXTENSION	DevExt,
	IN PUNICODE_STRING				FullFileName,
    IN BOOLEAN						CaseInSensitive
	)
{
	PNDAS_FCB		fcb = NULL;
    PLIST_ENTRY		listEntry;
	KIRQL			oldIrql;
	UNICODE_STRING	caseInSensitiveFullFileName;
	PWCHAR			caseInSensitiveFullFileNameBuffer;
	NTSTATUS		downcaseStatus;

	//
	//	Allocate a name buffer
	//

	caseInSensitiveFullFileNameBuffer = ExAllocatePoolWithTag(NonPagedPool, NDFS_MAX_PATH, LFS_ALLOC_TAG);
	
	if (caseInSensitiveFullFileNameBuffer == NULL) {
	
		ASSERT( LFS_REQUIRED );
		return NULL;
	}

	ASSERT( FullFileName->Length <= NDFS_MAX_PATH*sizeof(WCHAR) );

	if (CaseInSensitive == TRUE) {

		RtlInitEmptyUnicodeString( &caseInSensitiveFullFileName,
								   caseInSensitiveFullFileNameBuffer,
								   NDFS_MAX_PATH );

		downcaseStatus = RtlDowncaseUnicodeString( &caseInSensitiveFullFileName,
												   FullFileName,
												   FALSE );
	
		if (downcaseStatus != STATUS_SUCCESS) {

			ExFreePool( caseInSensitiveFullFileNameBuffer );
			ASSERT( LFS_UNEXPECTED );
			return NULL;
		}
	}

	KeAcquireSpinLock( &DevExt->LfsDeviceExt.Readonly->FcbQSpinLock, &oldIrql );

    for (listEntry = DevExt->LfsDeviceExt.Readonly->FcbQueue.Flink;
         listEntry != &DevExt->LfsDeviceExt.Readonly->FcbQueue;
         listEntry = listEntry->Flink) {

		fcb = CONTAINING_RECORD( listEntry, NDAS_FCB, ListEntry );
		
		if (fcb->FullFileName.Length != FullFileName->Length) {

			fcb = NULL;
			continue;
		}

		if (CaseInSensitive == TRUE) {

			if (RtlEqualMemory(fcb->CaseInSensitiveFullFileName.Buffer, 
							   caseInSensitiveFullFileName.Buffer, 
							   fcb->CaseInSensitiveFullFileName.Length)) {

				InterlockedIncrement( &fcb->ReferenceCount );
				break;
			}
		
		} else {

			if (RtlEqualMemory(fcb->FullFileName.Buffer,
							   FullFileName->Buffer,
							   fcb->FullFileName.Length)) {

				InterlockedIncrement( &fcb->ReferenceCount );
				break;
			}
		}

		fcb = NULL;
	}

	KeReleaseSpinLock( &DevExt->LfsDeviceExt.Readonly->FcbQSpinLock, oldIrql );

	ExFreePool( caseInSensitiveFullFileNameBuffer );

	return fcb;
}
Пример #26
0
DWORD
WINAPI
PlayLogonSoundThread(
    IN LPVOID lpParameter)
{
    BYTE TokenUserBuffer[256];
    PTOKEN_USER pTokenUser = (TOKEN_USER*)TokenUserBuffer;
    ULONG Length;
    HKEY hKey;
    WCHAR wszBuffer[MAX_PATH] = {0};
    WCHAR wszDest[MAX_PATH];
    DWORD dwSize = sizeof(wszBuffer), dwType;
    SERVICE_STATUS_PROCESS Info;
    UNICODE_STRING SidString;
    NTSTATUS Status;
    ULONG Index = 0;
    SC_HANDLE hSCManager, hService;

    /* Get SID of current user */
    Status = NtQueryInformationToken((HANDLE)lpParameter,
                                     TokenUser,
                                     TokenUserBuffer,
                                     sizeof(TokenUserBuffer),
                                     &Length);
    if (!NT_SUCCESS(Status))
    {
        ERR("NtQueryInformationToken failed: %x!\n", Status);
        return 0;
    }

    /* Convert SID to string */
    RtlInitEmptyUnicodeString(&SidString, wszBuffer, sizeof(wszBuffer));
    Status = RtlConvertSidToUnicodeString(&SidString, pTokenUser->User.Sid, FALSE);
    if (!NT_SUCCESS(Status))
    {
        ERR("RtlConvertSidToUnicodeString failed: %x!\n", Status);
        return 0;
    }

    /* Build path to logon sound registry key.
       Note: We can't use HKCU here, because Winlogon is owned by SYSTEM user */
    if (FAILED(StringCbCopyW(wszBuffer + SidString.Length/sizeof(WCHAR),
                             sizeof(wszBuffer) - SidString.Length,
                             L"\\AppEvents\\Schemes\\Apps\\.Default\\WindowsLogon\\.Current")))
    {
        /* SID is too long. Should not happen. */
        ERR("StringCbCopyW failed!\n");
        return 0;
    }

    /* Open registry key and query sound path */
    if (RegOpenKeyExW(HKEY_USERS, wszBuffer, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
    {
        ERR("RegOpenKeyExW(%ls) failed!\n", wszBuffer);
        return 0;
    }

    if (RegQueryValueExW(hKey, NULL, NULL, &dwType,
                      (LPBYTE)wszBuffer, &dwSize) != ERROR_SUCCESS ||
        (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
    {
        ERR("RegQueryValueExW failed!\n");
        RegCloseKey(hKey);
        return 0;
    }

    RegCloseKey(hKey);

    if (!wszBuffer[0])
    {
        /* No sound has been set */
        ERR("No sound has been set\n");
        return 0;
    }

    /* Expand environment variables */
    if (!ExpandEnvironmentStringsW(wszBuffer, wszDest, MAX_PATH))
    {
        ERR("ExpandEnvironmentStringsW failed!\n");
        return 0;
    }

    /* Open service manager */
    hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
    if (!hSCManager)
    {
        ERR("OpenSCManager failed (%x)\n", GetLastError());
        return 0;
    }

    /* Open wdmaud service */
    hService = OpenServiceW(hSCManager, L"wdmaud", GENERIC_READ);
    if (!hService)
    {
        /* Sound is not installed */
        TRACE("Failed to open wdmaud service (%x)\n", GetLastError());
        CloseServiceHandle(hSCManager);
        return 0;
    }

    /* Wait for wdmaud start */
    do
    {
        if (!QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&Info, sizeof(SERVICE_STATUS_PROCESS), &dwSize))
        {
            TRACE("QueryServiceStatusEx failed (%x)\n", GetLastError());
            break;
        }

        if (Info.dwCurrentState == SERVICE_RUNNING)
            break;

        Sleep(1000);

    } while (Index++ < 20);

    CloseServiceHandle(hService);
    CloseServiceHandle(hSCManager);

    /* If wdmaud is not running exit */
    if (Info.dwCurrentState != SERVICE_RUNNING)
    {
        WARN("wdmaud has not started!\n");
        return 0;
    }

    /* Sound subsystem is running. Play logon sound. */
    TRACE("Playing logon sound: %ls\n", wszDest);
    PlaySoundRoutine(wszDest, TRUE, SND_FILENAME);
    return 0;
}
Пример #27
0
BOOLEAN	
GetScsiportAdapter(
  	IN	PDEVICE_OBJECT				DiskDeviceObject,
  	IN	PDEVICE_OBJECT				*ScsiportAdapterDeviceObject
	) 
{
	SCSI_ADDRESS		ScsiAddress;
	NTSTATUS			ntStatus;
	UNICODE_STRING		ScsiportAdapterName;
	WCHAR				ScsiportAdapterNameBuffer[32];
	WCHAR				ScsiportAdapterNameTemp[32]	= L"";
    OBJECT_ATTRIBUTES	objectAttributes;
    HANDLE				fileHandle					= NULL;
	IO_STATUS_BLOCK		IoStatus;
	PFILE_OBJECT		ScsiportDeviceFileObject	= NULL;

	ntStatus = LfsFilterDeviceIoControl( 
								DiskDeviceObject,
			                    IOCTL_SCSI_GET_ADDRESS,
								NULL,
								0,
						        &ScsiAddress,
							    sizeof(SCSI_ADDRESS),
								NULL 
								);
	if(!NT_SUCCESS(ntStatus)) {
		SPY_LOG_PRINT( LFS_DEBUG_LFS_INFO, ("GetScsiportAdapter: LfsFilterDeviceIoControl() failed.\n"));
		goto error_out;

	}

    SPY_LOG_PRINT( LFS_DEBUG_LFS_TRACE, ("GetScsiportAdapter: ScsiAddress=Len:%d PortNumber:%d PathId:%d TargetId:%d Lun:%d\n",
						(LONG)ScsiAddress.Length,
						(LONG)ScsiAddress.PortNumber,
						(LONG)ScsiAddress.PathId,
						(LONG)ScsiAddress.TargetId,
						(LONG)ScsiAddress.Lun
						));


	_snwprintf(
		ScsiportAdapterNameTemp,
		32 * sizeof(WCHAR),
		L"\\Device\\ScsiPort%d",
		ScsiAddress.PortNumber
    );

	RtlInitEmptyUnicodeString( &ScsiportAdapterName, ScsiportAdapterNameBuffer, sizeof( ScsiportAdapterNameBuffer ) );
    RtlAppendUnicodeToString( &ScsiportAdapterName, ScsiportAdapterNameTemp );

	InitializeObjectAttributes( &objectAttributes,
							&ScsiportAdapterName,
							OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
							NULL,
							NULL);

    //
	// open the file object for the given device
	//
    ntStatus = ZwCreateFile( &fileHandle,
						   SYNCHRONIZE|FILE_READ_DATA,
						   &objectAttributes,
						   &IoStatus,
						   NULL,
						   0,
						   FILE_SHARE_READ | FILE_SHARE_WRITE,
						   FILE_OPEN,
						   FILE_SYNCHRONOUS_IO_NONALERT,
						   NULL,
						   0);
    if (!NT_SUCCESS( ntStatus )) {
	    SPY_LOG_PRINT( LFS_DEBUG_LFS_INFO, ("GetScsiportAdapter: ZwCreateFile() failed.\n"));
		goto error_out;

	}

    ntStatus = ObReferenceObjectByHandle( fileHandle,
										FILE_READ_DATA,
										*IoFileObjectType,
										KernelMode,
										&ScsiportDeviceFileObject,
										NULL);
    if(!NT_SUCCESS( ntStatus )) {

		SPY_LOG_PRINT( LFS_DEBUG_LFS_INFO, ("GetScsiportAdapter: ObReferenceObjectByHandle() failed.\n"));
        goto error_out;
    }

	*ScsiportAdapterDeviceObject = IoGetRelatedDeviceObject(
											ScsiportDeviceFileObject
									    );

	if(*ScsiportAdapterDeviceObject == NULL) {

		SPY_LOG_PRINT( LFS_DEBUG_LFS_INFO, ("GetScsiportAdapter: IoGetRelatedDeviceObject() failed.\n"));
		ObDereferenceObject(ScsiportDeviceFileObject);
        goto error_out;
	}

	ObDereferenceObject(ScsiportDeviceFileObject);
	ZwClose(fileHandle);
	ObReferenceObject(*ScsiportAdapterDeviceObject);

	return TRUE;

error_out:
	
	*ScsiportAdapterDeviceObject = NULL;
	if(fileHandle)
		ZwClose(fileHandle);

	return FALSE;
}
Пример #28
0
PPRIMARY_SESSION
PrimarySession_Create (
	IN  PIRP_CONTEXT			IrpContext,  
	IN	PVOLUME_DEVICE_OBJECT	VolDo,		 
	IN  PSESSION_INFORMATION	SessionInformation,
	IN  PIRP					Irp
	)
{
	PPRIMARY_SESSION	primarySession;
 	OBJECT_ATTRIBUTES	objectAttributes;
	NTSTATUS			status;
	LARGE_INTEGER		timeOut;

		
	ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );

	VolDo_Reference( VolDo );

	primarySession = FsRtlAllocatePoolWithTag( NonPagedPool, sizeof(PRIMARY_SESSION), NDFAT_ALLOC_TAG );
	
	if (primarySession == NULL) {

		ASSERT( NDASFAT_INSUFFICIENT_RESOURCES );
		VolDo_Dereference( VolDo );
		return NULL;
	}

	try {
	
		RtlZeroMemory( primarySession, sizeof(PRIMARY_SESSION) );

		primarySession->Flags = PRIMARY_SESSION_FLAG_INITIALIZING;

		primarySession->ReferenceCount = 1;
		primarySession->VolDo = VolDo;
		
		ExInitializeFastMutex( &primarySession->FastMutex )
		
		InitializeListHead( &primarySession->ListEntry );

		primarySession->NetdiskPartitionInformation = SessionInformation->NetdiskPartitionInformation;
	
		RtlInitEmptyUnicodeString( &primarySession->NetdiskPartitionInformation.VolumeName,
								   primarySession->NetdiskPartitionInformation.VolumeNameBuffer,
								   sizeof(primarySession->NetdiskPartitionInformation.VolumeNameBuffer) );

		if (RtlAppendUnicodeStringToString( &primarySession->NetdiskPartitionInformation.VolumeName,
											&SessionInformation->NetdiskPartitionInformation.VolumeName) != STATUS_SUCCESS) {

			ASSERT( NDASFAT_UNEXPECTED );
		}

		ASSERT( primarySession->NetdiskPartitionInformation.VolumeName.Buffer == primarySession->NetdiskPartitionInformation.VolumeNameBuffer );

		primarySession->ConnectionFileHandle		= SessionInformation->ConnectionFileHandle;
		primarySession->ConnectionFileObject		= SessionInformation->ConnectionFileObject;

		primarySession->RemoteAddress				= SessionInformation->RemoteAddress;
		primarySession->IsLocalAddress				= SessionInformation->IsLocalAddress;

		primarySession->Irp									= Irp;

		primarySession->SessionContext = SessionInformation->SessionContext;

		primarySession->SessionContext.PrimaryMaxDataSize	= DEFAULT_NDAS_MAX_DATA_SIZE; //SessionInformation->PrimaryMaxDataSize;
		primarySession->SessionContext.SecondaryMaxDataSize	= DEFAULT_NDAS_MAX_DATA_SIZE; // SessionInformation->SecondaryMaxDataSize;

		DebugTrace2( 0, Dbg2, ("primarySession->ConnectionFileHandle = %x " 
							   "primarySession->SessionContext.PrimaryMaxDataSize = %x primarySession->SessionContext.SecondaryMaxDataSize = %x\n", 
							    primarySession->ConnectionFileHandle, primarySession->SessionContext.PrimaryMaxDataSize, primarySession->SessionContext.SecondaryMaxDataSize) );

		KeInitializeEvent( &primarySession->ReadyEvent, NotificationEvent, FALSE );
	
		InitializeListHead( &primarySession->RequestQueue );
		KeInitializeSpinLock( &primarySession->RequestQSpinLock );
		KeInitializeEvent( &primarySession->RequestEvent, NotificationEvent, FALSE );

		primarySession->ThreadHandle = 0;
		primarySession->ThreadObject = NULL;

		primarySession->Thread.TdiReceiveContext.Irp = NULL;
		KeInitializeEvent( &primarySession->Thread.TdiReceiveContext.CompletionEvent, NotificationEvent, FALSE );

		InitializeObjectAttributes( &objectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL );

		primarySession->Thread.SessionState = SESSION_TREE_CONNECT;
	
		ExInterlockedInsertTailList( &VolDo->PrimarySessionQueue,
									 &primarySession->ListEntry,
									 &VolDo->PrimarySessionQSpinLock );

		status = PsCreateSystemThread( &primarySession->ThreadHandle,
									   THREAD_ALL_ACCESS,
									   &objectAttributes,
									   NULL,
									   NULL,
									   PrimarySessionThreadProc,
									   primarySession );
	
		if (!NT_SUCCESS(status)) {

			leave;
		}

		status = ObReferenceObjectByHandle( primarySession->ThreadHandle,
											FILE_READ_DATA,
											NULL,
											KernelMode,
											&primarySession->ThreadObject,
											NULL );

		if (!NT_SUCCESS(status)) {

			leave;
		}

		timeOut.QuadPart = -NDASFAT_TIME_OUT;
		status = KeWaitForSingleObject( &primarySession->ReadyEvent,
										Executive,
										KernelMode,
										FALSE,
										&timeOut );


		if (!NT_SUCCESS(status)) {

			leave;
		}

		KeClearEvent( &primarySession->ReadyEvent );

		DebugTrace2( 0, Dbg, ("PrimarySession_Create: The primary thread are ready\n") );
	
		DebugTrace2( 0, Dbg2, ("Fat PrimarySession_Create: primarySession = %p\n", primarySession) );
	
	} finally {

		if (AbnormalTermination()) {

			status = IrpContext->ExceptionStatus;
		}

		if (!NT_SUCCESS(status)) {

			ASSERT( NDASFAT_UNEXPECTED );
			PrimarySession_Close( primarySession );
			primarySession = NULL;
		}
	}

	return primarySession;
}
Пример #29
0
BOOL
NTAPI
BaseCreateVDMEnvironment(IN PWCHAR lpEnvironment,
                         IN PANSI_STRING AnsiEnv,
                         IN PUNICODE_STRING UnicodeEnv)
{
    BOOL Result;
    ULONG RegionSize, EnvironmentSize = 0;
    PWCHAR p, Environment, NewEnvironment;
    NTSTATUS Status;

    /* Make sure we have both strings */
    if (!(AnsiEnv) || !(UnicodeEnv))
    {
        /* Fail */
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    /* Check if an environment was passed in */
    if (!lpEnvironment)
    {
        /* Nope, create one */
        Status = RtlCreateEnvironment(TRUE, (PWCHAR*)&Environment);
        if (!NT_SUCCESS(Status)) goto Quickie;
    }
    else
    {
        /* Use the one we got */
        Environment = lpEnvironment;
    }

    /* Do we have something now ? */
    if (!Environment)
    {
        /* Still not, fail out */
        SetLastError(ERROR_BAD_ENVIRONMENT);
        goto Quickie;
    }

    /* Count how much space the whole environment takes */
    p = Environment;
    while ((*p++ != UNICODE_NULL) && (*p != UNICODE_NULL)) EnvironmentSize++;
    EnvironmentSize += sizeof(UNICODE_NULL);

    /* Allocate a new copy */
    RegionSize = (EnvironmentSize + MAX_PATH) * sizeof(WCHAR);
    if (!NT_SUCCESS(NtAllocateVirtualMemory(NtCurrentProcess(),
                                            (PVOID*)&NewEnvironment,
                                            0,
                                            &RegionSize,
                                            MEM_COMMIT,
                                            PAGE_READWRITE)))
    {
        /* We failed, bail out */
        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        NewEnvironment = NULL;
        goto Quickie;
    }

    /* Begin parsing the new environment */
    p = NewEnvironment;

    /* FIXME: Code here */

    /* Terminate it */
    *p++ = UNICODE_NULL;

    /* Initialize the unicode string to hold it */
    EnvironmentSize = (p - NewEnvironment) * sizeof(WCHAR);
    RtlInitEmptyUnicodeString(UnicodeEnv, NewEnvironment, EnvironmentSize);
    UnicodeEnv->Length = EnvironmentSize;

    /* Create the ASCII version of it */
    Status = RtlUnicodeStringToAnsiString(AnsiEnv, UnicodeEnv, TRUE);
    if (!NT_SUCCESS(Status))
    {
        /* Set last error if conversion failure */
        BaseSetLastNTError(Status);
    }
    else
    {
        /* Everything went okay, so return success */
        Result = TRUE;
        NewEnvironment = NULL;
    }

Quickie:
    /* Cleanup path starts here, start by destroying the envrionment copy */
    if (!(lpEnvironment) && (Environment)) RtlDestroyEnvironment(Environment);

    /* See if we are here due to failure */
    if (NewEnvironment)
    {
        /* Initialize the paths to be empty */
        RtlInitEmptyUnicodeString(UnicodeEnv, NULL, 0);
        RtlInitEmptyAnsiString(AnsiEnv, NULL, 0);

        /* Free the environment copy */
        RegionSize = 0;
        Status = NtFreeVirtualMemory(NtCurrentProcess(),
                                     (PVOID*)&NewEnvironment,
                                     &RegionSize,
                                     MEM_RELEASE);
        ASSERT(NT_SUCCESS(Status));
    }

    /* Return the result */
    return Result;
}
Пример #30
0
int _tmain(int argc, _TCHAR* argv[])
{
    NTSTATUS Status;
    HANDLE LinkHandle, OddHandle;
    WCHAR TargetBuffer[MAX_PATH] = {0};
    WCHAR TargetBuffer2[MAX_PATH] = {0};
    UNICODE_STRING TargetName;
    UNICODE_STRING TargetName2;
    UNICODE_STRING OkName = RTL_CONSTANT_STRING(L"\\TestLink");
    ULONG NameSize;

    //
    // Start with the create tests
    //
    LinkHandle = SymlinkCreateTests(&OddHandle);

    //
    // Setup the two empty strings. One will have a magic-char at the end
    //
    RtlInitEmptyUnicodeString(&TargetName, TargetBuffer, sizeof(TargetBuffer));
    RtlInitEmptyUnicodeString(&TargetName2, TargetBuffer2, sizeof(TargetBuffer2));

    //
    // Now query the odd link
    //
    Status = NtQuerySymbolicLinkObject(OddHandle,
                                       &TargetName,
                                       &NameSize);
    TEST_ASSERT(NT_SUCCESS(Status));
    TEST_ASSERT(NameSize == sizeof(WCHAR));
    TEST_ASSERT(TargetName.Length == NameSize);
    TEST_ASSERT(TargetName.Buffer[0] == OBJ_NAME_PATH_SEPARATOR);
    NtClose(OddHandle);

    //
    // Now query the test link
    //
    Status = NtQuerySymbolicLinkObject(LinkHandle,
                                       &TargetName,
                                       &NameSize);
    TEST_ASSERT(NT_SUCCESS(Status));
    TEST_ASSERT(NameSize == 2 * sizeof(WCHAR));
    TEST_ASSERT(TargetName.Length == NameSize - sizeof(WCHAR));
    TEST_ASSERT(TargetName.Buffer[0] == OBJ_NAME_PATH_SEPARATOR);

    //
    // Corrupt the characters
    //
    TargetName.Buffer[(NameSize - 2) / sizeof(WCHAR)] = 'v';
    TargetName.Buffer[(NameSize - 3) / sizeof(WCHAR)] = 'v';

    //
    // Now query the test link
    //
    Status = NtQuerySymbolicLinkObject(LinkHandle,
                                       &TargetName,
                                       &NameSize);
    TEST_ASSERT(NT_SUCCESS(Status));
    TEST_ASSERT(TargetName.Buffer[0] == OBJ_NAME_PATH_SEPARATOR);
    TEST_ASSERT(TargetName.Buffer[1] == UNICODE_NULL);

    //
    // Corrupt the characters
    //
    TargetName.Buffer[(NameSize - 2) / sizeof(WCHAR)] = 'v';
    TargetName.Buffer[(NameSize - 3) / sizeof(WCHAR)] = 'v';

    //
    // Now query the test link
    //
    Status = NtQuerySymbolicLinkObject(LinkHandle,
                                       &TargetName,
                                       NULL);
    TEST_ASSERT(NT_SUCCESS(Status));
    TEST_ASSERT(TargetName.Buffer[0] == OBJ_NAME_PATH_SEPARATOR);
    TEST_ASSERT(TargetName.Buffer[1] == 'v');

    //
    // Print out results
    //
    {
    RTL_OSVERSIONINFOW VersionInfo;
    VersionInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOW);
    RtlGetVersion(&VersionInfo);
    printf("Test complete on: %d\n", VersionInfo.dwBuildNumber);
    printf("Number of Failures: %d\n", Failures);
    printf("Number of Runs: %d\n", Runs);
    }
	return 0;
}