Пример #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
VOID
CsampUnload(
    __in PDRIVER_OBJECT DriverObject
    )
/*++

Routine Description:

    Free all the allocated resources, etc.

Arguments:

    DriverObject - pointer to a driver object.

Return Value:

    VOID
--*/
{
    PDEVICE_OBJECT      deviceObject = DriverObject->DeviceObject;
    UNICODE_STRING      uniWin32NameString;
    PDEVICE_EXTENSION   devExtension = deviceObject->DeviceExtension;

    PAGED_CODE();

    CSAMP_KDPRINT(("CsampUnload Enter\n"));

    //
    // Set the Stop flag
    //
    devExtension->ThreadShouldStop = TRUE;

    //
    // Make sure the thread wakes up
    //
    KeReleaseSemaphore(&devExtension->IrpQueueSemaphore,
                        0,  // No priority boost
                        1,  // Increment semaphore by 1
                        TRUE );// WaitForXxx after this call

    //
    // Wait for the thread to terminate
    //
    KeWaitForSingleObject(devExtension->ThreadObject,
                        Executive,
                        KernelMode,
                        FALSE,
                        NULL );

    ObDereferenceObject(devExtension->ThreadObject);

    //
    // Create counted string version of our Win32 device name.
    //

    RtlInitUnicodeString( &uniWin32NameString, CSAMP_DOS_DEVICE_NAME_U );

    IoDeleteSymbolicLink( &uniWin32NameString );

    ASSERT(!deviceObject->AttachedDevice);

    IoDeleteDevice( deviceObject );

    CSAMP_KDPRINT(("CsampUnload Exit\n"));
    return;
}
Пример #3
0
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,
                     IN PUNICODE_STRING RegistryPath)
/*++

Routine Description:

    This routine is called when the driver is loaded by NT.

Arguments:

    DriverObject - Pointer to driver object created by system.
    RegistryPath - Pointer to the name of the services node for this driver.

Return Value:

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

--*/
{
	
	
    NTSTATUS        ntStatus;
    PVOID           BufDriverString=NULL,BufProcessEventString=NULL,BufThreadEventString=NULL;
    UNICODE_STRING  uszDriverString;
    
    UNICODE_STRING  uszProcessEventString;
	UNICODE_STRING	uszThreadEventString;
    PDEVICE_OBJECT  pDeviceObject;
	HANDLE reg=0;
	OBJECT_ATTRIBUTES oa;

	UNICODE_STRING temp; 
	char wbuf[100]; 
	WORD this_cs, this_ss, this_ds, this_es, this_fs, this_gs;
	ULONG cr4reg;

	
	
	criticalSection csTest;
	
	DbgPrint("sizeof(DS_AREA_MANAGEMENT)=%d\n", sizeof(DS_AREA_MANAGEMENT));
	DbgPrint("sizeof(BTS)=%d\n", sizeof(BTS));



	//DbgPrint("%S",oa.ObjectName.Buffer); 
	
	KernelCodeStepping=0;
	

	

	this_cs=getCS();
	this_ss=getSS();
	this_ds=getDS();
	this_es=getES();
	this_fs=getFS();
	this_gs=getGS();	

#ifdef AMD64
	DbgPrint("cs=%x ss=%x ds=%x es=%x fs=%x gs=%x\n",getCS(), getSS(), getDS(), getES(), getFS(), getGS());

	DbgPrint("fsbase=%llx gsbase=%llx gskernel=%llx\n", readMSR(0xc0000100), readMSR(0xc0000101), readMSR(0xc0000102));

	DbgPrint("rbp=%llx\n", getRBP());

	DbgPrint("gs:188=%llx\n", __readgsqword(0x188));
	DbgPrint("current csr=%x\n", _mm_getcsr());
#endif
	
	

	DbgPrint("Test critical section routines\n");
	RtlZeroMemory(&csTest,sizeof(criticalSection));
	DbgPrint("csTest.locked=%d\n",csTest.locked);
	csEnter(&csTest);
	DbgPrint("After enter\n");
	DbgPrint("csTest.locked=%d\n",csTest.locked);
	csLeave(&csTest);
	
	DbgPrint("After leave\n");
	DbgPrint("csTest.locked=%d\n",csTest.locked);
	
	

	

	
	//lame antiviruses and more lamer users that keep crying rootkit virus....
	temp.Buffer=(PWCH)wbuf;
	temp.Length=0;
	temp.MaximumLength=100;
	
	RtlAppendUnicodeToString(&temp, L"Ke"); //KeServiceDescriptorTable 
	RtlAppendUnicodeToString(&temp, L"Service");
	RtlAppendUnicodeToString(&temp, L"Descriptor");
	RtlAppendUnicodeToString(&temp, L"Table");
	
	KeServiceDescriptorTable=MmGetSystemRoutineAddress(&temp);         

	DbgPrint("Loading driver\n");
	if (RegistryPath)
	{	
		DbgPrint("Registry path = %S\n", RegistryPath->Buffer);

		InitializeObjectAttributes(&oa,RegistryPath,OBJ_KERNEL_HANDLE ,NULL,NULL);
		ntStatus=ZwOpenKey(&reg,KEY_QUERY_VALUE,&oa);
		if (ntStatus == STATUS_SUCCESS)
		{
			UNICODE_STRING A,B,C,D;
			PKEY_VALUE_PARTIAL_INFORMATION bufA,bufB,bufC,bufD;
			ULONG ActualSize;

			DbgPrint("Opened the key\n");

			BufDriverString=ExAllocatePool(PagedPool,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100);
			BufDeviceString=ExAllocatePool(PagedPool,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100);
			BufProcessEventString=ExAllocatePool(PagedPool,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100);
			BufThreadEventString=ExAllocatePool(PagedPool,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100);

			bufA=BufDriverString;
			bufB=BufDeviceString;
			bufC=BufProcessEventString;
			bufD=BufThreadEventString;

			RtlInitUnicodeString(&A, L"A");
			RtlInitUnicodeString(&B, L"B");
			RtlInitUnicodeString(&C, L"C");
			RtlInitUnicodeString(&D, L"D");

			if (ntStatus == STATUS_SUCCESS)
				ntStatus=ZwQueryValueKey(reg,&A,KeyValuePartialInformation ,bufA,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100,&ActualSize);
			if (ntStatus == STATUS_SUCCESS)
				ntStatus=ZwQueryValueKey(reg,&B,KeyValuePartialInformation ,bufB,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100,&ActualSize);
			if (ntStatus == STATUS_SUCCESS)
				ntStatus=ZwQueryValueKey(reg,&C,KeyValuePartialInformation ,bufC,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100,&ActualSize);
			if (ntStatus == STATUS_SUCCESS)
				ntStatus=ZwQueryValueKey(reg,&D,KeyValuePartialInformation ,bufD,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100,&ActualSize);

			if (ntStatus == STATUS_SUCCESS)
			{
				DbgPrint("Read ok\n");
				RtlInitUnicodeString(&uszDriverString,(PCWSTR) bufA->Data);
				RtlInitUnicodeString(&uszDeviceString,(PCWSTR) bufB->Data);
				RtlInitUnicodeString(&uszProcessEventString,(PCWSTR) bufC->Data);
				RtlInitUnicodeString(&uszThreadEventString,(PCWSTR) bufD->Data);

				DbgPrint("DriverString=%S\n",uszDriverString.Buffer);
				DbgPrint("DeviceString=%S\n",uszDeviceString.Buffer);
				DbgPrint("ProcessEventString=%S\n",uszProcessEventString.Buffer);
				DbgPrint("ThreadEventString=%S\n",uszThreadEventString.Buffer);
			}
			else
			{
				ExFreePool(bufA);
				ExFreePool(bufB);
				ExFreePool(bufC);
				ExFreePool(bufD);

				DbgPrint("Failed reading the value\n");
				ZwClose(reg);
				return STATUS_UNSUCCESSFUL;;
			}

		}
		else
		{
			DbgPrint("Failed opening the key\n");
			return STATUS_UNSUCCESSFUL;;
		}
	}
	else
	  loadedbydbvm=TRUE;

	ntStatus = STATUS_SUCCESS;


	


	if (!loadedbydbvm)
	{

		// Point uszDriverString at the driver name
#ifndef CETC
		
		
		// Create and initialize device object
		ntStatus = IoCreateDevice(DriverObject,
								  0,
								  &uszDriverString,
								  FILE_DEVICE_UNKNOWN,
								  0,
								  FALSE,
								  &pDeviceObject);

		if(ntStatus != STATUS_SUCCESS)
		{
			DbgPrint("IoCreateDevice failed\n");
			ExFreePool(BufDriverString);
			ExFreePool(BufDeviceString);
			ExFreePool(BufProcessEventString);
			ExFreePool(BufThreadEventString);

			
			if (reg)
			  ZwClose(reg);

			return ntStatus;
		}

		// Point uszDeviceString at the device name
		
		// Create symbolic link to the user-visible name
		ntStatus = IoCreateSymbolicLink(&uszDeviceString, &uszDriverString);

		if(ntStatus != STATUS_SUCCESS)
		{
			DbgPrint("IoCreateSymbolicLink failed: %x\n",ntStatus);
			// Delete device object if not successful
			IoDeleteDevice(pDeviceObject);

			ExFreePool(BufDriverString);
			ExFreePool(BufDeviceString);
			ExFreePool(BufProcessEventString);
			ExFreePool(BufThreadEventString);
			

			if (reg)
			  ZwClose(reg);

			return ntStatus;
		}

#endif
	}

	//when loaded by dbvm driver object is 'valid' so store the function addresses


	DbgPrint("DriverObject=%p\n", DriverObject);

    // Load structure to point to IRP handlers...
    DriverObject->DriverUnload                         = UnloadDriver;
    DriverObject->MajorFunction[IRP_MJ_CREATE]         = DispatchCreate;
    DriverObject->MajorFunction[IRP_MJ_CLOSE]          = DispatchClose;	

	if (loadedbydbvm)
		DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = (PDRIVER_DISPATCH)DispatchIoctlDBVM;		
	else
		DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl;



	//Processlist init
#ifndef CETC

	ProcessEventCount=0;
	KeInitializeSpinLock(&ProcesslistSL);
#endif

	CreateProcessNotifyRoutineEnabled=FALSE;

	//threadlist init
	ThreadEventCount=0;
	
	BufferSize=0;
	processlist=NULL;

#ifndef AMD64
    //determine if PAE is used
	cr4reg=(ULONG)getCR4();

	if ((cr4reg & 0x20)==0x20)
	{
		PTESize=8; //pae
		PAGE_SIZE_LARGE=0x200000;
		MAX_PDE_POS=0xC0604000;
		MAX_PTE_POS=0xC07FFFF8;

		
	}
	else
	{
		PTESize=4;
		PAGE_SIZE_LARGE=0x400000;
		MAX_PDE_POS=0xC0301000;
		MAX_PTE_POS=0xC03FFFFC;
	}
#else
	PTESize=8; //pae
	PAGE_SIZE_LARGE=0x200000;
	MAX_PTE_POS=0xFFFFF6FFFFFFFFF8ULL;
	MAX_PDE_POS=0xFFFFF6FB7FFFFFF8ULL;
#endif

#ifdef CETC
	DbgPrint("Going to initialice CETC\n");
	InitializeCETC();
#endif


    //hideme(DriverObject); //ok, for those that see this, enabling this WILL f**k up try except routines, even in usermode you'll get a blue sreen

	DbgPrint("Initializing debugger\n");
	debugger_initialize();


	// Return success (don't do the devicestring, I need it for unload)
	DbgPrint("Cleaning up initialization buffers\n");
	if (BufDriverString)
	{
		ExFreePool(BufDriverString);
		BufDriverString=NULL;
	}

	if (BufProcessEventString)
	{
		ExFreePool(BufProcessEventString);
		BufProcessEventString=NULL;
	}

	if (BufThreadEventString)
	{
		ExFreePool(BufThreadEventString);
		BufThreadEventString=NULL;
	}

	if (reg)
	{
		ZwClose(reg); 
		reg=0;
	}

	

	//fetch cpu info
	{
		DWORD r[4];
		DWORD a;

		__cpuid(r,0);
		if (r[0]==0x756e6547) //Genu
		{

			__cpuid(r,1);

			a=r[0];
			
			cpu_stepping=a & 0xf;
			cpu_model=(a >> 4) & 0xf;
			cpu_familyID=(a >> 8) & 0xf;
			cpu_type=(a >> 12) & 0x3;
			cpu_ext_modelID=(a >> 16) & 0xf;
			cpu_ext_familyID=(a >> 20) & 0xff;

			cpu_model=cpu_model + (cpu_ext_modelID << 4);
			cpu_familyID=cpu_familyID + (cpu_ext_familyID << 4);
		}



	}
Пример #4
0
static NTSTATUS
IopGetRelatedDevice(PPLUGPLAY_CONTROL_RELATED_DEVICE_DATA RelatedDeviceData)
{
    UNICODE_STRING RootDeviceName;
    PDEVICE_OBJECT DeviceObject = NULL;
    PDEVICE_NODE DeviceNode = NULL;
    PDEVICE_NODE RelatedDeviceNode;
    UNICODE_STRING TargetDeviceInstance;
    NTSTATUS Status = STATUS_SUCCESS;
    ULONG Relation = 0;
    ULONG MaximumLength = 0;

    DPRINT("IopGetRelatedDevice() called\n");
    DPRINT("Device name: %wZ\n", &RelatedDeviceData->TargetDeviceInstance);

    Status = IopCaptureUnicodeString(&TargetDeviceInstance, &RelatedDeviceData->TargetDeviceInstance);
    if (!NT_SUCCESS(Status))
    {
        return Status;
    }

    _SEH2_TRY
    {
        Relation = RelatedDeviceData->Relation;
        MaximumLength = RelatedDeviceData->RelatedDeviceInstanceLength;
        ProbeForWrite(RelatedDeviceData->RelatedDeviceInstance,
                      MaximumLength,
                      sizeof(WCHAR));
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        if (TargetDeviceInstance.Buffer != NULL)
        {
            ExFreePool(TargetDeviceInstance.Buffer);
        }
        _SEH2_YIELD(return _SEH2_GetExceptionCode());
    }
    _SEH2_END;

    RtlInitUnicodeString(&RootDeviceName,
                         L"HTREE\\ROOT\\0");
    if (RtlEqualUnicodeString(&TargetDeviceInstance,
                              &RootDeviceName,
                              TRUE))
    {
        DeviceNode = IopRootDeviceNode;
        if (TargetDeviceInstance.Buffer != NULL)
        {
            ExFreePool(TargetDeviceInstance.Buffer);
        }
    }
    else
    {
        /* Get the device object */
        DeviceObject = IopGetDeviceObjectFromDeviceInstance(&TargetDeviceInstance);
        if (TargetDeviceInstance.Buffer != NULL)
        {
            ExFreePool(TargetDeviceInstance.Buffer);
        }
        if (DeviceObject == NULL)
            return STATUS_NO_SUCH_DEVICE;

        DeviceNode = ((PEXTENDED_DEVOBJ_EXTENSION)DeviceObject->DeviceObjectExtension)->DeviceNode;
    }

    switch (Relation)
    {
        case PNP_GET_PARENT_DEVICE:
            RelatedDeviceNode = DeviceNode->Parent;
            break;

        case PNP_GET_CHILD_DEVICE:
            RelatedDeviceNode = DeviceNode->Child;
            break;

        case PNP_GET_SIBLING_DEVICE:
            RelatedDeviceNode = DeviceNode->Sibling;
            break;

        default:
            if (DeviceObject != NULL)
            {
                ObDereferenceObject(DeviceObject);
            }

            return STATUS_INVALID_PARAMETER;
    }

    if (RelatedDeviceNode == NULL)
    {
        if (DeviceObject)
        {
            ObDereferenceObject(DeviceObject);
        }

        return STATUS_NO_SUCH_DEVICE;
    }

    if (RelatedDeviceNode->InstancePath.Length > MaximumLength)
    {
        if (DeviceObject)
        {
            ObDereferenceObject(DeviceObject);
        }

        return STATUS_BUFFER_TOO_SMALL;
    }

    /* Copy related device instance name */
    _SEH2_TRY
    {
        RtlCopyMemory(RelatedDeviceData->RelatedDeviceInstance,
                      RelatedDeviceNode->InstancePath.Buffer,
                      RelatedDeviceNode->InstancePath.Length);
        RelatedDeviceData->RelatedDeviceInstanceLength = RelatedDeviceNode->InstancePath.Length;
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        Status = _SEH2_GetExceptionCode();
    }
    _SEH2_END;

    if (DeviceObject != NULL)
    {
        ObDereferenceObject(DeviceObject);
    }

    DPRINT("IopGetRelatedDevice() done\n");

    return Status;
}
Пример #5
0
NTSTATUS
SetupCopyFile(
    PWCHAR SourceFileName,
    PWCHAR DestinationFileName)
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE FileHandleSource;
    HANDLE FileHandleDest;
    static IO_STATUS_BLOCK IoStatusBlock;
    FILE_STANDARD_INFORMATION FileStandard;
    FILE_BASIC_INFORMATION FileBasic;
    ULONG RegionSize;
    UNICODE_STRING FileName;
    NTSTATUS Status;
    PVOID SourceFileMap = 0;
    HANDLE SourceFileSection;
    SIZE_T SourceSectionSize = 0;
    LARGE_INTEGER ByteOffset;

#ifdef __REACTOS__
    RtlInitUnicodeString(&FileName,
                         SourceFileName);

    InitializeObjectAttributes(&ObjectAttributes,
                               &FileName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);

    Status = NtOpenFile(&FileHandleSource,
                        GENERIC_READ,
                        &ObjectAttributes,
                        &IoStatusBlock,
                        FILE_SHARE_READ,
                        FILE_SEQUENTIAL_ONLY);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtOpenFile failed: %x, %wZ\n", Status, &FileName);
        goto done;
    }
#else
    FileHandleSource = CreateFileW(SourceFileName,
                                   GENERIC_READ,
                                   FILE_SHARE_READ,
                                   NULL,
                                   OPEN_EXISTING,
                                   0,
                                   NULL);
    if (FileHandleSource == INVALID_HANDLE_VALUE)
    {
        Status = STATUS_UNSUCCESSFUL;
        goto done;
    }
#endif

    Status = NtQueryInformationFile(FileHandleSource,
                                    &IoStatusBlock,
                                    &FileStandard,
                                    sizeof(FILE_STANDARD_INFORMATION),
                                    FileStandardInformation);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtQueryInformationFile failed: %x\n", Status);
        goto closesrc;
    }

    Status = NtQueryInformationFile(FileHandleSource,
                                    &IoStatusBlock,&FileBasic,
                                    sizeof(FILE_BASIC_INFORMATION),
                                    FileBasicInformation);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtQueryInformationFile failed: %x\n", Status);
        goto closesrc;
    }

    Status = NtCreateSection(&SourceFileSection,
                             SECTION_MAP_READ,
                             NULL,
                             NULL,
                             PAGE_READONLY,
                             SEC_COMMIT,
                             FileHandleSource);
    if (!NT_SUCCESS(Status))
    {
      DPRINT1("NtCreateSection failed: %x, %S\n", Status, SourceFileName);
      goto closesrc;
    }

    Status = NtMapViewOfSection(SourceFileSection,
                                NtCurrentProcess(),
                                &SourceFileMap,
                                0,
                                0,
                                NULL,
                                &SourceSectionSize,
                                ViewUnmap,
                                0,
                                PAGE_READONLY );
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtMapViewOfSection failed: %x, %S\n", Status, SourceFileName);
        goto closesrcsec;
    }

    RtlInitUnicodeString(&FileName,
                         DestinationFileName);

    InitializeObjectAttributes(&ObjectAttributes,
                               &FileName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);

    Status = NtCreateFile(&FileHandleDest,
                          GENERIC_WRITE | SYNCHRONIZE,
                          &ObjectAttributes,
                          &IoStatusBlock,
                          NULL,
                          FILE_ATTRIBUTE_NORMAL,
                          0,
                          FILE_OVERWRITE_IF,
                          FILE_NO_INTERMEDIATE_BUFFERING |
                          FILE_SEQUENTIAL_ONLY |
                          FILE_SYNCHRONOUS_IO_NONALERT,
                          NULL,
                          0);
    if (!NT_SUCCESS(Status))
    {
        /* Open may have failed because the file to overwrite
         * is in readonly mode
         */
        if (Status == STATUS_ACCESS_DENIED)
        {
            FILE_BASIC_INFORMATION FileBasicInfo;

            /* Reattempt to open it with limited access */
            Status = NtCreateFile(&FileHandleDest,
                                  FILE_WRITE_ATTRIBUTES | SYNCHRONIZE,
                                  &ObjectAttributes,
                                  &IoStatusBlock,
                                  NULL,
                                  FILE_ATTRIBUTE_NORMAL,
                                  0,
                                  FILE_OPEN,
                                  FILE_NO_INTERMEDIATE_BUFFERING |
                                  FILE_SEQUENTIAL_ONLY |
                                  FILE_SYNCHRONOUS_IO_NONALERT,
                                  NULL,
                                  0);
            /* Fail for real if we cannot open it that way */
            if (!NT_SUCCESS(Status))
            {
                DPRINT1("NtCreateFile failed: %x, %wZ\n", Status, &FileName);
                goto unmapsrcsec;
            }

            /* Zero our basic info, just to set attributes */
            RtlZeroMemory(&FileBasicInfo, sizeof(FileBasicInfo));
            /* Reset attributes to normal, no read-only */
            FileBasicInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL;
            /* We basically don't care about whether it succeed:
             * if it didn't, later open will fail
             */
            NtSetInformationFile(FileHandleDest, &IoStatusBlock, &FileBasicInfo,
                                 sizeof(FileBasicInfo), FileBasicInformation);

            /* Close file */
            NtClose(FileHandleDest);

            /* And re-attempt overwrite */
            Status = NtCreateFile(&FileHandleDest,
                                  GENERIC_WRITE | SYNCHRONIZE,
                                  &ObjectAttributes,
                                  &IoStatusBlock,
                                  NULL,
                                  FILE_ATTRIBUTE_NORMAL,
                                  0,
                                  FILE_OVERWRITE_IF,
                                  FILE_NO_INTERMEDIATE_BUFFERING |
                                  FILE_SEQUENTIAL_ONLY |
                                  FILE_SYNCHRONOUS_IO_NONALERT,
                                  NULL,
                                  0);
        }

        /* We failed */
        if (!NT_SUCCESS(Status))
        {
            DPRINT1("NtCreateFile failed: %x, %wZ\n", Status, &FileName);
            goto unmapsrcsec;
        }
    }

    RegionSize = (ULONG)PAGE_ROUND_UP(FileStandard.EndOfFile.u.LowPart);
    IoStatusBlock.Status = 0;
    ByteOffset.QuadPart = 0ULL;
    Status = NtWriteFile(FileHandleDest,
                         NULL,
                         NULL,
                         NULL,
                         &IoStatusBlock,
                         SourceFileMap,
                         RegionSize,
                         &ByteOffset,
                         NULL);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtWriteFile failed: %x:%x, iosb: %p src: %p, size: %x\n", Status, IoStatusBlock.Status, &IoStatusBlock, SourceFileMap, RegionSize);
        goto closedest;
    }

    /* Copy file date/time from source file */
    Status = NtSetInformationFile(FileHandleDest,
                                  &IoStatusBlock,
                                  &FileBasic,
                                  sizeof(FILE_BASIC_INFORMATION),
                                  FileBasicInformation);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtSetInformationFile failed: %x\n", Status);
        goto closedest;
    }

    /* shorten the file back to it's real size after completing the write */
    Status = NtSetInformationFile(FileHandleDest,
                                  &IoStatusBlock,
                                  &FileStandard.EndOfFile,
                                  sizeof(FILE_END_OF_FILE_INFORMATION),
                                  FileEndOfFileInformation);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtSetInformationFile failed: %x\n", Status);
    }

closedest:
    NtClose(FileHandleDest);

unmapsrcsec:
    NtUnmapViewOfSection(NtCurrentProcess(), SourceFileMap);

closesrcsec:
    NtClose(SourceFileSection);

closesrc:
    NtClose(FileHandleSource);

done:
    return Status;
}
Пример #6
0
NTSTATUS
NTAPI
CmpInitializeMachineDependentConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
    UNICODE_STRING KeyName, ValueName, Data, SectionName;
    OBJECT_ATTRIBUTES ObjectAttributes;
    ULONG HavePae, Length, TotalLength = 0, i, Disposition;
    SIZE_T ViewSize;
    NTSTATUS Status;
    HANDLE KeyHandle, BiosHandle, SystemHandle, FpuHandle, SectionHandle;
    CONFIGURATION_COMPONENT_DATA ConfigData;
    CHAR Buffer[128];
    CPU_INFO CpuInfo;
    ULONG VendorId, ExtendedId;
    PKPRCB Prcb;
    USHORT IndexTable[MaximumType + 1] = {0};
    ANSI_STRING TempString;
    PCHAR PartialString = NULL, BiosVersion;
    CHAR CpuString[48];
    PVOID BaseAddress = NULL;
    LARGE_INTEGER ViewBase = {{0, 0}};
    ULONG_PTR VideoRomBase;
    PCHAR CurrentVersion;
    extern UNICODE_STRING KeRosProcessorName, KeRosBiosDate, KeRosBiosVersion;
    extern UNICODE_STRING KeRosVideoBiosDate, KeRosVideoBiosVersion;

    /* Open the SMSS Memory Management key */
    RtlInitUnicodeString(&KeyName,
                         L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\"
                         L"Control\\Session Manager\\Memory Management");
    InitializeObjectAttributes(&ObjectAttributes,
                               &KeyName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);
    Status = NtOpenKey(&KeyHandle, KEY_READ | KEY_WRITE, &ObjectAttributes);
    if (NT_SUCCESS(Status))
    {
        /* Detect if PAE is enabled */
        HavePae = SharedUserData->ProcessorFeatures[PF_PAE_ENABLED];

        /* Set the value */
        RtlInitUnicodeString(&ValueName, L"PhysicalAddressExtension");
        NtSetValueKey(KeyHandle,
                      &ValueName,
                      0,
                      REG_DWORD,
                      &HavePae,
                      sizeof(HavePae));

        /* Close the key */
        NtClose(KeyHandle);
    }

    /* Open the hardware description key */
    RtlInitUnicodeString(&KeyName,
                         L"\\Registry\\Machine\\Hardware\\Description\\System");
    InitializeObjectAttributes(&ObjectAttributes,
                               &KeyName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);
    Status = NtOpenKey(&SystemHandle, KEY_READ | KEY_WRITE, &ObjectAttributes);
    if (!NT_SUCCESS(Status)) return Status;

    /* Create the BIOS Information key */
    RtlInitUnicodeString(&KeyName,
                         L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\"
                         L"Control\\BIOSINFO");
    InitializeObjectAttributes(&ObjectAttributes,
                               &KeyName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);
    Status = NtCreateKey(&BiosHandle,
                         KEY_ALL_ACCESS,
                         &ObjectAttributes,
                         0,
                         NULL,
                         REG_OPTION_NON_VOLATILE,
                         &Disposition);
    if (ExpInTextModeSetup)
    {
        if (!NT_SUCCESS(Status))
            BiosHandle = NULL;
    }
    else if (!NT_SUCCESS(Status))
        return Status;

    /* Create the CPU Key, and check if it already existed */
    RtlInitUnicodeString(&KeyName, L"CentralProcessor");
    InitializeObjectAttributes(&ObjectAttributes,
                               &KeyName,
                               OBJ_CASE_INSENSITIVE,
                               SystemHandle,
                               NULL);
    Status = NtCreateKey(&KeyHandle,
                         KEY_READ | KEY_WRITE,
                         &ObjectAttributes,
                         0,
                         NULL,
                         0,
                         &Disposition);
    NtClose(KeyHandle);

    /* The key shouldn't already exist */
    if (Disposition == REG_CREATED_NEW_KEY)
    {
        /* Allocate the configuration data for cmconfig.c */
        CmpConfigurationData = ExAllocatePoolWithTag(PagedPool,
                                                     CmpConfigurationAreaSize,
                                                     TAG_CM);
        if (!CmpConfigurationData) return STATUS_INSUFFICIENT_RESOURCES;

        /* Loop all CPUs */
        for (i = 0; i < KeNumberProcessors; i++)
        {
            /* Get the PRCB */
            Prcb = KiProcessorBlock[i];

            /* Setup the Configuration Entry for the Processor */
            RtlZeroMemory(&ConfigData, sizeof (ConfigData));
            ConfigData.ComponentEntry.Class = ProcessorClass;
            ConfigData.ComponentEntry.Type = CentralProcessor;
            ConfigData.ComponentEntry.Key = i;
            ConfigData.ComponentEntry.AffinityMask = AFFINITY_MASK(i);
            ConfigData.ComponentEntry.Identifier = Buffer;

            /* Check if the CPU doesn't support CPUID */
            if (!Prcb->CpuID)
            {
                /* Build ID1-style string for older CPUs */
                sprintf(Buffer,
                        CmpID1,
                        Prcb->CpuType,
                        (Prcb->CpuStep >> 8) + 'A',
                        Prcb->CpuStep & 0xff);
            }
            else
            {
Пример #7
0
int
WINAPI
WinMain(
    IN HINSTANCE hInstance,
    IN HINSTANCE hPrevInstance,
    IN LPSTR lpCmdLine,
    IN int nShowCmd)
{
#if 0
    LSA_STRING ProcessName, PackageName;
    HANDLE LsaHandle;
    LSA_OPERATIONAL_MODE Mode;
    BOOLEAN Old;
    ULONG AuthenticationPackage;
    NTSTATUS Status;
#endif
    ULONG HardErrorResponse;
    MSG Msg;

    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);
    UNREFERENCED_PARAMETER(nShowCmd);

    hAppInstance = hInstance;

    /* Make us critical */
    RtlSetProcessIsCritical(TRUE, NULL, FALSE);
    RtlSetThreadIsCritical(TRUE, NULL, FALSE);

    if (!RegisterLogonProcess(GetCurrentProcessId(), TRUE))
    {
        ERR("WL: Could not register logon process\n");
        NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, NULL, OptionOk, &HardErrorResponse);
        ExitProcess(1);
    }

    WLSession = (PWLSESSION)HeapAlloc(GetProcessHeap(), 0, sizeof(WLSESSION));
    if (!WLSession)
    {
        ERR("WL: Could not allocate memory for winlogon instance\n");
        NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, NULL, OptionOk, &HardErrorResponse);
        ExitProcess(1);
    }

    ZeroMemory(WLSession, sizeof(WLSESSION));
    WLSession->DialogTimeout = 120; /* 2 minutes */

    /* Initialize the dialog tracking list */
    InitDialogListHead();

    if (!CreateWindowStationAndDesktops(WLSession))
    {
        ERR("WL: Could not create window station and desktops\n");
        NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, NULL, OptionOk, &HardErrorResponse);
        ExitProcess(1);
    }

    LockWorkstation(WLSession);

    /* Load default keyboard layouts */
    if (!InitKeyboardLayouts())
    {
        ERR("WL: Could not preload keyboard layouts\n");
        NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, NULL, OptionOk, &HardErrorResponse);
        ExitProcess(1);
    }

    if (!StartRpcServer())
    {
        ERR("WL: Could not start the RPC server\n");
        NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, NULL, OptionOk, &HardErrorResponse);
        ExitProcess(1);
    }

    if (!StartServicesManager())
    {
        ERR("WL: Could not start services.exe\n");
        NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, NULL, OptionOk, &HardErrorResponse);
        ExitProcess(1);
    }

    if (!StartLsass())
    {
        ERR("WL: Failed to start lsass.exe service (error %lu)\n", GetLastError());
        NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, NULL, OptionOk, &HardErrorResponse);
        ExitProcess(1);
    }

    /* Wait for the LSA server */
    WaitForLsass();

    /* Init Notifications */
    InitNotifications();

    /* Load and initialize gina */
    if (!GinaInit(WLSession))
    {
        ERR("WL: Failed to initialize Gina\n");
        // FIXME: Retrieve the real name of the GINA DLL we were trying to load.
        // It is known only inside the GinaInit function...
        DialogBoxParam(hAppInstance, MAKEINTRESOURCE(IDD_GINALOADFAILED), GetDesktopWindow(), GinaLoadFailedWindowProc, (LPARAM)L"msgina.dll");
        HandleShutdown(WLSession, WLX_SAS_ACTION_SHUTDOWN_REBOOT);
        ExitProcess(1);
    }

    DisplayStatusMessage(WLSession, WLSession->WinlogonDesktop, IDS_REACTOSISSTARTINGUP);

#if 0
    /* Connect to NetLogon service (lsass.exe) */
    /* Real winlogon uses "Winlogon" */
    RtlInitUnicodeString((PUNICODE_STRING)&ProcessName, L"Winlogon");
    Status = LsaRegisterLogonProcess(&ProcessName, &LsaHandle, &Mode);
    if (Status == STATUS_PORT_CONNECTION_REFUSED)
    {
        /* Add the 'SeTcbPrivilege' privilege and try again */
        Status = RtlAdjustPrivilege(SE_TCB_PRIVILEGE, TRUE, TRUE, &Old);
        if (!NT_SUCCESS(Status))
        {
            ERR("RtlAdjustPrivilege() failed with error %lu\n", LsaNtStatusToWinError(Status));
            return 1;
        }

        Status = LsaRegisterLogonProcess(&ProcessName, &LsaHandle, &Mode);
    }

    if (!NT_SUCCESS(Status))
    {
        ERR("LsaRegisterLogonProcess() failed with error %lu\n", LsaNtStatusToWinError(Status));
        return 1;
    }

    RtlInitUnicodeString((PUNICODE_STRING)&PackageName, MICROSOFT_KERBEROS_NAME_W);
    Status = LsaLookupAuthenticationPackage(LsaHandle, &PackageName, &AuthenticationPackage);
    if (!NT_SUCCESS(Status))
    {
        ERR("LsaLookupAuthenticationPackage() failed with error %lu\n", LsaNtStatusToWinError(Status));
        LsaDeregisterLogonProcess(LsaHandle);
        return 1;
    }
#endif

    CallNotificationDlls(WLSession, StartupHandler);

    /* Create a hidden window to get SAS notifications */
    if (!InitializeSAS(WLSession))
    {
        ERR("WL: Failed to initialize SAS\n");
        ExitProcess(2);
    }

    // DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_PREPARENETWORKCONNECTIONS);
    // DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_APPLYINGCOMPUTERSETTINGS);

    /* Display logged out screen */
    WLSession->LogonState = STATE_INIT;
    RemoveStatusMessage(WLSession);

    /* Check for pending setup */
    if (GetSetupType() != 0)
    {
        TRACE("WL: Setup mode detected\n");

        /* Run setup and reboot when done */
        SwitchDesktop(WLSession->ApplicationDesktop);
        RunSetup();
    }
    else
        PostMessageW(WLSession->SASWindow, WLX_WM_SAS, WLX_SAS_TYPE_CTRL_ALT_DEL, 0);

    (void)LoadLibraryW(L"sfc_os.dll");

    /* Tell kernel that CurrentControlSet is good (needed
     * to support Last good known configuration boot) */
    NtInitializeRegistry(CM_BOOT_FLAG_ACCEPTED | 1);

    /* Message loop for the SAS window */
    while (GetMessageW(&Msg, WLSession->SASWindow, 0, 0))
    {
        TranslateMessage(&Msg);
        DispatchMessageW(&Msg);
    }

    CleanupNotifications();

    /* We never go there */

    return 0;
}
Пример #8
0
NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT   pDriverObject,
    IN PUNICODE_STRING  pRegistryPath
    )
/*++

Routine Description:

    Called on loading. We create a device object to handle user-mode requests
    on, and register ourselves as a protocol with NDIS.

Arguments:

    pDriverObject - Pointer to driver object created by system.

    pRegistryPath - Pointer to the Unicode name of the registry path
        for this driver.

Return Value:

    NT Status code
    
--*/
{
    NDIS_PROTOCOL_CHARACTERISTICS   protocolChar;
    NTSTATUS                        status = STATUS_SUCCESS;
    NDIS_STRING                     protoName = NDIS_STRING_CONST("NdisProt");     
    UNICODE_STRING                  ntDeviceName;
    UNICODE_STRING                  win32DeviceName;
    BOOLEAN                         fSymbolicLink = FALSE;
    PDEVICE_OBJECT                  deviceObject = NULL;

    UNREFERENCED_PARAMETER(pRegistryPath);

    DEBUGP(DL_LOUD, ("DriverEntry\n"));

    Globals.pDriverObject = pDriverObject;
    NPROT_INIT_EVENT(&Globals.BindsComplete);

    do
    {

        //
        // Create our device object using which an application can
        // access NDIS devices.
        //
        RtlInitUnicodeString(&ntDeviceName, NT_DEVICE_NAME);
#ifndef WIN9X
        status = IoCreateDeviceSecure(pDriverObject,
                                 0,
                                 &ntDeviceName,
                                 FILE_DEVICE_NETWORK,
                                 FILE_DEVICE_SECURE_OPEN,
                                 FALSE,
                                 &SDDL_DEVOBJ_SYS_ALL_ADM_ALL,
                                 NULL,
                                 &deviceObject);

#else     
        status = IoCreateDevice(pDriverObject,
                                 0,
                                 &ntDeviceName,
                                 FILE_DEVICE_NETWORK,
                                 FILE_DEVICE_SECURE_OPEN,
                                 FALSE,
                                 &deviceObject);
#endif
        if (!NT_SUCCESS (status))
        {
            //
            // Either not enough memory to create a deviceobject or another
            // deviceobject with the same name exits. This could happen
            // if you install another instance of this device.
            //
            break;
        }

        RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME);

        status = IoCreateSymbolicLink(&win32DeviceName, &ntDeviceName);

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

        fSymbolicLink = TRUE;
    
        deviceObject->Flags |= DO_DIRECT_IO;
        Globals.ControlDeviceObject = deviceObject;

        NPROT_INIT_LIST_HEAD(&Globals.OpenList);
        NPROT_INIT_LOCK(&Globals.GlobalLock);

        //
        // Initialize the protocol characterstic structure
        //
    
        NdisZeroMemory(&protocolChar,sizeof(NDIS_PROTOCOL_CHARACTERISTICS));

        protocolChar.MajorNdisVersion            = 5;
        protocolChar.MinorNdisVersion            = 0;
        protocolChar.Name                        = protoName;
        protocolChar.OpenAdapterCompleteHandler  = NdisProtOpenAdapterComplete;
        protocolChar.CloseAdapterCompleteHandler = NdisProtCloseAdapterComplete;
        protocolChar.SendCompleteHandler         = NdisProtSendComplete;
        protocolChar.TransferDataCompleteHandler = NdisProtTransferDataComplete;
        protocolChar.ResetCompleteHandler        = NdisProtResetComplete;
        protocolChar.RequestCompleteHandler      = NdisProtRequestComplete;
        protocolChar.ReceiveHandler              = NdisProtReceive;
        protocolChar.ReceiveCompleteHandler      = NdisProtReceiveComplete;
        protocolChar.StatusHandler               = NdisProtStatus;
        protocolChar.StatusCompleteHandler       = NdisProtStatusComplete;
        protocolChar.BindAdapterHandler          = NdisProtBindAdapter;
        protocolChar.UnbindAdapterHandler        = NdisProtUnbindAdapter;
        protocolChar.UnloadHandler               = NULL;
        protocolChar.ReceivePacketHandler        = NdisProtReceivePacket;
        protocolChar.PnPEventHandler             = NdisProtPnPEventHandler;

        //
        // Register as a protocol driver
        //
    
        NdisRegisterProtocol(
            (PNDIS_STATUS)&status,
            &Globals.NdisProtocolHandle,
            &protocolChar,
            sizeof(NDIS_PROTOCOL_CHARACTERISTICS));

        if (status != NDIS_STATUS_SUCCESS)
        {
            DEBUGP(DL_WARN, ("Failed to register protocol with NDIS\n"));
            status = STATUS_UNSUCCESSFUL;
            break;
        }

#ifdef NDIS51
        Globals.PartialCancelId = NdisGeneratePartialCancelId();
        Globals.PartialCancelId <<= ((sizeof(PVOID) - 1) * 8);
        DEBUGP(DL_LOUD, ("DriverEntry: CancelId %lx\n", Globals.PartialCancelId));
#endif

        //
        // Now set only the dispatch points we would like to handle.
        //
        pDriverObject->MajorFunction[IRP_MJ_CREATE] = NdisProtOpen;
        pDriverObject->MajorFunction[IRP_MJ_CLOSE]  = NdisProtClose;
        pDriverObject->MajorFunction[IRP_MJ_READ]   = NdisProtRead; 
        pDriverObject->MajorFunction[IRP_MJ_WRITE]  = NdisProtWrite;
        pDriverObject->MajorFunction[IRP_MJ_CLEANUP]  = NdisProtCleanup;
        pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]  = NdisProtIoControl;
        pDriverObject->DriverUnload = NdisProtUnload;

        status = STATUS_SUCCESS;
        
    }
    while (FALSE);
       

    if (!NT_SUCCESS(status))
    {
        if (deviceObject)
        {
            #pragma prefast(disable:28107, "within critical section, device object is held")
            KeEnterCriticalRegion();
            IoDeleteDevice(deviceObject);
            Globals.ControlDeviceObject = NULL;
            KeLeaveCriticalRegion();
        }

        if (fSymbolicLink)
        {
            IoDeleteSymbolicLink(&win32DeviceName);
        }
        
    }
    
    return status;

}
Пример #9
0
NTSTATUS
RtlCreateUserProcess(
    IN PUNICODE_STRING NtImagePathName,
    IN ULONG Attributes,
    IN PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
    IN PSECURITY_DESCRIPTOR ProcessSecurityDescriptor OPTIONAL,
    IN PSECURITY_DESCRIPTOR ThreadSecurityDescriptor OPTIONAL,
    IN HANDLE ParentProcess OPTIONAL,
    IN BOOLEAN InheritHandles,
    IN HANDLE DebugPort OPTIONAL,
    IN HANDLE ExceptionPort OPTIONAL,
    OUT PRTL_USER_PROCESS_INFORMATION ProcessInformation
    )

/*++

Routine Description:

    This function creates a user mode process with a single thread with
    a suspend count of one.  The address space of the new process is
    initialized with the contents of specified image file.  The caller
    can specify the Access Control List for the new process and thread.
    The caller can also specify the parent process to inherit process
    priority and processor affinity from.  The default is to inherit
    these from the current process.  Finally the caller can specify
    whether the new process is to inherit any of the object handles
    from the specified parent process or not.

    Information about the new process and thread is returned via
    the ProcessInformation parameter.

Arguments:

    NtImagePathName - A required pointer that points to the NT Path string
        that identifies the image file that is to be loaded into the
        child process.

    ProcessParameters - A required pointer that points to parameters that
        are to passed to the child process.

    ProcessSecurityDescriptor - An optional pointer to the Security Descriptor
        give to the new process.

    ThreadSecurityDescriptor - An optional pointer to the Security Descriptor
        give to the new thread.

    ParentProcess - An optional process handle that will used to inherit
        certain properties from.

    InheritHandles - A boolean value.  TRUE specifies that object handles
        associated with the specified parent process are to be inherited
        by the new process, provided they have the OBJ_INHERIT attribute.
        FALSE specifies that the new process is to inherit no handles.

    DebugPort - An optional handle to the debug port associated with this
        process.

    ExceptionPort - An optional handle to the exception port associated with this
        process.

    ProcessInformation - A pointer to a variable that receives information
        about the new process and thread.

--*/

{
    NTSTATUS Status;
    HANDLE Section, File;
    OBJECT_ATTRIBUTES ObjectAttributes;
    PRTL_USER_PROCESS_PARAMETERS Parameters;
    SIZE_T ParameterLength;
    PVOID Environment;
    PWCHAR s;
    SIZE_T EnvironmentLength;
    SIZE_T RegionSize;
    PROCESS_BASIC_INFORMATION ProcessInfo;
    PPEB Peb;
    UNICODE_STRING Unicode;

    //
    // Zero output parameter and probe the addresses at the same time
    //

    RtlZeroMemory( ProcessInformation, sizeof( *ProcessInformation ) );
    ProcessInformation->Length = sizeof( *ProcessInformation );

    //
    // Open the specified image file.
    //

    Status = RtlpOpenImageFile( NtImagePathName,
                                Attributes & (OBJ_INHERIT | OBJ_CASE_INSENSITIVE),
                                &File,
                                TRUE
                              );
    if (!NT_SUCCESS( Status )) {
        return( Status );
        }


    //
    // Create a memory section backed by the opened image file
    //

    Status = ZwCreateSection( &Section,
                              SECTION_ALL_ACCESS,
                              NULL,
                              NULL,
                              PAGE_EXECUTE,
                              SEC_IMAGE,
                              File
                            );
    ZwClose( File );
    if ( !NT_SUCCESS( Status ) ) {
        return( Status );
        }


    //
    // Create the user mode process, defaulting the parent process to the
    // current process if one is not specified.  The new process will not
    // have a name nor will the handle be inherited by other processes.
    //

    if (!ARGUMENT_PRESENT( ParentProcess )) {
        ParentProcess = NtCurrentProcess();
        }

    InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL,
                                ProcessSecurityDescriptor );
    if ( RtlGetNtGlobalFlags() & FLG_ENABLE_CSRDEBUG ) {
        if ( wcsstr(NtImagePathName->Buffer,L"csrss") ||
             wcsstr(NtImagePathName->Buffer,L"CSRSS")
           ) {

            //
            // For Hydra we don't name the CSRSS process to avoid name
            // collissions when multiple CSRSS's are started
            //
            if (ISTERMINALSERVER()) {

                InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL,
                                            ProcessSecurityDescriptor );
            } else {

                RtlInitUnicodeString(&Unicode,L"\\WindowsSS");
                InitializeObjectAttributes( &ObjectAttributes, &Unicode, 0, NULL,
                                            ProcessSecurityDescriptor );
            }

            }
        }

    if ( !InheritHandles ) {
        ProcessParameters->CurrentDirectory.Handle = NULL;
        }
    Status = ZwCreateProcess( &ProcessInformation->Process,
                              PROCESS_ALL_ACCESS,
                              &ObjectAttributes,
                              ParentProcess,
                              InheritHandles,
                              Section,
                              DebugPort,
                              ExceptionPort
                            );
    if ( !NT_SUCCESS( Status ) ) {
        ZwClose( Section );
        return( Status );
        }


    //
    // Retrieve the interesting information from the image header
    //

    Status = ZwQuerySection( Section,
                             SectionImageInformation,
                             &ProcessInformation->ImageInformation,
                             sizeof( ProcessInformation->ImageInformation ),
                             NULL
                           );
    if ( !NT_SUCCESS( Status ) ) {
        ZwClose( ProcessInformation->Process );
        ZwClose( Section );
        return( Status );
        }

    Status = ZwQueryInformationProcess( ProcessInformation->Process,
                                        ProcessBasicInformation,
                                        &ProcessInfo,
                                        sizeof( ProcessInfo ),
                                        NULL
                                      );
    if ( !NT_SUCCESS( Status ) ) {
        ZwClose( ProcessInformation->Process );
        ZwClose( Section );
        return( Status );
        }

    Peb = ProcessInfo.PebBaseAddress;

    //
    // Duplicate Native handles into new process if any specified.
    // Note that the duplicated handles will overlay the input values.
    //

    try {
        Status = STATUS_SUCCESS;

        if ( ProcessParameters->StandardInput ) {

            Status = ZwDuplicateObject(
                        ParentProcess,
                        ProcessParameters->StandardInput,
                        ProcessInformation->Process,
                        &ProcessParameters->StandardInput,
                        0L,
                        0L,
                        DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES
                        );
            if ( !NT_SUCCESS(Status) ) {
                __leave;
            }
        }

        if ( ProcessParameters->StandardOutput ) {

            Status = ZwDuplicateObject(
                        ParentProcess,
                        ProcessParameters->StandardOutput,
                        ProcessInformation->Process,
                        &ProcessParameters->StandardOutput,
                        0L,
                        0L,
                        DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES
                        );
            if ( !NT_SUCCESS(Status) ) {
                __leave;
            }
        }

        if ( ProcessParameters->StandardError ) {

            Status = ZwDuplicateObject(
                        ParentProcess,
                        ProcessParameters->StandardError,
                        ProcessInformation->Process,
                        &ProcessParameters->StandardError,
                        0L,
                        0L,
                        DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES
                        );
            if ( !NT_SUCCESS(Status) ) {
                __leave;
            }
        }

    } finally {
        if ( !NT_SUCCESS(Status) ) {
            ZwClose( ProcessInformation->Process );
            ZwClose( Section );
        }
    }

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

    //
    // Possibly reserve some address space in the new process
    //

    if (ProcessInformation->ImageInformation.SubSystemType == IMAGE_SUBSYSTEM_NATIVE ) {
        if ( ProcessParameters->Flags & RTL_USER_PROC_RESERVE_1MB ) {

            Environment = (PVOID)(4);
            RegionSize = (1024*1024)-(256);

            Status = ZwAllocateVirtualMemory( ProcessInformation->Process,
                                              (PVOID *)&Environment,
                                              0,
                                              &RegionSize,
                                              MEM_RESERVE,
                                              PAGE_READWRITE
                                            );
            if ( !NT_SUCCESS( Status ) ) {
                ZwClose( ProcessInformation->Process );
                ZwClose( Section );
                return( Status );
                }
            }
        }

    //
    // Allocate virtual memory in the new process and use NtWriteVirtualMemory
    // to write a copy of the process environment block into the address
    // space of the new process.  Save the address of the allocated block in
    // the process parameter block so the new process can access it.
    //

    if (s = (PWCHAR)ProcessParameters->Environment) {
        while (*s++) {
            while (*s++) {
                }
            }
        EnvironmentLength = (SIZE_T)(s - (PWCHAR)ProcessParameters->Environment) * sizeof(WCHAR);

        Environment = NULL;
        RegionSize = EnvironmentLength;
        Status = ZwAllocateVirtualMemory( ProcessInformation->Process,
                                          (PVOID *)&Environment,
                                          0,
                                          &RegionSize,
                                          MEM_COMMIT,
                                          PAGE_READWRITE
                                        );
        if ( !NT_SUCCESS( Status ) ) {
            ZwClose( ProcessInformation->Process );
            ZwClose( Section );
            return( Status );
            }

        Status = ZwWriteVirtualMemory( ProcessInformation->Process,
                                       Environment,
                                       ProcessParameters->Environment,
                                       EnvironmentLength,
                                       NULL
                                     );
        if ( !NT_SUCCESS( Status ) ) {
            ZwClose( ProcessInformation->Process );
            ZwClose( Section );
            return( Status );
            }

        ProcessParameters->Environment = Environment;
        }

    //
    // Allocate virtual memory in the new process and use NtWriteVirtualMemory
    // to write a copy of the process parameters block into the address
    // space of the new process.  Set the initial parameter to the new thread
    // to be the address of the block in the new process's address space.
    //

    Parameters = NULL;
    ParameterLength = ProcessParameters->MaximumLength;
    Status = ZwAllocateVirtualMemory( ProcessInformation->Process,
                                      (PVOID *)&Parameters,
                                      0,
                                      &ParameterLength,
                                      MEM_COMMIT,
                                      PAGE_READWRITE
                                    );
    if ( !NT_SUCCESS( Status ) ) {
        ZwClose( ProcessInformation->Process );
        ZwClose( Section );
        return( Status );
        }

    Status = ZwWriteVirtualMemory( ProcessInformation->Process,
                                   Parameters,
                                   ProcessParameters,
                                   ProcessParameters->Length,
                                   NULL
                                 );
    if ( !NT_SUCCESS( Status ) ) {
            ZwClose( ProcessInformation->Process );
            ZwClose( Section );
            return( Status );
            }

    Status = ZwWriteVirtualMemory( ProcessInformation->Process,
                                   &Peb->ProcessParameters,
                                   &Parameters,
                                   sizeof( Parameters ),
                                   NULL
                                 );
    if ( !NT_SUCCESS( Status ) ) {
        ZwClose( ProcessInformation->Process );
        ZwClose( Section );
        return( Status );
        }

    //
    // Create a suspended thread in the new process.  Specify the size and
    // position of the stack, along with the start address, initial parameter
    // and an SECURITY_DESCRIPTOR.  The new thread will not have a name and its handle will
    // not be inherited by other processes.
    //

    Status = RtlCreateUserThread(
                 ProcessInformation->Process,
                 ThreadSecurityDescriptor,
                 TRUE,
                 ProcessInformation->ImageInformation.ZeroBits,
                 ProcessInformation->ImageInformation.MaximumStackSize,
                 ProcessInformation->ImageInformation.CommittedStackSize,
                 (PUSER_THREAD_START_ROUTINE)
                     ProcessInformation->ImageInformation.TransferAddress,
                 (PVOID)Peb,
                 &ProcessInformation->Thread,
                 &ProcessInformation->ClientId
                 );
    if ( !NT_SUCCESS( Status ) ) {
        ZwClose( ProcessInformation->Process );
        ZwClose( Section );
        return( Status );
        }

    //
    // Now close the section and file handles.  The objects they represent
    // will not actually go away until the process is destroyed.
    //

    ZwClose( Section );

    //
    // Return success status
    //

    return( STATUS_SUCCESS );
}
Пример #10
0
/************************************************************************
*************************************** PgDumpTimerTable
*************************************************************************

Description:

	All PatchGuard 2 related timers will wear the "suspect" sttribute.

	ATTENTION: The code uses undocumented kernel APIs. Please keep in mind
	that you shouldn't change the code logic and remember that during
	enumeration your code will run at DISPATCH_LEVEL! 

*/
NTSTATUS PgDumpTimerTable()
{
	KIRQL					OldIrql;
	ULONG					Index;
	PKSPIN_LOCK_QUEUE		LockQueue;
	PKTIMER_TABLE_ENTRY		TimerListHead;
	PLIST_ENTRY				TimerList;
	PKTIMER					Timer;
	PKDPC					TimerDpc;
	CHAR					LogEntryText[2048];
	NTSTATUS				Result = STATUS_SUCCESS;
	HANDLE					hLogFile;
	UNICODE_STRING			LogFileName;
	OBJECT_ATTRIBUTES		ObjAttr;
	IO_STATUS_BLOCK			IOStatus;
	ULONG					LogEntryTextLen;
	SINGLE_LIST_ENTRY		LogListHead = {NULL};
	PSINGLE_LIST_ENTRY		LogList;
	LOGENTRY*				LogEntry;

	ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);

	/*
		Open log file...
	*/
	RtlInitUnicodeString(&LogFileName, L"\\??\\C:\\patchguard.log");

	InitializeObjectAttributes(
		&ObjAttr, 
		&LogFileName, 
		OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
		NULL, NULL)

	if(!NT_SUCCESS(Result = ZwCreateFile(
			&hLogFile,
			GENERIC_WRITE,
			&ObjAttr,
			&IOStatus,
			NULL,
			FILE_ATTRIBUTE_NORMAL,
			FILE_SHARE_READ,
			FILE_OVERWRITE_IF,
			FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE,
			NULL, 0)))
	{
		KdPrint(("\r\n" "ERROR: Unable to open file \"\\??\\C:\\patchguard.log\". (NTSTATUS: 0x%p)\r\n", (void*)Result));

		return Result;
	}
	
	/*
		Lock the dispatcher database and loop through the timer list...
	*/
	Result = STATUS_SUCCESS;

	OldIrql = KiAcquireDispatcherLockRaiseToSynch();

	for(Index = 0; Index < TIMER_TABLE_SIZE; Index++)
	{
		// we have to emulate the windows timer bug "Index & 0xFF" for this to work...
		LockQueue = KeTimerIndexToLockQueue((UCHAR)(Index & 0xFF));

		KeAcquireQueuedSpinLockAtDpcLevel(LockQueue);
		
		// now we can work with the timer list...
		TimerListHead = &KiTimerTableListHead[Index];
		TimerList = TimerListHead->Entry.Flink;

		while(TimerList != (PLIST_ENTRY)TimerListHead)
		{
			Timer = CONTAINING_RECORD(TimerList, KTIMER, TimerListEntry);
			TimerDpc = PgDeobfuscateTimerDpc(Timer);
			TimerList = TimerList->Flink;

			if(TimerDpc != NULL)
			{
				memset(LogEntryText, 0, sizeof(LogEntryText));

				LogEntryTextLen = _snprintf(LogEntryText, sizeof(LogEntryText) - 1, 
					"<timer address=\"%p\" index=\"%d\" period=\"0x%p\" hand=\"%d\" duetime=\"0x%p\">\r\n"
					"%s"
					"    <dpc>\r\n"
					"        <DeferredContext value=\"0x%p\">%s</DeferredContext>\r\n"
					"        <DeferredRoutine>0x%p</DeferredRoutine>\r\n"
					"        <DpcListBlink value=\"0x%p\">%s</DpcListBlink>\r\n"
					"        <DpcListFlink value=\"0x%p\">%s</DpcListFlink>\r\n"
					"        <DpcData value=\"0x%p\">%s</DpcData>\r\n"
					"        <Importance>%d</Importance>\r\n"
					"        <Number>%d</Number>\r\n"
					"        <SystemArgument1 value=\"0x%p\">%s</SystemArgument1>\r\n"
					"        <SystemArgument2 value=\"0x%p\">%s</SystemArgument2>\r\n"
					"        <Type>%d</Type>\r\n"
					"    </dpc>\r\n"
					"</timer>\r\n\r\n",
					Timer,
					Index,
					(ULONGLONG)Timer->Period,
					(ULONG)Timer->Header.Hand,
					Timer->DueTime.QuadPart,
					PgIsPatchGuardContext(TimerDpc->DeferredContext)?"    <SUSPECT>true</SUSPECT>\t\n":"",
					TimerDpc->DeferredContext, PointerToString(TimerDpc->DeferredContext),
					TimerDpc->DeferredRoutine, 
					TimerDpc->DpcListEntry.Blink, PointerToString(TimerDpc->DpcListEntry.Blink),
					TimerDpc->DpcListEntry.Flink, PointerToString(TimerDpc->DpcListEntry.Flink),
					TimerDpc->DpcData, PointerToString(TimerDpc->DpcData),
					(ULONG)TimerDpc->Importance,
					(ULONG)TimerDpc->Number,
					TimerDpc->SystemArgument1, PointerToString(TimerDpc->SystemArgument1),
					TimerDpc->SystemArgument2, PointerToString(TimerDpc->SystemArgument2),
					(ULONG)TimerDpc->Type
				);

				// allocate memory and add log entry to list...
				if((LogEntry = (LOGENTRY*)ExAllocatePool(NonPagedPool, sizeof(LOGENTRY) + LogEntryTextLen + 1)) == NULL)
				{
					KeReleaseQueuedSpinLockFromDpcLevel(LockQueue);

					Result = STATUS_NO_MEMORY;

					DbgPrint("\r\n" "WARNING: Not enough non-paged memory to write suspect timer to file. Aborting enumeration...\r\n");

					break;
				}

				LogEntry->Text = (CHAR*)(LogEntry + 1);
				LogEntry->Length = LogEntryTextLen;

				memcpy(LogEntry->Text, LogEntryText, LogEntryTextLen);

				PushEntryList(&LogListHead, &LogEntry->List);
			}
		}

		KeReleaseQueuedSpinLockFromDpcLevel(LockQueue);
	}

	KiReleaseDispatcherLockFromSynchLevel();

	KiExitDispatcher(OldIrql);
		
	KdPrint(("\r\n" "INFORMATION: Completed PatchGuard scan...\r\n"));

	/*
		Loop through the log entries and flush them to disk...
		In case of an error during enumeration this actually won't write any
		files, but just free allocated memory...
	*/
	LogList = PopEntryList(&LogListHead);

	while(LogList != NULL)
	{
		LogEntry = CONTAINING_RECORD(LogList, LOGENTRY, List);

		if(NT_SUCCESS(Result))
		{
			Result = ZwWriteFile(
					hLogFile,
					NULL, NULL, NULL,
					&IOStatus,
					LogEntry->Text,
					LogEntry->Length,
					NULL, NULL);
		}

		ExFreePool(LogEntry);

		LogList = PopEntryList(&LogListHead);
	}

	ZwClose(hLogFile);

	return Result;
}
Пример #11
0
PVOID FlushRingBuffre(){
	IO_STATUS_BLOCK    ioStatusBlock;
	HANDLE   handle;
	NTSTATUS ntstatus;
	NTSTATUS FlushingToFile;
	OBJECT_ATTRIBUTES ObjAttr;
	UNICODE_STRING pathBuffer;
	size_t  cb;
	PVOID pEvent;
	NTSTATUS Status;
	HANDLE hEvent;
	OBJECT_ATTRIBUTES oa;
	UNICODE_STRING us;
	__debugbreak();
	RtlInitUnicodeString(
		&pathBuffer,
		L"\\DosDevices\\C:\\MyBufferLogger.txt");
	InitializeObjectAttributes(
		&ObjAttr,
		&pathBuffer,  			//ObjectName
		OBJ_CASE_INSENSITIVE, 	//Attributes
		NULL,			//RootDirectory
		NULL);			//SecurityDescriptor
	// Do not try to perform any file operations at higher IRQL levels.
	// Instead, you may use a work item or a system worker thread to perform file operations.

	if(KeGetCurrentIrql() != PASSIVE_LEVEL)
		//  return STATUS_INVALID_DEVICE_STATE; 
		DbgPrint("STATUS_INVALID_DEVICE_STATE\n");

	ntstatus = ZwCreateFile(&handle,
		GENERIC_WRITE,
		&ObjAttr,
		&ioStatusBlock,
		NULL,
		FILE_ATTRIBUTE_NORMAL,
		0,
		FILE_OVERWRITE_IF, 
		FILE_SYNCHRONOUS_IO_NONALERT,
		NULL, 0);


	RtlInitUnicodeString(
		&us,
		L"\\BaseNamedObjects\\TestEvent");

	InitializeObjectAttributes(
		&oa,
		&us,  			//ObjectName
		OBJ_CASE_INSENSITIVE, 	//Attributes
		NULL,			//RootDirectory
		NULL);			//SecurityDescriptor

	FlushingToFile=ZwWriteFile(
		handle,
		NULL,
		NULL,
		NULL,
		&ioStatusBlock,
		RingBuffer.tail,
		RingBuffer.head-RingBuffer.tail,
		NULL,
		NULL
		);


	if(FlushingToFile!=STATUS_SUCCESS){
		DbgPrint("Writing to file problem");
	}else{
		DbgPrint("I do not know why");
	}

	ZwClose(handle);

}
Пример #12
0
VOID
	MyThreadStart(__in PVOID  StartContext){
		HANDLE   handle;//Create File handle
		NTSTATUS ntstatus;
		NTSTATUS timerStatus;
		//IO_STATUS_BLOCK    ioStatusBlock;
		//OBJECT_ATTRIBUTES ObjAttr;
		//UNICODE_STRING path;
		LARGE_INTEGER timeout;
//#define  BUFFER_SIZE 30
	//	CHAR     buffer[BUFFER_SIZE];
		//size_t  cb;

		NTSTATUS Status;
		HANDLE hEvent;
		//OBJECT_ATTRIBUTES oa;
		//UNICODE_STRING us;
		int counter=20;
		SIZE_T BytesNUM;
		char* dataPtr;

		__debugbreak();
		dataPtr="123";
		BytesNUM=strlen(dataPtr)*sizeof(char);
		WriteToRingBuffer(&dataPtr, BytesNUM);
		FlushRingBuffre();
		RtlInitUnicodeString(
			&path,
			L"\\DosDevices\\C:\\MyLogger.txt");
		InitializeObjectAttributes(
			&ObjAttr,
			&path,  			//ObjectName
			OBJ_CASE_INSENSITIVE, 	//Attributes
			NULL,			//RootDirectory
			NULL);			//SecurityDescriptor
		// Do not try to perform any file operations at higher IRQL levels.
		// Instead, you may use a work item or a system worker thread to perform file operations.

		if(KeGetCurrentIrql() != PASSIVE_LEVEL)
			//  return STATUS_INVALID_DEVICE_STATE; 
			DbgPrint("STATUS_INVALID_DEVICE_STATE\n");

		ntstatus = ZwCreateFile(&handle,
			GENERIC_WRITE,
			&ObjAttr, &ioStatusBlock, NULL,
			FILE_ATTRIBUTE_NORMAL,
			0,
			FILE_OVERWRITE_IF, 
			FILE_SYNCHRONOUS_IO_NONALERT,
			NULL, 0);


		timeout.QuadPart = -5 * 1000000;

		RtlInitUnicodeString(
			&us,
			L"\\BaseNamedObjects\\TestEvent");

		InitializeObjectAttributes(
			&oa,
			&us,  			//ObjectName
			OBJ_CASE_INSENSITIVE, 	//Attributes
			NULL,			//RootDirectory
			NULL);			//SecurityDescriptor

		Status = ZwCreateEvent(&hEvent,
			EVENT_ALL_ACCESS,
			&oa,
			NotificationEvent,
			FALSE);

		if(NT_SUCCESS(Status)){
			DbgPrint("Event created");
		} else {
			DbgPrint("Event Not created");
		}

		Status = ObReferenceObjectByHandle(
			hEvent, 		//Handle
			EVENT_ALL_ACCESS,	//DesiredAccess
			NULL,			//ObjectType
			KernelMode,		//AccessMode
			&pEvent,		//Object
			NULL);			//HandleInformation

		if (!NT_SUCCESS(Status)) {
			ZwClose(hEvent);
			DbgPrint("Failed to reference event \n");
			//return Status;
		};

		while(counter!=0){



			timerStatus = KeWaitForSingleObject(
				pEvent,
				Executive,
				KernelMode,
				FALSE,
				&timeout
				);




			if(timerStatus == STATUS_TIMEOUT){
				if(NT_SUCCESS(ntstatus)) {
					ntstatus = RtlStringCbPrintfA(buffer, sizeof(buffer), "This is %d test\r\n", counter);
					if(NT_SUCCESS(ntstatus)) {
						ntstatus = RtlStringCbLengthA(buffer, sizeof(buffer), &cb);
						if(NT_SUCCESS(ntstatus)) {
							ntstatus = ZwWriteFile(handle, NULL, NULL, NULL, &ioStatusBlock,
								buffer, cb, NULL, NULL);
						}
					}
					//ZwClose(handle);
				}
			}
			counter--;
		}
		ZwClose(handle);
}
Пример #13
0
vxtctrlr_handle_t
vxtdev_open(char * device, unsigned int permissions)
{
    HANDLE          filehandle;
    OBJECT_ATTRIBUTES objattrs;
    NTSTATUS        status;
    IO_STATUS_BLOCK iostatus;
    UNICODE_STRING  cwsname;
    wchar_t         wszname[1024];
    wchar_t         *wcp;
    wchar_t         wc;
    const char      *cp;
    vxtctrlr_handle_t vh;
    vxt_fd_struct_t vps;
    vh = malloc(sizeof(*vh));    

    /*
     * form a Unicode pathname.  If the object directory is not
     * given (the name does not begin with / or \) then prefix
     * with the raw volume object directory.
     */
    if (device[0] != '/' && device[0] != '\\') {
        wcscpy(wszname, L"\\Device\\Vxt\\");
            wcp = wszname + wcslen(wszname);
    } else {
            wcp = wszname;
    }
    for (cp = device; (wc = (wchar_t)(uchar_t)*cp) != 0; cp++) {
            if (wc == L'/') {
                wc = L'\\';
            }
            *wcp++ = wc;
    }
    *wcp = 0;
    RtlInitUnicodeString(&cwsname, wszname);

    /*
     * open the device.  If the open fails, then return NULL and
     * set volnt_devfile_errno to indicate the error
     */
    InitializeObjectAttributes(&objattrs, &cwsname, OBJ_CASE_INSENSITIVE,
                                  NULL, NULL);
    status = NtOpenFile(&(vh->handle),
                        SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
                        &objattrs, &iostatus,
                        FILE_SHARE_READ | FILE_SHARE_WRITE,
                        FILE_SYNCHRONOUS_IO_ALERT);
    if (status != STATUS_SUCCESS) {
            return VXT_INVALID_DEV_OBJ;
    }
    if (iostatus.Status != STATUS_SUCCESS || vh->handle == NULL) {
        if (vh->handle) {
            NtClose(vh->handle);
        }
        free(vh);
        return VXT_INVALID_DEV_OBJ;
    }


    vh->privdata = vh->vde = NULL;
	if(vxtdev_ioctl(vh, IOCTL_FD_OPEN, &vps)){
        NtClose(vh->handle);
        free(vh);         
        return VXT_INVALID_DEV_OBJ;
    }
    vh->privdata = vps.private_data;
    vh->vde = vps.vde;
    return vh;
}
Пример #14
0
NTSTATUS TdProtectNameCallback (
    _In_ PTD_PROTECTNAME_INPUT pProtectName
)
{
    NTSTATUS Status = STATUS_SUCCESS;

    if (!pProtectName) {
        DbgPrintEx (
            DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,
            "ObCallbackTest: TdProtectNameCallback: name to protect/filter NULL pointer\n"
        );
    }
    else {
        DbgPrintEx (
            DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL,
            "ObCallbackTest: TdProtectNameCallback: entering name to protect/filter %ls\n", pProtectName->Name
        );
    }
    KeAcquireGuardedMutex (&TdCallbacksMutex);

    // Need to copy out the name and then set the flag to filter
    // This will allow process creation to watch for the process to be created and get the PID
    // and then prevent any other process from opening up that PID to terminate

    memcpy(TdwProtectName, pProtectName->Name, sizeof(TdwProtectName));

    DbgPrintEx (
        DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL,
        "ObCallbackTest: name copied     %ls\n", TdwProtectName
    );

    // Need to enable the OB callbacks
    // once the process is matched to a newly created process, the callbacks will protect the process
    if (bCallbacksInstalled == FALSE) {
        DbgPrintEx (
            DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL,
            "ObCallbackTest: TdProtectNameCallback: installing callbacks\n"
        );

        // Setup the Ob Registration calls

        CBOperationRegistrations[0].ObjectType = PsProcessType;
        CBOperationRegistrations[0].Operations |= OB_OPERATION_HANDLE_CREATE;
        CBOperationRegistrations[0].Operations |= OB_OPERATION_HANDLE_DUPLICATE;
        CBOperationRegistrations[0].PreOperation = CBTdPreOperationCallback;
        CBOperationRegistrations[0].PostOperation = CBTdPostOperationCallback;

        CBOperationRegistrations[1].ObjectType = PsThreadType;
        CBOperationRegistrations[1].Operations |= OB_OPERATION_HANDLE_CREATE;
        CBOperationRegistrations[1].Operations |= OB_OPERATION_HANDLE_DUPLICATE;
        CBOperationRegistrations[1].PreOperation = CBTdPreOperationCallback;
        CBOperationRegistrations[1].PostOperation = CBTdPostOperationCallback;


        RtlInitUnicodeString (&CBAltitude, L"1000");

        CBObRegistration.Version                    = OB_FLT_REGISTRATION_VERSION;
        CBObRegistration.OperationRegistrationCount = 2;
        CBObRegistration.Altitude                   = CBAltitude;
        CBObRegistration.RegistrationContext        = &CBCallbackRegistration;
        CBObRegistration.OperationRegistration      = CBOperationRegistrations;


        Status = ObRegisterCallbacks (
            &CBObRegistration,
            &pCBRegistrationHandle       // save the registration handle to remove callbacks later
        );

        if (!NT_SUCCESS (Status))   {
            DbgPrintEx (
                DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,
                "ObCallbackTest: installing OB callbacks failed  status 0x%x\n", Status
            );
            KeReleaseGuardedMutex (&TdCallbacksMutex); // Release the lock before exit
            goto Exit;
        }
        bCallbacksInstalled = TRUE;

    }


    KeReleaseGuardedMutex (&TdCallbacksMutex);


    DbgPrintEx (
        DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL,
        "ObCallbackTest: TdProtectNameCallback: name to protect/filter %ls\n", TdwProtectName
    );

Exit:
    DbgPrintEx (
        DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL,
        "ObCallbackTest: TdProtectNameCallback: exiting  status 0x%x\n", Status
    );
    return Status;
}
Пример #15
0
MMRESULT
OpenDevice(
    DeviceInfo** private_data,
    MIDIOPENDESC* open_desc,
    DWORD flags)
{
    NTSTATUS status;
    HANDLE heap;
    HANDLE kernel_device;
    UNICODE_STRING beep_device_name;
    OBJECT_ATTRIBUTES attribs;
    IO_STATUS_BLOCK status_block;

    /* One at a time.. */
    if ( the_device )
    {
        DPRINT("Already allocated\n");
        return MMSYSERR_ALLOCATED;
    }

    /* Make the device name into a unicode string and open it */

    RtlInitUnicodeString(&beep_device_name,
                            L"\\Device\\Beep");

    InitializeObjectAttributes(&attribs,
                                &beep_device_name,
                                0,
                                NULL,
                                NULL);

    status = NtCreateFile(&kernel_device,
                            FILE_READ_DATA | FILE_WRITE_DATA,
                            &attribs,
                            &status_block,
                            NULL,
                            0,
                            FILE_SHARE_READ | FILE_SHARE_WRITE,
                            FILE_OPEN_IF,
                            0,
                            NULL,
                            0);

    if ( ! NT_SUCCESS(status) )
    {
        DPRINT("Could not connect to BEEP device - %d\n", (int) GetLastError());
        return MMSYSERR_ERROR;
    }

    DPRINT("Opened!\n");

    /* Allocate and initialize the device info */

    heap = GetProcessHeap();

    the_device = HeapAlloc(heap, HEAP_ZERO_MEMORY, sizeof(DeviceInfo));

    if ( ! the_device )
    {
        DPRINT("Out of memory\n");
        return MMSYSERR_NOMEM;
    }

    /* Initialize */
    the_device->kernel_device = kernel_device;
    the_device->playing_notes_count = 0;
    the_device->note_list = NULL;
    the_device->thread_handle = 0;
    the_device->terminate_thread = FALSE;
    the_device->running_status = 0;

    // TODO
    the_device->mme_handle = (HDRVR) open_desc->hMidi;
    the_device->callback = open_desc->dwCallback;
    the_device->instance = open_desc->dwInstance;
    the_device->flags = flags;

    /* Store the pointer in the user data */
    *private_data = the_device;

    /* This is threading-related code */
#ifdef CONTINUOUS_NOTES
    the_device->work_available = CreateEvent(NULL, TRUE, FALSE, NULL);

    if ( ! the_device->work_available )
    {
        DPRINT("CreateEvent failed\n");
        HeapFree(heap, 0, the_device);
        return MMSYSERR_NOMEM;
    }

    the_device->thread_handle = CreateThread(NULL,
                                             0,
                                             ProcessPlayingNotes,
                                             (PVOID) the_device,
                                             0,
                                             NULL);

    if ( ! the_device->thread_handle )
    {
        DPRINT("CreateThread failed\n");
        CloseHandle(the_device->work_available);
        HeapFree(heap, 0, the_device);
        return MMSYSERR_NOMEM;
    }
#endif

    /* Now we call the client application to say the device is open */
    DPRINT("Sending MOM_OPEN\n");
    DPRINT("Success? %d\n", (int) CallClient(the_device, MOM_OPEN, 0, 0));

    return MMSYSERR_NOERROR;
}
Пример #16
0
NTSTATUS
LinkDeviceToDescription(
    IN PUNICODE_STRING     RegistryPath,
    IN PUNICODE_STRING     DeviceName,
    IN INTERFACE_TYPE      BusType,
    IN ULONG               BusNumber,
    IN CONFIGURATION_TYPE  ControllerType,
    IN ULONG               ControllerNumber,
    IN CONFIGURATION_TYPE  PeripheralType,
    IN ULONG               PeripheralNumber
    )
{
    //
    // This routine will create a volatile "Description" key under the
    // drivers service key. It will store values of the following form
    // in that key:
    //
    // \\Device\\PointerPortX:REG_BINARY:...
    // \\Device\\KeyboardPortX:REG_BINARY:...
    //
    // Where the binary data is six ULONG values (passed as parameters
    // to this routine) that describe the physical location of the device.
    //

    NTSTATUS            Status = STATUS_SUCCESS;
    HANDLE              ServiceKey = NULL, DescriptionKey = NULL;
    UNICODE_STRING      RegString;
    OBJECT_ATTRIBUTES   ObjectAttributes;
    ULONG               disposition;
    HWDESC_INFO         HwDescInfo;

    HwDescInfo.InterfaceType    = BusType;
    HwDescInfo.InterfaceNumber  = BusNumber;
    HwDescInfo.ControllerType   = ControllerType;
    HwDescInfo.ControllerNumber = ControllerNumber;
    HwDescInfo.PeripheralType   = PeripheralType;
    HwDescInfo.PeripheralNumber = PeripheralNumber;


    //
    // Open the service subkey
    //
    InitializeObjectAttributes(&ObjectAttributes,
                               RegistryPath,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);

    Status = ZwOpenKey(&ServiceKey,
                       KEY_WRITE,
                       &ObjectAttributes);

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

    //
    // Create a volatile Description subkey under the service subkey
    //
    RtlInitUnicodeString(&RegString, L"Description");

    InitializeObjectAttributes(&ObjectAttributes,
                               &RegString,
                               OBJ_CASE_INSENSITIVE,
                               ServiceKey,
                               NULL);

    Status = ZwCreateKey(&DescriptionKey,
                         KEY_ALL_ACCESS,
                         &ObjectAttributes,
                         0,
                         (PUNICODE_STRING)NULL,
                         REG_OPTION_VOLATILE,
                         &disposition);

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

    //
    // The description data is stored under a REG_BINARY value (name
    // is the DeviceName passed in as a parameter)
    //
    Status = ZwSetValueKey(DescriptionKey,
                           DeviceName,
                           0,
                           REG_BINARY,
                           &HwDescInfo,
                           sizeof(HwDescInfo));


    Clean0:

    if (DescriptionKey) {
        ZwClose(DescriptionKey);
    }

    if (ServiceKey) {
        ZwClose(ServiceKey);
    }

    return Status;
}
Пример #17
0
/* I really want PCSZ strings as last arguments because
 * PnP ids are ANSI-encoded in PnP device string
 * identification */
NTSTATUS
SerenumInitMultiSzString(
	OUT PUNICODE_STRING Destination,
	... /* list of PCSZ */)
{
	va_list args;
	PCSZ Source;
	ANSI_STRING AnsiString;
	UNICODE_STRING UnicodeString;
	ULONG DestinationSize = 0;
	NTSTATUS Status = STATUS_SUCCESS;

	ASSERT(Destination);

	/* Calculate length needed for destination unicode string */
	va_start(args, Destination);
	Source = va_arg(args, PCSZ);
	while (Source != NULL)
	{
		RtlInitAnsiString(&AnsiString, Source);
		DestinationSize += RtlAnsiStringToUnicodeSize(&AnsiString)
			+ sizeof(WCHAR) /* final NULL */;
		Source = va_arg(args, PCSZ);
	}
	va_end(args);
	if (DestinationSize == 0)
	{
		RtlInitUnicodeString(Destination, NULL);
		return STATUS_SUCCESS;
	}

	/* Initialize destination string */
	DestinationSize += sizeof(WCHAR); // final NULL
	Destination->Buffer = (PWSTR)ExAllocatePoolWithTag(PagedPool, DestinationSize, SERENUM_TAG);
	if (!Destination->Buffer)
		return STATUS_INSUFFICIENT_RESOURCES;
	Destination->Length = 0;
	Destination->MaximumLength = (USHORT)DestinationSize;

	/* Copy arguments to destination string */
	/* Use a temporary unicode string, which buffer is shared with
	 * destination string, to copy arguments */
	UnicodeString.Length = Destination->Length;
	UnicodeString.MaximumLength = Destination->MaximumLength;
	UnicodeString.Buffer = Destination->Buffer;
	va_start(args, Destination);
	Source = va_arg(args, PCSZ);
	while (Source != NULL)
	{
		RtlInitAnsiString(&AnsiString, Source);
		Status = RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, FALSE);
		if (!NT_SUCCESS(Status))
		{
			ExFreePoolWithTag(Destination->Buffer, SERENUM_TAG);
			break;
		}
		Destination->Length += UnicodeString.Length + sizeof(WCHAR);
		UnicodeString.MaximumLength -= UnicodeString.Length + sizeof(WCHAR);
		UnicodeString.Buffer += UnicodeString.Length / sizeof(WCHAR) + 1;
		UnicodeString.Length = 0;
		Source = va_arg(args, PCSZ);
	}
	va_end(args);
	if (NT_SUCCESS(Status))
	{
		/* Finish multi-sz string */
		Destination->Buffer[Destination->Length / sizeof(WCHAR)] = L'\0';
		Destination->Length += sizeof(WCHAR);
	}
	return Status;
}
Пример #18
0
static
NTSTATUS
LfsFiltOpenControl (
	OUT PHANDLE					ControlFileHandle, 
	OUT	PFILE_OBJECT			*ControlFileObject
	)
{
	HANDLE						controlFileHandle; 
	PFILE_OBJECT				controlFileObject;

	UNICODE_STRING	    		nameString;
	OBJECT_ATTRIBUTES	    	objectAttributes;
	IO_STATUS_BLOCK				ioStatusBlock;
	NTSTATUS	    			status;
	
	Bus_KdPrint_Def(BUS_DBG_SS_TRACE, ("Entered\n"));

	//
	// Init object attributes
	//

	RtlInitUnicodeString (&nameString, LFSFILT_CTLDEVICE_NAME);
	InitializeObjectAttributes (
		&objectAttributes,
		&nameString,
		0,
		NULL,
		NULL
		);

	status = ZwCreateFile(
				&controlFileHandle,
				GENERIC_READ,
				&objectAttributes,
				&ioStatusBlock,
				NULL,
				FILE_ATTRIBUTE_NORMAL,
				0,
				0,
				0,
				NULL,	// Open as control
				0		// 
				);

	if (!NT_SUCCESS(status)) {
		Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("FAILURE, ZwCreateFile returned status code=%x\n", status));
		*ControlFileHandle = NULL;
		*ControlFileObject = NULL;
		return status;
	}

	status = ioStatusBlock.Status;

	if (!NT_SUCCESS(status)) {
		Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("FAILURE, IoStatusBlock.Status contains status code=%x\n", status));
		*ControlFileHandle = NULL;
		*ControlFileObject = NULL;
		return status;
	}

	status = ObReferenceObjectByHandle (
		        controlFileHandle,
		        0L,
		        NULL,
		        KernelMode,
		        (PVOID *) &controlFileObject,
		        NULL
				);

	if (!NT_SUCCESS(status)) {
		Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("ObReferenceObjectByHandle() failed. STATUS=%08lx\n", status));
		ZwClose(controlFileHandle);
		*ControlFileHandle = NULL;
		*ControlFileObject = NULL;
		return status;
	}
	 
	*ControlFileHandle = controlFileHandle;
	*ControlFileObject = controlFileObject;

	return status;
}
Пример #19
0
NTSTATUS
DriverEntry(
    __in PDRIVER_OBJECT  DriverObject,
    __in PUNICODE_STRING RegistryPath
    )
/*++

Routine Description:

    Installable driver initialization entry point.
    This entry point is called directly by the I/O system.

Arguments:

    DriverObject - pointer to the driver object

    registryPath - pointer to a unicode string representing the path,
                   to driver-specific key in the registry.

Return Value:

    STATUS_SUCCESS if successful,
    STATUS_UNSUCCESSFUL otherwise

--*/
{
    NTSTATUS            status = STATUS_SUCCESS;
    UNICODE_STRING      unicodeDeviceName;
    UNICODE_STRING      unicodeDosDeviceName;
    PDEVICE_OBJECT      deviceObject;
    PDEVICE_EXTENSION   devExtension;
    HANDLE              threadHandle;
    UNICODE_STRING      sddlString;

    UNREFERENCED_PARAMETER (RegistryPath);

    CSAMP_KDPRINT(("DriverEntry Enter \n"));


    (void) RtlInitUnicodeString(&unicodeDeviceName, CSAMP_DEVICE_NAME_U);

    (void) RtlInitUnicodeString( &sddlString, L"D:P(A;;GA;;;SY)(A;;GA;;;BA)");

    //
    // We will create a secure deviceobject so that only processes running
    // in admin and local system account can access the device. Refer
    // "Security Descriptor String Format" section in the platform
    // SDK documentation to understand the format of the sddl string.
    // We need to do because this is a legacy driver and there is no INF
    // involved in installing the driver. For PNP drivers, security descriptor
    // is typically specified for the FDO in the INF file.
    //

    status = IoCreateDeviceSecure(
                DriverObject,
                sizeof(DEVICE_EXTENSION),
                &unicodeDeviceName,
                FILE_DEVICE_UNKNOWN,
                FILE_DEVICE_SECURE_OPEN,
                (BOOLEAN) FALSE,
                &sddlString,
                (LPCGUID)&GUID_DEVCLASS_CANCEL_SAMPLE,
                &deviceObject
                );
    if (!NT_SUCCESS(status))
    {
        return status;
    }

    DbgPrint("DeviceObject %p\n", deviceObject);

    //
    // Allocate and initialize a Unicode String containing the Win32 name
    // for our device.
    //

    (void)RtlInitUnicodeString( &unicodeDosDeviceName, CSAMP_DOS_DEVICE_NAME_U );


    status = IoCreateSymbolicLink(
                (PUNICODE_STRING) &unicodeDosDeviceName,
                (PUNICODE_STRING) &unicodeDeviceName
                );

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

    devExtension = deviceObject->DeviceExtension;

    DriverObject->MajorFunction[IRP_MJ_CREATE]=
    DriverObject->MajorFunction[IRP_MJ_CLOSE] = CsampCreateClose;
    DriverObject->MajorFunction[IRP_MJ_READ] = CsampRead;
    DriverObject->MajorFunction[IRP_MJ_CLEANUP] = CsampCleanup;

    DriverObject->DriverUnload = CsampUnload;

    //
    // Set the flag signifying that we will do buffered I/O. This causes NT
    // to allocate a buffer on a ReadFile operation which will then be copied
    // back to the calling application by the I/O subsystem
    //

    deviceObject->Flags |= DO_BUFFERED_IO;

    //
    // This is used to serailize access to the queue.
    //

    KeInitializeSpinLock(&devExtension->QueueLock);

    KeInitializeSemaphore(&devExtension->IrpQueueSemaphore, 0, MAXLONG );

    //
    // Initialize the pending Irp devicequeue
    //

    InitializeListHead( &devExtension->PendingIrpQueue );

    //
    // Initialize the cancel safe queue
    //
    IoCsqInitialize( &devExtension->CancelSafeQueue,
                     CsampInsertIrp,
                     CsampRemoveIrp,
                     CsampPeekNextIrp,
                     CsampAcquireLock,
                     CsampReleaseLock,
                     CsampCompleteCanceledIrp );
    //
    // 10 is multiplied because system time is specified in 100ns units
    //

    devExtension->PollingInterval.QuadPart = Int32x32To64(
                                CSAMP_RETRY_INTERVAL, -10);
    //
    // Note down system time
    //

    KeQuerySystemTime (&devExtension->LastPollTime);

    //
    // Start the polling thread.
    //

    devExtension->ThreadShouldStop = FALSE;

    status = PsCreateSystemThread(&threadHandle,
                                (ACCESS_MASK)0,
                                NULL,
                                (HANDLE) 0,
                                NULL,
                                CsampPollingThread,
                                deviceObject );

    if ( !NT_SUCCESS( status ))
    {
        IoDeleteSymbolicLink( &unicodeDosDeviceName );
        IoDeleteDevice( deviceObject );
        return status;
    }

    //
    // Convert the Thread object handle into a pointer to the Thread object
    // itself. Then close the handle.
    //

    ObReferenceObjectByHandle(threadHandle,
                            THREAD_ALL_ACCESS,
                            NULL,
                            KernelMode,
                            &devExtension->ThreadObject,
                            NULL );

    ZwClose(threadHandle);

    CSAMP_KDPRINT(("DriverEntry Exit = %x\n", status));

    ASSERT(NT_SUCCESS(status));

    return status;
}
Пример #20
0
NTSTATUS 
HotKeyKrnlAttachDevices( 
    IN PDRIVER_OBJECT   DriverObject, 
    IN PUNICODE_STRING  RegistryPath 
    ) 
{ 
    NTSTATUS status = 0; 
    UNICODE_STRING uniNtNameString; 
    PDEVICE_EXTENSION   devExt; 
    PDEVICE_OBJECT pFilterDeviceObject = NULL; 
    PDEVICE_OBJECT pTargetDeviceObject = NULL; 
    PDEVICE_OBJECT pLowerDeviceObject  = NULL; 
    PDRIVER_OBJECT KbdDriverObject     = NULL;
    extern POBJECT_TYPE *IoDriverObjectType;    // Exported by ntoskrnl.exe, shit !

    // ref kbdclass driver object
    RtlInitUnicodeString(&uniNtNameString, KBD_DRIVER_NAME); 
    status = ObReferenceObjectByName(&uniNtNameString, OBJ_CASE_INSENSITIVE, NULL, 0, *IoDriverObjectType, KernelMode, NULL, &KbdDriverObject);
    if(!NT_SUCCESS(status))
    {
        KdPrint(("[shadow] ObReferenceObjectByName failed,cann't access Kbdclass.\n"));
        return status; 
    }
    else
    {
        ObDereferenceObject(KbdDriverObject);
    }

    // 绑定该驱动对象中的所有设备对象
    pTargetDeviceObject = KbdDriverObject->DeviceObject;
    while (pTargetDeviceObject) 
    {
        // 创建过滤设备
        status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), NULL, pTargetDeviceObject->DeviceType, pTargetDeviceObject->Characteristics, FALSE, &pFilterDeviceObject);
        if (!NT_SUCCESS(status)) 
        { 
            KdPrint(("[shadow] IoCreateDevice(filter device) failed.\n")); 
            return status; 
        } 
        // 绑定
        if(!(pLowerDeviceObject = IoAttachDeviceToDeviceStack(pFilterDeviceObject, pTargetDeviceObject)))
        { 
            KdPrint(("[shadow] IoAttachDeviceToDeviceStack failed.\n")); 
            IoDeleteDevice(pFilterDeviceObject);
            pFilterDeviceObject = NULL; 
            return status; 
        }

        devExt = (PDEVICE_EXTENSION)(pFilterDeviceObject->DeviceExtension); 
        RtlZeroMemory(devExt, sizeof(DEVICE_EXTENSION)); 
        devExt->NodeSize = sizeof(DEVICE_EXTENSION); 
        devExt->pFilterDeviceObject = pFilterDeviceObject;
        devExt->TargetDeviceObject = pTargetDeviceObject; 
        devExt->LowerDeviceObject = pLowerDeviceObject; 

        pFilterDeviceObject->DeviceType = pLowerDeviceObject->DeviceType; 
        pFilterDeviceObject->Characteristics = pLowerDeviceObject->Characteristics; 
        pFilterDeviceObject->StackSize = pLowerDeviceObject->StackSize+1; 
        pFilterDeviceObject->Flags |= pLowerDeviceObject->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE); 

        pTargetDeviceObject = pTargetDeviceObject->NextDevice;
    }
    return status; 
} 
Пример #21
0
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject,
                      IN PUNICODE_STRING RegistryPath )
{
    /* IRQL == PASSIVE_LEVEL */

    UNREFERENCED_PARAMETER( DriverObject );
    UNREFERENCED_PARAMETER( RegistryPath );

    NTSTATUS status;

    DbgPrint( "file system protection filter start" );

    /* initialize IRP */

    InitializeIrpDispatchers( DriverObject );

    /* create device */

    UNICODE_STRING deviceObjectName;
    RtlInitUnicodeString( &deviceObjectName, L"\\device\\disklocker_fsprotdrv" );

    PDEVICE_OBJECT DeviceObject;
    status = CreateIoDevice( deviceObjectName, DriverObject, &DeviceObject );

    if (!NT_SUCCESS( status ))
    {
        DbgPrint( "CreateIoDevice() failed with code = %08x\n", status );
        return status;
    }

    SetDeviceExt( DeviceObject->DeviceExtension );

    /* initialize device extension */

    GetDeviceExt()->DeviceObject = DeviceObject;
    GetDeviceExt()->DriverObject = DriverObject;
    GetDeviceExt()->UnloadRoutine = OnUnload;
    GetDeviceExt()->FileListHead = NULL;
    GetDeviceExt()->LastUniqueKey = 1;

    KeInitializeSpinLock( &(GetDeviceExt()->FileListAccessSpinLock) );

    /* create symlink */

    RtlInitUnicodeString( &SymbolicLinkName, L"\\DosDevices\\disklocker_fsprotdrv" );

    status = IoCreateSymbolicLink( &SymbolicLinkName, &deviceObjectName );

    if (!NT_SUCCESS( status ))
    {
        /* delete registered device */
        IoDeleteDevice( GetDeviceExt()->DeviceObject );

        DbgPrint( "IoCreateSymbolicLink() failed with code = %08x\n", status );
        return status;
    }

    /* register filter */

    status = FltRegisterFilter( DriverObject, &FilterRegistration, &(GetDeviceExt()->FltFilter) );

    if (!NT_SUCCESS( status ))
    {
        /* delete registered symbolic link */
        IoDeleteSymbolicLink( &SymbolicLinkName );

        /* delete registered device */
        IoDeleteDevice( GetDeviceExt()->DeviceObject );

        DbgPrint( "FltRegisterFilter() failed with code = %08x\n", status );
        return status;
    }

    /* start filtering */

    status = FltStartFiltering( GetDeviceExt()->FltFilter );
    if (!NT_SUCCESS( status ))
    {
        /* delete registered symbolic link */
        IoDeleteSymbolicLink( &SymbolicLinkName );

        /* delete registered device */
        IoDeleteDevice( GetDeviceExt()->DeviceObject );

        /* unregister filter */
        FltUnregisterFilter( GetDeviceExt()->FltFilter );

        DbgPrint( "FltStartFiltering() failed with code = %08x\n", status );
        return status;
    }

    /* initialization done */

    DbgPrint( "file system filter initialization done..." );
    return STATUS_SUCCESS;
}
Пример #22
0
BOOLEAN
ndisprotRegisterExCallBack()
{
    OBJECT_ATTRIBUTES   ObjectAttr;
    UNICODE_STRING      CallBackObjectName;
    NTSTATUS            Status;
    BOOLEAN             bResult = TRUE;

    DEBUGP(DL_LOUD, ("--> ndisprotRegisterExCallBack\n"));

    PAGED_CODE();

    do {

        RtlInitUnicodeString(&CallBackObjectName, NDISPROT_CALLBACK_NAME);

        InitializeObjectAttributes(&ObjectAttr,
                                   &CallBackObjectName,
                                   OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
                                   NULL,
                                   NULL);

        Status = ExCreateCallback(&CallbackObject,
                                  &ObjectAttr,
                                  TRUE,
                                  TRUE);


        if (!NT_SUCCESS(Status)) {

            DEBUGP(DL_ERROR, ("RegisterExCallBack: failed to create callback %lx\n", Status));
            bResult = FALSE;
            break;
        }

        CallbackRegisterationHandle = ExRegisterCallback(CallbackObject,
                                                                 ndisprotCallback,
                                                                 (PVOID)NULL);
        if (CallbackRegisterationHandle == NULL) {
            DEBUGP(DL_ERROR,("RegisterExCallBack: failed to register a Callback routine%lx\n", Status));
            bResult = FALSE;
            break;
        }

        ExNotifyCallback(CallbackObject,
                        (PVOID)CALLBACK_SOURCE_NDISPROT,
                        (PVOID)NULL);


    }WHILE(FALSE);

    if(!bResult) {
        if (CallbackRegisterationHandle) {
            ExUnregisterCallback(CallbackRegisterationHandle);
            CallbackRegisterationHandle = NULL;
        }

        if (CallbackObject) {
            ObDereferenceObject(CallbackObject);
            CallbackObject = NULL;
        }
    }

    DEBUGP(DL_LOUD, ("<-- ndisprotRegisterExCallBack\n"));

    return bResult;

}
Пример #23
0
/***********************************************************************
 *      CryptCATEnumerateMember  (WINTRUST.@)
 */
CRYPTCATMEMBER * WINAPI CryptCATEnumerateMember(HANDLE hCatalog, CRYPTCATMEMBER *prev)
{
    struct cryptcat *cc = hCatalog;
    CRYPTCATMEMBER *member = prev;
    CTL_ENTRY *entry;
    DWORD size, i;

    TRACE("%p, %p\n", hCatalog, prev);

    if (!hCatalog || hCatalog == INVALID_HANDLE_VALUE || cc->magic != CRYPTCAT_MAGIC)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return NULL;
    }

    /* dumping the contents makes me think that dwReserved is the iteration number */
    if (!member)
    {
        if (!(member = HeapAlloc(GetProcessHeap(), 0, sizeof(*member))))
        {
            SetLastError(ERROR_OUTOFMEMORY);
            return NULL;
        }
        member->cbStruct = sizeof(*member);
        member->pwszFileName = member->pwszReferenceTag = NULL;
        member->dwReserved = 0;
        member->hReserved = NULL;
        member->gSubjectType = cc->subject;
        member->fdwMemberFlags = 0;
        member->pIndirectData = NULL;
        member->dwCertVersion = cc->inner->dwVersion;
    }
    else member->dwReserved++;

    if (member->dwReserved >= cc->inner->cCTLEntry)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        goto error;
    }

    /* list them backwards, like native */
    entry = &cc->inner->rgCTLEntry[cc->inner->cCTLEntry - member->dwReserved - 1];

    member->sEncodedIndirectData.cbData = member->sEncodedMemberInfo.cbData = 0;
    member->sEncodedIndirectData.pbData = member->sEncodedMemberInfo.pbData = NULL;
    HeapFree(GetProcessHeap(), 0, member->pIndirectData);
    member->pIndirectData = NULL;

    for (i = 0; i < entry->cAttribute; i++)
    {
        CRYPT_ATTRIBUTE *attr = entry->rgAttribute + i;

        if (attr->cValue != 1)
        {
            ERR("Can't handle attr->cValue of %u\n", attr->cValue);
            continue;
        }
        if (!strcmp(attr->pszObjId, CAT_MEMBERINFO_OBJID))
        {
            CAT_MEMBERINFO *mi;
            BOOL ret;

            member->sEncodedMemberInfo.cbData = attr->rgValue->cbData;
            member->sEncodedMemberInfo.pbData = attr->rgValue->pbData;

            CryptDecodeObject(cc->encoding, CAT_MEMBERINFO_OBJID, attr->rgValue->pbData, attr->rgValue->cbData, 0, NULL, &size);

            if (!(mi = HeapAlloc(GetProcessHeap(), 0, size)))
            {
                SetLastError(ERROR_OUTOFMEMORY);
                goto error;
            }
            ret = CryptDecodeObject(cc->encoding, CAT_MEMBERINFO_OBJID, attr->rgValue->pbData, attr->rgValue->cbData, 0, mi, &size);
            if (ret)
            {
                UNICODE_STRING guid;

                member->dwCertVersion = mi->dwCertVersion;
                RtlInitUnicodeString(&guid, mi->pwszSubjGuid);
                if (RtlGUIDFromString(&guid, &member->gSubjectType))
                {
                    HeapFree(GetProcessHeap(), 0, mi);
                    goto error;
                }
            }
            HeapFree(GetProcessHeap(), 0, mi);
            if (!ret) goto error;
        }
        else if (!strcmp(attr->pszObjId, SPC_INDIRECT_DATA_OBJID))
        {
            /* SPC_INDIRECT_DATA_CONTENT is equal to SIP_INDIRECT_DATA */

            member->sEncodedIndirectData.cbData = attr->rgValue->cbData;
            member->sEncodedIndirectData.pbData = attr->rgValue->pbData;

            CryptDecodeObject(cc->encoding, SPC_INDIRECT_DATA_OBJID, attr->rgValue->pbData, attr->rgValue->cbData, 0, NULL, &size);

            if (!(member->pIndirectData = HeapAlloc(GetProcessHeap(), 0, size)))
            {
                SetLastError(ERROR_OUTOFMEMORY);
                goto error;
            }
            CryptDecodeObject(cc->encoding, SPC_INDIRECT_DATA_OBJID, attr->rgValue->pbData, attr->rgValue->cbData, 0, member->pIndirectData, &size);
        }
        else
            /* this object id should probably be handled in CryptCATEnumerateAttr */
            FIXME("unhandled object id \"%s\"\n", attr->pszObjId);
    }

    if (!member->sEncodedMemberInfo.cbData || !member->sEncodedIndirectData.cbData)
    {
        ERR("Corrupted catalog entry?\n");
        SetLastError(CRYPT_E_ATTRIBUTES_MISSING);
        goto error;
    }
    size = (2 * member->pIndirectData->Digest.cbData + 1) * sizeof(WCHAR);
    if (member->pwszReferenceTag)
        member->pwszReferenceTag = HeapReAlloc(GetProcessHeap(), 0, member->pwszReferenceTag, size);
    else
        member->pwszReferenceTag = HeapAlloc(GetProcessHeap(), 0, size);

    if (!member->pwszReferenceTag)
    {
        SetLastError(ERROR_OUTOFMEMORY);
        goto error;
    }
    /* FIXME: reference tag is usually the file hash but doesn't have to be */
    for (i = 0; i < member->pIndirectData->Digest.cbData; i++)
    {
        DWORD sub;

        sub = member->pIndirectData->Digest.pbData[i] >> 4;
        member->pwszReferenceTag[i * 2] = (sub < 10 ? '0' + sub : 'A' + sub - 10);
        sub = member->pIndirectData->Digest.pbData[i] & 0xf;
        member->pwszReferenceTag[i * 2 + 1] = (sub < 10 ? '0' + sub : 'A' + sub - 10);
    }
    member->pwszReferenceTag[i * 2] = 0;
    return member;

error:
    HeapFree(GetProcessHeap(), 0, member->pIndirectData);
    HeapFree(GetProcessHeap(), 0, member->pwszReferenceTag);
    HeapFree(GetProcessHeap(), 0, member);
    return NULL;
}
Пример #24
0
BOOLEAN
INIT_FUNCTION
NTAPI
ObInitSystem(VOID)
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    UNICODE_STRING Name;
    OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
    OBP_LOOKUP_CONTEXT Context;
    HANDLE Handle;
    PKPRCB Prcb = KeGetCurrentPrcb();
    PLIST_ENTRY ListHead, NextEntry;
    POBJECT_HEADER Header;
    POBJECT_HEADER_CREATOR_INFO CreatorInfo;
    POBJECT_HEADER_NAME_INFO NameInfo;
    NTSTATUS Status;

    /* Check if this is actually Phase 1 initialization */
    if (ObpInitializationPhase != 0) goto ObPostPhase0;

    /* Initialize the OBJECT_CREATE_INFORMATION List */
    ExInitializeSystemLookasideList(&ObpCreateInfoLookasideList,
                                    NonPagedPool,
                                    sizeof(OBJECT_CREATE_INFORMATION),
                                    'ICbO',
                                    32,
                                    &ExSystemLookasideListHead);

    /* Set the captured UNICODE_STRING Object Name List */
    ExInitializeSystemLookasideList(&ObpNameBufferLookasideList,
                                    PagedPool,
                                    248,
                                    'MNbO',
                                    16,
                                    &ExSystemLookasideListHead);

    /* Temporarily setup both pointers to the shared list */
    Prcb->PPLookasideList[LookasideCreateInfoList].L = &ObpCreateInfoLookasideList;
    Prcb->PPLookasideList[LookasideCreateInfoList].P = &ObpCreateInfoLookasideList;
    Prcb->PPLookasideList[LookasideNameBufferList].L = &ObpNameBufferLookasideList;
    Prcb->PPLookasideList[LookasideNameBufferList].P = &ObpNameBufferLookasideList;

    /* Initialize the security descriptor cache */
    ObpInitSdCache();

    /* Initialize the Default Event */
    KeInitializeEvent(&ObpDefaultObject, NotificationEvent, TRUE);

    /* Initialize the Dos Device Map mutex */
    KeInitializeGuardedMutex(&ObpDeviceMapLock);

    /* Setup default access for the system process */
    PsGetCurrentProcess()->GrantedAccess = PROCESS_ALL_ACCESS;
    PsGetCurrentThread()->GrantedAccess = THREAD_ALL_ACCESS;

    /* Setup the Object Reaper */
    ExInitializeWorkItem(&ObpReaperWorkItem, ObpReapObject, NULL);

    /* Initialize default Quota block */
    PsInitializeQuotaSystem();

    /* Create kernel handle table */
    PsGetCurrentProcess()->ObjectTable = ExCreateHandleTable(NULL);
    ObpKernelHandleTable = PsGetCurrentProcess()->ObjectTable;

    /* Create the Type Type */
    RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
    RtlInitUnicodeString(&Name, L"Type");
    ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
    ObjectTypeInitializer.ValidAccessMask = OBJECT_TYPE_ALL_ACCESS;
    ObjectTypeInitializer.UseDefaultObject = TRUE;
    ObjectTypeInitializer.MaintainTypeList = TRUE;
    ObjectTypeInitializer.PoolType = NonPagedPool;
    ObjectTypeInitializer.GenericMapping = ObpTypeMapping;
    ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_TYPE);
    ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
    ObjectTypeInitializer.DeleteProcedure = ObpDeleteObjectType;
    ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ObpTypeObjectType);

    /* Create the Directory Type */
    RtlInitUnicodeString(&Name, L"Directory");
    ObjectTypeInitializer.ValidAccessMask = DIRECTORY_ALL_ACCESS;
    ObjectTypeInitializer.CaseInsensitive = TRUE;
    ObjectTypeInitializer.MaintainTypeList = FALSE;
    ObjectTypeInitializer.GenericMapping = ObpDirectoryMapping;
    ObjectTypeInitializer.DeleteProcedure = NULL;
    ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_DIRECTORY);
    ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ObDirectoryType);

    /* Create 'symbolic link' object type */
    RtlInitUnicodeString(&Name, L"SymbolicLink");
    ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_SYMBOLIC_LINK);
    ObjectTypeInitializer.GenericMapping = ObpSymbolicLinkMapping;
    ObjectTypeInitializer.ValidAccessMask = SYMBOLIC_LINK_ALL_ACCESS;
    ObjectTypeInitializer.ParseProcedure = ObpParseSymbolicLink;
    ObjectTypeInitializer.DeleteProcedure = ObpDeleteSymbolicLink;
    ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ObSymbolicLinkType);

    /* Phase 0 initialization complete */
    ObpInitializationPhase++;
    return TRUE;

ObPostPhase0:

    /* Re-initialize lookaside lists */
    ObInit2();

    /* Initialize Object Types directory attributes */
    RtlInitUnicodeString(&Name, L"\\");
    InitializeObjectAttributes(&ObjectAttributes,
                               &Name,
                               OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
                               NULL,
                               SePublicDefaultUnrestrictedSd);

    /* Create the directory */
    Status = NtCreateDirectoryObject(&Handle,
                                     DIRECTORY_ALL_ACCESS,
                                     &ObjectAttributes);
    if (!NT_SUCCESS(Status)) return FALSE;

    /* Get a handle to it */
    Status = ObReferenceObjectByHandle(Handle,
                                       0,
                                       ObDirectoryType,
                                       KernelMode,
                                       (PVOID*)&ObpRootDirectoryObject,
                                       NULL);
    if (!NT_SUCCESS(Status)) return FALSE;

    /* Close the extra handle */
    Status = NtClose(Handle);
    if (!NT_SUCCESS(Status)) return FALSE;

    /* Initialize Object Types directory attributes */
    RtlInitUnicodeString(&Name, L"\\KernelObjects");
    InitializeObjectAttributes(&ObjectAttributes,
                               &Name,
                               OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
                               NULL,
                               NULL);
    
    /* Create the directory */
    Status = NtCreateDirectoryObject(&Handle,
                                     DIRECTORY_ALL_ACCESS,
                                     &ObjectAttributes);
    if (!NT_SUCCESS(Status)) return FALSE;
    
    /* Close the extra handle */
    Status = NtClose(Handle);
    if (!NT_SUCCESS(Status)) return FALSE;

    /* Initialize Object Types directory attributes */
    RtlInitUnicodeString(&Name, L"\\ObjectTypes");
    InitializeObjectAttributes(&ObjectAttributes,
                               &Name,
                               OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
                               NULL,
                               NULL);

    /* Create the directory */
    Status = NtCreateDirectoryObject(&Handle,
                                     DIRECTORY_ALL_ACCESS,
                                     &ObjectAttributes);
    if (!NT_SUCCESS(Status)) return FALSE;

    /* Get a handle to it */
    Status = ObReferenceObjectByHandle(Handle,
                                       0,
                                       ObDirectoryType,
                                       KernelMode,
                                       (PVOID*)&ObpTypeDirectoryObject,
                                       NULL);
    if (!NT_SUCCESS(Status)) return FALSE;

    /* Close the extra handle */
    Status = NtClose(Handle);
    if (!NT_SUCCESS(Status)) return FALSE;

    /* Initialize lookup context */
    ObpInitializeLookupContext(&Context);

    /* Lock it */
    ObpAcquireDirectoryLockExclusive(ObpTypeDirectoryObject, &Context);

    /* Loop the object types */
    ListHead = &ObpTypeObjectType->TypeList;
    NextEntry = ListHead->Flink;
    while (ListHead != NextEntry)
    {
        /* Get the creator info from the list */
        CreatorInfo = CONTAINING_RECORD(NextEntry,
                                        OBJECT_HEADER_CREATOR_INFO,
                                        TypeList);

        /* Recover the header and the name header from the creator info */
        Header = (POBJECT_HEADER)(CreatorInfo + 1);
        NameInfo = OBJECT_HEADER_TO_NAME_INFO(Header);

        /* Make sure we have a name, and aren't inserted yet */
        if ((NameInfo) && !(NameInfo->Directory))
        {
            /* Do the initial lookup to setup the context */
            if (!ObpLookupEntryDirectory(ObpTypeDirectoryObject,
                                         &NameInfo->Name,
                                         OBJ_CASE_INSENSITIVE,
                                         FALSE,
                                         &Context))
            {
                /* Insert this object type */
                ObpInsertEntryDirectory(ObpTypeDirectoryObject,
                                        &Context,
                                        Header);
            }
        }

        /* Move to the next entry */
        NextEntry = NextEntry->Flink;
    }

    /* Cleanup after lookup */
    ObpReleaseLookupContext(&Context);

    /* Initialize DOS Devices Directory and related Symbolic Links */
    Status = ObpCreateDosDevicesDirectory();
    if (!NT_SUCCESS(Status)) return FALSE;
    return TRUE;
}
Пример #25
0
PPCI_REGISTRY_INFO_INTERNAL
NTAPI
INIT_FUNCTION
HalpQueryPciRegistryInfo(VOID)
{
#ifndef _MINIHAL_
    WCHAR NameBuffer[8];
    OBJECT_ATTRIBUTES  ObjectAttributes;
    UNICODE_STRING KeyName, ConfigName, IdentName;
    HANDLE KeyHandle, BusKeyHandle, CardListHandle;
    NTSTATUS Status;
    UCHAR KeyBuffer[sizeof(CM_FULL_RESOURCE_DESCRIPTOR) + 100];
    PKEY_VALUE_FULL_INFORMATION ValueInfo = (PVOID)KeyBuffer;
    UCHAR PartialKeyBuffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) +
                           sizeof(PCI_CARD_DESCRIPTOR)];
    PKEY_VALUE_PARTIAL_INFORMATION PartialValueInfo = (PVOID)PartialKeyBuffer;
    KEY_FULL_INFORMATION KeyInformation;
    ULONG ResultLength;
    PWSTR Tag;
    ULONG i, ElementCount;
    PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptor;
    PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
    PPCI_REGISTRY_INFO PciRegInfo;
    PPCI_REGISTRY_INFO_INTERNAL PciRegistryInfo;
    PPCI_CARD_DESCRIPTOR CardDescriptor;

    /* Setup the object attributes for the key */
    RtlInitUnicodeString(&KeyName,
                         L"\\Registry\\Machine\\Hardware\\Description\\"
                         L"System\\MultiFunctionAdapter");
    InitializeObjectAttributes(&ObjectAttributes,
                               &KeyName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);

    /* Open the key */
    Status = ZwOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes);
    if (!NT_SUCCESS(Status)) return NULL;

    /* Setup the receiving string */
    KeyName.Buffer = NameBuffer;
    KeyName.MaximumLength = sizeof(NameBuffer);

    /* Setup the configuration and identifier key names */
    RtlInitUnicodeString(&ConfigName, L"Configuration Data");
    RtlInitUnicodeString(&IdentName, L"Identifier");

    /* Keep looping for each ID */
    for (i = 0; TRUE; i++)
    {
        /* Setup the key name */
        RtlIntegerToUnicodeString(i, 10, &KeyName);
        InitializeObjectAttributes(&ObjectAttributes,
                                   &KeyName,
                                   OBJ_CASE_INSENSITIVE,
                                   KeyHandle,
                                   NULL);

        /* Open it */
        Status = ZwOpenKey(&BusKeyHandle, KEY_READ, &ObjectAttributes);
        if (!NT_SUCCESS(Status))
        {
            /* None left, fail */
            ZwClose(KeyHandle);
            return NULL;
        }

        /* Read the registry data */
        Status = ZwQueryValueKey(BusKeyHandle,
                                 &IdentName,
                                 KeyValueFullInformation,
                                 ValueInfo,
                                 sizeof(KeyBuffer),
                                 &ResultLength);
        if (!NT_SUCCESS(Status))
        {
            /* Failed, try the next one */
            ZwClose(BusKeyHandle);
            continue;
        }

        /* Get the PCI Tag and validate it */
        Tag = (PWSTR)((ULONG_PTR)ValueInfo + ValueInfo->DataOffset);
        if ((Tag[0] != L'P') ||
            (Tag[1] != L'C') ||
            (Tag[2] != L'I') ||
            (Tag[3]))
        {
            /* Not a valid PCI entry, skip it */
            ZwClose(BusKeyHandle);
            continue;
        }

        /* Now read our PCI structure */
        Status = ZwQueryValueKey(BusKeyHandle,
                                 &ConfigName,
                                 KeyValueFullInformation,
                                 ValueInfo,
                                 sizeof(KeyBuffer),
                                 &ResultLength);
        ZwClose(BusKeyHandle);
        if (!NT_SUCCESS(Status)) continue;

        /* We read it OK! Get the actual resource descriptors */
        FullDescriptor  = (PCM_FULL_RESOURCE_DESCRIPTOR)
                          ((ULONG_PTR)ValueInfo + ValueInfo->DataOffset);
        PartialDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)
                            ((ULONG_PTR)FullDescriptor->
                                        PartialResourceList.PartialDescriptors);

        /* Check if this is our PCI Registry Information */
        if (PartialDescriptor->Type == CmResourceTypeDeviceSpecific)
        {
            /* It is, stop searching */
            break;
        }
    }

    /* Close the key */
    ZwClose(KeyHandle);

    /* Save the PCI information for later */
    PciRegInfo = (PPCI_REGISTRY_INFO)(PartialDescriptor + 1);

    /* Assume no Card List entries */
    ElementCount = 0;

    /* Set up for checking the PCI Card List key */
    RtlInitUnicodeString(&KeyName,
                         L"\\Registry\\Machine\\System\\CurrentControlSet\\"
                         L"Control\\PnP\\PCI\\CardList");
    InitializeObjectAttributes(&ObjectAttributes,
                               &KeyName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);

    /* Attempt to open it */
    Status = ZwOpenKey(&CardListHandle, KEY_READ, &ObjectAttributes);
    if (NT_SUCCESS(Status))
    {
        /* It exists, so let's query it */
        Status = ZwQueryKey(CardListHandle,
                            KeyFullInformation,
                            &KeyInformation,
                            sizeof(KEY_FULL_INFORMATION),
                            &ResultLength);
        if (!NT_SUCCESS(Status))
        {
            /* Failed to query, so no info */
            PciRegistryInfo = NULL;
        }
        else
        {
            /* Allocate the full structure */
            PciRegistryInfo =
                ExAllocatePoolWithTag(NonPagedPool,
                                      sizeof(PCI_REGISTRY_INFO_INTERNAL) +
                                      (KeyInformation.Values *
                                       sizeof(PCI_CARD_DESCRIPTOR)),
                                       TAG_HAL);
            if (PciRegistryInfo)
            {
                /* Get the first card descriptor entry */
                CardDescriptor = (PPCI_CARD_DESCRIPTOR)(PciRegistryInfo + 1);

                /* Loop all the values */
                for (i = 0; i < KeyInformation.Values; i++)
                {
                    /* Attempt to get the value */
                    Status = ZwEnumerateValueKey(CardListHandle,
                                                 i,
                                                 KeyValuePartialInformation,
                                                 PartialValueInfo,
                                                 sizeof(PartialKeyBuffer),
                                                 &ResultLength);
                    if (!NT_SUCCESS(Status))
                    {
                        /* Something went wrong, stop the search */
                        break;
                    }

                    /* Make sure it is correctly sized */
                    if (PartialValueInfo->DataLength == sizeof(PCI_CARD_DESCRIPTOR))
                    {
                        /* Sure is, copy it over */
                        *CardDescriptor = *(PPCI_CARD_DESCRIPTOR)
                                           PartialValueInfo->Data;

                        /* One more Card List entry */
                        ElementCount++;

                        /* Move to the next descriptor */
                        CardDescriptor = (CardDescriptor + 1);
                    }
                }
            }
        }

        /* Close the Card List key */
        ZwClose(CardListHandle);
    }
    else
    {
       /* No key, no Card List */
       PciRegistryInfo = NULL;
    }

    /* Check if we failed to get the full structure */
    if (!PciRegistryInfo)
    {
        /* Just allocate the basic structure then */
        PciRegistryInfo = ExAllocatePoolWithTag(NonPagedPool,
                                                sizeof(PCI_REGISTRY_INFO_INTERNAL),
                                                TAG_HAL);
        if (!PciRegistryInfo) return NULL;
    }

    /* Save the info we got */
    PciRegistryInfo->MajorRevision = PciRegInfo->MajorRevision;
    PciRegistryInfo->MinorRevision = PciRegInfo->MinorRevision;
    PciRegistryInfo->NoBuses = PciRegInfo->NoBuses;
    PciRegistryInfo->HardwareMechanism = PciRegInfo->HardwareMechanism;
    PciRegistryInfo->ElementCount = ElementCount;

    /* Return it */
    return PciRegistryInfo;
#else
    return NULL;
#endif
}
Пример #26
0
static void find_reg_tz_info(RTL_TIME_ZONE_INFORMATION *tzi)
{
    static const WCHAR Time_ZonesW[] = { 'M','a','c','h','i','n','e','\\',
        'S','o','f','t','w','a','r','e','\\',
        'M','i','c','r','o','s','o','f','t','\\',
        'W','i','n','d','o','w','s',' ','N','T','\\',
        'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
        'T','i','m','e',' ','Z','o','n','e','s',0 };
    HANDLE hkey;
    ULONG idx;
    OBJECT_ATTRIBUTES attr;
    UNICODE_STRING nameW;
    WCHAR buf[128];

    attr.Length = sizeof(attr);
    attr.RootDirectory = 0;
    attr.ObjectName = &nameW;
    attr.Attributes = 0;
    attr.SecurityDescriptor = NULL;
    attr.SecurityQualityOfService = NULL;
    RtlInitUnicodeString(&nameW, Time_ZonesW);
    if (NtOpenKey(&hkey, KEY_READ, &attr))
    {
        WARN("Unable to open the time zones key\n");
        return;
    }

    idx = 0;
    nameW.Buffer = buf;
    nameW.Length = sizeof(buf);
    nameW.MaximumLength = sizeof(buf);

    while (!RtlpNtEnumerateSubKey(hkey, &nameW, idx++))
    {
        static const WCHAR stdW[] = { 'S','t','d',0 };
        static const WCHAR dltW[] = { 'D','l','t',0 };
        static const WCHAR tziW[] = { 'T','Z','I',0 };
        RTL_TIME_ZONE_INFORMATION reg_tzi;
        HANDLE hSubkey;
        struct tz_reg_data
        {
            LONG bias;
            LONG std_bias;
            LONG dlt_bias;
            RTL_SYSTEM_TIME std_date;
            RTL_SYSTEM_TIME dlt_date;
        } tz_data;

        attr.Length = sizeof(attr);
        attr.RootDirectory = hkey;
        attr.ObjectName = &nameW;
        attr.Attributes = 0;
        attr.SecurityDescriptor = NULL;
        attr.SecurityQualityOfService = NULL;
        if (NtOpenKey(&hSubkey, KEY_READ, &attr))
        {
            WARN("Unable to open subkey %s\n", debugstr_wn(nameW.Buffer, nameW.Length/sizeof(WCHAR)));
            continue;
        }

#define get_value(hkey, name, type, data, len) \
    if (!reg_query_value(hkey, name, type, data, len)) \
    { \
        WARN("can't read data from %s\n", debugstr_w(name)); \
        NtClose(hkey); \
        continue; \
    }

        get_value(hSubkey, stdW, REG_SZ, reg_tzi.StandardName, sizeof(reg_tzi.StandardName));
        get_value(hSubkey, dltW, REG_SZ, reg_tzi.DaylightName, sizeof(reg_tzi.DaylightName));
        get_value(hSubkey, tziW, REG_BINARY, &tz_data, sizeof(tz_data));

#undef get_value

        reg_tzi.Bias = tz_data.bias;
        reg_tzi.StandardBias = tz_data.std_bias;
        reg_tzi.DaylightBias = tz_data.dlt_bias;
        reg_tzi.StandardDate = tz_data.std_date;
        reg_tzi.DaylightDate = tz_data.dlt_date;

        TRACE("%s: bias %d\n", debugstr_wn(nameW.Buffer, nameW.Length/sizeof(WCHAR)), reg_tzi.Bias);
        TRACE("std (d/m/y): %u/%02u/%04u day of week %u %u:%02u:%02u.%03u bias %d\n",
            reg_tzi.StandardDate.wDay, reg_tzi.StandardDate.wMonth,
            reg_tzi.StandardDate.wYear, reg_tzi.StandardDate.wDayOfWeek,
            reg_tzi.StandardDate.wHour, reg_tzi.StandardDate.wMinute,
            reg_tzi.StandardDate.wSecond, reg_tzi.StandardDate.wMilliseconds,
            reg_tzi.StandardBias);
        TRACE("dst (d/m/y): %u/%02u/%04u day of week %u %u:%02u:%02u.%03u bias %d\n",
            reg_tzi.DaylightDate.wDay, reg_tzi.DaylightDate.wMonth,
            reg_tzi.DaylightDate.wYear, reg_tzi.DaylightDate.wDayOfWeek,
            reg_tzi.DaylightDate.wHour, reg_tzi.DaylightDate.wMinute,
            reg_tzi.DaylightDate.wSecond, reg_tzi.DaylightDate.wMilliseconds,
            reg_tzi.DaylightBias);

        NtClose(hSubkey);

        if (match_tz_info(tzi, &reg_tzi))
        {
            *tzi = reg_tzi;
            NtClose(hkey);
            return;
        }

        /* reset len */
        nameW.Length = sizeof(buf);
        nameW.MaximumLength = sizeof(buf);
    }

    NtClose(hkey);

    FIXME("Can't find matching timezone information in the registry for "
          "bias %d, std (d/m/y): %u/%02u/%04u, dlt (d/m/y): %u/%02u/%04u\n",
          tzi->Bias,
          tzi->StandardDate.wDay, tzi->StandardDate.wMonth, tzi->StandardDate.wYear,
          tzi->DaylightDate.wDay, tzi->DaylightDate.wMonth, tzi->DaylightDate.wYear);
}
Пример #27
0
NET_API_STATUS
NetpRdrFsControlTree(
    IN LPTSTR TreeName,
    IN LPTSTR TransportName OPTIONAL,
    IN DWORD ConnectionType,
    IN DWORD FsControlCode,
    IN LPVOID SecurityDescriptor OPTIONAL,
    IN LPVOID InputBuffer OPTIONAL,
    IN DWORD InputBufferSize,
    OUT LPVOID OutputBuffer OPTIONAL,
    IN DWORD OutputBufferSize,
    IN BOOL NoPermissionRequired
    )

/*++

Routine Description:

    NetpRdrFsControlTree performs a given FSCTL (file system control)
    on a given tree connection name.

Arguments:

    TreeName - Remote name to do fsctl to (in \\server\share format).

    FsControlCode - function code to pass to the redirector.  These are
        defined in <ntddnfs.h>.

    SecurityDescriptor - optionally points to a security descriptor to be
        used when creating the tree connection.

    InputBuffer - optionally points to a structure to be passed to the
        redirector.

    InputBufferSize - size of InputBuffer in bytes; must be zero if
        InputBuffer is a NULL pointer.

    OutputBuffer - optionally points to a structure to be filled in by the
        redirector.

    OutputBufferSize - size of OutputBuffer in bytes; must be zero if
        OutputBuffer is a NULL pointer.

    NoPermissionRequired - TRUE if this is a no permission required API.  (I.e.
        TRUE if the null session may be used.)

Return Value:

    NET_API_STATUS

--*/

{
    NET_API_STATUS ApiStatus;
    IO_STATUS_BLOCK iosb;
    NTSTATUS ntstatus;                      // Status from NT operations.
    OBJECT_ATTRIBUTES objattrTreeConn;      // Attrs for tree conn.
    LPTSTR pszTreeConn;                      // See strTreeConn below.
#ifndef UNICODE
    STRING strTreeConn;                     // \Device\LanManRedir\server\share
#endif
    UNICODE_STRING ucTreeConn;
    HANDLE TreeConnHandle;

    PFILE_FULL_EA_INFORMATION EaBuffer = NULL;
    PFILE_FULL_EA_INFORMATION Ea;
    USHORT TransportNameSize = 0;
    ULONG EaBufferSize = 0;
    PWSTR UnicodeTransportName = NULL;

    UCHAR EaNameDomainNameSize = (UCHAR) (ROUND_UP_COUNT(
                                             strlen(EA_NAME_DOMAIN) + sizeof(CHAR),
                                             ALIGN_WCHAR
                                             ) - sizeof(CHAR));

    UCHAR EaNamePasswordSize = (UCHAR) (ROUND_UP_COUNT(
                                             strlen(EA_NAME_PASSWORD) + sizeof(CHAR),
                                             ALIGN_WCHAR
                                             ) - sizeof(CHAR));

    UCHAR EaNameTransportNameSize = (UCHAR) (ROUND_UP_COUNT(
                                             strlen(EA_NAME_TRANSPORT) + sizeof(CHAR),
                                             ALIGN_WCHAR
                                             ) - sizeof(CHAR));

    UCHAR EaNameTypeSize = (UCHAR) (ROUND_UP_COUNT(
                                        strlen(EA_NAME_TYPE) + sizeof(CHAR),
                                        ALIGN_DWORD
                                        ) - sizeof(CHAR));

    UCHAR EaNameUserNameSize = (UCHAR) (ROUND_UP_COUNT(
                                             strlen(EA_NAME_USERNAME) + sizeof(CHAR),
                                             ALIGN_WCHAR
                                             ) - sizeof(CHAR));

    USHORT TypeSize = sizeof(ULONG);




    IF_DEBUG(RDRFSCTL) {
        NetpKdPrint(( PREFIX_NETLIB
                "NetpRdrFsControlTree: entered, TreeName='"
                FORMAT_LPTSTR "', " FORMAT_LPTSTR " session.\n",
                TreeName,
                NoPermissionRequired ? TEXT("null") : TEXT("non-null") ));
    }

    if ((TreeName == NULL) || (TreeName[0] == 0)) {
        return (ERROR_INVALID_PARAMETER);
    }

    if (! NetpIsRemoteNameValid(TreeName)) {
        return (ERROR_INVALID_PARAMETER);
    }

    //
    // Build NT-style name for what we're connecting to.  Note that there is
    // NOT a pair of backslashes anywhere in this name.
    //

    {
        DWORD NameSize =

            // /Device/LanManRedirector      /    server/share     \0
#ifdef UNICODE
            ( ( STRLEN((LPTSTR)DD_NFS_DEVICE_NAME_U) + 1 + STRLEN(TreeName) + 1 ) )
#else
            ( ( STRLEN((LPTSTR)DD_NFS_DEVICE_NAME) + 1 + STRLEN(TreeName) + 1 ) )
#endif
            * sizeof(TCHAR);

        pszTreeConn = (LPTSTR)NetpMemoryAllocate( NameSize );
    }

    if (pszTreeConn == NULL) {
        return (ERROR_NOT_ENOUGH_MEMORY);
    }

    //
    // Build the tree connect name.
    //

#ifdef UNICODE
    (void) STRCPY(pszTreeConn, (LPTSTR) DD_NFS_DEVICE_NAME_U);
#else
    (void) STRCPY(pszTreeConn, (LPTSTR) DD_NFS_DEVICE_NAME);
#endif

    //
    // NOTE: We add 1, (not sizeof(TCHAR)) because pointer arithmetic is done
    // in terms of multiples of sizeof(*pointer), not bytes
    //

    (void) STRCAT(pszTreeConn, TreeName+1); // \server\share

#ifdef UNICODE
    RtlInitUnicodeString(&ucTreeConn, pszTreeConn);
#else
    RtlInitString( & strTreeConn, pszTreeConn);
    (void) RtlOemStringToUnicodeString(&ucTreeConn, &strTreeConn, TRUE);
#endif

    IF_DEBUG(RDRFSCTL) {
        NetpKdPrint(( PREFIX_NETLIB
                "NetpRdrFsControlTree: UNICODE name is " FORMAT_LPWSTR
                ".\n", ucTreeConn.Buffer ));
    }



    //
    // Calculate the number of bytes needed for the EA buffer.
    // This may have the transport name.  For regular sessions, the user
    // name, password, and domain name are implicit.  For null sessions, we
    // must give 0-len user name, 0-len password, and 0-len domain name.
    //

    if (ARGUMENT_PRESENT(TransportName)) {
        ASSERT(ConnectionType == USE_IPC);

#ifdef UNICODE
        UnicodeTransportName = TransportName;
#else
        UnicodeTransportName = NetpAllocWStrFromStr(TransportName);

        if (UnicodeTransportName == NULL) {

            NetpMemoryFree(pszTreeConn);

            return ERROR_NOT_ENOUGH_MEMORY;
        }
#endif
        TransportNameSize = (USHORT) (wcslen(UnicodeTransportName) * sizeof(WCHAR));

        EaBufferSize += ROUND_UP_COUNT(
                            FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName[0]) +
                            EaNameTransportNameSize + sizeof(CHAR) +
                            TransportNameSize,
                            ALIGN_DWORD
                            );
    }

    if (NoPermissionRequired) {

        // Domain name (0-len).
        EaBufferSize += ROUND_UP_COUNT(
                            FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName[0]) +
                            EaNameDomainNameSize + sizeof(CHAR),
                            ALIGN_DWORD
                            );

        // Password (0-len).
        EaBufferSize += ROUND_UP_COUNT(
                            FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName[0]) +
                            EaNamePasswordSize + sizeof(CHAR),
                            ALIGN_DWORD
                            );

        // User name (0-len).
        EaBufferSize += ROUND_UP_COUNT(
                            FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName[0]) +
                            EaNameUserNameSize + sizeof(CHAR),
                            ALIGN_DWORD
                            );
    }

    EaBufferSize += ((ULONG)FIELD_OFFSET( FILE_FULL_EA_INFORMATION, EaName[0]))+
                    EaNameTypeSize + sizeof(CHAR) +
                    TypeSize;


    //
    // Allocate the EA buffer
    //

    if ((EaBuffer = NetpMemoryAllocate( EaBufferSize )) == NULL) {

        NetpMemoryFree(pszTreeConn);

#ifndef UNICODE
        if (UnicodeTransportName != NULL) {
            NetpMemoryFree(UnicodeTransportName);
        }
#endif

        return ERROR_NOT_ENOUGH_MEMORY;
    }

    //
    // Fill-in the EA buffer.
    //

    RtlZeroMemory(EaBuffer, EaBufferSize);

    Ea = EaBuffer;

    if (ARGUMENT_PRESENT(TransportName)) {

        //
        // Copy the EA name into EA buffer.  EA name length does not
        // include the zero terminator.
        //
        strcpy(Ea->EaName, EA_NAME_TRANSPORT);
        Ea->EaNameLength = EaNameTransportNameSize;

        //
        // Copy the EA value into EA buffer.  EA value length does not
        // include the zero terminator.
        //
        (VOID) wcscpy(
            (LPWSTR) &(Ea->EaName[EaNameTransportNameSize + sizeof(CHAR)]),
            UnicodeTransportName
            );

        Ea->EaValueLength = TransportNameSize;

        Ea->NextEntryOffset = ROUND_UP_COUNT(
                                  FIELD_OFFSET( FILE_FULL_EA_INFORMATION, EaName[0]) +
                                  EaNameTransportNameSize + sizeof(CHAR) +
                                  TransportNameSize,
                                  ALIGN_DWORD
                                  );
        Ea->Flags = 0;

        (ULONG) Ea += Ea->NextEntryOffset;
    }

    if (NoPermissionRequired) {

        //
        // *** DOMAIN NAME ***
        // Copy the EA name into EA buffer.  EA name length does not
        // include the zero terminator.
        //
        (VOID) strcpy(Ea->EaName, EA_NAME_DOMAIN);
        Ea->EaNameLength = EaNameDomainNameSize;

        Ea->EaValueLength = 0;  // There is no EA value for this.

        Ea->NextEntryOffset = ROUND_UP_COUNT(
                                  FIELD_OFFSET( FILE_FULL_EA_INFORMATION, EaName[0]) +
                                  EaNameDomainNameSize + sizeof(CHAR),
                                  ALIGN_DWORD
                                  );
        Ea->Flags = 0;

        (ULONG) Ea += Ea->NextEntryOffset;

        //
        // *** PASSWORD ***
        // Copy the EA name into EA buffer.  EA name length does not
        // include the zero terminator.
        //
        (VOID) strcpy(Ea->EaName, EA_NAME_PASSWORD);
        Ea->EaNameLength = EaNamePasswordSize;

        Ea->EaValueLength = 0;  // There is no EA value for this.

        Ea->NextEntryOffset = ROUND_UP_COUNT(
                                  FIELD_OFFSET( FILE_FULL_EA_INFORMATION, EaName[0]) +
                                  EaNamePasswordSize + sizeof(CHAR),
                                  ALIGN_DWORD
                                  );
        Ea->Flags = 0;

        (ULONG) Ea += Ea->NextEntryOffset;

        //
        // *** USER NAME ***
        // Copy the EA name into EA buffer.  EA name length does not
        // include the zero terminator.
        //
        (VOID) strcpy(Ea->EaName, EA_NAME_USERNAME);
        Ea->EaNameLength = EaNameUserNameSize;

        Ea->EaValueLength = 0;  // There is no EA value for this.

        Ea->NextEntryOffset = ROUND_UP_COUNT(
                                  FIELD_OFFSET( FILE_FULL_EA_INFORMATION, EaName[0]) +
                                  EaNameUserNameSize + sizeof(CHAR),
                                  ALIGN_DWORD
                                  );
        Ea->Flags = 0;

        (ULONG) Ea += Ea->NextEntryOffset;
    }

    //
    // Copy the EA for the connection type name into EA buffer.  EA name length
    // does not include the zero terminator.
    //
    strcpy(Ea->EaName, EA_NAME_TYPE);
    Ea->EaNameLength = EaNameTypeSize;

    *((PULONG) &(Ea->EaName[EaNameTypeSize + sizeof(CHAR)])) = ConnectionType;

    Ea->EaValueLength = TypeSize;

    Ea->NextEntryOffset = 0;
    Ea->Flags = 0;

    // Set object attributes for the tree conn.
    InitializeObjectAttributes(
                & objattrTreeConn,                       // obj attr to init
                (LPVOID) & ucTreeConn,                   // string to use
                OBJ_CASE_INSENSITIVE,                    // Attributes
                NULL,                                    // Root directory
                SecurityDescriptor);                     // Security Descriptor

    //
    // Open a tree connection to the remote server.
    //

    IF_DEBUG(RDRFSCTL) {
        NetpKdPrint(( PREFIX_NETLIB
                "NetpRdrFsControlTree: opening " FORMAT_LPTSTR ".\n",
                pszTreeConn ));
    }
    ntstatus = NtCreateFile(
                & TreeConnHandle,                        // ptr to handle
                SYNCHRONIZE                              // desired...
                | GENERIC_READ | GENERIC_WRITE,          // ...access
                & objattrTreeConn,                       // name & attributes
                & iosb,                                  // I/O status block.
                NULL,                                    // alloc size.
                FILE_ATTRIBUTE_NORMAL,                   // (ignored)
                FILE_SHARE_READ | FILE_SHARE_WRITE,      // ...access
                FILE_OPEN_IF,                            // create disposition
                FILE_CREATE_TREE_CONNECTION              // create...
                | FILE_SYNCHRONOUS_IO_NONALERT,          // ...options
                EaBuffer,                                // EA buffer
                EaBufferSize );                          // Ea buffer size

#ifndef UNICODE
    RtlFreeUnicodeString( &ucTreeConn );
#endif

    if (! NT_SUCCESS(ntstatus)) {

#ifndef UNICODE
        if (UnicodeTransportName != NULL) {
            NetpMemoryFree(UnicodeTransportName);

        }
#endif

        if (EaBuffer != NULL) {
            NetpMemoryFree(EaBuffer);
        }

        NetpMemoryFree(pszTreeConn);
        ApiStatus = NetpNtStatusToApiStatus(ntstatus);
        if (ApiStatus == ERROR_BAD_NET_NAME) {
            ApiStatus = NERR_BadTransactConfig;  // Special meaning if no IPC$
        }

        if (ApiStatus != ERROR_BAD_NETPATH) {
            NetpKdPrint(( PREFIX_NETLIB
                    "NetpRdrFsControlTree: unexpected create error,\n"
                    "  tree name='" FORMAT_LPTSTR "', "
                    "ntstatus=" FORMAT_NTSTATUS ",\n"
                    "  iosb.Status=" FORMAT_NTSTATUS ", "
                    "iosb.Info=" FORMAT_HEX_ULONG ", "
                    "  returning " FORMAT_API_STATUS ".\n",
                    TreeName, ntstatus,
                    iosb.Status, iosb.Information, ApiStatus ));
        }

        return (ApiStatus);
    }

    // Do the FSCTL.
    IF_DEBUG(RDRFSCTL) {
        NetpKdPrint(( PREFIX_NETLIB
                "NetpRdrFsControlTree: doing fsctl...\n" ));
    }
    ntstatus = NtFsControlFile(
                        TreeConnHandle,                  // handle
                        NULL,                            // no event
                        NULL,                            // no APC routine
                        NULL,                            // no APC context
                        & iosb,                          // I/O stat blk (set)
                        FsControlCode,                   // func code
                        InputBuffer,
                        InputBufferSize,
                        OutputBuffer,
                        OutputBufferSize);

    if (! NT_SUCCESS(ntstatus)) {
       NTSTATUS Status;

       Status = NtClose(TreeConnHandle);
#if DBG
       if (!NT_SUCCESS(Status)) {
           NetpKdPrint(( PREFIX_NETLIB
                   "NetpRdrFsControlTree: "
                   "Unexpected error closing tree connect handle: "
                   FORMAT_NTSTATUS "\n",
                   Status ));
       }
#endif

       NetpMemoryFree(pszTreeConn);

#ifndef UNICODE
        if (UnicodeTransportName != NULL) {
            NetpMemoryFree(UnicodeTransportName);

        }
#endif

        if (EaBuffer != NULL) {
            NetpMemoryFree(EaBuffer);
        }
        ApiStatus = NetpNtStatusToApiStatus(ntstatus);

        NetpKdPrint(( PREFIX_NETLIB
                "NetpRdrFsControlTree: unexpected FSCTL error,\n"
                "  tree name='" FORMAT_LPTSTR "', "
                "ntstatus=" FORMAT_NTSTATUS ".\n"
                "  ApiStatus=" FORMAT_API_STATUS ", "
                "iosb.Status=" FORMAT_NTSTATUS ", "
                "iosb.Info=" FORMAT_HEX_ULONG ".\n",
                TreeName, ntstatus, ApiStatus, iosb.Status, iosb.Information ));

        return (ApiStatus);
    }

    // Clean up.
    ntstatus = NtClose(TreeConnHandle);
#if DBG
       if (!NT_SUCCESS(ntstatus)) {
           NetpKdPrint(( PREFIX_NETLIB
                   "NetpRdrFsControlTree: "
                   "Unexpected error closing tree connect handle: "
                   FORMAT_NTSTATUS "\n", ntstatus ));
       }
#endif

    NetpMemoryFree(pszTreeConn);

#ifndef UNICODE
    if (UnicodeTransportName != NULL) {
        NetpMemoryFree(UnicodeTransportName);

    }
#endif

    if (EaBuffer != NULL) {
        NetpMemoryFree(EaBuffer);
    }

    return (NERR_Success);

} // NetpRdrFsControlTree
Пример #28
0
NTSTATUS GSTOpenVolume (PDEVICE_OBJECT DeviceObject,
	       PEXTENSION Extension,
	       MOUNT_STRUCT *mount,
	       PWSTR pwszMountVolume,
	       BOOL bRawDevice)
{
	FILE_STANDARD_INFORMATION FileStandardInfo;
	FILE_BASIC_INFORMATION FileBasicInfo;
	OBJECT_ATTRIBUTES oaFileAttributes;
	UNICODE_STRING FullFileName;
	IO_STATUS_BLOCK IoStatusBlock;
	PCRYPTO_INFO cryptoInfoPtr = NULL;
	PCRYPTO_INFO tmpCryptoInfo = NULL;
	LARGE_INTEGER lDiskLength;
	__int64 partitionStartingOffset = 0;
	int volumeType;
	char *readBuffer = 0;
	NTSTATUS ntStatus = 0;
	BOOL forceAccessCheck = (!bRawDevice && !(OsMajorVersion == 5 &&OsMinorVersion == 0)); // Windows 2000 does not support OBJ_FORCE_ACCESS_CHECK attribute
	BOOL disableBuffering = TRUE;
	BOOL exclusiveAccess = mount->bExclusiveAccess;

	Extension->pfoDeviceFile = NULL;
	Extension->hDeviceFile = NULL;
	Extension->bTimeStampValid = FALSE;

	RtlInitUnicodeString (&FullFileName, pwszMountVolume);
	InitializeObjectAttributes (&oaFileAttributes, &FullFileName, OBJ_CASE_INSENSITIVE | (forceAccessCheck ? OBJ_FORCE_ACCESS_CHECK : 0) | OBJ_KERNEL_HANDLE, NULL, NULL);
	KeInitializeEvent (&Extension->keVolumeEvent, NotificationEvent, FALSE);

	if (Extension->SecurityClientContextValid)
	{
		ntStatus = SeImpersonateClientEx (&Extension->SecurityClientContext, NULL);
		if (!NT_SUCCESS (ntStatus))
			goto error;
	}

	mount->VolumeMountedReadOnlyAfterDeviceWriteProtected = FALSE;

	// If we are opening a device, query its size first
	if (bRawDevice)
	{
		PARTITION_INFORMATION pi;
		PARTITION_INFORMATION_EX pix;
		LARGE_INTEGER diskLengthInfo;
		DISK_GEOMETRY dg;

		ntStatus = IoGetDeviceObjectPointer (&FullFileName,
			FILE_READ_DATA | FILE_READ_ATTRIBUTES,
			&Extension->pfoDeviceFile,
			&Extension->pFsdDevice);

		if (!NT_SUCCESS (ntStatus))
			goto error;

		ntStatus = GSTSendHostDeviceIoControlRequest (DeviceObject, Extension, IOCTL_DISK_GET_DRIVE_GEOMETRY, (char *) &dg, sizeof (dg));
		if (!NT_SUCCESS (ntStatus))
			goto error;

		lDiskLength.QuadPart = dg.Cylinders.QuadPart * dg.SectorsPerTrack * dg.TracksPerCylinder * dg.BytesPerSector;
		Extension->HostBytesPerSector = dg.BytesPerSector;

		// Drive geometry is used only when IOCTL_DISK_GET_PARTITION_INFO fails
		if (NT_SUCCESS (GSTSendHostDeviceIoControlRequest (DeviceObject, Extension, IOCTL_DISK_GET_PARTITION_INFO_EX, (char *) &pix, sizeof (pix))))
		{
			lDiskLength.QuadPart = pix.PartitionLength.QuadPart;
			partitionStartingOffset = pix.StartingOffset.QuadPart;
		}
		// Windows 2000 does not support IOCTL_DISK_GET_PARTITION_INFO_EX
		else if (NT_SUCCESS (GSTSendHostDeviceIoControlRequest (DeviceObject, Extension, IOCTL_DISK_GET_PARTITION_INFO, (char *) &pi, sizeof (pi))))
		{
			lDiskLength.QuadPart = pi.PartitionLength.QuadPart;
			partitionStartingOffset = pi.StartingOffset.QuadPart;
		}
		else if (NT_SUCCESS (GSTSendHostDeviceIoControlRequest (DeviceObject, Extension, IOCTL_DISK_GET_LENGTH_INFO, &diskLengthInfo, sizeof (diskLengthInfo))))
		{
			lDiskLength = diskLengthInfo;
		}

		ProbingHostDeviceForWrite = TRUE;

		if (!mount->bMountReadOnly
			&& GSTSendHostDeviceIoControlRequest (DeviceObject, Extension,
				IsHiddenSystemRunning() ? GST_IOCTL_DISK_IS_WRITABLE : IOCTL_DISK_IS_WRITABLE, NULL, 0) == STATUS_MEDIA_WRITE_PROTECTED)
		{
			mount->bMountReadOnly = TRUE;
			DeviceObject->Characteristics |= FILE_READ_ONLY_DEVICE;
			mount->VolumeMountedReadOnlyAfterDeviceWriteProtected = TRUE;
		}

		ProbingHostDeviceForWrite = FALSE;

		// Some Windows tools (e.g. diskmgmt, diskpart, vssadmin) fail or experience timeouts when there is a raw device
		// open for exclusive access. Therefore, exclusive access is used only for file-hosted volumes.
		// Applications requiring a consistent device image need to acquire exclusive write access first. This is prevented
		// when a device-hosted volume is mounted.

		exclusiveAccess = FALSE;
	}
	else
	{
		// Limit the maximum required buffer size
		if (mount->BytesPerSector > 128 * BYTES_PER_KB)
		{
			ntStatus = STATUS_INVALID_PARAMETER;
			goto error;
		}

		Extension->HostBytesPerSector = mount->BytesPerSector;

		if (Extension->HostBytesPerSector != GST_SECTOR_SIZE_FILE_HOSTED_VOLUME)
			disableBuffering = FALSE;
	}

	// Open the volume hosting file/device
	if (!mount->bMountReadOnly)
	{
		ntStatus = ZwCreateFile (&Extension->hDeviceFile,
			GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
			&oaFileAttributes,
			&IoStatusBlock,
			NULL,
			FILE_ATTRIBUTE_NORMAL |
			FILE_ATTRIBUTE_SYSTEM,
			exclusiveAccess ? 0 : FILE_SHARE_READ | FILE_SHARE_WRITE,
			FILE_OPEN,
			FILE_RANDOM_ACCESS |
			FILE_WRITE_THROUGH |
			(disableBuffering ? FILE_NO_INTERMEDIATE_BUFFERING : 0) |
			FILE_SYNCHRONOUS_IO_NONALERT,
			NULL,
			0);
	}

	/* 26-4-99 NT for some partitions returns this code, it is really a	access denied */
	if (ntStatus == 0xc000001b)
		ntStatus = STATUS_ACCESS_DENIED;

	mount->VolumeMountedReadOnlyAfterAccessDenied = FALSE;

	if (mount->bMountReadOnly || ntStatus == STATUS_ACCESS_DENIED)
	{
		ntStatus = ZwCreateFile (&Extension->hDeviceFile,
			GENERIC_READ | SYNCHRONIZE,
			&oaFileAttributes,
			&IoStatusBlock,
			NULL,
			FILE_ATTRIBUTE_NORMAL |
			FILE_ATTRIBUTE_SYSTEM,
			exclusiveAccess ? FILE_SHARE_READ : FILE_SHARE_READ | FILE_SHARE_WRITE,
			FILE_OPEN,
			FILE_RANDOM_ACCESS |
			FILE_WRITE_THROUGH |
			(disableBuffering ? FILE_NO_INTERMEDIATE_BUFFERING : 0) |
			FILE_SYNCHRONOUS_IO_NONALERT,
			NULL,
			0);

		if (NT_SUCCESS (ntStatus) && !mount->bMountReadOnly)
			mount->VolumeMountedReadOnlyAfterAccessDenied = TRUE;

		Extension->bReadOnly = TRUE;
		DeviceObject->Characteristics |= FILE_READ_ONLY_DEVICE;
	}
	else
		Extension->bReadOnly = FALSE;

	/* 26-4-99 NT for some partitions returns this code, it is really a
	access denied */
	if (ntStatus == 0xc000001b)
	{
		/* Partitions which return this code can still be opened with
		FILE_SHARE_READ but this causes NT problems elsewhere in
		particular if you do FILE_SHARE_READ NT will die later if
		anyone even tries to open the partition (or file for that
		matter...)  */
		ntStatus = STATUS_SHARING_VIOLATION;
	}

	if (!NT_SUCCESS (ntStatus))
	{
		goto error;
	}

	// If we have opened a file, query its size now
	if (bRawDevice == FALSE)
	{
		ntStatus = ZwQueryInformationFile (Extension->hDeviceFile,
			&IoStatusBlock,
			&FileBasicInfo,
			sizeof (FileBasicInfo),
			FileBasicInformation);

		if (NT_SUCCESS (ntStatus))
		{
			if (mount->bPreserveTimestamp)
			{
				Extension->fileCreationTime = FileBasicInfo.CreationTime;
				Extension->fileLastAccessTime = FileBasicInfo.LastAccessTime;
				Extension->fileLastWriteTime = FileBasicInfo.LastWriteTime;
				Extension->fileLastChangeTime = FileBasicInfo.ChangeTime;
				Extension->bTimeStampValid = TRUE;
			}

			ntStatus = ZwQueryInformationFile (Extension->hDeviceFile,
				&IoStatusBlock,
				&FileStandardInfo,
				sizeof (FileStandardInfo),
				FileStandardInformation);
		}

		if (!NT_SUCCESS (ntStatus))
		{
			Dump ("ZwQueryInformationFile failed while opening file: NTSTATUS 0x%08x\n",
				ntStatus);
			goto error;
		}

		lDiskLength.QuadPart = FileStandardInfo.EndOfFile.QuadPart;

		if (FileBasicInfo.FileAttributes & FILE_ATTRIBUTE_COMPRESSED)
		{
			Dump ("File \"%ls\" is marked as compressed - not supported!\n", pwszMountVolume);
			mount->nReturnCode = ERR_COMPRESSION_NOT_SUPPORTED;
			ntStatus = STATUS_SUCCESS;
			goto error;
		}

		ntStatus = ObReferenceObjectByHandle (Extension->hDeviceFile,
			FILE_ALL_ACCESS,
			*IoFileObjectType,
			KernelMode,
			&Extension->pfoDeviceFile,
			0);

		if (!NT_SUCCESS (ntStatus))
		{
			goto error;
		}

		/* Get the FSD device for the file (probably either NTFS or	FAT) */
		Extension->pFsdDevice = IoGetRelatedDeviceObject (Extension->pfoDeviceFile);
	}
	else
	{
		// Try to gain "raw" access to the partition in case there is a live filesystem on it (otherwise, 
		// the NTFS driver guards hidden sectors and prevents mounting using a backup header e.g. after the user 
		// accidentally quick-formats a dismounted partition-hosted GostCrypt volume as NTFS).

		PFILE_OBJECT pfoTmpDeviceFile = NULL;

		if (NT_SUCCESS (ObReferenceObjectByHandle (Extension->hDeviceFile, FILE_ALL_ACCESS, *IoFileObjectType, KernelMode, &pfoTmpDeviceFile, NULL))
			&& pfoTmpDeviceFile != NULL)
		{
			GSTFsctlCall (pfoTmpDeviceFile, FSCTL_ALLOW_EXTENDED_DASD_IO, NULL, 0, NULL, 0);
			ObDereferenceObject (pfoTmpDeviceFile);
		}
	}

	// Check volume size
	if (lDiskLength.QuadPart < GST_MIN_VOLUME_SIZE_LEGACY || lDiskLength.QuadPart > GST_MAX_VOLUME_SIZE)
	{
		mount->nReturnCode = ERR_VOL_SIZE_WRONG;
		ntStatus = STATUS_SUCCESS;
		goto error;
	}

	Extension->DiskLength = lDiskLength.QuadPart;
	Extension->HostLength = lDiskLength.QuadPart;

	readBuffer = GSTalloc (max (max (GST_VOLUME_HEADER_EFFECTIVE_SIZE, PAGE_SIZE), Extension->HostBytesPerSector));
	if (readBuffer == NULL)
	{
		ntStatus = STATUS_INSUFFICIENT_RESOURCES;
		goto error;
	}

	// Go through all volume types (e.g., normal, hidden)
	for (volumeType = GST_VOLUME_TYPE_NORMAL;
		volumeType < GST_VOLUME_TYPE_COUNT;
		volumeType++)	
	{
		Dump ("Trying to open volume type %d\n", volumeType);

		if (mount->bPartitionInInactiveSysEncScope
			&& volumeType == GST_VOLUME_TYPE_HIDDEN_LEGACY)
			continue;		

		/* Read the volume header */

		if (!mount->bPartitionInInactiveSysEncScope
			|| (mount->bPartitionInInactiveSysEncScope && volumeType == GST_VOLUME_TYPE_HIDDEN))
		{
			// Header of a volume that is not within the scope of system encryption, or
			// header of a system hidden volume (containing a hidden OS)

			LARGE_INTEGER headerOffset;

			if (mount->UseBackupHeader && lDiskLength.QuadPart <= GST_TOTAL_VOLUME_HEADERS_SIZE)
				continue;

			switch (volumeType)
			{
			case GST_VOLUME_TYPE_NORMAL:
				headerOffset.QuadPart = mount->UseBackupHeader ? lDiskLength.QuadPart - GST_VOLUME_HEADER_GROUP_SIZE : GST_VOLUME_HEADER_OFFSET;
				break;

			case GST_VOLUME_TYPE_HIDDEN:
				if (lDiskLength.QuadPart <= GST_VOLUME_HEADER_GROUP_SIZE)
					continue;

				headerOffset.QuadPart = mount->UseBackupHeader ? lDiskLength.QuadPart - GST_HIDDEN_VOLUME_HEADER_OFFSET : GST_HIDDEN_VOLUME_HEADER_OFFSET;
				break;

			case GST_VOLUME_TYPE_HIDDEN_LEGACY:
				if (mount->UseBackupHeader)
					continue;

				if (bRawDevice && Extension->HostBytesPerSector != GST_SECTOR_SIZE_LEGACY)
					continue;

				headerOffset.QuadPart = lDiskLength.QuadPart - GST_HIDDEN_VOLUME_HEADER_OFFSET_LEGACY;
				break;
			}

			Dump ("Reading volume header at %I64d\n", headerOffset.QuadPart);

			ntStatus = ZwReadFile (Extension->hDeviceFile,
			NULL,
			NULL,
			NULL,
			&IoStatusBlock,
			readBuffer,
			bRawDevice ? max (GST_VOLUME_HEADER_EFFECTIVE_SIZE, Extension->HostBytesPerSector) : GST_VOLUME_HEADER_EFFECTIVE_SIZE,
			&headerOffset,
			NULL);
		}
		else
		{
			// Header of a partition that is within the scope of system encryption

			WCHAR parentDrivePath [47+1] = {0};
			HANDLE hParentDeviceFile = NULL;
			UNICODE_STRING FullParentPath;
			OBJECT_ATTRIBUTES oaParentFileAttributes;
			LARGE_INTEGER parentKeyDataOffset;

			_snwprintf (parentDrivePath,
				sizeof (parentDrivePath) / sizeof (WCHAR) - 1,
				WIDE ("\\Device\\Harddisk%d\\Partition0"),
				mount->nPartitionInInactiveSysEncScopeDriveNo);

			Dump ("Mounting partition within scope of system encryption (reading key data from: %ls)\n", parentDrivePath);

			RtlInitUnicodeString (&FullParentPath, parentDrivePath);
			InitializeObjectAttributes (&oaParentFileAttributes, &FullParentPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,	NULL, NULL);

			ntStatus = ZwCreateFile (&hParentDeviceFile,
				GENERIC_READ | SYNCHRONIZE,
				&oaParentFileAttributes,
				&IoStatusBlock,
				NULL,
				FILE_ATTRIBUTE_NORMAL |
				FILE_ATTRIBUTE_SYSTEM,
				FILE_SHARE_READ | FILE_SHARE_WRITE,
				FILE_OPEN,
				FILE_RANDOM_ACCESS |
				FILE_WRITE_THROUGH |
				FILE_NO_INTERMEDIATE_BUFFERING |
				FILE_SYNCHRONOUS_IO_NONALERT,
				NULL,
				0);

			if (!NT_SUCCESS (ntStatus))
			{
				if (hParentDeviceFile != NULL)
					ZwClose (hParentDeviceFile);

				Dump ("Cannot open %ls\n", parentDrivePath);

				goto error;
			}

			parentKeyDataOffset.QuadPart = GST_BOOT_VOLUME_HEADER_SECTOR_OFFSET;

			ntStatus = ZwReadFile (hParentDeviceFile,
				NULL,
				NULL,
				NULL,
				&IoStatusBlock,
				readBuffer,
				max (GST_VOLUME_HEADER_EFFECTIVE_SIZE, Extension->HostBytesPerSector),
				&parentKeyDataOffset,
				NULL);

			if (hParentDeviceFile != NULL)
				ZwClose (hParentDeviceFile);
		}

		if (!NT_SUCCESS (ntStatus) && ntStatus != STATUS_END_OF_FILE)
		{
			Dump ("Read failed: NTSTATUS 0x%08x\n", ntStatus);
			goto error;
		}

		if (ntStatus == STATUS_END_OF_FILE || IoStatusBlock.Information < GST_VOLUME_HEADER_EFFECTIVE_SIZE)
		{
			Dump ("Read didn't read enough data\n");

			// If FSCTL_ALLOW_EXTENDED_DASD_IO failed and there is a live filesystem on the partition, then the
			// filesystem driver may report EOF when we are reading hidden sectors (when the filesystem is 
			// shorter than the partition). This can happen for example after the user quick-formats a dismounted
			// partition-hosted GostCrypt volume and then tries to mount the volume using the embedded backup header.
			memset (readBuffer, 0, GST_VOLUME_HEADER_EFFECTIVE_SIZE);
		}

		/* Attempt to recognize the volume (decrypt the header) */

		ReadVolumeHeaderRecoveryMode = mount->RecoveryMode;

		if ((volumeType == GST_VOLUME_TYPE_HIDDEN || volumeType == GST_VOLUME_TYPE_HIDDEN_LEGACY) && mount->bProtectHiddenVolume)
		{
			mount->nReturnCode = ReadVolumeHeaderWCache (
				FALSE,
				mount->bCache,
				readBuffer,
				&mount->ProtectedHidVolPassword,
				&tmpCryptoInfo);
		}
		else
		{
			mount->nReturnCode = ReadVolumeHeaderWCache (
				mount->bPartitionInInactiveSysEncScope && volumeType == GST_VOLUME_TYPE_NORMAL,
				mount->bCache,
				readBuffer,
				&mount->VolumePassword,
				&Extension->cryptoInfo);
		}

		ReadVolumeHeaderRecoveryMode = FALSE;

		if (mount->nReturnCode == 0 || mount->nReturnCode == ERR_CIPHER_INIT_WEAK_KEY)
		{
			/* Volume header successfully decrypted */

			Dump ("Volume header decrypted\n");
			Dump ("Required program version = %x\n", (int) Extension->cryptoInfo->RequiredProgramVersion);
			Dump ("Legacy volume = %d\n", (int) Extension->cryptoInfo->LegacyVolume);

			if (IsHiddenSystemRunning() && !Extension->cryptoInfo->hiddenVolume)
			{
				Extension->bReadOnly = mount->bMountReadOnly = TRUE;
				HiddenSysLeakProtectionCount++;
			}

			Extension->cryptoInfo->bProtectHiddenVolume = FALSE;
			Extension->cryptoInfo->bHiddenVolProtectionAction = FALSE;

			Extension->cryptoInfo->bPartitionInInactiveSysEncScope = mount->bPartitionInInactiveSysEncScope;

			if (volumeType == GST_VOLUME_TYPE_NORMAL)
			{
				if (mount->bPartitionInInactiveSysEncScope)
				{
					if (Extension->cryptoInfo->EncryptedAreaStart.Value > (unsigned __int64) partitionStartingOffset
						|| Extension->cryptoInfo->EncryptedAreaStart.Value + Extension->cryptoInfo->VolumeSize.Value <= (unsigned __int64) partitionStartingOffset)
					{
						// The partition is not within the key scope of system encryption
						mount->nReturnCode = ERR_PASSWORD_WRONG;
						ntStatus = STATUS_SUCCESS;
						goto error;
					}

					if (Extension->cryptoInfo->EncryptedAreaLength.Value != Extension->cryptoInfo->VolumeSize.Value)
					{
						// Partial encryption is not supported for volumes mounted as regular
						mount->nReturnCode = ERR_ENCRYPTION_NOT_COMPLETED;
						ntStatus = STATUS_SUCCESS;
						goto error;
					}
				}
				else if (Extension->cryptoInfo->HeaderFlags & GST_HEADER_FLAG_NONSYS_INPLACE_ENC)
				{
					if (Extension->cryptoInfo->EncryptedAreaLength.Value != Extension->cryptoInfo->VolumeSize.Value)
					{
						// Non-system in-place encryption process has not been completed on this volume
						mount->nReturnCode = ERR_NONSYS_INPLACE_ENC_INCOMPLETE;
						ntStatus = STATUS_SUCCESS;
						goto error;
					}
				}
			}

			Extension->cryptoInfo->FirstDataUnitNo.Value = 0;

			if (Extension->cryptoInfo->hiddenVolume && IsHiddenSystemRunning())
			{
				// Prevent mount of a hidden system partition if the system hosted on it is currently running
				if (memcmp (Extension->cryptoInfo->master_keydata, GetSystemDriveCryptoInfo()->master_keydata, EAGetKeySize (Extension->cryptoInfo->ea)) == 0)
				{
					mount->nReturnCode = ERR_VOL_ALREADY_MOUNTED;
					ntStatus = STATUS_SUCCESS;
					goto error;
				}
			}

			switch (volumeType)
			{
			case GST_VOLUME_TYPE_NORMAL:

				Extension->cryptoInfo->hiddenVolume = FALSE;

				if (mount->bPartitionInInactiveSysEncScope)
				{
					Extension->cryptoInfo->volDataAreaOffset = 0;
					Extension->DiskLength = lDiskLength.QuadPart;
					Extension->cryptoInfo->FirstDataUnitNo.Value = partitionStartingOffset / ENCRYPTION_DATA_UNIT_SIZE;
				}
				else if (Extension->cryptoInfo->LegacyVolume)
				{
					Extension->cryptoInfo->volDataAreaOffset = GST_VOLUME_HEADER_SIZE_LEGACY;
					Extension->DiskLength = lDiskLength.QuadPart - GST_VOLUME_HEADER_SIZE_LEGACY;
				}
				else
				{
					Extension->cryptoInfo->volDataAreaOffset = Extension->cryptoInfo->EncryptedAreaStart.Value;
					Extension->DiskLength = Extension->cryptoInfo->VolumeSize.Value;
				}

				break;

			case GST_VOLUME_TYPE_HIDDEN:
			case GST_VOLUME_TYPE_HIDDEN_LEGACY:

				cryptoInfoPtr = mount->bProtectHiddenVolume ? tmpCryptoInfo : Extension->cryptoInfo;

				if (volumeType == GST_VOLUME_TYPE_HIDDEN_LEGACY)
					Extension->cryptoInfo->hiddenVolumeOffset = lDiskLength.QuadPart - cryptoInfoPtr->hiddenVolumeSize - GST_HIDDEN_VOLUME_HEADER_OFFSET_LEGACY;
				else
					Extension->cryptoInfo->hiddenVolumeOffset = cryptoInfoPtr->EncryptedAreaStart.Value;

				Dump ("Hidden volume offset = %I64d\n", Extension->cryptoInfo->hiddenVolumeOffset);
				Dump ("Hidden volume size = %I64d\n", cryptoInfoPtr->hiddenVolumeSize);
				Dump ("Hidden volume end = %I64d\n", Extension->cryptoInfo->hiddenVolumeOffset + cryptoInfoPtr->hiddenVolumeSize - 1);

				// Validate the offset
				if (Extension->cryptoInfo->hiddenVolumeOffset % ENCRYPTION_DATA_UNIT_SIZE != 0)
				{
					mount->nReturnCode = ERR_VOL_SIZE_WRONG;
					ntStatus = STATUS_SUCCESS;
					goto error;
				}

				// If we are supposed to actually mount the hidden volume (not just to protect it)
				if (!mount->bProtectHiddenVolume)	
				{
					Extension->DiskLength = cryptoInfoPtr->hiddenVolumeSize;
					Extension->cryptoInfo->hiddenVolume = TRUE;
					Extension->cryptoInfo->volDataAreaOffset = Extension->cryptoInfo->hiddenVolumeOffset;
				}
				else
				{
					// Hidden volume protection
					Extension->cryptoInfo->hiddenVolume = FALSE;
					Extension->cryptoInfo->bProtectHiddenVolume = TRUE;
					
					Extension->cryptoInfo->hiddenVolumeProtectedSize = tmpCryptoInfo->hiddenVolumeSize;

					if (volumeType == GST_VOLUME_TYPE_HIDDEN_LEGACY)
						Extension->cryptoInfo->hiddenVolumeProtectedSize += GST_VOLUME_HEADER_SIZE_LEGACY;

					Dump ("Hidden volume protection active: %I64d-%I64d (%I64d)\n", Extension->cryptoInfo->hiddenVolumeOffset, Extension->cryptoInfo->hiddenVolumeProtectedSize + Extension->cryptoInfo->hiddenVolumeOffset - 1, Extension->cryptoInfo->hiddenVolumeProtectedSize);
				}

				break;
			}

			Dump ("Volume data offset = %I64d\n", Extension->cryptoInfo->volDataAreaOffset);
			Dump ("Volume data size = %I64d\n", Extension->DiskLength);
			Dump ("Volume data end = %I64d\n", Extension->cryptoInfo->volDataAreaOffset + Extension->DiskLength - 1);

			if (Extension->DiskLength == 0)
			{
				Dump ("Incorrect volume size\n");
				continue;
			}

			// If this is a hidden volume, make sure we are supposed to actually
			// mount it (i.e. not just to protect it)
			if (volumeType == GST_VOLUME_TYPE_NORMAL || !mount->bProtectHiddenVolume)	
			{
				// Validate sector size
				if (bRawDevice && Extension->cryptoInfo->SectorSize != Extension->HostBytesPerSector)
				{
					mount->nReturnCode = ERR_PARAMETER_INCORRECT;
					ntStatus = STATUS_SUCCESS;
					goto error;
				}

				// Calculate virtual volume geometry
				Extension->TracksPerCylinder = 1;
				Extension->SectorsPerTrack = 1;
				Extension->BytesPerSector = Extension->cryptoInfo->SectorSize;
				Extension->NumberOfCylinders = Extension->DiskLength / Extension->BytesPerSector;
				Extension->PartitionType = 0;

				Extension->bRawDevice = bRawDevice;
				
				memset (Extension->wszVolume, 0, sizeof (Extension->wszVolume));
				if (wcsstr (pwszMountVolume, WIDE ("\\??\\UNC\\")) == pwszMountVolume)
				{
					/* UNC path */
					_snwprintf (Extension->wszVolume,
						sizeof (Extension->wszVolume) / sizeof (WCHAR) - 1,
						WIDE ("\\??\\\\%s"),
						pwszMountVolume + 7);
				}
				else
				{
					wcsncpy (Extension->wszVolume, pwszMountVolume, sizeof (Extension->wszVolume) / sizeof (WCHAR) - 1);
				}
			}

			// If we are to protect a hidden volume we cannot exit yet, for we must also
			// decrypt the hidden volume header.
			if (!(volumeType == GST_VOLUME_TYPE_NORMAL && mount->bProtectHiddenVolume))
			{
				GSTfree (readBuffer);

				if (tmpCryptoInfo != NULL)
				{
					crypto_close (tmpCryptoInfo);
					tmpCryptoInfo = NULL;
				}
				
				return STATUS_SUCCESS;
			}
		}
		else if ((mount->bProtectHiddenVolume && volumeType == GST_VOLUME_TYPE_NORMAL)
			  || mount->nReturnCode != ERR_PASSWORD_WRONG)
		{
			 /* If we are not supposed to protect a hidden volume, the only error that is
				tolerated is ERR_PASSWORD_WRONG (to allow mounting a possible hidden volume). 

				If we _are_ supposed to protect a hidden volume, we do not tolerate any error
				(both volume headers must be successfully decrypted). */

			break;
		}
	}

	/* Failed due to some non-OS reason so we drop through and return NT
	   SUCCESS then nReturnCode is checked later in user-mode */

	if (mount->nReturnCode == ERR_OUTOFMEMORY)
		ntStatus = STATUS_INSUFFICIENT_RESOURCES;
	else
		ntStatus = STATUS_SUCCESS;

error:
	if (mount->nReturnCode == ERR_SUCCESS)
		mount->nReturnCode = ERR_PASSWORD_WRONG;

	if (tmpCryptoInfo != NULL)
	{
		crypto_close (tmpCryptoInfo);
		tmpCryptoInfo = NULL;
	}

	if (Extension->cryptoInfo)
	{
		crypto_close (Extension->cryptoInfo);
		Extension->cryptoInfo = NULL;
	}

	if (Extension->bTimeStampValid)
	{
		RestoreTimeStamp (Extension);
	}

	/* Close the hDeviceFile */
	if (Extension->hDeviceFile != NULL)
		ZwClose (Extension->hDeviceFile);

	/* The cryptoInfo pointer is deallocated if the readheader routines
	   fail so there is no need to deallocate here  */

	/* Dereference the user-mode file object */
	if (Extension->pfoDeviceFile != NULL)
		ObDereferenceObject (Extension->pfoDeviceFile);

	/* Free the tmp IO buffers */
	if (readBuffer != NULL)
		GSTfree (readBuffer);

	return ntStatus;
}
Пример #29
0
/**********************************************************************
 * SmCreateUserProcess/5
 *
 * DESCRIPTION
 *
 * ARGUMENTS
 *	ImagePath: absolute path of the image to run;
 *	CommandLine: arguments and options for ImagePath;
 *	Flags: Wait flag: Set for boot time processes and unset for
 *			subsystems bootstrapping;
 *		1Mb reserve flag: Set for subsystems, unset for everything
*			else
 *	Timeout: optional: used if WaitForIt==TRUE;
 *	ProcessHandle: optional: a duplicated handle for
 		the child process (storage provided by the caller).
 *
 * RETURN VALUE
 * 	NTSTATUS:
 *
 */
NTSTATUS NTAPI
SmCreateUserProcess (LPWSTR ImagePath,
		     LPWSTR CommandLine,
		     ULONG Flags,
		     PLARGE_INTEGER Timeout OPTIONAL,
		     PRTL_USER_PROCESS_INFORMATION UserProcessInfo OPTIONAL)
{
	UNICODE_STRING			ImagePathString   = { 0, 0, NULL };
	UNICODE_STRING			CommandLineString = { 0, 0, NULL };
	UNICODE_STRING			SystemDirectory   = { 0, 0, NULL };
	PRTL_USER_PROCESS_PARAMETERS	ProcessParameters = NULL;
	RTL_USER_PROCESS_INFORMATION	ProcessInfo  = {0};
	PRTL_USER_PROCESS_INFORMATION	pProcessInfo = & ProcessInfo;
	NTSTATUS			Status = STATUS_SUCCESS;

	DPRINT("SM: %s called\n", __FUNCTION__);

	if (NULL != UserProcessInfo)
	{
		pProcessInfo = UserProcessInfo;
	}

	RtlInitUnicodeString (& ImagePathString, ImagePath);
	RtlInitUnicodeString (& CommandLineString, CommandLine);

	SystemDirectory.MaximumLength = (wcslen(SharedUserData->NtSystemRoot) * sizeof(WCHAR)) + sizeof(szSystemDirectory);
	SystemDirectory.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
						 0,
						 SystemDirectory.MaximumLength);
	if (SystemDirectory.Buffer == NULL)
	{
		Status = STATUS_NO_MEMORY;
		DPRINT1("SM: %s: Allocating system directory string failed (Status=0x%08lx)\n",
			__FUNCTION__, Status);
		return Status;
	}

	Status = RtlAppendUnicodeToString(& SystemDirectory,
					  SharedUserData->NtSystemRoot);
	if (!NT_SUCCESS(Status))
	{
		goto FailProcParams;
	}

	Status = RtlAppendUnicodeToString(& SystemDirectory,
					  szSystemDirectory);
	if (!NT_SUCCESS(Status))
	{
		goto FailProcParams;
	}


	Status = RtlCreateProcessParameters(& ProcessParameters,
					    & ImagePathString,
					    NULL,
					    & SystemDirectory,
					    & CommandLineString,
					    SmSystemEnvironment,
					    NULL,
					    NULL,
					    NULL,
					    NULL);

	RtlFreeHeap(RtlGetProcessHeap(),
		    0,
		    SystemDirectory.Buffer);

	if (!NT_SUCCESS(Status))
	{
FailProcParams:
		DPRINT1("SM: %s: Creating process parameters failed (Status=0x%08lx)\n",
			__FUNCTION__, Status);
		return Status;
	}

	/* Reserve lower 1Mb, if requested */
	if (Flags & SM_CREATE_FLAG_RESERVE_1MB)
		ProcessParameters->Flags |= RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB;

	/* Create the user process */
	Status = RtlCreateUserProcess (& ImagePathString,
				       OBJ_CASE_INSENSITIVE,
				       ProcessParameters,
				       NULL,
				       NULL,
				       NULL,
				       FALSE,
				       NULL,
				       NULL,
				       pProcessInfo);

	RtlDestroyProcessParameters (ProcessParameters);

	if (!NT_SUCCESS(Status))
	{
		DPRINT1("SM: %s: Running \"%S\" failed (Status=0x%08lx)\n",
			__FUNCTION__, ImagePathString.Buffer, Status);
		return Status;
	}
	/*
	 * It the caller is *not* interested in the child info,
	 * resume it immediately.
	 */
	if (NULL == UserProcessInfo)
	{
		Status = NtResumeThread (ProcessInfo.ThreadHandle, NULL);
		if(!NT_SUCCESS(Status))
		{
			DPRINT1("SM: %s: NtResumeThread failed (Status=0x%08lx)\n",
				__FUNCTION__, Status);
		}
	}

	/* Wait for process termination */
	if (Flags & SM_CREATE_FLAG_WAIT)
	{
		Status = NtWaitForSingleObject (pProcessInfo->ProcessHandle,
						FALSE,
						Timeout);
		if (!NT_SUCCESS(Status))
		{
			DPRINT1("SM: %s: NtWaitForSingleObject failed with Status=0x%08lx\n",
				__FUNCTION__, Status);
		}
	}

    if (NULL == UserProcessInfo)
    {
        NtClose(pProcessInfo->ProcessHandle);
        NtClose(pProcessInfo->ThreadHandle);
    }
	return Status;
}
Пример #30
-1
RT_C_DECLS_END

#ifdef ALLOC_PRAGMA
# pragma alloc_text(INIT, vbgdNt4CreateDevice)
# pragma alloc_text(INIT, vbgdNt4FindPciDevice)
#endif


/**
 * Legacy helper function to create the device object.
 *
 * @returns NT status code.
 *
 * @param   pDrvObj         The driver object.
 * @param   pDevObj         Unused. NULL. Dunno why it's here, makes no sense.
 * @param   pRegPath        The driver registry path.
 */
NTSTATUS vbgdNt4CreateDevice(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj, PUNICODE_STRING pRegPath)
{
    Log(("VBoxGuest::vbgdNt4CreateDevice: pDrvObj=%p, pDevObj=%p, pRegPath=%p\n", pDrvObj, pDevObj, pRegPath));

    /*
     * Find our virtual PCI device
     */
    ULONG uBusNumber;
    PCI_SLOT_NUMBER SlotNumber;
    NTSTATUS rc = vbgdNt4FindPciDevice(&uBusNumber, &SlotNumber);
    if (NT_ERROR(rc))
    {
        Log(("VBoxGuest::vbgdNt4CreateDevice: Device not found!\n"));
        return rc;
    }

    /*
     * Create device.
     */
    UNICODE_STRING szDevName;
    RtlInitUnicodeString(&szDevName, VBOXGUEST_DEVICE_NAME_NT);
    PDEVICE_OBJECT pDeviceObject = NULL;
    rc = IoCreateDevice(pDrvObj, sizeof(VBOXGUESTDEVEXTWIN), &szDevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDeviceObject);
    if (NT_SUCCESS(rc))
    {
        Log(("VBoxGuest::vbgdNt4CreateDevice: Device created\n"));

        UNICODE_STRING DosName;
        RtlInitUnicodeString(&DosName, VBOXGUEST_DEVICE_NAME_DOS);
        rc = IoCreateSymbolicLink(&DosName, &szDevName);
        if (NT_SUCCESS(rc))
        {
            Log(("VBoxGuest::vbgdNt4CreateDevice: Symlink created\n"));

            /*
             * Setup the device extension.
             */
            Log(("VBoxGuest::vbgdNt4CreateDevice: Setting up device extension ...\n"));

            PVBOXGUESTDEVEXTWIN pDevExt = (PVBOXGUESTDEVEXTWIN)pDeviceObject->DeviceExtension;
            RT_ZERO(*pDevExt);

            Log(("VBoxGuest::vbgdNt4CreateDevice: Device extension created\n"));

            /* Store a reference to ourself. */
            pDevExt->pDeviceObject = pDeviceObject;

            /* Store bus and slot number we've queried before. */
            pDevExt->busNumber  = uBusNumber;
            pDevExt->slotNumber = SlotNumber.u.AsULONG;

#ifdef VBOX_WITH_GUEST_BUGCHECK_DETECTION
            rc = hlpRegisterBugCheckCallback(pDevExt);
#endif

            /* Do the actual VBox init ... */
            if (NT_SUCCESS(rc))
            {
                rc = vbgdNtInit(pDrvObj, pDeviceObject, pRegPath);
                if (NT_SUCCESS(rc))
                {
                    Log(("VBoxGuest::vbgdNt4CreateDevice: Returning rc = 0x%x (succcess)\n", rc));
                    return rc;
                }

                /* bail out */
            }
            IoDeleteSymbolicLink(&DosName);
        }
        else
            Log(("VBoxGuest::vbgdNt4CreateDevice: IoCreateSymbolicLink failed with rc = %#x\n", rc));
        IoDeleteDevice(pDeviceObject);
    }
    else
        Log(("VBoxGuest::vbgdNt4CreateDevice: IoCreateDevice failed with rc = %#x\n", rc));
    Log(("VBoxGuest::vbgdNt4CreateDevice: Returning rc = 0x%x\n", rc));
    return rc;
}