Exemplo n.º 1
0
NTSTATUS
NTAPI
KspCreateObjectType(
    IN HANDLE ParentHandle,
    IN LPWSTR ObjectType,
    PVOID CreateParameters,
    UINT CreateParametersSize,
    IN  ACCESS_MASK DesiredAccess,
    OUT PHANDLE NodeHandle)
{
    NTSTATUS Status;
    IO_STATUS_BLOCK IoStatusBlock;
    OBJECT_ATTRIBUTES ObjectAttributes;
    UNICODE_STRING Name;

    /* calculate request length */
    Name.Length = 0;
    Name.MaximumLength = wcslen(ObjectType) * sizeof(WCHAR) + CreateParametersSize +  1 * sizeof(WCHAR);
    Name.MaximumLength += sizeof(WCHAR);
    /* acquire request buffer */
    Name.Buffer = AllocateItem(NonPagedPool, Name.MaximumLength);
    /* check for success */
    if (!Name.Buffer)
    {
        /* insufficient resources */
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    /* build a request which looks like {ObjectClass}\CreateParameters
     * For pins the parent is the reference string used in registration
     * For clocks it is full path for pin\{ClockGuid}\ClockCreateParams
     */
    RtlAppendUnicodeToString(&Name, ObjectType);
    RtlAppendUnicodeToString(&Name, L"\\");
    /* append create parameters */
    RtlMoveMemory(Name.Buffer + (Name.Length / sizeof(WCHAR)), CreateParameters, CreateParametersSize);
    Name.Length += CreateParametersSize;
    Name.Buffer[Name.Length / 2] = L'\0';

    InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE | OBJ_OPENIF, ParentHandle, NULL);
    /* create the instance */
    Status = IoCreateFile(NodeHandle,
                          DesiredAccess,
                          &ObjectAttributes,
                          &IoStatusBlock,
                          NULL,
                          0,
                          0,
                          FILE_OPEN,
                          0,
                          NULL,
                          0,
                          CreateFileTypeNone,
                          NULL,
                          IO_NO_PARAMETER_CHECKING | IO_FORCE_ACCESS_CHECK);

    /* free request buffer */
    FreeItem(Name.Buffer);
    return Status;
}
Exemplo n.º 2
0
Arquivo: fcb.c Projeto: RPG-7/reactos
PFCB
CdfsCreateFCB(PCWSTR FileName)
{
    PFCB Fcb;

    Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(FCB), TAG_FCB);
    if(!Fcb) return NULL;

    RtlZeroMemory(Fcb, sizeof(FCB));
    RtlInitEmptyUnicodeString(&Fcb->PathName, Fcb->PathNameBuffer, sizeof(Fcb->PathNameBuffer));

    if (FileName)
    {
        RtlAppendUnicodeToString(&Fcb->PathName, FileName);
        if (wcsrchr(Fcb->PathName.Buffer, '\\') != 0)
        {
            Fcb->ObjectName = wcsrchr(Fcb->PathName.Buffer, '\\');
        }
        else
        {
            Fcb->ObjectName = Fcb->PathName.Buffer;
        }
    }

    ExInitializeResourceLite(&Fcb->PagingIoResource);
    ExInitializeResourceLite(&Fcb->MainResource);
    ExInitializeResourceLite(&Fcb->NameListResource);
    Fcb->RFCB.PagingIoResource = &Fcb->PagingIoResource;
    Fcb->RFCB.Resource = &Fcb->MainResource;
    Fcb->RFCB.IsFastIoPossible = FastIoIsNotPossible;
    InitializeListHead(&Fcb->ShortNameList);

    return(Fcb);
}
Exemplo n.º 3
0
NTSTATUS
NTAPI
SmpInvokeAutoChk(IN PUNICODE_STRING FileName,
                 IN PUNICODE_STRING Directory,
                 IN PUNICODE_STRING Arguments,
                 IN ULONG Flags)
{
    ANSI_STRING MessageString;
    CHAR MessageBuffer[256];
    UNICODE_STRING Destination;
    WCHAR Buffer[1024];
    BOOLEAN BootState, BootOkay, ShutdownOkay;

    /* Check if autochk should show dots (if the user booted with /SOS) */
    if (SmpQueryRegistrySosOption()) SmpEnableDots = FALSE;

    /* Make sure autochk was actually found */
    if (Flags & SMP_INVALID_PATH)
    {
        /* It wasn't, so create an error message to print on the screen */
        sprintf_nt(MessageBuffer,
                   "%wZ program not found - skipping AUTOCHECK\r\n",
                   FileName);
        RtlInitAnsiString(&MessageString, MessageBuffer);
        if (NT_SUCCESS(RtlAnsiStringToUnicodeString(&Destination,
                                                    &MessageString,
                                                    TRUE)))
        {
            /* And show it */
            NtDisplayString(&Destination);
            RtlFreeUnicodeString(&Destination);
        }
    }
    else
    {
        /* Autochk is there, so record the BSD state */
        BootState = SmpSaveAndClearBootStatusData(&BootOkay, &ShutdownOkay);

        /* Build the path to autochk and place its arguments */
        RtlInitEmptyUnicodeString(&Destination, Buffer, sizeof(Buffer));
        RtlAppendUnicodeStringToString(&Destination, FileName);
        RtlAppendUnicodeToString(&Destination, L" ");
        RtlAppendUnicodeStringToString(&Destination, Arguments);

        /* Execute it */
        SmpExecuteImage(FileName,
                        Directory,
                        &Destination,
                        0,
                        Flags & ~SMP_AUTOCHK_FLAG,
                        NULL);

        /* Restore the BSD state */
        if (BootState) SmpRestoreBootStatusData(BootOkay, ShutdownOkay);
    }

    /* We're all done! */
    return STATUS_SUCCESS;
}
Exemplo n.º 4
0
// 
// 实现我们自己的AddDevice函数
//
NTSTATUS myAddDevice(
					 IN PDRIVER_OBJECT  DriverObject,
					 IN PDEVICE_OBJECT  PhysicalDeviceObject 
					 )
{
	if(gDeviceObject != NULL)
	{
		// 在这里面创建我们自己的设备对象,或者申请所需要的资源。
		// 为了区分不同实例,将设备对象名构造成:”MyNdisDevice”+HardwareID。
		UNICODE_STRING nameString; 
		WCHAR wcsName[256];
		UNICODE_STRING preName = RTL_CONSTANT_STRING(L"\\Device\\MyNdisDevice");

		// 首先取得设备的HDID。
		ULONG nameLength = 0;
		WCHAR wcsHardwareID[256]; //足够大了
		NTSTATUS status = IoGetDeviceProperty (PhysicalDeviceObject,
			DevicePropertyHardwareID,
			256,
			wcsHardwareID,
			&nameLength);
		if(status != STATUS_SUCCESS){
			KdPrint(("Failed to get hardware ID %x\n", status));
			return status;
		}

		// 下面构造设备对象的名字,根据上面的规则:“MyNdisDevice”+ HardwareID。
		RtlInitEmptyUnicodeString( &nameString, wcsName, 256*2);
		RtlCopyUnicodeString( &nameString, &preName);
		//RtlUnicodeStringPrintf(&nameString, L"%wZ_%d_", &preName, 0);
		RtlAppendUnicodeToString( &nameString, wcsHardwareID);

		status = IoCreateDevice(DriverObject,
			0,
			&nameString,
			FILE_DEVICE_UNKNOWN,
			FILE_DEVICE_SECURE_OPEN,
			FALSE,
			&gDeviceObject); 

		// 如果创建失败了,我们有权利让函数以失败返回
		// 但这样我们的驱动加载也就失败了
		if(status != STATUS_SUCCESS){
			KdPrint(("Failed to create device %ws\n", nameString));
			return status;
		}
	}

	//ExAllocatePoolWithTag(); //申请资源及其他

	// 
	// 还可以加入其他正确的操作
	//

	// 现在调用保存的Ndis库中的AddDevice实现
	// 千万不要忘记,否则就会大错特错了
	return systemAddDevice(DriverObject, PhysicalDeviceObject);
}
Exemplo n.º 5
0
NTSTATUS
MyDLPKBF_CreateDevice (IN PDRIVER_OBJECT pDriverObject,
					   IN ULONG DeviceNumber)
{
	PDEVICE_OBJECT pDevObj;
	UNICODE_STRING uniNtDeviceName, uniDosDeviceName, uniNumber;
	WCHAR ntDeviceNameBuffer[MYDLP_MAX_NAME_LENGTH];
	WCHAR dosDeviceNameBuffer[MYDLP_MAX_NAME_LENGTH];
	WCHAR numberBuffer[2];
	PMYDLPKBF_DEVICE_EXTENSION pDevExt;
	NTSTATUS status;

	DbgPrint("MyDLPKBF_CreateDevice: Start\n");
	status = STATUS_SUCCESS;

	uniNtDeviceName.Buffer = ntDeviceNameBuffer;
	uniNtDeviceName.MaximumLength = MYDLP_MAX_NAME_LENGTH * 2;
	uniNtDeviceName.Length = 0;

	uniDosDeviceName.Buffer = dosDeviceNameBuffer;
	uniDosDeviceName.MaximumLength = MYDLP_MAX_NAME_LENGTH * 2;
	uniDosDeviceName.Length = 0;

	uniNumber.Buffer = numberBuffer;
	uniNumber.MaximumLength = 4;
	uniNumber.Length = 0;

	RtlIntegerToUnicodeString( DeviceNumber, 10, &uniNumber);
	RtlAppendUnicodeToString( &uniNtDeviceName, NT_DEVICE_NAME);
	RtlAppendUnicodeStringToString( &uniNtDeviceName, &uniNumber);
	RtlAppendUnicodeToString( &uniDosDeviceName, DOS_DEVICE_NAME);
	RtlAppendUnicodeStringToString( &uniDosDeviceName, &uniNumber);

	status = IoCreateDevice(pDriverObject, sizeof(MYDLPKBF_DEVICE_EXTENSION),
		&uniNtDeviceName, FILE_DEVICE_UNKNOWN,
		0,
		TRUE,
		&pDevObj);

	if(!NT_SUCCESS(status))
	{
		DbgPrint("MyDLPKBF_CreateDevice: IoCreateDevice failed\
				 device no:%d\n", DeviceNumber);
		return status;
	}
Exemplo n.º 6
0
/****************************************************************************\
 *
 * NT_ConcatUnicodeStrings()
 *
 * DESCRIPTION:
 *
 *  This routine concatenates two NULL terminated strings and returns 
 *  the result as an allocated UNICODE string. 
 *
 * ARGUMENTS:
 *
 *  s1, s2 - strings to concatenate
 *  MaxLength - max length of the UNICODE string. If 0, then max length of 
 *              the allocated string equals the length of the concatenated
 *              string.
 *
 * RETURN VALUE:
 *
 *  Pointer to the allocated string, NULL if the allocation failed
 *
\****************************************************************************/
PUNICODE_STRING 
NT_ConcatUnicodeStrings( IN PWSTR s1, IN PWSTR s2, IN USHORT MaxLength )
{
    PUNICODE_STRING String;
    size_t ActualMaxLength = (wcslen(s1) + wcslen(s2) + 1);
    ASSERT( (MaxLength > ActualMaxLength) || MaxLength == 0 );
    if ( MaxLength > ActualMaxLength ) ActualMaxLength = MaxLength;
    String = NT_AllocUnicodeString( (USHORT)ActualMaxLength );
    if ( String ) {
        /* RtlAppendUnicodeToString must not fail here if we have correctly 
         * calculated the required size. */
        NTSTATUS Status = RtlAppendUnicodeToString( String, s1 );
        ASSERT( Status == STATUS_SUCCESS );
        Status = RtlAppendUnicodeToString( String, s2 );
        ASSERT( Status == STATUS_SUCCESS );
    }
    return (String);
}
Exemplo n.º 7
0
static NTSTATUS
XenM2BPdoQueryDeviceText(PXENM2B_PDO_EXTENSION pPdoExt,
                         PIRP pIrp)
{
    PIO_STACK_LOCATION pIrpStack;
    PVOID              pBuffer;
    UNICODE_STRING     Text;
    NTSTATUS           Status;

    pIrpStack = IoGetCurrentIrpStackLocation(pIrp);

    switch (pIrpStack->Parameters.QueryDeviceText.DeviceTextType) {
    case DeviceTextDescription:
        TraceDebug(("%s: DeviceTextDescription\n", __FUNCTION__));
        break;

    case DeviceTextLocationInformation:
        TraceDebug(("%s: DeviceTextLocationInformation\n", __FUNCTION__));
        break;

    default:
        pIrp->IoStatus.Information = 0;
        return STATUS_NOT_SUPPORTED;
    }

    pBuffer = ExAllocatePoolWithTag(PagedPool,
                                    XENM2B_MAX_TEXT_LENGTH,
                                    XENM2B_POOL_TAG);
    if (pBuffer == NULL)
        return STATUS_INSUFFICIENT_RESOURCES;
    RtlZeroMemory(pBuffer, XENM2B_MAX_TEXT_LENGTH);

    Text.Buffer = pBuffer;
    Text.MaximumLength = XENM2B_MAX_TEXT_LENGTH;
    Text.Length = 0;

    switch (pIrpStack->Parameters.QueryDeviceText.DeviceTextType) {
    case DeviceTextDescription:
        RtlAppendUnicodeStringToString(&Text, &pPdoExt->DeviceName);        
        break;

    case DeviceTextLocationInformation:
        RtlAppendUnicodeToString(&Text, L"Xen PV HID Device on XenM2B Bus");
        break;

    default:
        ASSERT(FALSE);
        break;
    }

    TraceDebug(("%s: %wZ\n", __FUNCTION__, &Text));

    pIrp->IoStatus.Information = (ULONG_PTR)pBuffer;
    return STATUS_SUCCESS;
}
Exemplo n.º 8
0
NTSTATUS NTAPI
IoQueryDeviceDescription(PINTERFACE_TYPE BusType OPTIONAL,
			 PULONG BusNumber OPTIONAL,
			 PCONFIGURATION_TYPE ControllerType OPTIONAL,
			 PULONG ControllerNumber OPTIONAL,
			 PCONFIGURATION_TYPE PeripheralType OPTIONAL,
			 PULONG PeripheralNumber OPTIONAL,
			 PIO_QUERY_DEVICE_ROUTINE CalloutRoutine,
			 PVOID Context)
{
   NTSTATUS Status;
   ULONG BusLoopNumber = -1; /* Root Bus */
   OBJECT_ATTRIBUTES ObjectAttributes;
   UNICODE_STRING RootRegKey;
   HANDLE RootRegHandle;
   IO_QUERY Query;

   /* Set up the String */
   RootRegKey.Length = 0;
   RootRegKey.MaximumLength = 2048;
   RootRegKey.Buffer = ExAllocatePoolWithTag(PagedPool, RootRegKey.MaximumLength, TAG_IO_RESOURCE);
   RtlAppendUnicodeToString(&RootRegKey, L"\\REGISTRY\\MACHINE\\HARDWARE\\DESCRIPTION\\SYSTEM");

   /* Open a handle to the Root Registry Key */
   InitializeObjectAttributes(
      &ObjectAttributes,
      &RootRegKey,
      OBJ_CASE_INSENSITIVE,
      NULL,
      NULL);

   Status = ZwOpenKey(&RootRegHandle, KEY_READ, &ObjectAttributes);

   if (NT_SUCCESS(Status))
   {
      /* Use a helper function to loop though this key and get the info */
      Query.BusType = BusType;
      Query.BusNumber = BusNumber;
      Query.ControllerType = ControllerType;
      Query.ControllerNumber = ControllerNumber;
      Query.PeripheralType = PeripheralType;
      Query.PeripheralNumber = PeripheralNumber;
      Query.CalloutRoutine = CalloutRoutine;
      Query.Context = Context;
      Status = IopQueryBusDescription(&Query, RootRegKey, RootRegHandle, &BusLoopNumber, TRUE);

      /* Close registry */
      ZwClose(RootRegHandle);
   }

   /* Free Memory */
   ExFreePoolWithTag(RootRegKey.Buffer, TAG_IO_RESOURCE);

   return Status;
}
Exemplo n.º 9
0
NTSTATUS DriverEntry (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
 NTSTATUS	ntStatus;
 
 ntStatus= STATUS_SUCCESS;
 PPJoyBus_DebugLevel= PPJOY_DEFAULT_DEBUGLEVEL;

 PPJOY_DBGPRINT (FILE_PPJOYBUS|PPJOY_WARN, ("Built " __DATE__ " at " __TIME__) );
 PPJOY_DBGPRINT (FILE_PPJOYBUS|PPJOY_FENTRY, ("DriverEntry (DriverObject=0x%p,RegistryPath=0x%p)",DriverObject, RegistryPath) );

 RtlZeroMemory (&Globals,sizeof(Globals));

 /* Setup copy of DriverObject first so we can use it for event log function */
 Globals.DriverObject= DriverObject;

 /* Allocate buffer to store registry path to the parameters registry key */
 Globals.ParamRegistryPath.MaximumLength= RegistryPath->Length+sizeof(UNICODE_NULL)+sizeof(PARAM_KEY_NAME);
 Globals.ParamRegistryPath.Length= RegistryPath->Length;
 Globals.ParamRegistryPath.Buffer= ExAllocatePoolWithTag (PagedPool,Globals.ParamRegistryPath.MaximumLength,PPJOYBUS_POOL_TAG);    

 if (!Globals.ParamRegistryPath.Buffer)
 {
  PPJoyBus_WriteEventLog (PPJ_MSG_ERRORALLOCMEM,&ntStatus,sizeof(ntStatus),L"");
  ntStatus= STATUS_INSUFFICIENT_RESOURCES;
  goto Exit;
 }

 /* Copy driver registry path and append the parameters subkey name */
 RtlCopyUnicodeString (&Globals.ParamRegistryPath,RegistryPath);
 RtlAppendUnicodeToString (&Globals.ParamRegistryPath,PARAM_KEY_NAME);

 ExInitializeFastMutex (&Globals.Mutex);

 PPJOY_DBGPRINT (FILE_PPJOYBUS|PPJOY_BABBLE2, ("ParamRegistryPath=%S",Globals.ParamRegistryPath.Buffer) );

 /* Set up pointers to our other entry points in the DeviceObject */
 DriverObject->MajorFunction[IRP_MJ_CREATE]= PPJoyBus_CreateClose;
 DriverObject->MajorFunction[IRP_MJ_CLOSE]=	PPJoyBus_CreateClose;
 DriverObject->MajorFunction[IRP_MJ_POWER]= PPJoyBus_Power;
 DriverObject->MajorFunction[IRP_MJ_PNP]= PPJoyBus_PnP;
 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]= PPJoyBus_Ioctl;
 DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL]= PPJoyBus_InternalIoctl;
 DriverObject->DriverUnload= PPJoyBus_Unload;
 DriverObject->DriverExtension->AddDevice= PPJoyBus_AddDevice;

 PPJoyBus_WriteEventLog (PPJ_MSG_DRIVERSTARTEDVER,&ntStatus,sizeof(ntStatus),LVER_PRODUCTVERSION_STR);

Exit:
 PPJOY_EXITPROC (FILE_PPJOYBUS|PPJOY_FEXIT_STATUSOK , "DriverEntry", ntStatus);

 return ntStatus;
} /* DriverEntry */
Exemplo n.º 10
0
static
BOOL
AppendUserEnvironmentVariable(PWSTR* Environment,
                              LPWSTR lpName,
                              LPWSTR lpValue)
{
    NTSTATUS Status;
    UNICODE_STRING Name, Value;

    RtlInitUnicodeString(&Name, lpName);

    Value.Length = 0;
    Value.MaximumLength = 1024 * sizeof(WCHAR);
    Value.Buffer = LocalAlloc(LPTR, Value.MaximumLength);
    if (Value.Buffer == NULL)
        return FALSE;

    Value.Buffer[0] = UNICODE_NULL;

    Status = RtlQueryEnvironmentVariable_U(*Environment,
                                           &Name,
                                           &Value);
    if (NT_SUCCESS(Status))
        RtlAppendUnicodeToString(&Value, L";");

    RtlAppendUnicodeToString(&Value, lpValue);

    Status = RtlSetEnvironmentVariable(Environment,
                                       &Name,
                                       &Value);
    LocalFree(Value.Buffer);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("RtlSetEnvironmentVariable() failed (Status %lx)\n", Status);
        return FALSE;
    }

    return TRUE;
}
Exemplo n.º 11
0
//read EnableReplace key from reg to check if replace the key with our define key
void ReadRegistery(IN PUNICODE_STRING RegistryPath)
{
	UNICODE_STRING              parameter_path;
	RTL_QUERY_REGISTRY_TABLE    query_table[2];
	NTSTATUS                    status;

	parameter_path.Length = 0;
	parameter_path.MaximumLength = RegistryPath->Length + sizeof(PARAMETER_KEY);
	parameter_path.Buffer = (PWSTR) ExAllocatePool(PagedPool, parameter_path.MaximumLength);

	if (parameter_path.Buffer == NULL)
	{
		return;
	}
    RtlZeroMemory(parameter_path.Buffer,parameter_path.MaximumLength);

	RtlCopyUnicodeString(&parameter_path, RegistryPath);

	RtlAppendUnicodeToString(&parameter_path, PARAMETER_KEY);

	RtlZeroMemory(&query_table[0], sizeof(query_table));

	query_table[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
	query_table[0].Name = ENABLEWRITEPORT_VALUE;
	query_table[0].EntryContext = &bEnableReplace;

	status = RtlQueryRegistryValues(
		RTL_REGISTRY_ABSOLUTE,
		parameter_path.Buffer,
		&query_table[0],
		NULL,
		NULL
		);

	ExFreePool(parameter_path.Buffer);

	if (!NT_SUCCESS(status))
	{
		KdPrint(("Kb_sniff_Mp: Query registry failed.\n"));
	}
}
Exemplo n.º 12
0
VOID
InitializeProvider(
    PWCH ProviderName,
    ULONG Priority
    )

/*++

Routine Description:

    This routine reads provider information out of the registry and
    creates an unregistered provider entry.

Arguments:

    ProviderName - The registry name for the provider.

    Priority - The priority to assign to this provider.

Return Value:

    None.

--*/

{
    UNICODE_STRING keyName;
    PVOID buffer = NULL;
    ULONG bufferLength;
    NTSTATUS status;
    OBJECT_ATTRIBUTES objectAttributes;
    ULONG lengthRequired;
    UNICODE_STRING valueName;
    HANDLE handle;

    PAGED_CODE();
    //
    // Allocate space for the registry string
    //

    bufferLength = sizeof( L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\" ) +
                   wcslen( ProviderName ) * sizeof( WCHAR ) +
                   sizeof( L"\\NetworkProvider" );

    buffer = ExAllocatePoolWithTag( PagedPool, bufferLength, ' puM' );
    if ( buffer == NULL ) {
        return;
    }

    //
    // Build the registry string
    //

    RtlMoveMemory(
        buffer,
        L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
        sizeof( L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\" )
        );

    keyName.Buffer = buffer;
    keyName.MaximumLength = (USHORT)bufferLength;
    keyName.Length = sizeof( L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\" ) - 2;

    status = RtlAppendUnicodeToString( &keyName, ProviderName );
    ASSERT( NT_SUCCESS( status ) );
    status = RtlAppendUnicodeToString( &keyName, L"\\NetworkProvider" );
    ASSERT( NT_SUCCESS( status ) );

    InitializeObjectAttributes(
        &objectAttributes,
        &keyName,
        OBJ_CASE_INSENSITIVE,
        0,
        NULL
        );

    status = ZwOpenKey(
                 &handle,
                 KEY_QUERY_VALUE,
                 &objectAttributes
                 );

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

    buffer = NULL;
    RtlInitUnicodeString( &valueName, L"DeviceName" );

    status = ZwQueryValueKey(
                 handle,
                 &valueName,
                 KeyValueFullInformation,
                 buffer,
                 0,
                 &lengthRequired
                 );

    if ( status == STATUS_BUFFER_TOO_SMALL ) {
        buffer = ExAllocatePoolWithTag( PagedPool, lengthRequired + 2, ' puM' );
        if ( buffer == NULL) {
            return;
        }

        status = ZwQueryValueKey(
                     handle,
                     &valueName,
                     KeyValueFullInformation,
                     buffer,
                     lengthRequired,
                     &lengthRequired
                     );
    }

    if ( !NT_SUCCESS( status) ) {
        if ( buffer != NULL ) {
            ExFreePool( buffer );
        }
        ZwClose( handle );
        return;
    }

    //
    // Wahoo!  We actually have the device name in hand.  Add the
    // provider to the unregistered list.
    //

    AddUnregisteredProvider(
        (PWCH)((PCHAR)buffer + ((PKEY_VALUE_FULL_INFORMATION)buffer)->DataOffset),
        Priority
        );

    ExFreePool( buffer );
    ZwClose( handle );
    return;
}
Exemplo n.º 13
0
static
NTSTATUS
OpenRegistryHandlesFromSymbolicLink(IN PUNICODE_STRING SymbolicLinkName,
                                    IN ACCESS_MASK DesiredAccess,
                                    IN OPTIONAL PHANDLE GuidKey,
                                    IN OPTIONAL PHANDLE DeviceKey,
                                    IN OPTIONAL PHANDLE InstanceKey)
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    WCHAR PathBuffer[MAX_PATH];
    UNICODE_STRING BaseKeyU;
    UNICODE_STRING GuidString, SubKeyName, ReferenceString;
    PWCHAR StartPosition, EndPosition;
    HANDLE ClassesKey;
    PHANDLE GuidKeyRealP, DeviceKeyRealP, InstanceKeyRealP;
    HANDLE GuidKeyReal, DeviceKeyReal, InstanceKeyReal;
    NTSTATUS Status;

    SubKeyName.Buffer = NULL;

    if (GuidKey != NULL)
        GuidKeyRealP = GuidKey;
    else
        GuidKeyRealP = &GuidKeyReal;

    if (DeviceKey != NULL)
        DeviceKeyRealP = DeviceKey;
    else
        DeviceKeyRealP = &DeviceKeyReal;

    if (InstanceKey != NULL)
        InstanceKeyRealP = InstanceKey;
    else
        InstanceKeyRealP = &InstanceKeyReal;

    *GuidKeyRealP = INVALID_HANDLE_VALUE;
    *DeviceKeyRealP = INVALID_HANDLE_VALUE;
    *InstanceKeyRealP = INVALID_HANDLE_VALUE;

    BaseKeyU.Buffer = PathBuffer;
    BaseKeyU.Length = 0;
    BaseKeyU.MaximumLength = MAX_PATH * sizeof(WCHAR);

    RtlAppendUnicodeToString(&BaseKeyU, BaseKeyString);

    /* Open the DeviceClasses key */
    InitializeObjectAttributes(&ObjectAttributes,
                               &BaseKeyU,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               NULL,
                               NULL);
    Status = ZwOpenKey(&ClassesKey,
                       DesiredAccess | KEY_ENUMERATE_SUB_KEYS,
                       &ObjectAttributes);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Failed to open %wZ\n", &BaseKeyU);
        goto cleanup;
    }

    StartPosition = wcschr(SymbolicLinkName->Buffer, L'{');
    EndPosition = wcschr(SymbolicLinkName->Buffer, L'}');
    if (!StartPosition || !EndPosition || StartPosition > EndPosition)
    {
        DPRINT1("Bad symbolic link: %wZ\n", SymbolicLinkName);
        return STATUS_INVALID_PARAMETER_1;
    }
    GuidString.Buffer = StartPosition;
    GuidString.MaximumLength = GuidString.Length = (USHORT)((ULONG_PTR)(EndPosition + 1) - (ULONG_PTR)StartPosition);

    InitializeObjectAttributes(&ObjectAttributes,
                               &GuidString,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               ClassesKey,
                               NULL);
    Status = ZwOpenKey(GuidKeyRealP,
                       DesiredAccess | KEY_ENUMERATE_SUB_KEYS,
                       &ObjectAttributes);
    ZwClose(ClassesKey);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Failed to open %wZ%wZ (%x)\n", &BaseKeyU, &GuidString, Status);
        goto cleanup;
    }

    SubKeyName.MaximumLength = SymbolicLinkName->Length + sizeof(WCHAR);
    SubKeyName.Length = 0;
    SubKeyName.Buffer = ExAllocatePool(PagedPool, SubKeyName.MaximumLength);
    if (!SubKeyName.Buffer)
    {
        Status = STATUS_INSUFFICIENT_RESOURCES;
        goto cleanup;
    }

    RtlAppendUnicodeStringToString(&SubKeyName,
                                   SymbolicLinkName);

    SubKeyName.Buffer[SubKeyName.Length / sizeof(WCHAR)] = UNICODE_NULL;

    SubKeyName.Buffer[0] = L'#';
    SubKeyName.Buffer[1] = L'#';
    SubKeyName.Buffer[2] = L'?';
    SubKeyName.Buffer[3] = L'#';

    ReferenceString.Buffer = wcsrchr(SubKeyName.Buffer, '\\');
    if (ReferenceString.Buffer != NULL)
    {
        ReferenceString.Buffer[0] = L'#';

        SubKeyName.Length = (USHORT)((ULONG_PTR)(ReferenceString.Buffer) - (ULONG_PTR)SubKeyName.Buffer);
        ReferenceString.Length = SymbolicLinkName->Length - SubKeyName.Length;
    }
    else
    {
        RtlInitUnicodeString(&ReferenceString, L"#");
    }

    InitializeObjectAttributes(&ObjectAttributes,
                               &SubKeyName,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               *GuidKeyRealP,
                               NULL);
    Status = ZwOpenKey(DeviceKeyRealP,
                       DesiredAccess | KEY_ENUMERATE_SUB_KEYS,
                       &ObjectAttributes);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Failed to open %wZ%wZ\\%wZ\n", &BaseKeyU, &GuidString, &SubKeyName);
        goto cleanup;
    }

    InitializeObjectAttributes(&ObjectAttributes,
                               &ReferenceString,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               *DeviceKeyRealP,
                               NULL);
    Status = ZwOpenKey(InstanceKeyRealP,
                       DesiredAccess,
                       &ObjectAttributes);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Failed to open %wZ%wZ\\%wZ%\\%wZ (%x)\n", &BaseKeyU, &GuidString, &SubKeyName, &ReferenceString, Status);
        goto cleanup;
    }

    Status = STATUS_SUCCESS;

cleanup:
    if (SubKeyName.Buffer != NULL)
       ExFreePool(SubKeyName.Buffer);

    if (NT_SUCCESS(Status))
    {
       if (!GuidKey)
          ZwClose(*GuidKeyRealP);

       if (!DeviceKey)
          ZwClose(*DeviceKeyRealP);

       if (!InstanceKey)
          ZwClose(*InstanceKeyRealP);
    }
    else
    {
       if (*GuidKeyRealP != INVALID_HANDLE_VALUE)
          ZwClose(*GuidKeyRealP);

       if (*DeviceKeyRealP != INVALID_HANDLE_VALUE)
          ZwClose(*DeviceKeyRealP);

       if (*InstanceKeyRealP != INVALID_HANDLE_VALUE)
          ZwClose(*InstanceKeyRealP);
    }

    return Status;
}
Exemplo n.º 14
0
/*++
 * @name IopOpenInterfaceKey
 *
 * Returns the alias device interface of the specified device interface
 *
 * @param InterfaceClassGuid
 *        FILLME
 *
 * @param DesiredAccess
 *        FILLME
 *
 * @param pInterfaceKey
 *        FILLME
 *
 * @return Usual NTSTATUS
 *
 * @remarks None
 *
 *--*/
static NTSTATUS
IopOpenInterfaceKey(IN CONST GUID *InterfaceClassGuid,
                    IN ACCESS_MASK DesiredAccess,
                    OUT HANDLE *pInterfaceKey)
{
    UNICODE_STRING LocalMachine = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\");
    UNICODE_STRING GuidString;
    UNICODE_STRING KeyName;
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE InterfaceKey = INVALID_HANDLE_VALUE;
    NTSTATUS Status;

    GuidString.Buffer = KeyName.Buffer = NULL;

    Status = RtlStringFromGUID(InterfaceClassGuid, &GuidString);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("RtlStringFromGUID() failed with status 0x%08lx\n", Status);
        goto cleanup;
    }

    KeyName.Length = 0;
    KeyName.MaximumLength = LocalMachine.Length + ((USHORT)wcslen(REGSTR_PATH_DEVICE_CLASSES) + 1) * sizeof(WCHAR) + GuidString.Length;
    KeyName.Buffer = ExAllocatePool(PagedPool, KeyName.MaximumLength);
    if (!KeyName.Buffer)
    {
        DPRINT("ExAllocatePool() failed\n");
        Status = STATUS_INSUFFICIENT_RESOURCES;
        goto cleanup;
    }

    Status = RtlAppendUnicodeStringToString(&KeyName, &LocalMachine);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("RtlAppendUnicodeStringToString() failed with status 0x%08lx\n", Status);
        goto cleanup;
    }
    Status = RtlAppendUnicodeToString(&KeyName, REGSTR_PATH_DEVICE_CLASSES);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("RtlAppendUnicodeToString() failed with status 0x%08lx\n", Status);
        goto cleanup;
    }
    Status = RtlAppendUnicodeToString(&KeyName, L"\\");
    if (!NT_SUCCESS(Status))
    {
        DPRINT("RtlAppendUnicodeToString() failed with status 0x%08lx\n", Status);
        goto cleanup;
    }
    Status = RtlAppendUnicodeStringToString(&KeyName, &GuidString);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("RtlAppendUnicodeStringToString() failed with status 0x%08lx\n", Status);
        goto cleanup;
    }

    InitializeObjectAttributes(
        &ObjectAttributes,
        &KeyName,
        OBJ_CASE_INSENSITIVE,
        NULL,
        NULL);
    Status = ZwOpenKey(
        &InterfaceKey,
        DesiredAccess,
        &ObjectAttributes);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
        goto cleanup;
    }

    *pInterfaceKey = InterfaceKey;
    Status = STATUS_SUCCESS;

cleanup:
    if (!NT_SUCCESS(Status))
    {
        if (InterfaceKey != INVALID_HANDLE_VALUE)
            ZwClose(InterfaceKey);
    }
    RtlFreeUnicodeString(&GuidString);
    RtlFreeUnicodeString(&KeyName);
    return Status;
}
Exemplo n.º 15
0
PLDEVOBJ
NTAPI
EngLoadImageEx(
    _In_z_ LPWSTR pwszDriverName,
    _In_ ULONG ldevtype)
{
    WCHAR acwBuffer[MAX_PATH];
    PLDEVOBJ pldev;
    UNICODE_STRING strDriverName;
    SIZE_T cwcLength;
    LPWSTR pwsz;

    TRACE("EngLoadImageEx(%ls, %lu)\n", pwszDriverName, ldevtype);
    ASSERT(pwszDriverName);

    /* Initialize buffer for the the driver name */
    RtlInitEmptyUnicodeString(&strDriverName, acwBuffer, sizeof(acwBuffer));

    /* Start path with systemroot */
    RtlAppendUnicodeToString(&strDriverName, L"\\SystemRoot\\System32\\");

    /* Get Length of given string */
    cwcLength = wcslen(pwszDriverName);

    /* Check if we have a system32 path given */
    pwsz = pwszDriverName + cwcLength;
    while (pwsz > pwszDriverName)
    {
        if ((*pwsz == L'\\') && (_wcsnicmp(pwsz, L"\\system32\\", 10) == 0))
        {
            /* Driver name starts after system32 */
            pwsz += 10;
            break;
        }
        pwsz--;
    }

    /* Append the driver name */
    RtlAppendUnicodeToString(&strDriverName, pwsz);

    /* MSDN says "The driver must include this suffix in the pwszDriver string."
       But in fact it's optional. The function can also load .sys files without
       appending the .dll extension. */
    if ((cwcLength < 4) ||
        ((_wcsnicmp(pwszDriverName + cwcLength - 4, L".dll", 4) != 0) &&
         (_wcsnicmp(pwszDriverName + cwcLength - 4, L".sys", 4) != 0)) )
    {
        /* Append the .dll suffix */
        RtlAppendUnicodeToString(&strDriverName, L".dll");
    }

    /* Lock loader */
    EngAcquireSemaphore(ghsemLDEVList);

    /* Search the List of LDEVS for the driver name */
    for (pldev = gpldevHead; pldev != NULL; pldev = pldev->pldevNext)
    {
        /* Check if the ldev is associated with a file */
        if (pldev->pGdiDriverInfo)
        {
            ERR("Driver Name 1 %wZ\n", &strDriverName);
            ERR("Driver Name 2 %wZ\n", &pldev->pGdiDriverInfo->DriverName);
            /* Check for match (case insensative) */
            if (RtlEqualUnicodeString(&pldev->pGdiDriverInfo->DriverName, &strDriverName, 1))
            {
                /* Image found in LDEV list */
                break;
            }
        }
    }

    /* Did we find one? */
    if (!pldev)
    {
        /* No, allocate a new LDEVOBJ */
        pldev = LDEVOBJ_AllocLDEV(ldevtype);
        if (!pldev)
        {
            ERR("Could not allocate LDEV\n");
            goto leave;
        }

        /* Load the image */
        if (!LDEVOBJ_bLoadImage(pldev, &strDriverName))
        {
            LDEVOBJ_vFreeLDEV(pldev);
            pldev = NULL;
            ERR("LDEVOBJ_bLoadImage failed\n");
            goto leave;
        }

        /* Shall we load a driver? */
        if (ldevtype != LDEV_IMAGE)
        {
            /* Load the driver */
            if (!LDEVOBJ_bEnableDriver(pldev))
            {
                ERR("LDEVOBJ_bEnableDriver failed\n");

                /* Unload the image. */
                LDEVOBJ_vUnloadImage(pldev);
                LDEVOBJ_vFreeLDEV(pldev);
                pldev = NULL;
                goto leave;
            }
        }

        /* Insert the LDEV into the global list */
        pldev->pldevPrev = NULL;
        pldev->pldevNext = gpldevHead;
        if (gpldevHead)
            gpldevHead->pldevPrev = pldev;
        gpldevHead = pldev;
    }

    /* Increase ref count */
    pldev->cRefs++;

leave:
    /* Unlock loader */
    EngReleaseSemaphore(ghsemLDEVList);

    TRACE("EngLoadImageEx returning %p\n", pldev);
    return pldev;
}
Exemplo n.º 16
0
BOOLEAN
Ext2QueryGlobalParameters( IN PUNICODE_STRING  RegistryPath)
{
    NTSTATUS                    Status;
    UNICODE_STRING              ParameterPath;
    RTL_QUERY_REGISTRY_TABLE    QueryTable[2];

    ULONG                       WritingSupport = 0;
    ULONG                       CheckingBitmap = 0;
    ULONG                       Ext3ForceWriting = 0;
    ULONG                       AutoMount = 0;

    UNICODE_STRING              UniName;
    ANSI_STRING                 AnsiName;

    WCHAR                       UniBuffer[CODEPAGE_MAXLEN];
    USHORT                      Buffer[HIDINGPAT_LEN];

    ParameterPath.Length = 0;

    ParameterPath.MaximumLength =
        RegistryPath->Length + sizeof(PARAMETERS_KEY) + sizeof(WCHAR);

    ParameterPath.Buffer =
        (PWSTR) Ext2AllocatePool(
            PagedPool,
            ParameterPath.MaximumLength,
            'LG2E'
        );

    if (!ParameterPath.Buffer) {
        DbgBreak();
        DEBUG(DL_ERR, ( "Ex2QueryParameters: failed to allocate Parameters...\n"));
        return FALSE;
    }

    RtlCopyUnicodeString(&ParameterPath, RegistryPath);
    RtlAppendUnicodeToString(&ParameterPath, PARAMETERS_KEY);

    /* querying value of WritingSupport */
    RtlZeroMemory(&QueryTable[0], sizeof(RTL_QUERY_REGISTRY_TABLE) * 2);

    QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
    QueryTable[0].Name = WRITING_SUPPORT;
    QueryTable[0].EntryContext = &WritingSupport;

    Status = RtlQueryRegistryValues(
                 RTL_REGISTRY_ABSOLUTE,
                 ParameterPath.Buffer,
                 &QueryTable[0],
                 NULL,
                 NULL        );

    DEBUG(DL_ERR, ( "Ext2QueryParameters: WritingSupport=%xh\n", WritingSupport));

    /* querying value of CheckingBitmap */
    RtlZeroMemory(&QueryTable[0], sizeof(RTL_QUERY_REGISTRY_TABLE) * 2);
    QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
    QueryTable[0].Name = CHECKING_BITMAP;
    QueryTable[0].EntryContext = &CheckingBitmap;

    Status = RtlQueryRegistryValues(
                 RTL_REGISTRY_ABSOLUTE,
                 ParameterPath.Buffer,
                 &QueryTable[0],
                 NULL,
                 NULL        );

    DEBUG(DL_ERR, ( "Ext2QueryParameters: CheckingBitmap=%xh\n", CheckingBitmap));

    /* querying value of Ext3ForceWriting */
    RtlZeroMemory(&QueryTable[0], sizeof(RTL_QUERY_REGISTRY_TABLE) * 2);
    QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
    QueryTable[0].Name = EXT3_FORCEWRITING;
    QueryTable[0].EntryContext = &Ext3ForceWriting;

    Status = RtlQueryRegistryValues(
                 RTL_REGISTRY_ABSOLUTE,
                 ParameterPath.Buffer,
                 &QueryTable[0],
                 NULL,
                 NULL        );

    DEBUG(DL_ERR, ( "Ext2QueryParameters: Ext3ForceWriting=%xh\n", Ext3ForceWriting));


    /* querying value of AutoMount */
    RtlZeroMemory(&QueryTable[0], sizeof(RTL_QUERY_REGISTRY_TABLE) * 2);

    QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
    QueryTable[0].Name = AUTO_MOUNT;
    QueryTable[0].EntryContext = &AutoMount;

    Status = RtlQueryRegistryValues(
                 RTL_REGISTRY_ABSOLUTE,
                 ParameterPath.Buffer,
                 &QueryTable[0],
                 NULL,
                 NULL        );

    SetLongFlag(Ext2Global->Flags, EXT2_AUTO_MOUNT);
    if (NT_SUCCESS(Status) && AutoMount == 0) {
        ClearLongFlag(Ext2Global->Flags, EXT2_AUTO_MOUNT);
    }

    DEBUG(DL_ERR, ( "Ext2QueryParameters: AutoMount=%xh\n", AutoMount));

    /* querying codepage */
    RtlZeroMemory(&QueryTable[0], sizeof(RTL_QUERY_REGISTRY_TABLE) * 2);
    QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
    QueryTable[0].Name = CODEPAGE_NAME;
    QueryTable[0].EntryContext = &(UniName);
    UniName.MaximumLength = CODEPAGE_MAXLEN * sizeof(WCHAR);
    UniName.Length = 0;
    UniName.Buffer = (PWSTR)UniBuffer;

    Status = RtlQueryRegistryValues(
                 RTL_REGISTRY_ABSOLUTE,
                 ParameterPath.Buffer,
                 &QueryTable[0],
                 NULL,
                 NULL        );

    if (NT_SUCCESS(Status)) {
        DEBUG(DL_ERR, ( "Ext2QueryParameters: Ext2CodePage=%wZ\n", &UniName));
        AnsiName.MaximumLength = CODEPAGE_MAXLEN;
        AnsiName.Length = 0;
        AnsiName.Buffer = &(Ext2Global->Codepage.AnsiName[0]);

        Status = RtlUnicodeStringToAnsiString(
                     &AnsiName,
                     &UniName,
                     FALSE);

        if (!NT_SUCCESS(Status)) {
            DEBUG(DL_ERR, ( "Ext2QueryParameters: Wrong CodePage %wZ ...\n", &UniName));
            RtlCopyMemory(&(Ext2Global->Codepage.AnsiName[0]),"default\0", 8);
        }
    } else {
        DEBUG(DL_ERR, ( "Ext2QueryParameters: CodePage not specified.\n"));
        RtlCopyMemory(&(Ext2Global->Codepage.AnsiName[0]),"default\0", 8);
    }
    Ext2Global->Codepage.AnsiName[CODEPAGE_MAXLEN - 1] = 0;

    /* querying name hiding patterns: prefix*/
    RtlZeroMemory(&QueryTable[0], sizeof(RTL_QUERY_REGISTRY_TABLE) * 2);
    QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
    QueryTable[0].Name = HIDING_PREFIX;
    QueryTable[0].EntryContext = &(UniName);
    UniName.MaximumLength = HIDINGPAT_LEN * sizeof(WCHAR);
    UniName.Length = 0;
    UniName.Buffer = Buffer;

    Status = RtlQueryRegistryValues(
                 RTL_REGISTRY_ABSOLUTE,
                 ParameterPath.Buffer,
                 &QueryTable[0],
                 NULL,
                 NULL        );

    if (NT_SUCCESS(Status)) {
        DEBUG(DL_ERR, ( "Ext2QueryParameters: HidingPrefix=%wZ\n", &UniName));
        AnsiName.MaximumLength =HIDINGPAT_LEN;
        AnsiName.Length = 0;
        AnsiName.Buffer = &(Ext2Global->sHidingPrefix[0]);

        Status = RtlUnicodeStringToAnsiString(
                     &AnsiName,
                     &UniName,
                     FALSE);
        if (NT_SUCCESS(Status)) {
            Ext2Global->bHidingPrefix = TRUE;
        } else {
            DEBUG(DL_ERR, ( "Ext2QueryParameters: Wrong HidingPrefix ...\n"));
        }
    } else {
        DEBUG(DL_ERR, ( "Ext2QueryParameters: HidingPrefix not specified.\n"));
    }
    Ext2Global->sHidingPrefix[HIDINGPAT_LEN - 1] = 0;

    /* querying name hiding patterns: suffix */
    RtlZeroMemory(&QueryTable[0], sizeof(RTL_QUERY_REGISTRY_TABLE) * 2);
    QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
    QueryTable[0].Name = HIDING_SUFFIX;
    QueryTable[0].EntryContext = &(UniName);
    UniName.MaximumLength = HIDINGPAT_LEN * sizeof(WCHAR);
    UniName.Length = 0;
    UniName.Buffer = Buffer;

    Status = RtlQueryRegistryValues(
                 RTL_REGISTRY_ABSOLUTE,
                 ParameterPath.Buffer,
                 &QueryTable[0],
                 NULL,
                 NULL
             );

    if (NT_SUCCESS(Status)) {

        DEBUG(DL_ERR, ( "Ext2QueryParameters: HidingSuffix=%wZ\n", &UniName));
        AnsiName.MaximumLength = HIDINGPAT_LEN;
        AnsiName.Length = 0;
        AnsiName.Buffer = &(Ext2Global->sHidingSuffix[0]);

        Status = RtlUnicodeStringToAnsiString(
                     &AnsiName,
                     &UniName,
                     FALSE);
        if (NT_SUCCESS(Status)) {
            Ext2Global->bHidingSuffix = TRUE;
        } else {
            DEBUG(DL_ERR, ( "Ext2QueryParameters: Wrong HidingSuffix ...\n"));
        }
    } else {
        DEBUG(DL_ERR, ( "Ext2QueryParameters: HidingSuffix not specified.\n"));
    }
    Ext2Global->sHidingPrefix[HIDINGPAT_LEN - 1] = 0;

    {
        if (WritingSupport) {
            SetLongFlag(Ext2Global->Flags, EXT2_SUPPORT_WRITING);
        } else {
            ClearLongFlag(Ext2Global->Flags, EXT2_SUPPORT_WRITING);
        }

        if (CheckingBitmap) {
            SetLongFlag(Ext2Global->Flags, EXT2_CHECKING_BITMAP);
        } else {
            ClearLongFlag(Ext2Global->Flags, EXT2_CHECKING_BITMAP);
        }

        if (Ext3ForceWriting) {
            DbgPrint("Ext2Fsd -- Warning: Ext3ForceWriting enabled !!!\n");

            SetLongFlag(Ext2Global->Flags, EXT3_FORCE_WRITING);
            SetLongFlag(Ext2Global->Flags, EXT2_SUPPORT_WRITING);
        } else {
            ClearLongFlag(Ext2Global->Flags, EXT3_FORCE_WRITING);
        }
    }

    Ext2Global->RegistryPath.Buffer = ParameterPath.Buffer;
    Ext2Global->RegistryPath.Length = 0;
    Ext2Global->RegistryPath.MaximumLength = ParameterPath.MaximumLength;
    RtlCopyUnicodeString(&Ext2Global->RegistryPath, RegistryPath);
    RtlAppendUnicodeToString(&Ext2Global->RegistryPath, VOLUMES_KEY);

    return TRUE;
}
Exemplo n.º 17
0
BOOLEAN
Ext2QueryRegistrySettings(IN PUNICODE_STRING  RegistryPath)
{
    UNICODE_STRING              ParameterPath;
    UNICODE_STRING              UniName;
    ANSI_STRING                 AnsiName;

    ULONG                       WritingSupport = 0;
    ULONG                       CheckingBitmap = 0;
    ULONG                       Ext3ForceWriting = 0;
    ULONG                       AutoMount = 0;

    WCHAR                       UniBuffer[CODEPAGE_MAXLEN];
    USHORT                      Buffer[HIDINGPAT_LEN];

    NTSTATUS                    Status;

    ParameterPath.Length = 0;
    ParameterPath.MaximumLength =
        RegistryPath->Length + sizeof(PARAMETERS_KEY) + sizeof(WCHAR);
    ParameterPath.Buffer =
        (PWSTR) Ext2AllocatePool(
            PagedPool,
            ParameterPath.MaximumLength,
            'LG2E'
        );
    if (!ParameterPath.Buffer) {
        DbgBreak();
        DEBUG(DL_ERR, ( "Ex2QueryParameters: failed to allocate Parameters...\n"));
        return FALSE;
    }

    RtlCopyUnicodeString(&ParameterPath, RegistryPath);
    RtlAppendUnicodeToString(&ParameterPath, PARAMETERS_KEY);

    /* enable automount of ext2/3/4 volumes */
    SetLongFlag(Ext2Global->Flags, EXT2_AUTO_MOUNT);

    /* query parameter settings from registry */
    Ext2QueryGlobalParameters(&ParameterPath);

    /* set global codepage settings */
    if (wcslen(&Ext2Global->Codepage.PageName[0])) {
        UniName.Length = sizeof(WCHAR) * wcslen(&Ext2Global->Codepage.PageName[0]);
        UniName.MaximumLength = CODEPAGE_MAXLEN * sizeof(WCHAR);
        UniName.Buffer = &Ext2Global->Codepage.PageName[0];
        AnsiName.MaximumLength = CODEPAGE_MAXLEN;
        AnsiName.Length = 0;
        AnsiName.Buffer = &Ext2Global->Codepage.AnsiName[0];
        Status = RtlUnicodeStringToAnsiString(
                     &AnsiName,
                     &UniName,
                     FALSE);
        if (!NT_SUCCESS(Status)) {
            DEBUG(DL_ERR, ( "Ext2QueryParameters: Wrong CodePage %wZ ...\n", &UniName));
            RtlCopyMemory(&(Ext2Global->Codepage.AnsiName[0]),"default\0", 8);
        }
    } else {
        DEBUG(DL_ERR, ( "Ext2QueryParameters: CodePage not specified.\n"));
        RtlCopyMemory(&(Ext2Global->Codepage.AnsiName[0]),"default\0", 8);
    }
    Ext2Global->Codepage.AnsiName[CODEPAGE_MAXLEN - 1] = 0;


    /* set global hidden prefix pattern */
    if (wcslen(&Ext2Global->wHidingPrefix[0])) {
        UniName.Length = sizeof(WCHAR) * wcslen(&Ext2Global->wHidingPrefix[0]);
        UniName.MaximumLength = HIDINGPAT_LEN * sizeof(WCHAR);
        UniName.Buffer = &Ext2Global->wHidingPrefix[0];
        AnsiName.MaximumLength = HIDINGPAT_LEN;
        AnsiName.Length = 0;
        AnsiName.Buffer = &(Ext2Global->sHidingPrefix[0]);

        Status = RtlUnicodeStringToAnsiString(
                     &AnsiName,
                     &UniName,
                     FALSE);
        if (NT_SUCCESS(Status)) {
            Ext2Global->bHidingPrefix = TRUE;
        } else {
            DEBUG(DL_ERR, ( "Ext2QueryParameters: Wrong HidingPrefix ...\n"));
        }
    } else {
        DEBUG(DL_ERR, ( "Ext2QueryParameters: HidingPrefix not specified.\n"));
    }
    Ext2Global->sHidingPrefix[HIDINGPAT_LEN - 1] = 0;


    /* set global hidden suffix pattern */
    if (wcslen(&Ext2Global->wHidingSuffix[0])) {
        UniName.Length = sizeof(WCHAR) * wcslen(&Ext2Global->wHidingSuffix[0]);
        UniName.MaximumLength = HIDINGPAT_LEN * sizeof(WCHAR);
        UniName.Buffer = &Ext2Global->wHidingSuffix[0];
        AnsiName.MaximumLength = HIDINGPAT_LEN;
        AnsiName.Length = 0;
        AnsiName.Buffer = &(Ext2Global->sHidingSuffix[0]);

        Status = RtlUnicodeStringToAnsiString(
                     &AnsiName,
                     &UniName,
                     FALSE);
        if (NT_SUCCESS(Status)) {
            Ext2Global->bHidingSuffix = TRUE;
        } else {
            DEBUG(DL_ERR, ( "Ext2QueryParameters: Wrong HidingSuffix ...\n"));
        }
    } else {
        DEBUG(DL_ERR, ( "Ext2QueryParameters: HidingSuffix not specified.\n"));
    }
    Ext2Global->sHidingPrefix[HIDINGPAT_LEN - 1] = 0;

    Ext2Global->RegistryPath.Buffer = ParameterPath.Buffer;
    Ext2Global->RegistryPath.Length = 0;
    Ext2Global->RegistryPath.MaximumLength = ParameterPath.MaximumLength;
    RtlCopyUnicodeString(&Ext2Global->RegistryPath, RegistryPath);
    RtlAppendUnicodeToString(&Ext2Global->RegistryPath, VOLUMES_KEY);

    return TRUE;
}
Exemplo n.º 18
0
/// <summary>
/// Get exported function address
/// </summary>
/// <param name="pBase">Module base</param>
/// <param name="name_ord">Function name or ordinal</param>
/// <param name="pProcess">Target process for user module</param>
/// <param name="baseName">Dll name for api schema</param>
/// <returns>Found address, NULL if not found</returns>
PVOID BBGetModuleExport( IN PVOID pBase, IN PCCHAR name_ord, IN PEPROCESS pProcess, IN PUNICODE_STRING baseName )
{
    PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)pBase;
    PIMAGE_NT_HEADERS32 pNtHdr32 = NULL;
    PIMAGE_NT_HEADERS64 pNtHdr64 = NULL;
    PIMAGE_EXPORT_DIRECTORY pExport = NULL;
    ULONG expSize = 0;
    ULONG_PTR pAddress = 0;

    ASSERT( pBase != NULL );
    if (pBase == NULL)
        return NULL;

    // Protect from UserMode AV
    __try
    {
        // Not a PE file
        if (pDosHdr->e_magic != IMAGE_DOS_SIGNATURE)
            return NULL;

        pNtHdr32 = (PIMAGE_NT_HEADERS32)((PUCHAR)pBase + pDosHdr->e_lfanew);
        pNtHdr64 = (PIMAGE_NT_HEADERS64)((PUCHAR)pBase + pDosHdr->e_lfanew);

        // Not a PE file
        if (pNtHdr32->Signature != IMAGE_NT_SIGNATURE)
            return NULL;

        // 64 bit image
        if (pNtHdr32->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
        {
            pExport = (PIMAGE_EXPORT_DIRECTORY)(pNtHdr64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + (ULONG_PTR)pBase);
            expSize = pNtHdr64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
        }
        // 32 bit image
        else
        {
            pExport = (PIMAGE_EXPORT_DIRECTORY)(pNtHdr32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + (ULONG_PTR)pBase);
            expSize = pNtHdr32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
        }

        PUSHORT pAddressOfOrds = (PUSHORT)(pExport->AddressOfNameOrdinals + (ULONG_PTR)pBase);
        PULONG  pAddressOfNames = (PULONG)(pExport->AddressOfNames + (ULONG_PTR)pBase);
        PULONG  pAddressOfFuncs = (PULONG)(pExport->AddressOfFunctions + (ULONG_PTR)pBase);

        for (ULONG i = 0; i < pExport->NumberOfFunctions; ++i)
        {
            USHORT OrdIndex = 0xFFFF;
            PCHAR  pName = NULL;

            // Find by index
            if ((ULONG_PTR)name_ord <= 0xFFFF)
            {
                OrdIndex = (USHORT)i;
            }
            // Find by name
            else if ((ULONG_PTR)name_ord > 0xFFFF && i < pExport->NumberOfNames)
            {
                pName = (PCHAR)(pAddressOfNames[i] + (ULONG_PTR)pBase);
                OrdIndex = pAddressOfOrds[i];
            }
            // Weird params
            else
                return NULL;

            if (((ULONG_PTR)name_ord <= 0xFFFF && (USHORT)((ULONG_PTR)name_ord) == OrdIndex + pExport->Base) ||
                 ((ULONG_PTR)name_ord > 0xFFFF && strcmp( pName, name_ord ) == 0))
            {
                pAddress = pAddressOfFuncs[OrdIndex] + (ULONG_PTR)pBase;

                // Check forwarded export
                if (pAddress >= (ULONG_PTR)pExport && pAddress <= (ULONG_PTR)pExport + expSize)
                {
                    WCHAR strbuf[256] = { 0 };
                    ANSI_STRING forwarder = { 0 };
                    ANSI_STRING import = { 0 };

                    UNICODE_STRING uForwarder = { 0 };              
                    ULONG delimIdx = 0;
                    PVOID forwardBase = NULL;
                    PVOID result = NULL;

                    // System image, not supported
                    if (pProcess == NULL)
                        return NULL;

                    RtlInitAnsiString( &forwarder, (PCSZ)pAddress );
                    RtlInitEmptyUnicodeString( &uForwarder, strbuf, sizeof( strbuf ) );

                    RtlAnsiStringToUnicodeString( &uForwarder, &forwarder, FALSE );
                    for (ULONG i = 0; i < uForwarder.Length / sizeof( WCHAR ); i++)
                    {
                        if (uForwarder.Buffer[i] == L'.')
                        {
                            uForwarder.Length = (USHORT)(i * sizeof( WCHAR ));
                            uForwarder.Buffer[i] = L'\0';
                            delimIdx = i;
                            break;
                        }
                    }

                    // Get forward function name/ordinal
                    RtlInitAnsiString( &import, forwarder.Buffer + delimIdx + 1 );
                    RtlAppendUnicodeToString( &uForwarder, L".dll" );

                    //
                    // Check forwarded module
                    //
                    UNICODE_STRING resolved = { 0 };
                    UNICODE_STRING resolvedName = { 0 };
                    BBResolveImagePath( NULL, pProcess, KApiShemaOnly, &uForwarder, baseName, &resolved );
                    BBStripPath( &resolved, &resolvedName );

                    forwardBase = BBGetUserModule( pProcess, &resolvedName, PsGetProcessWow64Process( pProcess ) != NULL );
                    result = BBGetModuleExport( forwardBase, import.Buffer, pProcess, &resolvedName );
                    RtlFreeUnicodeString( &resolved );

                    return result;
                }

                break;
            }
        }
    }
    __except (EXCEPTION_EXECUTE_HANDLER)
    {
        DPRINT( "BlackBone: %s: Exception\n", __FUNCTION__ );
    }

    return (PVOID)pAddress;
}
Exemplo n.º 19
0
/*++
 * @name IoRegisterDeviceInterface
 * @implemented
 *
 * Registers a device interface class, if it has not been previously registered,
 * and creates a new instance of the interface class, which a driver can
 * subsequently enable for use by applications or other system components.
 * Documented in WDK.
 *
 * @param PhysicalDeviceObject
 *        Points to an optional PDO that narrows the search to only the
 *        device interfaces of the device represented by the PDO
 *
 * @param InterfaceClassGuid
 *        Points to a class GUID specifying the device interface class
 *
 * @param ReferenceString
 *        Optional parameter, pointing to a unicode string. For a full
 *        description of this rather rarely used param (usually drivers
 *        pass NULL here) see WDK
 *
 * @param SymbolicLinkName
 *        Pointer to the resulting unicode string
 *
 * @return Usual NTSTATUS
 *
 * @remarks Must be called at IRQL = PASSIVE_LEVEL in the context of a
 *          system thread
 *
 *--*/
NTSTATUS
NTAPI
IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject,
                          IN CONST GUID *InterfaceClassGuid,
                          IN PUNICODE_STRING ReferenceString OPTIONAL,
                          OUT PUNICODE_STRING SymbolicLinkName)
{
    PUNICODE_STRING InstancePath;
    UNICODE_STRING GuidString;
    UNICODE_STRING SubKeyName;
    UNICODE_STRING InterfaceKeyName;
    UNICODE_STRING BaseKeyName;
    UCHAR PdoNameInfoBuffer[sizeof(OBJECT_NAME_INFORMATION) + (256 * sizeof(WCHAR))];
    POBJECT_NAME_INFORMATION PdoNameInfo = (POBJECT_NAME_INFORMATION)PdoNameInfoBuffer;
    UNICODE_STRING DeviceInstance = RTL_CONSTANT_STRING(L"DeviceInstance");
    UNICODE_STRING SymbolicLink = RTL_CONSTANT_STRING(L"SymbolicLink");
    HANDLE ClassKey;
    HANDLE InterfaceKey;
    HANDLE SubKey;
    ULONG StartIndex;
    OBJECT_ATTRIBUTES ObjectAttributes;
    ULONG i;
    NTSTATUS Status, SymLinkStatus;
    PEXTENDED_DEVOBJ_EXTENSION DeviceObjectExtension;

    ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    DPRINT("IoRegisterDeviceInterface(): PDO %p, RefString: %wZ\n",
        PhysicalDeviceObject, ReferenceString);

    /* Parameters must pass three border of checks */
    DeviceObjectExtension = (PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension;

    /* 1st level: Presence of a Device Node */
    if (DeviceObjectExtension->DeviceNode == NULL)
    {
        DPRINT("PhysicalDeviceObject 0x%p doesn't have a DeviceNode\n", PhysicalDeviceObject);
        return STATUS_INVALID_DEVICE_REQUEST;
    }

    /* 2nd level: Presence of an non-zero length InstancePath */
    if (DeviceObjectExtension->DeviceNode->InstancePath.Length == 0)
    {
        DPRINT("PhysicalDeviceObject 0x%p's DOE has zero-length InstancePath\n", PhysicalDeviceObject);
        return STATUS_INVALID_DEVICE_REQUEST;
    }

    /* 3rd level: Optional, based on WDK documentation */
    if (ReferenceString != NULL)
    {
        /* Reference string must not contain path-separator symbols */
        for (i = 0; i < ReferenceString->Length / sizeof(WCHAR); i++)
        {
            if ((ReferenceString->Buffer[i] == '\\') ||
                (ReferenceString->Buffer[i] == '/'))
                return STATUS_INVALID_DEVICE_REQUEST;
        }
    }

    Status = RtlStringFromGUID(InterfaceClassGuid, &GuidString);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("RtlStringFromGUID() failed with status 0x%08lx\n", Status);
        return Status;
    }

    /* Create Pdo name: \Device\xxxxxxxx (unnamed device) */
    Status = ObQueryNameString(
        PhysicalDeviceObject,
        PdoNameInfo,
        sizeof(PdoNameInfoBuffer),
        &i);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("ObQueryNameString() failed with status 0x%08lx\n", Status);
        return Status;
    }
    ASSERT(PdoNameInfo->Name.Length);

    /* Create base key name for this interface: HKLM\SYSTEM\CurrentControlSet\Control\DeviceClasses\{GUID} */
    ASSERT(((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode);
    InstancePath = &((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode->InstancePath;
    BaseKeyName.Length = (USHORT)wcslen(BaseKeyString) * sizeof(WCHAR);
    BaseKeyName.MaximumLength = BaseKeyName.Length
        + GuidString.Length;
    BaseKeyName.Buffer = ExAllocatePool(
        PagedPool,
        BaseKeyName.MaximumLength);
    if (!BaseKeyName.Buffer)
    {
        DPRINT("ExAllocatePool() failed\n");
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    wcscpy(BaseKeyName.Buffer, BaseKeyString);
    RtlAppendUnicodeStringToString(&BaseKeyName, &GuidString);

    /* Create BaseKeyName key in registry */
    InitializeObjectAttributes(
        &ObjectAttributes,
        &BaseKeyName,
        OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE | OBJ_OPENIF,
        NULL, /* RootDirectory */
        NULL); /* SecurityDescriptor */

    Status = ZwCreateKey(
        &ClassKey,
        KEY_WRITE,
        &ObjectAttributes,
        0, /* TileIndex */
        NULL, /* Class */
        REG_OPTION_VOLATILE,
        NULL); /* Disposition */

    if (!NT_SUCCESS(Status))
    {
        DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
        ExFreePool(BaseKeyName.Buffer);
        return Status;
    }

    /* Create key name for this interface: ##?#ACPI#PNP0501#1#{GUID} */
    InterfaceKeyName.Length = 0;
    InterfaceKeyName.MaximumLength =
        4 * sizeof(WCHAR) + /* 4  = size of ##?# */
        InstancePath->Length +
        sizeof(WCHAR) +     /* 1  = size of # */
        GuidString.Length;
    InterfaceKeyName.Buffer = ExAllocatePool(
        PagedPool,
        InterfaceKeyName.MaximumLength);
    if (!InterfaceKeyName.Buffer)
    {
        DPRINT("ExAllocatePool() failed\n");
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    RtlAppendUnicodeToString(&InterfaceKeyName, L"##?#");
    StartIndex = InterfaceKeyName.Length / sizeof(WCHAR);
    RtlAppendUnicodeStringToString(&InterfaceKeyName, InstancePath);
    for (i = 0; i < InstancePath->Length / sizeof(WCHAR); i++)
    {
        if (InterfaceKeyName.Buffer[StartIndex + i] == '\\')
            InterfaceKeyName.Buffer[StartIndex + i] = '#';
    }
    RtlAppendUnicodeToString(&InterfaceKeyName, L"#");
    RtlAppendUnicodeStringToString(&InterfaceKeyName, &GuidString);

    /* Create the interface key in registry */
    InitializeObjectAttributes(
        &ObjectAttributes,
        &InterfaceKeyName,
        OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE | OBJ_OPENIF,
        ClassKey,
        NULL); /* SecurityDescriptor */

    Status = ZwCreateKey(
        &InterfaceKey,
        KEY_WRITE,
        &ObjectAttributes,
        0, /* TileIndex */
        NULL, /* Class */
        REG_OPTION_VOLATILE,
        NULL); /* Disposition */

    if (!NT_SUCCESS(Status))
    {
        DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
        ZwClose(ClassKey);
        ExFreePool(BaseKeyName.Buffer);
        return Status;
    }

    /* Write DeviceInstance entry. Value is InstancePath */
    Status = ZwSetValueKey(
        InterfaceKey,
        &DeviceInstance,
        0, /* TileIndex */
        REG_SZ,
        InstancePath->Buffer,
        InstancePath->Length);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status);
        ZwClose(InterfaceKey);
        ZwClose(ClassKey);
        ExFreePool(InterfaceKeyName.Buffer);
        ExFreePool(BaseKeyName.Buffer);
        return Status;
    }

    /* Create subkey. Name is #ReferenceString */
    SubKeyName.Length = 0;
    SubKeyName.MaximumLength = sizeof(WCHAR);
    if (ReferenceString && ReferenceString->Length)
        SubKeyName.MaximumLength += ReferenceString->Length;
    SubKeyName.Buffer = ExAllocatePool(
        PagedPool,
        SubKeyName.MaximumLength);
    if (!SubKeyName.Buffer)
    {
        DPRINT("ExAllocatePool() failed\n");
        ZwClose(InterfaceKey);
        ZwClose(ClassKey);
        ExFreePool(InterfaceKeyName.Buffer);
        ExFreePool(BaseKeyName.Buffer);
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    RtlAppendUnicodeToString(&SubKeyName, L"#");
    if (ReferenceString && ReferenceString->Length)
        RtlAppendUnicodeStringToString(&SubKeyName, ReferenceString);

    /* Create SubKeyName key in registry */
    InitializeObjectAttributes(
        &ObjectAttributes,
        &SubKeyName,
        OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
        InterfaceKey, /* RootDirectory */
        NULL); /* SecurityDescriptor */

    Status = ZwCreateKey(
        &SubKey,
        KEY_WRITE,
        &ObjectAttributes,
        0, /* TileIndex */
        NULL, /* Class */
        REG_OPTION_VOLATILE,
        NULL); /* Disposition */

    if (!NT_SUCCESS(Status))
    {
        DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
        ZwClose(InterfaceKey);
        ZwClose(ClassKey);
        ExFreePool(InterfaceKeyName.Buffer);
        ExFreePool(BaseKeyName.Buffer);
        return Status;
    }

    /* Create symbolic link name: \??\ACPI#PNP0501#1#{GUID}\ReferenceString */
    SymbolicLinkName->Length = 0;
    SymbolicLinkName->MaximumLength = SymbolicLinkName->Length
        + 4 * sizeof(WCHAR) /* 4 = size of \??\ */
        + InstancePath->Length
        + sizeof(WCHAR)     /* 1  = size of # */
        + GuidString.Length
        + sizeof(WCHAR);    /* final NULL */
    if (ReferenceString && ReferenceString->Length)
        SymbolicLinkName->MaximumLength += sizeof(WCHAR) + ReferenceString->Length;
    SymbolicLinkName->Buffer = ExAllocatePool(
        PagedPool,
        SymbolicLinkName->MaximumLength);
    if (!SymbolicLinkName->Buffer)
    {
        DPRINT("ExAllocatePool() failed\n");
        ZwClose(SubKey);
        ZwClose(InterfaceKey);
        ZwClose(ClassKey);
        ExFreePool(InterfaceKeyName.Buffer);
        ExFreePool(SubKeyName.Buffer);
        ExFreePool(BaseKeyName.Buffer);
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    RtlAppendUnicodeToString(SymbolicLinkName, L"\\??\\");
    StartIndex = SymbolicLinkName->Length / sizeof(WCHAR);
    RtlAppendUnicodeStringToString(SymbolicLinkName, InstancePath);
    for (i = 0; i < InstancePath->Length / sizeof(WCHAR); i++)
    {
        if (SymbolicLinkName->Buffer[StartIndex + i] == '\\')
            SymbolicLinkName->Buffer[StartIndex + i] = '#';
    }
    RtlAppendUnicodeToString(SymbolicLinkName, L"#");
    RtlAppendUnicodeStringToString(SymbolicLinkName, &GuidString);
    SymbolicLinkName->Buffer[SymbolicLinkName->Length/sizeof(WCHAR)] = L'\0';

    /* Create symbolic link */
    DPRINT("IoRegisterDeviceInterface(): creating symbolic link %wZ -> %wZ\n", SymbolicLinkName, &PdoNameInfo->Name);
    SymLinkStatus = IoCreateSymbolicLink(SymbolicLinkName, &PdoNameInfo->Name);

    /* If the symbolic link already exists, return an informational success status */
    if (SymLinkStatus == STATUS_OBJECT_NAME_COLLISION)
    {
        /* HACK: Delete the existing symbolic link and update it to the new PDO name */
        IoDeleteSymbolicLink(SymbolicLinkName);
        IoCreateSymbolicLink(SymbolicLinkName, &PdoNameInfo->Name);
        SymLinkStatus = STATUS_OBJECT_NAME_EXISTS;
    }

    if (!NT_SUCCESS(SymLinkStatus))
    {
        DPRINT1("IoCreateSymbolicLink() failed with status 0x%08lx\n", SymLinkStatus);
        ZwClose(SubKey);
        ZwClose(InterfaceKey);
        ZwClose(ClassKey);
        ExFreePool(SubKeyName.Buffer);
        ExFreePool(InterfaceKeyName.Buffer);
        ExFreePool(BaseKeyName.Buffer);
        ExFreePool(SymbolicLinkName->Buffer);
        return SymLinkStatus;
    }

    if (ReferenceString && ReferenceString->Length)
    {
        RtlAppendUnicodeToString(SymbolicLinkName, L"\\");
        RtlAppendUnicodeStringToString(SymbolicLinkName, ReferenceString);
    }
    SymbolicLinkName->Buffer[SymbolicLinkName->Length/sizeof(WCHAR)] = L'\0';

    /* Write symbolic link name in registry */
    SymbolicLinkName->Buffer[1] = '\\';
    Status = ZwSetValueKey(
        SubKey,
        &SymbolicLink,
        0, /* TileIndex */
        REG_SZ,
        SymbolicLinkName->Buffer,
        SymbolicLinkName->Length);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("ZwSetValueKey() failed with status 0x%08lx\n", Status);
        ExFreePool(SymbolicLinkName->Buffer);
    }
    else
    {
        SymbolicLinkName->Buffer[1] = '?';
    }

    ZwClose(SubKey);
    ZwClose(InterfaceKey);
    ZwClose(ClassKey);
    ExFreePool(SubKeyName.Buffer);
    ExFreePool(InterfaceKeyName.Buffer);
    ExFreePool(BaseKeyName.Buffer);

    return NT_SUCCESS(Status) ? SymLinkStatus : Status;
}
Exemplo n.º 20
0
NTSTATUS
GetRegistrySettings(
    _In_ PUNICODE_STRING RegistryPath
   )
/*++

Routine Description:

    Initialize Driver Framework settings from the driver
    specific registry settings under

    \REGISTRY\MACHINE\SYSTEM\ControlSetxxx\Services\<driver>\Parameters

Arguments:

    RegistryPath - Registry path passed to DriverEntry

Returns:

    NTSTATUS - SUCCESS if able to configure the framework

--*/

{
    NTSTATUS                    ntStatus;
    UNICODE_STRING              parametersPath;
    RTL_QUERY_REGISTRY_TABLE    paramTable[3];
    
    DPF(D_TERSE, ("[GetRegistrySettings]"));
    
    PAGED_CODE(); 

    RtlInitUnicodeString(&parametersPath, NULL);

    parametersPath.MaximumLength =
        RegistryPath->Length + sizeof(L"\\Parameters") + sizeof(WCHAR);

    parametersPath.Buffer = (PWCH) ExAllocatePoolWithTag(PagedPool, parametersPath.MaximumLength, MINADAPTER_POOLTAG);
    if (parametersPath.Buffer == NULL) 
    {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    RtlZeroMemory(parametersPath.Buffer, parametersPath.MaximumLength);

    RtlAppendUnicodeToString(&parametersPath, RegistryPath->Buffer);
    RtlAppendUnicodeToString(&parametersPath, L"\\Parameters");

    RtlZeroMemory(&paramTable[0], sizeof(paramTable));

    g_DoNotCreateDataFiles = 0; // default is off.
    
    paramTable[0].Flags         = RTL_QUERY_REGISTRY_DIRECT;
    paramTable[0].Name          = L"DoNotCreateDataFiles";
    paramTable[0].EntryContext  = &g_DoNotCreateDataFiles;
    paramTable[0].DefaultType   = REG_DWORD;
    paramTable[0].DefaultData   = &g_DoNotCreateDataFiles;
    paramTable[0].DefaultLength = sizeof(ULONG);
    
#ifdef SYSVAD_BTH_BYPASS
    g_DisableBthScoBypass = 0;  // default is off.
    
    paramTable[1].Flags         = RTL_QUERY_REGISTRY_DIRECT;
    paramTable[1].Name          = L"DisableBthScoBypass";
    paramTable[1].EntryContext  = &g_DisableBthScoBypass;
    paramTable[1].DefaultType   = REG_DWORD;
    paramTable[1].DefaultData   = &g_DisableBthScoBypass;
    paramTable[1].DefaultLength = sizeof(ULONG);
#endif // SYSVAD_BTH_BYPASS

    ntStatus = RtlQueryRegistryValues(
                 RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
                 parametersPath.Buffer,
                 &paramTable[0],
                 NULL,
                 NULL
                );

    if (!NT_SUCCESS(ntStatus)) 
    {
        DPF(D_VERBOSE, ("RtlQueryRegistryValues failed, using default values, 0x%x", ntStatus));
        //
        // Don't return error because we will operate with default values.
        //
    }

    //
    // Dump settings.
    //
    DPF(D_VERBOSE, ("DoNotCreateDataFiles: %u", g_DoNotCreateDataFiles));
#ifdef SYSVAD_BTH_BYPASS
    DPF(D_VERBOSE, ("DisableBthScoBypass: %u", g_DisableBthScoBypass));
#endif // SYSVAD_BTH_BYPASS
    
    //
    // Cleanup.
    //
    ExFreePool(parametersPath.Buffer);

    return STATUS_SUCCESS;
}
Exemplo n.º 21
0
Arquivo: init.c Projeto: GYGit/reactos
/*++
 * @name CsrSbApiPortInitialize
 *
 * The CsrSbApiPortInitialize routine initializes the LPC Port used for
 * communications with the Session Manager (SM) and initializes the static
 * thread that will handle connection requests and APIs.
 *
 * @param None
 *
 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL otherwise.
 *
 * @remarks None.
 *
 *--*/
NTSTATUS
NTAPI
CsrSbApiPortInitialize(VOID)
{
    ULONG Size;
    PSECURITY_DESCRIPTOR PortSd;
    OBJECT_ATTRIBUTES ObjectAttributes;
    NTSTATUS Status;
    HANDLE hRequestThread;
    CLIENT_ID ClientId;

    /* Calculate how much space we'll need for the Port Name */
    Size = CsrDirectoryName.Length + sizeof(SB_PORT_NAME) + sizeof(WCHAR);

    /* Create the buffer for it */
    CsrSbApiPortName.Buffer = RtlAllocateHeap(CsrHeap, 0, Size);
    if (!CsrSbApiPortName.Buffer) return STATUS_NO_MEMORY;

    /* Setup the rest of the empty string */
    CsrSbApiPortName.Length = 0;
    CsrSbApiPortName.MaximumLength = (USHORT)Size;

    /* Now append the full port name */
    RtlAppendUnicodeStringToString(&CsrSbApiPortName, &CsrDirectoryName);
    RtlAppendUnicodeToString(&CsrSbApiPortName, UNICODE_PATH_SEP);
    RtlAppendUnicodeToString(&CsrSbApiPortName, SB_PORT_NAME);
    if (CsrDebug & 2) DPRINT1("CSRSS: Creating %wZ port and associated thread\n", &CsrSbApiPortName);

    /* Create Security Descriptor for this Port */
    Status = CsrCreateLocalSystemSD(&PortSd);
    if (!NT_SUCCESS(Status)) return Status;

    /* Initialize the Attributes */
    InitializeObjectAttributes(&ObjectAttributes,
                               &CsrSbApiPortName,
                               0,
                               NULL,
                               PortSd);

    /* Create the Port Object */
    Status = NtCreatePort(&CsrSbApiPort,
                          &ObjectAttributes,
                          sizeof(SB_CONNECTION_INFO),
                          sizeof(SB_API_MSG),
                          32 * sizeof(SB_API_MSG));
    if (PortSd) RtlFreeHeap(CsrHeap, 0, PortSd);

    if (NT_SUCCESS(Status))
    {
        /* Create the Thread to handle the API Requests */
        Status = RtlCreateUserThread(NtCurrentProcess(),
                                     NULL,
                                     TRUE,
                                     0,
                                     0,
                                     0,
                                     (PVOID)CsrSbApiRequestThread,
                                     NULL,
                                     &hRequestThread,
                                     &ClientId);
        if (NT_SUCCESS(Status))
        {
            /* Add it as a Static Server Thread */
            CsrSbApiRequestThreadPtr = CsrAddStaticServerThread(hRequestThread,
                                                                &ClientId,
                                                                0);

            /* Activate it */
            Status = NtResumeThread(hRequestThread, NULL);
        }
    }

    return Status;
}
Exemplo n.º 22
0
NTSTATUS
NTAPI
IntCreateNewRegistryPath(
    PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension)
{
    static UNICODE_STRING VideoIdValueName = RTL_CONSTANT_STRING(L"VideoId");
    static UNICODE_STRING ControlVideoPathName =
        RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Video\\");
    HANDLE DevInstRegKey, SettingsKey, NewKey;
    UCHAR VideoIdBuffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + GUID_STRING_LENGTH];
    UNICODE_STRING VideoIdString;
    UUID VideoId;
    PKEY_VALUE_PARTIAL_INFORMATION ValueInformation ;
    NTSTATUS Status;
    ULONG ResultLength;
    USHORT KeyMaxLength;
    OBJECT_ATTRIBUTES ObjectAttributes;

    /* Open the hardware key: HKLM\System\CurrentControlSet\Enum\... */
    Status = IoOpenDeviceRegistryKey(DeviceExtension->PhysicalDeviceObject,
                                     PLUGPLAY_REGKEY_DEVICE,
                                     KEY_ALL_ACCESS,
                                     &DevInstRegKey);
    if (Status != STATUS_SUCCESS)
    {
        ERR_(VIDEOPRT, "IoOpenDeviceRegistryKey failed: status 0x%lx\n", Status);
        return Status;
    }

    /* Query the VideoId value */
    ValueInformation = (PKEY_VALUE_PARTIAL_INFORMATION)VideoIdBuffer;
    Status = ZwQueryValueKey(DevInstRegKey,
                             &VideoIdValueName,
                             KeyValuePartialInformation,
                             ValueInformation,
                             sizeof(VideoIdBuffer),
                             &ResultLength);
    if (!NT_SUCCESS(Status))
    {
        /* Create a new video Id */
        Status = ExUuidCreate(&VideoId);
        if (!NT_SUCCESS(Status))
        {
            ERR_(VIDEOPRT, "ExUuidCreate failed: status 0x%lx\n", Status);
            ObCloseHandle(DevInstRegKey, KernelMode);
            return Status;
        }

        /* Convert the GUID into a string */
        Status = RtlStringFromGUID(&VideoId, &VideoIdString);
        if (!NT_SUCCESS(Status))
        {
            ERR_(VIDEOPRT, "RtlStringFromGUID failed: status 0x%lx\n", Status);
            ObCloseHandle(DevInstRegKey, KernelMode);
            return Status;
        }

        /* Copy the GUID String to our buffer */
        ValueInformation->DataLength = min(VideoIdString.Length, GUID_STRING_LENGTH);
        RtlCopyMemory(ValueInformation->Data,
                      VideoIdString.Buffer,
                      ValueInformation->DataLength);

        /* Free the GUID string */
        RtlFreeUnicodeString(&VideoIdString);

        /* Write the VideoId registry value */
        Status = ZwSetValueKey(DevInstRegKey,
                               &VideoIdValueName,
                               0,
                               REG_SZ,
                               ValueInformation->Data,
                               ValueInformation->DataLength);
        if (!NT_SUCCESS(Status))
        {
            ERR_(VIDEOPRT, "ZwSetValueKey failed: status 0x%lx\n", Status);
            ObCloseHandle(DevInstRegKey, KernelMode);
            return Status;
        }
    }

    /* Initialize the VideoId string from the registry data */
    VideoIdString.Buffer = (PWCHAR)ValueInformation->Data;
    VideoIdString.Length = (USHORT)ValueInformation->DataLength;
    VideoIdString.MaximumLength = VideoIdString.Length;

    /* Close the hardware key */
    ObCloseHandle(DevInstRegKey, KernelMode);

    /* Calculate the size needed for the new registry path name */
    KeyMaxLength = ControlVideoPathName.Length +
                   VideoIdString.Length +
                   sizeof(L"\\0000");

    /* Allocate the path name buffer */
    DeviceExtension->NewRegistryPath.Length = 0;
    DeviceExtension->NewRegistryPath.MaximumLength = KeyMaxLength;
    DeviceExtension->NewRegistryPath.Buffer = ExAllocatePoolWithTag(PagedPool,
                                                                    KeyMaxLength,
                                                                    TAG_VIDEO_PORT);
    if (DeviceExtension->NewRegistryPath.Buffer == NULL)
    {
        ERR_(VIDEOPRT, "Failed to allocate key name buffer.\n");
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    /* Copy the root key name and append the VideoId string */
    RtlCopyUnicodeString(&DeviceExtension->NewRegistryPath,
                         &ControlVideoPathName);
    RtlAppendUnicodeStringToString(&DeviceExtension->NewRegistryPath,
                                   &VideoIdString);

    /* Check if we have the key already */
    Status = RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE,
                                 DeviceExtension->NewRegistryPath.Buffer);
    if (Status != STATUS_SUCCESS)
    {
        /* Try to create the new key */
        Status = RtlCreateRegistryKey(RTL_REGISTRY_ABSOLUTE,
                                      DeviceExtension->NewRegistryPath.Buffer);
    }

    /* Append a the instance path */ /// \todo HACK
    RtlAppendUnicodeToString(&DeviceExtension->NewRegistryPath, L"\\");
    RtlAppendUnicodeToString(&DeviceExtension->NewRegistryPath, L"0000");

    /* Check this key again */
    Status = RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE,
                                 DeviceExtension->NewRegistryPath.Buffer);
    if (Status != STATUS_SUCCESS)
    {
        /* Try to create the new key */
        Status = RtlCreateRegistryKey(RTL_REGISTRY_ABSOLUTE,
                                      DeviceExtension->NewRegistryPath.Buffer);
        if (!NT_SUCCESS(Status))
        {
            ERR_(VIDEOPRT, "Failed create key '%wZ'\n", &DeviceExtension->NewRegistryPath);
            return Status;
        }

        /* Open the new key */
        InitializeObjectAttributes(&ObjectAttributes,
                                   &DeviceExtension->NewRegistryPath,
                                   OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
                                   NULL,
                                   NULL);
        Status = ZwOpenKey(&NewKey, KEY_READ, &ObjectAttributes);
        if (!NT_SUCCESS(Status))
        {
            ERR_(VIDEOPRT, "Failed to open settings key. Status 0x%lx\n", Status);
            return Status;
        }

        /* Open the device profile key */
        InitializeObjectAttributes(&ObjectAttributes,
                                   &DeviceExtension->RegistryPath,
                                   OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
                                   NULL,
                                   NULL);
        Status = ZwOpenKey(&SettingsKey, KEY_READ, &ObjectAttributes);
        if (!NT_SUCCESS(Status))
        {
            ERR_(VIDEOPRT, "Failed to open settings key. Status 0x%lx\n", Status);
            ObCloseHandle(NewKey, KernelMode);
            return Status;
        }

        /* Copy the registry data from the legacy key */
        Status = IntCopyRegistryKey(SettingsKey, NewKey);
    }


    return Status;
}
Exemplo n.º 23
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;

	HANDLE Ultimap2Handle;

	
	KernelCodeStepping=0;
	KernelWritesIgnoreWP = 0;

	

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



	//InitializeObjectAttributes(&ao, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
	//PsCreateSystemThread(&Ultimap2Handle, 0, NULL, 0, NULL, TestThread, PsGetCurrentProcess());

	DbgPrint("DBK loading...");
#ifdef TOBESIGNED
	DbgPrint("Signed version");
#endif

	
	//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);
		DbgPrint("cpuid.0: r[1]=%x", r[1]);
		if (r[1]==0x756e6547) //GenuineIntel
		{

			__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);

			if ((r[2]<<9) & 1)
			{
				DbgPrint("Intel cpu. IA32_FEATURE_CONTROL MSR=%x", readMSR(0x3a));		
			}
			else
			{
				DbgPrint("Intel cpu without IA32_FEATURE_CONTROL MSR");		
			}

			vmx_init_dovmcall(1);
			setup_APIC_BASE(); //for ultimap

		}
		else
		{
Exemplo n.º 24
0
NTSTATUS
NTAPI
IntCreateRegistryPath(
    IN PCUNICODE_STRING DriverRegistryPath,
    OUT PUNICODE_STRING DeviceRegistryPath)
{
    static WCHAR RegistryMachineSystem[] = L"\\REGISTRY\\MACHINE\\SYSTEM\\";
    static WCHAR CurrentControlSet[] = L"CURRENTCONTROLSET\\";
    static WCHAR ControlSet[] = L"CONTROLSET";
    static WCHAR Insert1[] = L"Hardware Profiles\\Current\\System\\CurrentControlSet\\";
    static WCHAR Insert2[] = L"\\Device0";
    BOOLEAN Valid;
    UNICODE_STRING AfterControlSet;

    AfterControlSet = *DriverRegistryPath;

    /* Check if path begins with \\REGISTRY\\MACHINE\\SYSTEM\\ */
    Valid = (DriverRegistryPath->Length > sizeof(RegistryMachineSystem) &&
             0 == _wcsnicmp(DriverRegistryPath->Buffer, RegistryMachineSystem,
                            wcslen(RegistryMachineSystem)));
    if (Valid)
    {
        AfterControlSet.Buffer += wcslen(RegistryMachineSystem);
        AfterControlSet.Length -= sizeof(RegistryMachineSystem) - sizeof(UNICODE_NULL);

        /* Check if path contains CURRENTCONTROLSET */
        if (AfterControlSet.Length > sizeof(CurrentControlSet) &&
            0 == _wcsnicmp(AfterControlSet.Buffer, CurrentControlSet, wcslen(CurrentControlSet)))
        {
            AfterControlSet.Buffer += wcslen(CurrentControlSet);
            AfterControlSet.Length -= sizeof(CurrentControlSet) - sizeof(UNICODE_NULL);
        }
        /* Check if path contains CONTROLSETnum */
        else if (AfterControlSet.Length > sizeof(ControlSet) &&
                 0 == _wcsnicmp(AfterControlSet.Buffer, ControlSet, wcslen(ControlSet)))
        {
            AfterControlSet.Buffer += wcslen(ControlSet);
            AfterControlSet.Length -= sizeof(ControlSet) - sizeof(UNICODE_NULL);
            while (AfterControlSet.Length > 0 &&
                    *AfterControlSet.Buffer >= L'0' &&
                    *AfterControlSet.Buffer <= L'9')
            {
                AfterControlSet.Buffer++;
                AfterControlSet.Length -= sizeof(WCHAR);
            }

            Valid = (AfterControlSet.Length > 0 && L'\\' == *AfterControlSet.Buffer);
            AfterControlSet.Buffer++;
            AfterControlSet.Length -= sizeof(WCHAR);
            AfterControlSet.MaximumLength = AfterControlSet.Length;
        }
        else
        {
            Valid = FALSE;
        }
    }

    if (Valid)
    {
        DeviceRegistryPath->MaximumLength = DriverRegistryPath->Length + sizeof(Insert1) + sizeof(Insert2);
        DeviceRegistryPath->Buffer = ExAllocatePoolWithTag(PagedPool,
                                                           DeviceRegistryPath->MaximumLength,
                                                           TAG_VIDEO_PORT);
        if (DeviceRegistryPath->Buffer != NULL)
        {
            /* Build device path */
            wcsncpy(DeviceRegistryPath->Buffer,
                    DriverRegistryPath->Buffer,
                    AfterControlSet.Buffer - DriverRegistryPath->Buffer);
            DeviceRegistryPath->Length = (AfterControlSet.Buffer - DriverRegistryPath->Buffer) * sizeof(WCHAR);
            RtlAppendUnicodeToString(DeviceRegistryPath, Insert1);
            RtlAppendUnicodeStringToString(DeviceRegistryPath, &AfterControlSet);
            RtlAppendUnicodeToString(DeviceRegistryPath, Insert2);

            /* Check if registry key exists */
            Valid = NT_SUCCESS(RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, DeviceRegistryPath->Buffer));

            if (!Valid)
                ExFreePoolWithTag(DeviceRegistryPath->Buffer, TAG_VIDEO_PORT);
        }
        else
        {
            Valid = FALSE;
        }
    }
    else
    {
        WARN_(VIDEOPRT, "Unparsable registry path %wZ", DriverRegistryPath);
    }

    /* If path doesn't point to *ControlSet*, use DriverRegistryPath directly */
    if (!Valid)
    {
        DeviceRegistryPath->MaximumLength = DriverRegistryPath->Length + sizeof(Insert2);
        DeviceRegistryPath->Buffer = ExAllocatePoolWithTag(NonPagedPool,
                                                           DeviceRegistryPath->MaximumLength,
                                                           TAG_VIDEO_PORT);

        if (!DeviceRegistryPath->Buffer)
            return STATUS_NO_MEMORY;

        RtlCopyUnicodeString(DeviceRegistryPath, DriverRegistryPath);
        RtlAppendUnicodeToString(DeviceRegistryPath, Insert2);
    }

    DbgPrint("Formatted registry key '%wZ' -> '%wZ'\n",
             DriverRegistryPath, DeviceRegistryPath);

    return STATUS_SUCCESS;
}
Exemplo n.º 25
0
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Description :
//		Registry callback. Logs any registry interaction performed by monitored processes.
//	Parameters :
//		See http://msdn.microsoft.com/en-us/library/windows/hardware/ff560903(v=vs.85).aspx
//	Return value :
//		See http://msdn.microsoft.com/en-us/library/windows/hardware/ff560903(v=vs.85).aspx
//	Process :
//		Checks the operation and logs the associated data.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
NTSTATUS regCallback (PVOID CallbackContext, PVOID Argument1, PVOID Argument2)
{
	NTSTATUS status, tmpCall;
	UNICODE_STRING full_data, test;
	PUNICODE_STRING tmp = NULL;
	PUNICODE_STRING valueName = NULL;
	PREG_SET_VALUE_KEY_INFORMATION arg = NULL;
	ULONG returnedLength = 0;
	PWCHAR pwBuf = NULL;
	PWCHAR tmp_data = NULL;
	ULONG pid = (ULONG)PsGetCurrentProcessId();
	DWORD i = 0;
	
	if(!isProcessMonitoredByPid(pid) || ExGetPreviousMode() == KernelMode)
		return STATUS_SUCCESS;
	
	pwBuf = ExAllocatePoolWithTag(NonPagedPool, (MAXSIZE+1)*sizeof(WCHAR), BUFFER_TAG);
	if(pwBuf == NULL)
		return STATUS_SUCCESS;
	
	tmp = ExAllocatePoolWithTag(NonPagedPool, MAXSIZE*sizeof(WCHAR), TEMP_TAG);
	if(tmp == NULL)
	{
		ExFreePool(tmp);
		return STATUS_SUCCESS;
	}
	
	switch((REG_NOTIFY_CLASS)Argument1)
	{	
		case RegNtPreDeleteKey:
			status = ObQueryNameString(((PREG_DELETE_KEY_INFORMATION)Argument2)->Object, (POBJECT_NAME_INFORMATION)tmp, MAXSIZE, &returnedLength);
			if(NT_SUCCESS(status))
			{
				#ifdef DEBUG
				DbgPrint("call DeleteKey() \n");
				#endif
				
				if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,s,SubKey->%wZ", tmp)))
					sendLogs(pid, L"REGISTRY_DELETE_KEY", pwBuf);
				else
					sendLogs(pid, L"REGISTRY_DELETE_KEY", L"1,0,s,SubKey->ERROR");
			}
			else
				sendLogs(pid, L"REGISTRY_DELETE_KEY", L"0,-1,s,SubKey->ERROR");
		break;
		
		case RegNtPreSetValueKey: 
			arg = (PREG_SET_VALUE_KEY_INFORMATION)Argument2; 
			status = ObQueryNameString(arg->Object, (POBJECT_NAME_INFORMATION)tmp, MAXSIZE, &returnedLength);
			if(NT_SUCCESS(status))
			{
				#ifdef DEBUG
				DbgPrint("call SetValueKey() \n");
				#endif
				
				switch(arg->Type)
				{
					case REG_SZ:
						tmpCall = RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,sss,SubKey->%wZ,ValueName->%wZ,Data->%ws", tmp, arg->ValueName, ((PWCHAR)arg->Data));
					break;
					default :					
						tmp_data = ExAllocatePoolWithTag(NonPagedPool, MAXSIZE, 'gnaA');
						full_data.MaximumLength = MAXSIZE;
						full_data.Buffer = ExAllocatePoolWithTag(NonPagedPool, full_data.MaximumLength, 'baaH');
						RtlZeroMemory(full_data.Buffer, full_data.MaximumLength);
						for(i=0; i<arg->DataSize; i++)
						{
							if(i==100)
								break;
							RtlStringCchPrintfW(tmp_data, MAXSIZE, L"\\x%02x", *((PWCHAR)arg->Data+i));
							if(i==0)
							{
								RtlInitUnicodeString(&test, tmp_data);
								RtlCopyUnicodeString(&full_data, &test);
							}
							if(NT_SUCCESS(RtlAppendUnicodeToString(&full_data, tmp_data)))
								RtlZeroMemory(tmp_data, MAXSIZE);
						}
						tmpCall = RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,sss,SubKey->%wZ,ValueName->%wZ,Data->%wZ", tmp, arg->ValueName, &full_data);
						ExFreePool(full_data.Buffer);
						ExFreePool(tmp_data);
					break;	
				}
				if(NT_SUCCESS(tmpCall))
					sendLogs(pid, L"REGISTRY_VALUE_KEY_SET", pwBuf);
				else
					sendLogs(pid, L"REGISTRY_VALUE_KEY_SET", L"1,0,sss,SubKey->ERROR,ValueName->ERROR,Data->ERROR");
			}
			else
				sendLogs(pid, L"REGISTRY_VALUE_KEY_SET", L"1,0,sss,SubKey->ERROR,ValueName->ERROR,Data->ERROR");
		break;
		
		case RegNtPreDeleteValueKey:
			status = ObQueryNameString(((PREG_DELETE_VALUE_KEY_INFORMATION)Argument2)->Object, (POBJECT_NAME_INFORMATION)tmp, MAXSIZE, &returnedLength);
			if(NT_SUCCESS(status))
			{
				#ifdef DEBUG
				DbgPrint("call DeleteValueKey() !\n");
				#endif
				if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,ss,SubKey->%wZ,ValueName->%wZ", tmp, ((PREG_DELETE_VALUE_KEY_INFORMATION)Argument2)->ValueName)))
					sendLogs(pid, L"REGISTRY_VALUE_KEY_DELETE", pwBuf);
				else
					sendLogs(pid, L"REGISTRY_VALUE_KEY_DELETE", L"1,0,ss,SubKey->ERROR,ValueName->ERROR");
			}
			else
				sendLogs(pid, L"REGISTRY_VALUE_KEY_DELETE", L"1,0,ss,SubKey->ERROR,ValueName->ERROR");
		break;

		case RegNtPreRenameKey:
			status = ObQueryNameString(((PREG_RENAME_KEY_INFORMATION)Argument2)->Object, (POBJECT_NAME_INFORMATION)tmp, MAXSIZE, &returnedLength);
			if(NT_SUCCESS(status))
			{
				#ifdef DEBUG
				DbgPrint("call RenameKey() !\n");
				#endif
				
				if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,ss,SubKey->%wZ,NewName->%wZ", tmp, ((PREG_RENAME_KEY_INFORMATION)Argument2)->NewName)))
					sendLogs(pid, L"REGISTRY_KEY_RENAME", pwBuf);
				else
					sendLogs(pid, L"REGISTRY_KEY_RENAME", L"1,0,ss,SubKey->ERROR,NewName->ERROR");
			}
			else
				sendLogs(pid, L"REGISTRY_KEY_RENAME", L"1,0,ss,SubKey->ERROR,NewName->ERROR");
		break;
		
		case RegNtPreEnumerateKey:
			status = ObQueryNameString(((PREG_ENUMERATE_KEY_INFORMATION)Argument2)->Object, (POBJECT_NAME_INFORMATION)tmp, MAXSIZE, &returnedLength);
			if(NT_SUCCESS(status))
			{
				#ifdef DEBUG
				DbgPrint("call EnumerateKey() !\n");
				#endif
				
				if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,s,SubKey->%wZ", tmp)))
					sendLogs(pid, L"REGISTRY_ENUMERATE_KEY", pwBuf);
				else
					sendLogs(pid, L"REGISTRY_ENUMERATE_KEY", L"1,0,s,SubKey->ERROR");
			}
			else
				sendLogs(pid, L"REGISTRY_ENUMERATE_KEY", L"1,0,s,SubKey->ERROR");
		break;
		
		case RegNtPreEnumerateValueKey:
			status = ObQueryNameString(((PREG_ENUMERATE_VALUE_KEY_INFORMATION)Argument2)->Object, (POBJECT_NAME_INFORMATION)tmp, MAXSIZE, &returnedLength);
			if(NT_SUCCESS(status))
			{
				#ifdef DEBUG
				DbgPrint("call EnumerateValueKey() !\n");
				#endif
				
				if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,s,SubKey->%wZ", tmp)))
					sendLogs(pid, L"REGISTRY_ENUMERATE_VALUE_KEY", pwBuf);
				else
					sendLogs(pid, L"REGISTRY_ENUMERATE_VALUE_KEY", L"1,0,s,SubKey->ERROR");
			}
			else
				sendLogs(pid, L"REGISTRY_ENUMERATE_VALUE_KEY", L"1,0,s,SubKey->ERROR");
		break;
		
		case RegNtPreQueryKey:
			status = ObQueryNameString(((PREG_QUERY_KEY_INFORMATION)Argument2)->Object, (POBJECT_NAME_INFORMATION)tmp, MAXSIZE, &returnedLength);
			if(NT_SUCCESS(status))
			{
				#ifdef DEBUG
				DbgPrint("call QueryKey()! \n");
				#endif
				if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,s,SubKey->%wZ", tmp)))
					sendLogs(pid, L"REGISTRY_QUERY_KEY", pwBuf);
				else
					sendLogs(pid, L"REGISTRY_QUERY_KEY", L"1,0,s,SubKey->ERROR");
			}
			else
				sendLogs(pid, L"REGISTRY_QUERY_KEY", L"1,0,s,SubKey->ERROR");
		break;
		
		case RegNtPreQueryValueKey:
			status = ObQueryNameString(((PREG_QUERY_VALUE_KEY_INFORMATION)Argument2)->Object, (POBJECT_NAME_INFORMATION)tmp, MAXSIZE, &returnedLength);
			if(NT_SUCCESS(status))
			{
				#ifdef DEBUG
				DbgPrint("call QueryValueKey() !\n");
				#endif
				
				if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,ss,SubKey->%wZ,ValueName->%wZ", tmp, ((PREG_QUERY_VALUE_KEY_INFORMATION)Argument2)->ValueName)))
					sendLogs(pid, L"REGISTRY_QUERY_VALUE_KEY", pwBuf);	
				else
					sendLogs(pid, L"REGISTRY_QUERY_VALUE_KEY", L"1,0,ss,SubKey->ERROR,ValueName->ERROR");
			}
			else
				sendLogs(pid, L"REGISTRY_QUERY_VALUE_KEY", L"1,0,ss,SubKey->ERROR,ValueName->ERROR");
		break;
		
		case RegNtPreCreateKey:
			#ifdef DEBUG
			DbgPrint("call CreateKey() !\n");
			#endif
			if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,s,SubKey->%wZ", ((PREG_PRE_CREATE_KEY_INFORMATION)Argument2)->CompleteName)))
				sendLogs(pid,L"REGISTRY_CREATE_KEY", pwBuf);
			else
				sendLogs(pid, L"REGISTRY_CREATE_KEY", L"1,0,s,SubKey->ERROR");
		break;
		
		case RegNtPreCreateKeyEx:
			#ifdef DEBUG
			DbgPrint("call CreateKeyEx() !\n");
			#endif
			if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,s,SubKey->%wZ", ((PREG_PRE_CREATE_KEY_INFORMATION)Argument2)->CompleteName)))
				sendLogs(pid,L"REGISTRY_CREATE_KEY", pwBuf);
			else
				sendLogs(pid, L"REGISTRY_CREATE_KEY", L"1,0,s,SubKey->ERROR");
		break;
		
		case RegNtPreOpenKey:
			#ifdef DEBUG
			DbgPrint("call OpenKey() !\n");
			#endif
			
			if(((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName->Buffer != NULL)
			{
				if(!_wcsicmp(((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName->Buffer, L"SOFTWARE\\Oracle\\VirtualBox Guest Additions") || !_wcsicmp(((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName->Buffer, L"SOFTWARE\\VMware, Inc.\\VMware Tools"))
				{
					if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"0,0,s,SubKey->%wZ", ((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName)))
						sendLogs(pid,L"REGISTRY_OPEN_KEY", pwBuf);
					return STATUS_OBJECT_NAME_NOT_FOUND;
				}
				if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,s,SubKey->%wZ", ((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName)))
					sendLogs(pid,L"REGISTRY_OPEN_KEY", pwBuf);
				else
					sendLogs(pid, L"REGISTRY_OPEN_KEY", L"1,0,s,SubKey->ERROR");	
			}
			else
				sendLogs(pid, L"REGISTRY_OPEN_KEY", L"1,0,s,SubKey->ERROR");
		break;
		
		case RegNtPreOpenKeyEx:
			#ifdef DEBUG
			DbgPrint("call OpenKeyEx() !\n");
			#endif
			
			if(((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName->Buffer != NULL)
			{
				if(!_wcsicmp(((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName->Buffer, L"SOFTWARE\\Oracle\\VirtualBox Guest Additions") || !_wcsicmp(((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName->Buffer, L"SOFTWARE\\VMware, Inc.\\VMware Tools"))
				{
					if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"0,0,s,SubKey->%wZ", ((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName)))
						sendLogs(pid,L"REGISTRY_OPEN_KEY", pwBuf);
					return STATUS_OBJECT_NAME_NOT_FOUND;
				}
				if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,s,SubKey->%wZ", ((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName)))
					sendLogs(pid,L"REGISTRY_OPEN_KEY", pwBuf);
				else
					sendLogs(pid, L"REGISTRY_OPEN_KEY", L"1,0,s,SubKey->ERROR");	
			}
			else
				sendLogs(pid, L"REGISTRY_OPEN_KEY", L"1,0,s,SubKey->ERROR");
		break;

		default:
		break;
	}
	
	ExFreePool(tmp);
	ExFreePool(pwBuf);
		
	return STATUS_SUCCESS;
 }
Exemplo n.º 26
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("I'm alive!\n");

	//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,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);



	}

	{
		APIC y;
		
		DebugStackState x;
		DbgPrint("offset of LBR_Count=%d\n", (UINT_PTR)&x.LBR_Count-(UINT_PTR)&x);

		DbgPrint("Testing forEachCpu(...)\n");
		forEachCpu(TestDPC, NULL, NULL, NULL);

		forEachCpuPassive(TestPassive, 0);

		DbgPrint("LVT_Performance_Monitor=%x\n", (UINT_PTR)&y.LVT_Performance_Monitor-(UINT_PTR)&y);
	}
	
    return STATUS_SUCCESS;
}
Exemplo n.º 27
0
BOOLEAN
WinLdrAddDriverToList(LIST_ENTRY *BootDriverListHead,
                      LPWSTR RegistryPath,
                      LPWSTR ImagePath,
                      LPWSTR ServiceName)
{
	PBOOT_DRIVER_LIST_ENTRY BootDriverEntry;
	NTSTATUS Status;
	USHORT PathLength;

	BootDriverEntry = MmHeapAlloc(sizeof(BOOT_DRIVER_LIST_ENTRY));

	if (!BootDriverEntry)
		return FALSE;

	// DTE will be filled during actual load of the driver
	BootDriverEntry->LdrEntry = NULL;

	// Check - if we have a valid ImagePath, if not - we need to build it
	// like "System32\\Drivers\\blah.sys"
	if (ImagePath && (wcslen(ImagePath) > 0))
	{
		// Just copy ImagePath to the corresponding field in the structure
		PathLength = wcslen(ImagePath) * sizeof(WCHAR) + sizeof(UNICODE_NULL);

		BootDriverEntry->FilePath.Length = 0;
		BootDriverEntry->FilePath.MaximumLength = PathLength;
		BootDriverEntry->FilePath.Buffer = MmHeapAlloc(PathLength);

		if (!BootDriverEntry->FilePath.Buffer)
		{
			MmHeapFree(BootDriverEntry);
			return FALSE;
		}

		Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, ImagePath);
		if (!NT_SUCCESS(Status))
		{
			MmHeapFree(BootDriverEntry->FilePath.Buffer);
			MmHeapFree(BootDriverEntry);
			return FALSE;
		}
	}
	else
	{
		// we have to construct ImagePath ourselves
		PathLength = wcslen(ServiceName)*sizeof(WCHAR) + sizeof(L"system32\\drivers\\.sys");
		BootDriverEntry->FilePath.Length = 0;
		BootDriverEntry->FilePath.MaximumLength = PathLength;
		BootDriverEntry->FilePath.Buffer = MmHeapAlloc(PathLength);

		if (!BootDriverEntry->FilePath.Buffer)
		{
			MmHeapFree(BootDriverEntry);
			return FALSE;
		}

		Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, L"system32\\drivers\\");
		if (!NT_SUCCESS(Status))
		{
			MmHeapFree(BootDriverEntry->FilePath.Buffer);
			MmHeapFree(BootDriverEntry);
			return FALSE;
		}

		Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, ServiceName);
		if (!NT_SUCCESS(Status))
		{
			MmHeapFree(BootDriverEntry->FilePath.Buffer);
			MmHeapFree(BootDriverEntry);
			return FALSE;
		}

		Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, L".sys");
		if (!NT_SUCCESS(Status))
		{
			MmHeapFree(BootDriverEntry->FilePath.Buffer);
			MmHeapFree(BootDriverEntry);
			return FALSE;
		}
	}

	// Add registry path
	PathLength = (wcslen(RegistryPath) + wcslen(ServiceName))*sizeof(WCHAR) + sizeof(UNICODE_NULL);
	BootDriverEntry->RegistryPath.Length = 0;
	BootDriverEntry->RegistryPath.MaximumLength = PathLength;
	BootDriverEntry->RegistryPath.Buffer = MmHeapAlloc(PathLength);
	if (!BootDriverEntry->RegistryPath.Buffer)
		return FALSE;

	Status = RtlAppendUnicodeToString(&BootDriverEntry->RegistryPath, RegistryPath);
	if (!NT_SUCCESS(Status))
		return FALSE;

	Status = RtlAppendUnicodeToString(&BootDriverEntry->RegistryPath, ServiceName);
	if (!NT_SUCCESS(Status))
		return FALSE;

	// Insert entry at top of the list
	InsertTailList(BootDriverListHead, &BootDriverEntry->Link);

	return TRUE;
}
Exemplo n.º 28
0
NTSTATUS
CsrpConnectToServer(
    IN PWSTR ObjectDirectory
    )
{
    NTSTATUS Status;
    REMOTE_PORT_VIEW ServerView;
    ULONG MaxMessageLength;
    ULONG ConnectionInformationLength;
    CSR_API_CONNECTINFO ConnectionInformation;
    SECURITY_QUALITY_OF_SERVICE DynamicQos;
    HANDLE PortSection;
    PORT_VIEW ClientView;
    ULONG n;
    LARGE_INTEGER SectionSize;

    //
    // Create the port name string by combining the passed in object directory
    // name with the port name.
    //

    n = ((wcslen( ObjectDirectory ) + 1) * sizeof( WCHAR )) +
        sizeof( CSR_API_PORT_NAME );
    CsrPortName.Length = 0;
    CsrPortName.MaximumLength = (USHORT)n;
    CsrPortName.Buffer = RtlAllocateHeap( CsrHeap, MAKE_TAG( CSR_TAG ), n );
    if (CsrPortName.Buffer == NULL) {
        return( STATUS_NO_MEMORY );
        }
    RtlAppendUnicodeToString( &CsrPortName, ObjectDirectory );
    RtlAppendUnicodeToString( &CsrPortName, L"\\" );
    RtlAppendUnicodeToString( &CsrPortName, CSR_API_PORT_NAME );

    //
    // Set up the security quality of service parameters to use over the
    // port.  Use the most efficient (least overhead) - which is dynamic
    // rather than static tracking.
    //

    DynamicQos.ImpersonationLevel = SecurityImpersonation;
    DynamicQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
    DynamicQos.EffectiveOnly = TRUE;


    //
    // Create a section to contain the Port Memory.  Port Memory is private
    // memory that is shared between the client and server processes.
    // This allows data that is too large to fit into an API request message
    // to be passed to the server.
    //

    SectionSize.LowPart = CSR_PORT_MEMORY_SIZE;
    SectionSize.HighPart = 0;

    Status = NtCreateSection( &PortSection,
                              SECTION_ALL_ACCESS,
                              NULL,
                              &SectionSize,
                              PAGE_READWRITE,
                              SEC_RESERVE,
                              NULL
                            );
    if (!NT_SUCCESS( Status )) {
        return( Status );
        }

    //
    // Connect to the server.  This includes a description of the Port Memory
    // section so that the LPC connection logic can make the section visible
    // to both the client and server processes.  Also pass information the
    // server needs in the connection information structure.
    //

    ClientView.Length = sizeof( ClientView );
    ClientView.SectionHandle = PortSection;
    ClientView.SectionOffset = 0;
    ClientView.ViewSize = SectionSize.LowPart;
    ClientView.ViewBase = 0;
    ClientView.ViewRemoteBase = 0;

    ServerView.Length = sizeof( ServerView );
    ServerView.ViewSize = 0;
    ServerView.ViewBase = 0;

    ConnectionInformationLength = sizeof( ConnectionInformation );
    ConnectionInformation.ExpectedVersion = CSR_VERSION;

    Status = NtConnectPort( &CsrPortHandle,
                            &CsrPortName,
                            &DynamicQos,
                            &ClientView,
                            &ServerView,
                            (PULONG)&MaxMessageLength,
                            (PVOID)&ConnectionInformation,
                            (PULONG)&ConnectionInformationLength
                          );
    NtClose( PortSection );
    if (!NT_SUCCESS( Status )) {
        IF_DEBUG {
            DbgPrint( "CSRDLL: Unable to connect to %wZ Server - Status == %X\n",
                      &CsrPortName,
                      Status
                    );
            }

        return( Status );
        }
Exemplo n.º 29
0
BOOLEAN LogMessage(PCHAR szFormat, ...)
{
	ULONG Length;
	char messagebuf[256];
	va_list va;
    IO_STATUS_BLOCK  IoStatus;
	OBJECT_ATTRIBUTES objectAttributes;
	NTSTATUS status;
	HANDLE FileHandle;
    UNICODE_STRING fileName;


	//format the string
    va_start(va,szFormat);
	vsprintf(messagebuf,szFormat,va);
	va_end(va);

	//get a handle to the log file object
    fileName.Buffer = NULL;
    fileName.Length = 0;
    fileName.MaximumLength = sizeof(DEFAULT_LOG_FILE_NAME) + sizeof(UNICODE_NULL);
    fileName.Buffer = ExAllocatePool(PagedPool,
                                        fileName.MaximumLength);
    if (!fileName.Buffer)
    {
        return FALSE;
    }
    RtlZeroMemory(fileName.Buffer, fileName.MaximumLength);
    status = RtlAppendUnicodeToString(&fileName, (PWSTR)DEFAULT_LOG_FILE_NAME);

	//DbgPrint("\n Initializing Object attributes");

	InitializeObjectAttributes (&objectAttributes,
								(PUNICODE_STRING)&fileName,
								OBJ_CASE_INSENSITIVE,
								NULL,
								NULL );

	DbgPrint("\n BusLogic - Creating the file");

	status = ZwCreateFile(&FileHandle,
					  FILE_APPEND_DATA | SYNCHRONIZE,
					  &objectAttributes,
					  &IoStatus,
					  0,
					  FILE_ATTRIBUTE_NORMAL,
					  FILE_SHARE_WRITE,
					  FILE_OPEN_IF,
					  FILE_SYNCHRONOUS_IO_NONALERT,
					  NULL,
					  0 );

	if(NT_SUCCESS(status))
	{
		CHAR buf[300];
		LARGE_INTEGER time;
		KeQuerySystemTime(&time);

		DbgPrint("\n BusLogic - Created the file");

		//put a time stamp on the output message
		sprintf(buf,"%10u-%10u  %s",time.HighPart,time.LowPart,messagebuf);

		//format the string to make sure it appends a newline carrage-return to the
		//end of the string.
		Length=strlen(buf);
		if(buf[Length-1]=='\n')
		{
			buf[Length-1]='\r';
			strcat(buf,"\n");
			Length++;
		}
		else
		{
			strcat(buf,"\r\n");
			Length+=2;
		}

		buf[Length+1] = '\0';
		DbgPrint("\n BusLogic - Writing to the file");
		DbgPrint("\n BusLogic - Buf = %s", buf);

		status = ZwWriteFile(FileHandle,
				  NULL,
				  NULL,
				  NULL,
				  &IoStatus,
				  buf,
				  Length,
				  NULL,
				  NULL );

		ZwClose(FileHandle);
	}
	if (fileName.Buffer)
        ExFreePool (fileName.Buffer);

	return STATUS_SUCCESS;
}
Exemplo n.º 30
0
BOOLEAN
AddKbLayoutsToRegistry(
    IN const MUI_LAYOUTS *MuiLayouts)
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    UNICODE_STRING KeyName;
    UNICODE_STRING ValueName;
    HANDLE KeyHandle;
    HANDLE SubKeyHandle;
    NTSTATUS Status;
    ULONG Disposition;
    ULONG uIndex = 0;
    ULONG uCount = 0;
    WCHAR szKeyName[48] = L".DEFAULT\\Keyboard Layout";
    WCHAR szValueName[3 + 1];
    WCHAR szLangID[8 + 1];

    // Open the keyboard layout key
    RtlInitUnicodeString(&KeyName, szKeyName);
    InitializeObjectAttributes(&ObjectAttributes,
                               &KeyName,
                               OBJ_CASE_INSENSITIVE,
                               GetRootKeyByPredefKey(HKEY_USERS, NULL),
                               NULL);

    Status =  NtCreateKey(&KeyHandle,
                          KEY_CREATE_SUB_KEY,
                          &ObjectAttributes,
                          0,
                          NULL,
                          REG_OPTION_NON_VOLATILE,
                          &Disposition);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtCreateKey() failed (Status %lx)\n", Status);
        return FALSE;
    }

    NtClose(KeyHandle);

    KeyName.MaximumLength = sizeof(szKeyName);
    Status = RtlAppendUnicodeToString(&KeyName, L"\\Preload");

    if (!NT_SUCCESS(Status))
    {
        DPRINT1("RtlAppend failed! (%lx)\n", Status);
        DPRINT1("String is %wZ\n", &KeyName);
        return FALSE;
    }

    InitializeObjectAttributes(&ObjectAttributes,
                               &KeyName,
                               OBJ_CASE_INSENSITIVE,
                               GetRootKeyByPredefKey(HKEY_USERS, NULL),
                               NULL);

    Status = NtCreateKey(&KeyHandle,
                         KEY_SET_VALUE,
                         &ObjectAttributes,
                         0,
                         NULL,
                         REG_OPTION_NON_VOLATILE,
                         &Disposition);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtCreateKey() failed (Status %lx)\n", Status);
        return FALSE;
    }

    RtlInitUnicodeString(&KeyName, L".DEFAULT\\Keyboard Layout\\Substitutes");
    InitializeObjectAttributes(&ObjectAttributes,
                               &KeyName,
                               OBJ_CASE_INSENSITIVE,
                               GetRootKeyByPredefKey(HKEY_USERS, NULL),
                               NULL);

    Status =  NtCreateKey(&SubKeyHandle,
                          KEY_SET_VALUE,
                          &ObjectAttributes,
                          0,
                          NULL,
                          REG_OPTION_NON_VOLATILE,
                          &Disposition);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtCreateKey() failed (Status %lx)\n", Status);
        NtClose(SubKeyHandle);
        NtClose(KeyHandle);
        return FALSE;
    }

    while (MuiLayouts[uIndex].LangID != NULL)
    {
        if (uIndex > 19) break;

        RtlStringCchPrintfW(szValueName, ARRAYSIZE(szValueName), L"%u", uIndex + 1);
        RtlInitUnicodeString(&ValueName, szValueName);

        RtlStringCchPrintfW(szLangID, ARRAYSIZE(szLangID), L"0000%s", MuiLayouts[uIndex].LangID);

        if (_wcsicmp(szLangID, MuiLayouts[uIndex].LayoutID) == 0)
        {
            Status = NtSetValueKey(KeyHandle,
                                   &ValueName,
                                   0,
                                   REG_SZ,
                                   (PVOID)MuiLayouts[uIndex].LayoutID,
                                   (wcslen(MuiLayouts[uIndex].LayoutID)+1) * sizeof(WCHAR));
            if (!NT_SUCCESS(Status))
            {
                DPRINT1("NtSetValueKey() failed (Status = %lx, uIndex = %d)\n", Status, uIndex);
                NtClose(SubKeyHandle);
                NtClose(KeyHandle);
                return FALSE;
            }
        }
        else
        {
            RtlStringCchPrintfW(szLangID, ARRAYSIZE(szLangID), L"d%03lu%s", uCount, MuiLayouts[uIndex].LangID);
            Status = NtSetValueKey(KeyHandle,
                                   &ValueName,
                                   0,
                                   REG_SZ,
                                   (PVOID)szLangID,
                                   (wcslen(szLangID)+1) * sizeof(WCHAR));
            if (!NT_SUCCESS(Status))
            {
                DPRINT1("NtSetValueKey() failed (Status = %lx, uIndex = %d)\n", Status, uIndex);
                NtClose(SubKeyHandle);
                NtClose(KeyHandle);
                return FALSE;
            }

            RtlInitUnicodeString(&ValueName, szLangID);

            Status = NtSetValueKey(SubKeyHandle,
                                   &ValueName,
                                   0,
                                   REG_SZ,
                                   (PVOID)MuiLayouts[uIndex].LayoutID,
                                   (wcslen(MuiLayouts[uIndex].LayoutID)+1) * sizeof(WCHAR));
            if (!NT_SUCCESS(Status))
            {
                DPRINT1("NtSetValueKey() failed (Status = %lx, uIndex = %u)\n", Status, uIndex);
                NtClose(SubKeyHandle);
                NtClose(KeyHandle);
                return FALSE;
            }

            uCount++;
        }

        uIndex++;
    }

    if (uIndex > 1)
        AddHotkeySettings(L"2", L"2", L"1");
    else
        AddHotkeySettings(L"3", L"3", L"3");

    NtClose(SubKeyHandle);
    NtClose(KeyHandle);
    return TRUE;
}