Ejemplo n.º 1
0
VOID EnumSubKeyTest()
{
	WCHAR MY_KEY_NAME[] = L"\\Registry\\Machine\\Software";
	UNICODE_STRING RegUnicodeString;
	HANDLE hRegister;
	OBJECT_ATTRIBUTES objectAttributes;
	NTSTATUS ntStatus;
	ULONG ulSize,i;
	UNICODE_STRING uniKeyName;
	PKEY_FULL_INFORMATION pfi;
	//初始化UNICODE_STRING字符串
	RtlInitUnicodeString( &RegUnicodeString, MY_KEY_NAME);
	//初始化objectAttributes
	InitializeObjectAttributes(&objectAttributes,
							&RegUnicodeString,
							OBJ_CASE_INSENSITIVE,//对大小写敏感
							NULL, 
							NULL );
	//打开注册表
	ntStatus = ZwOpenKey( &hRegister,
							KEY_ALL_ACCESS,
							&objectAttributes);
	if (NT_SUCCESS(ntStatus))
	{
		DbgPrint("Open register successfully\n");
	}
	//第一次调用ZwQueryKey为了获取KEY_FULL_INFORMATION数据的长度
	ZwQueryKey(hRegister,KeyFullInformation,NULL,0,&ulSize);
	pfi = (PKEY_FULL_INFORMATION)ExAllocatePool(PagedPool,ulSize);
	//第二次调用ZwQueryKey为了获取KEY_FULL_INFORMATION数据的数据
	ZwQueryKey(hRegister,KeyFullInformation,pfi,ulSize,&ulSize);
	for (i=0;i<pfi->SubKeys;i++)
	{
		PKEY_BASIC_INFORMATION pbi;
		//第一次调用ZwEnumerateKey为了获取KEY_BASIC_INFORMATION数据的长度
		ZwEnumerateKey(hRegister,i,KeyBasicInformation,NULL,0,&ulSize);
		pbi =(PKEY_BASIC_INFORMATION)ExAllocatePool(PagedPool,ulSize);
		//第二次调用ZwEnumerateKey为了获取KEY_BASIC_INFORMATION数据的数据
		ZwEnumerateKey(hRegister,i,KeyBasicInformation,pbi,ulSize,&ulSize);
		uniKeyName.Length = (USHORT)pbi->NameLength;
		uniKeyName.MaximumLength = (USHORT)pbi->NameLength;
		uniKeyName.Buffer = pbi->Name;
		DbgPrint("The %d sub item name:%wZ\n",i,&uniKeyName);
		ExFreePool(pbi);
	}
	ExFreePool(pfi);
	ZwClose(hRegister);
}
Ejemplo n.º 2
0
NTSTATUS
SampRegEnumerateSubKey(IN HANDLE KeyHandle,
                       IN ULONG Index,
                       IN ULONG Length,
                       OUT LPWSTR Buffer)
{
    PKEY_BASIC_INFORMATION KeyInfo = NULL;
    ULONG BufferLength = 0;
    ULONG ReturnedLength;
    NTSTATUS Status;

    /* Check if we have a name */
    if (Length)
    {
        /* Allocate a buffer for it */
        BufferLength = sizeof(KEY_BASIC_INFORMATION) + Length * sizeof(WCHAR);

        KeyInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength);
        if (KeyInfo == NULL)
            return STATUS_NO_MEMORY;
    }

    /* Enumerate the key */
    Status = ZwEnumerateKey(KeyHandle,
                            Index,
                            KeyBasicInformation,
                            KeyInfo,
                            BufferLength,
                            &ReturnedLength);
    if (NT_SUCCESS(Status))
    {
        /* Check if the name fits */
        if (KeyInfo->NameLength < (Length * sizeof(WCHAR)))
        {
            /* Copy it */
            RtlMoveMemory(Buffer,
                          KeyInfo->Name,
                          KeyInfo->NameLength);

            /* Terminate the string */
            Buffer[KeyInfo->NameLength / sizeof(WCHAR)] = 0;
        }
        else
        {
            /* Otherwise, we ran out of buffer space */
            Status = STATUS_BUFFER_OVERFLOW;
        }
    }

    /* Free the buffer and return status */
    if (KeyInfo)
        RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo);

    return Status;
}
Ejemplo n.º 3
0
static SshRegKey
ssh_registry_platform_open_key_by_index(SshRegKey parent_key,
                                        SshRegIndex index)
{
  SshRegKey key;
  SshRegSize size;
  PKEY_NODE_INFORMATION info;

  SSH_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);

  size = ssh_registry_key_info_get(parent_key, SSH_REG_KEY_INFO_SUBKEY_SIZE);
  if (size == 0)
    {
      SSH_DEBUG(SSH_D_FAIL, ("Failed to get subkey size"));
      return NULL;
    }

  size += sizeof(*info);

  info = ssh_calloc(1, size);
  if (info == NULL)
    {
      SSH_DEBUG(SSH_D_FAIL, 
                ("Failed to allocate memory for subkey information"));
      return NULL;
    }

  if (!NT_SUCCESS(ZwEnumerateKey(parent_key, index, 
                  KeyNodeInformation, info, size, &size)))
    {
      SSH_DEBUG(SSH_D_FAIL, 
                ("Failed to get information about subkey %d", index));

      ssh_free(info);
      return NULL;
    }

  key = ssh_registry_key_open(parent_key, NULL, info->Name);

  ssh_free(info);

  return key;
}
Ejemplo n.º 4
0
NTSTATUS SetLowerFilters(PUNICODE_STRING szUName,ULONG uFlag)
{
    //设置底层过滤函数,完成对注册表的处理

	UNICODE_STRING dst,src,ValueName;
	HANDLE hRegister,hSubKey;
	WCHAR dst_buf[256];

	//初始化UNICODE_STRING字符串
	RtlInitEmptyUnicodeString(&dst,dst_buf,256*sizeof(WCHAR));
	RtlInitUnicodeString(&src,USBSTOR);
	RtlCopyUnicodeString(&dst,&src);
	RtlAppendUnicodeStringToString(&dst,szUName);

	OBJECT_ATTRIBUTES objectAttributes;

	//初始化objectAttributes
	InitializeObjectAttributes(&objectAttributes,
		&dst,
		OBJ_CASE_INSENSITIVE,//对大小写敏感
		NULL,
		NULL );

	//打开注册表
	NTSTATUS ntStatus = ZwOpenKey( &hRegister,
		KEY_ALL_ACCESS,
		&objectAttributes);

    //打开注册表成功
	if (NT_SUCCESS(ntStatus))
	{
		DbgPrint("Open register successfully\n");
	}

	RtlInitUnicodeString(&ValueName,L"LowerFilters");
	PWCHAR strValue=L"USBFilter";

	ULONG ulSize;

	//第一次调用ZwQueryKey为了获取KEY_FULL_INFORMATION数据的长度
	ZwQueryKey(hRegister,
		KeyFullInformation,
		NULL,
		0,
		&ulSize);

	PKEY_FULL_INFORMATION pfi =
		(PKEY_FULL_INFORMATION)
		ExAllocatePool(PagedPool,ulSize);

	//第二次调用ZwQueryKey为了获取KEY_FULL_INFORMATION数据的数据
	ZwQueryKey(hRegister,
		KeyFullInformation,
		pfi,
		ulSize,
		&ulSize);

	for (ULONG i=0;i<pfi->SubKeys;i++)
	{
		//第一次调用ZwEnumerateKey为了获取KEY_BASIC_INFORMATION数据的长度
		ZwEnumerateKey(hRegister,
			i,
			KeyBasicInformation,
			NULL,
			0,
			&ulSize);

		PKEY_BASIC_INFORMATION pbi =
			(PKEY_BASIC_INFORMATION)
			ExAllocatePool(PagedPool,ulSize);

		//第二次调用ZwEnumerateKey为了获取KEY_BASIC_INFORMATION数据的数据
		ZwEnumerateKey(hRegister,
			i,
			KeyBasicInformation,
			pbi,
			ulSize,
			&ulSize);

		UNICODE_STRING uniKeyName;
		uniKeyName.Length =
			uniKeyName.MaximumLength =
			(USHORT)pbi->NameLength;

		uniKeyName.Buffer = pbi->Name;

		WCHAR bufTmp[256];

		//初始化值
		RtlInitEmptyUnicodeString(&src,bufTmp,256*sizeof(WCHAR));
		RtlCopyUnicodeString(&src,&dst);

		UNICODE_STRING szX;
		RtlInitUnicodeString(&szX,L"\\");
		RtlAppendUnicodeStringToString(&src,&szX),
			RtlAppendUnicodeStringToString(&src,&uniKeyName);

        //初始化ObjectAttributes
		InitializeObjectAttributes(&objectAttributes,
			&src,
			OBJ_CASE_INSENSITIVE,//对大小写敏感
			NULL,
			NULL );

        //打开注册表
		ZwOpenKey( &hSubKey,
			KEY_ALL_ACCESS,
			&objectAttributes);

        //uFlag为0则删除注册表键值,否则设置注册表键值
		if(uFlag==0)
		{
			ntStatus=ZwDeleteValueKey(hSubKey,&ValueName);
		}
		else
		{
		ntStatus=ZwSetValueKey(hSubKey,&ValueName,0,REG_SZ,strValue,wcslen(strValue)*2+2);
		}

		//成功的话
		if (NT_SUCCESS(ntStatus))
		{
			DbgPrint("Charge Value successfully\n");
		}
		else
			DbgPrint("Charge Value failed!\n");

		DbgPrint("The %d sub item name:%wZ\n",i,&src);

        //回收内存
		ExFreePool(pbi);

		//关闭句柄
		ZwClose(hSubKey);
	}

	ExFreePool(pfi);
	ZwClose(hRegister);

	return STATUS_SUCCESS;
}
Ejemplo n.º 5
0
void otPlatSettingsWipe(otInstance *otCtx)
{
    NT_ASSERT(otCtx);
    PMS_FILTER pFilter = otCtxToFilter(otCtx);

    LogFuncEntry(DRIVER_DEFAULT);

    // Delete all subkeys of 'OpenThread'
    if (pFilter->otSettingsRegKey)
    {
        NTSTATUS status = STATUS_SUCCESS;
        ULONG index = 0;
        UCHAR keyInfo[sizeof(KEY_BASIC_INFORMATION) + 64];

        while (status == STATUS_SUCCESS)
        {
            ULONG size = sizeof(keyInfo);
            status =
                ZwEnumerateKey(
                    pFilter->otSettingsRegKey,
                    index,
                    KeyBasicInformation,
                    keyInfo,
                    size,
                    &size);

            bool deleted = false;
            if (NT_SUCCESS(status))
            {
                HANDLE subKey = NULL;
                OBJECT_ATTRIBUTES attributes;
                PKEY_BASIC_INFORMATION pKeyInfo = (PKEY_BASIC_INFORMATION)keyInfo;

                UNICODE_STRING subKeyName = 
                {
                    (USHORT)pKeyInfo->NameLength,
                    (USHORT)pKeyInfo->NameLength,
                    pKeyInfo->Name
                };

                InitializeObjectAttributes(
                    &attributes,
                    &subKeyName,
                    OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                    pFilter->otSettingsRegKey,
                    NULL);

                // Open the sub key
                status =
                    ZwOpenKey(
                        &subKey,
                        KEY_ALL_ACCESS,
                        &attributes);

                if (NT_SUCCESS(status))
                {
                    // Delete the key
                    status = ZwDeleteKey(subKey);
                    if (!NT_SUCCESS(status))
                    {
                        LogError(DRIVER_DEFAULT, "ZwDeleteKey for subkey failed, %!STATUS!", status);
                    }
                    else
                    {
                        deleted = true;
                    }

                    // Close handle
                    ZwClose(subKey);
                }
                else
                {
                    LogError(DRIVER_DEFAULT, "ZwOpenKey for subkey failed, %!STATUS!", status);
                }
            }

            // Only increment index if we didn't delete
            if (!deleted)
            {
                index++;
            }
        }
    }

    LogFuncExit(DRIVER_DEFAULT);
}
Ejemplo n.º 6
0
 //在注册表子项中设置LowerFilters子项
NTSTATUS SetLowerFilters(PUNICODE_STRING szUName,ULONG uFlag)
{
	UNICODE_STRING dst,src,ValueName;
	HANDLE hRegister,hSubKey;
	WCHAR dst_buf[256];

	//初始化UNICODE_STRING字符串
	RtlInitEmptyUnicodeString(&dst,dst_buf,256*sizeof(WCHAR));
	//初始化src为U盘注册表位置
	RtlInitUnicodeString(&src,USBSTOR);
	RtlCopyUnicodeString(&dst,&src);

	//将U盘名字追加到注册表位置末尾,为选中U盘的实际注册表位置
	RtlAppendUnicodeStringToString(&dst,szUName);

	OBJECT_ATTRIBUTES objectAttributes;

	//初始化objectAttributes
	InitializeObjectAttributes(&objectAttributes,
		&dst,               //文件名
		OBJ_CASE_INSENSITIVE,//对大小写敏感
		NULL,
		NULL );

	//打开注册表
	NTSTATUS ntStatus = ZwOpenKey( &hRegister,   //返回被打开的句柄
		KEY_ALL_ACCESS,         //打开权限,一般都这么设置
		&objectAttributes);

    //打开注册表成功
	if (NT_SUCCESS(ntStatus))
	{
		DbgPrint("Open register successfully\n");
	}

    //要在注册表子项下添加LowerFilters的表项
	RtlInitUnicodeString(&ValueName,L"LowerFilters");

	//键值设为过滤类名,如果随便设一个会导致U盘连接状态但是不能查看到
	PWCHAR strValue=L"UsbFilter";

	ULONG ulSize;

	//第一次调用ZwQueryKey为了获取KEY_FULL_INFORMATION数据的长度(因为是变长的)
	ZwQueryKey(hRegister,
		KeyFullInformation,  //查询类别,一般都这么设置
		NULL,
		0,
		&ulSize);         //返回数据KEY_FULL_INFORMATION的长度

	PKEY_FULL_INFORMATION pfi =
		(PKEY_FULL_INFORMATION)
		ExAllocatePool(PagedPool,ulSize);

	//第二次调用ZwQueryKey为了获取KEY_FULL_INFORMATION数据的数据
	ZwQueryKey(hRegister,
		KeyFullInformation,
		pfi,      //查询数据的指针
		ulSize,   //数据长度
		&ulSize);

    //ZwQueryKey的作用主要就是获得某注册表究竟有多少个子项
    //而ZwEnumerateKey的作用主要是针对第几个子项获取该子项的具体信息

	for (ULONG i=0;i<pfi->SubKeys;i++)
	{
		//第一次调用ZwEnumerateKey为了获取KEY_BASIC_INFORMATION数据的长度
		ZwEnumerateKey(hRegister,
			i,
			KeyBasicInformation,
			NULL,
			0,
			&ulSize);

		PKEY_BASIC_INFORMATION pbi =
			(PKEY_BASIC_INFORMATION)
			ExAllocatePool(PagedPool,ulSize);

		//第二次调用ZwEnumerateKey为了获取KEY_BASIC_INFORMATION数据的数据
		ZwEnumerateKey(hRegister,
			i,
			KeyBasicInformation,
			pbi,
			ulSize,
			&ulSize);

		UNICODE_STRING uniKeyName;

		//获取子项名字的长度
		uniKeyName.Length =
			uniKeyName.MaximumLength =
			(USHORT)pbi->NameLength;

		uniKeyName.Buffer = pbi->Name;

		WCHAR bufTmp[256];

		//初始化值
		RtlInitEmptyUnicodeString(&src,bufTmp,256*sizeof(WCHAR));
		RtlCopyUnicodeString(&src,&dst);

		UNICODE_STRING szX;
		RtlInitUnicodeString(&szX,L"\\");
		RtlAppendUnicodeStringToString(&src,&szX),

		//这里就得到注册表子项名字的具体路径名,保存在src中
        RtlAppendUnicodeStringToString(&src,&uniKeyName);

        //初始化ObjectAttributes
		InitializeObjectAttributes(&objectAttributes,
			&src,
			OBJ_CASE_INSENSITIVE,//对大小写敏感
			NULL,
			NULL );

        //打开注册表
		ZwOpenKey( &hSubKey,
			KEY_ALL_ACCESS,
			&objectAttributes);

        //uFlag为0则删除注册表键值(既关写保护),否则设置注册表键值(既开写保护)
		if(uFlag==0)
		{
			ntStatus=ZwDeleteValueKey(hSubKey,&ValueName);
		}
		else
		{
		ntStatus=ZwSetValueKey(hSubKey,&ValueName,0,REG_SZ,strValue,wcslen(strValue)*2+2);
		}

		//成功的话
		if (NT_SUCCESS(ntStatus))
		{
			DbgPrint("Charge Value successfully\n");
		}
		else
			DbgPrint("Charge Value failed!\n");

		DbgPrint("The %d sub item name:%wZ\n",i,&src);

        //回收内存
		ExFreePool(pbi);

		//关闭句柄
		ZwClose(hSubKey);
	}

	ExFreePool(pfi);
	ZwClose(hRegister);

	return STATUS_SUCCESS;
}
Ejemplo n.º 7
0
NTSTATUS EnumServices()
{
	//_asm int 3
	NTSTATUS status = STATUS_SUCCESS;
	ULONG	SubKeyIndex, ResultLength, ulSize;
	HANDLE					i, HandleRegKey = NULL;
	UNICODE_STRING			RegistryKeyName, KeyValue;
	UNICODE_STRING			KeyName;
	OBJECT_ATTRIBUTES		ObjectAttributes;
	PLIST_ENTRY pListHead = NULL, pListCur = NULL;
	PLDR_DATA_TABLE_ENTRY pLdrDataTable = NULL;
	PSERVICES_INFO pServicesInfo = NULL,\
		pPreServicesInfo = NULL;
	PKEY_BASIC_INFORMATION pKeyBasicInfo = NULL;
	PKEY_FULL_INFORMATION pKeyFullInfo = NULL;
	/************************************************************************/
	/* 
	User-mode Handle		Corresponding Object Name 
	HKEY_LOCAL_MACHINE		\Registry\Machine 
	HKEY_USERS				\Registry\User 
	HKEY_CLASSES_ROOT		No kernel-mode equivalent 
	HKEY_CURRENT_USER		No simple kernel-mode equivalent, but see Registry Run-Time Library Routines 
	*/
	/************************************************************************/

	WCHAR ServiceRegisterPath[] = L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\";

	//pListHead = ((PLIST_ENTRY)pDriverObj->DriverSection)->Flink;
	//pListCur = pListHead;

	__try
	{

		FreePagedLookasideListForServices();
		ExInitializePagedLookasideList(&g_PageListServices, NULL, NULL, 0, sizeof(SERVICES_INFO), NULL, 0);

		RtlInitUnicodeString(&RegistryKeyName, ServiceRegisterPath);
		InitializeObjectAttributes(&ObjectAttributes, 
			&RegistryKeyName,
			OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
			NULL,    // handle
			NULL);
		status = ZwOpenKey(&HandleRegKey, KEY_READ, &ObjectAttributes);

		// 第一次调用是为了获取需要的长度
		ZwQueryKey(HandleRegKey, KeyFullInformation, NULL, 0, &ulSize);
		pKeyFullInfo = (PKEY_FULL_INFORMATION)ExAllocatePool(PagedPool, ulSize);
		// 第二次调用是为了获取数据
		ZwQueryKey(HandleRegKey, KeyFullInformation, pKeyFullInfo, ulSize, &ulSize);

		//循环遍历各个子项
		for (SubKeyIndex = 0; SubKeyIndex <pKeyFullInfo->SubKeys; SubKeyIndex++)
		{
			ZwEnumerateKey(HandleRegKey, SubKeyIndex, KeyBasicInformation, NULL, 0, &ulSize);
			pKeyBasicInfo = (PKEY_BASIC_INFORMATION)ExAllocatePool(PagedPool, ulSize);
			//获取第I个子项的数据
			ZwEnumerateKey(HandleRegKey, SubKeyIndex, KeyBasicInformation, pKeyBasicInfo, ulSize, &ulSize);

			pServicesInfo = (PSERVICES_INFO)ExAllocateFromPagedLookasideList(&g_PageListServices);
			RtlZeroMemory(pServicesInfo, sizeof(SERVICES_INFO));


			//服务的名称
			RtlCopyMemory(pServicesInfo->lpwzSrvName, pKeyBasicInfo->Name, pKeyBasicInfo->NameLength);
			KeyName.Buffer = (PWCH)ExAllocatePool(PagedPool, RegistryKeyName.Length + pKeyBasicInfo->NameLength);
			KeyName.Length = RegistryKeyName.Length + pKeyBasicInfo->NameLength;
			KeyName.MaximumLength = KeyName.Length;
			RtlZeroMemory(KeyName.Buffer, KeyName.Length);
			RtlCopyMemory(KeyName.Buffer, RegistryKeyName.Buffer, RegistryKeyName.Length);
			RtlCopyMemory((PUCHAR)KeyName.Buffer + RegistryKeyName.Length, pKeyBasicInfo->Name, pKeyBasicInfo->NameLength);
			if (!QueryServiceRunType(&KeyName, pServicesInfo))
			{
				if (NULL != pServicesInfo)
				{
					ExFreeToPagedLookasideList(&g_PageListServices, pServicesInfo);
					pServicesInfo = NULL;
				}
			}
			else
			{
				pServicesInfo->next = NULL;

				if (g_pServicesInfo == NULL)
				{
					g_pServicesInfo = pServicesInfo;
					pPreServicesInfo = pServicesInfo;
				}
				else
				{
					pPreServicesInfo->next = pServicesInfo;
					pPreServicesInfo = pServicesInfo;
				}
			}


			if (KeyName.Buffer != NULL)
			{
				ExFreePool(KeyName.Buffer);
				KeyName.Buffer = NULL;
			}

			if (pKeyBasicInfo != NULL)
			{
				ExFreePool(pKeyBasicInfo);
				pKeyBasicInfo = NULL;
			}
		}

	}
	__except(EXCEPTION_EXECUTE_HANDLER)
	{
		FreePagedLookasideListForServices();
		KdPrint(("Services:EnumServices failed!"));
		status = STATUS_UNSUCCESSFUL;
	}

	if (NULL != HandleRegKey)
	{
		ZwClose(HandleRegKey);
		HandleRegKey = NULL;
	}

	if (pKeyBasicInfo != NULL)
	{
		ExFreePool(pKeyBasicInfo);
		pKeyBasicInfo = NULL;
	}

	if (pKeyFullInfo != NULL)
	{
		ExFreePool(pKeyFullInfo);
		pKeyFullInfo = NULL;
	}

	return status;
}
Ejemplo n.º 8
0
/*++
 * @name IoGetDeviceInterfaces
 * @implemented
 *
 * Returns a list of device interfaces of a particular device interface class.
 * Documented in WDK
 *
 * @param InterfaceClassGuid
 *        Points to a class GUID specifying the device interface class
 *
 * @param PhysicalDeviceObject
 *        Points to an optional PDO that narrows the search to only the
 *        device interfaces of the device represented by the PDO
 *
 * @param Flags
 *        Specifies flags that modify the search for device interfaces. The
 *        DEVICE_INTERFACE_INCLUDE_NONACTIVE flag specifies that the list of
 *        returned symbolic links should contain also disabled device
 *        interfaces in addition to the enabled ones.
 *
 * @param SymbolicLinkList
 *        Points to a character pointer that is filled in on successful return
 *        with a list of unicode strings identifying the device interfaces
 *        that match the search criteria. The newly allocated buffer contains
 *        a list of symbolic link names. Each unicode string in the list is
 *        null-terminated; the end of the whole list is marked by an additional
 *        NULL. The caller is responsible for freeing the buffer (ExFreePool)
 *        when it is no longer needed.
 *        If no device interfaces match the search criteria, this routine
 *        returns STATUS_SUCCESS and the string contains a single NULL
 *        character.
 *
 * @return Usual NTSTATUS
 *
 * @remarks None
 *
 *--*/
NTSTATUS
NTAPI
IoGetDeviceInterfaces(IN CONST GUID *InterfaceClassGuid,
                      IN PDEVICE_OBJECT PhysicalDeviceObject OPTIONAL,
                      IN ULONG Flags,
                      OUT PWSTR *SymbolicLinkList)
{
    UNICODE_STRING Control = RTL_CONSTANT_STRING(L"Control");
    UNICODE_STRING SymbolicLink = RTL_CONSTANT_STRING(L"SymbolicLink");
    HANDLE InterfaceKey = INVALID_HANDLE_VALUE;
    HANDLE DeviceKey = INVALID_HANDLE_VALUE;
    HANDLE ReferenceKey = INVALID_HANDLE_VALUE;
    HANDLE ControlKey = INVALID_HANDLE_VALUE;
    PKEY_BASIC_INFORMATION DeviceBi = NULL;
    PKEY_BASIC_INFORMATION ReferenceBi = NULL;
    PKEY_VALUE_PARTIAL_INFORMATION bip = NULL;
    PKEY_VALUE_PARTIAL_INFORMATION PartialInfo;
    UNICODE_STRING KeyName;
    OBJECT_ATTRIBUTES ObjectAttributes;
    BOOLEAN FoundRightPDO = FALSE;
    ULONG i = 0, j, Size, NeededLength, ActualLength, LinkedValue;
    UNICODE_STRING ReturnBuffer = { 0, 0, NULL };
    NTSTATUS Status;

    PAGED_CODE();

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

    /* Enumerate subkeys (i.e. the different device objects) */
    while (TRUE)
    {
        Status = ZwEnumerateKey(
            InterfaceKey,
            i,
            KeyBasicInformation,
            NULL,
            0,
            &Size);
        if (Status == STATUS_NO_MORE_ENTRIES)
        {
            break;
        }
        else if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL)
        {
            DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
            goto cleanup;
        }

        DeviceBi = ExAllocatePool(PagedPool, Size);
        if (!DeviceBi)
        {
            DPRINT("ExAllocatePool() failed\n");
            Status = STATUS_INSUFFICIENT_RESOURCES;
            goto cleanup;
        }
        Status = ZwEnumerateKey(
            InterfaceKey,
            i++,
            KeyBasicInformation,
            DeviceBi,
            Size,
            &Size);
        if (!NT_SUCCESS(Status))
        {
            DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
            goto cleanup;
        }

        /* Open device key */
        KeyName.Length = KeyName.MaximumLength = (USHORT)DeviceBi->NameLength;
        KeyName.Buffer = DeviceBi->Name;
        InitializeObjectAttributes(
            &ObjectAttributes,
            &KeyName,
            OBJ_CASE_INSENSITIVE,
            InterfaceKey,
            NULL);
        Status = ZwOpenKey(
            &DeviceKey,
            KEY_ENUMERATE_SUB_KEYS,
            &ObjectAttributes);
        if (!NT_SUCCESS(Status))
        {
            DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
            goto cleanup;
        }

        if (PhysicalDeviceObject)
        {
            /* Check if we are on the right physical device object,
            * by reading the DeviceInstance string
            */
            DPRINT1("PhysicalDeviceObject != NULL. Case not implemented.\n");
            //FoundRightPDO = TRUE;
            Status = STATUS_NOT_IMPLEMENTED;
            goto cleanup;
        }

        /* Enumerate subkeys (ie the different reference strings) */
        j = 0;
        while (TRUE)
        {
            Status = ZwEnumerateKey(
                DeviceKey,
                j,
                KeyBasicInformation,
                NULL,
                0,
                &Size);
            if (Status == STATUS_NO_MORE_ENTRIES)
            {
                break;
            }
            else if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL)
            {
                DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
                goto cleanup;
            }

            ReferenceBi = ExAllocatePool(PagedPool, Size);
            if (!ReferenceBi)
            {
                DPRINT("ExAllocatePool() failed\n");
                Status = STATUS_INSUFFICIENT_RESOURCES;
                goto cleanup;
            }
            Status = ZwEnumerateKey(
                DeviceKey,
                j++,
                KeyBasicInformation,
                ReferenceBi,
                Size,
                &Size);
            if (!NT_SUCCESS(Status))
            {
                DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
                goto cleanup;
            }

            KeyName.Length = KeyName.MaximumLength = (USHORT)ReferenceBi->NameLength;
            KeyName.Buffer = ReferenceBi->Name;
            if (RtlEqualUnicodeString(&KeyName, &Control, TRUE))
            {
                /* Skip Control subkey */
                goto NextReferenceString;
            }

            /* Open reference key */
            InitializeObjectAttributes(
                &ObjectAttributes,
                &KeyName,
                OBJ_CASE_INSENSITIVE,
                DeviceKey,
                NULL);
            Status = ZwOpenKey(
                &ReferenceKey,
                KEY_QUERY_VALUE,
                &ObjectAttributes);
            if (!NT_SUCCESS(Status))
            {
                DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
                goto cleanup;
            }

            if (!(Flags & DEVICE_INTERFACE_INCLUDE_NONACTIVE))
            {
                /* We have to check if the interface is enabled, by
                * reading the Linked value in the Control subkey
                */
                InitializeObjectAttributes(
                    &ObjectAttributes,
                    &Control,
                    OBJ_CASE_INSENSITIVE,
                    ReferenceKey,
                    NULL);
                Status = ZwOpenKey(
                    &ControlKey,
                    KEY_QUERY_VALUE,
                    &ObjectAttributes);
                if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
                {
                    /* That's OK. The key doesn't exist (yet) because
                    * the interface is not activated.
                    */
                    goto NextReferenceString;
                }
                else if (!NT_SUCCESS(Status))
                {
                    DPRINT1("ZwOpenKey() failed with status 0x%08lx\n", Status);
                    goto cleanup;
                }

                RtlInitUnicodeString(&KeyName, L"Linked");
                Status = ZwQueryValueKey(ControlKey,
                                         &KeyName,
                                         KeyValuePartialInformation,
                                         NULL,
                                         0,
                                         &NeededLength);
                if (Status == STATUS_BUFFER_TOO_SMALL)
                {
                    ActualLength = NeededLength;
                    PartialInfo = ExAllocatePool(NonPagedPool, ActualLength);
                    if (!PartialInfo)
                    {
                        Status = STATUS_INSUFFICIENT_RESOURCES;
                        goto cleanup;
                    }

                    Status = ZwQueryValueKey(ControlKey,
                                             &KeyName,
                                             KeyValuePartialInformation,
                                             PartialInfo,
                                             ActualLength,
                                             &NeededLength);
                    if (!NT_SUCCESS(Status))
                    {
                        DPRINT1("ZwQueryValueKey #2 failed (%x)\n", Status);
                        ExFreePool(PartialInfo);
                        goto cleanup;
                    }

                    if (PartialInfo->Type != REG_DWORD || PartialInfo->DataLength != sizeof(ULONG))
                    {
                        DPRINT1("Bad registry read\n");
                        ExFreePool(PartialInfo);
                        goto cleanup;
                    }

                    RtlCopyMemory(&LinkedValue,
                                  PartialInfo->Data,
                                  PartialInfo->DataLength);

                    ExFreePool(PartialInfo);
                    if (LinkedValue == 0)
                    {
                        /* This interface isn't active */
                        goto NextReferenceString;
                    }
                }
                else
                {
                    DPRINT1("ZwQueryValueKey #1 failed (%x)\n", Status);
                    goto cleanup;
                }
            }

            /* Read the SymbolicLink string and add it into SymbolicLinkList */
            Status = ZwQueryValueKey(
                ReferenceKey,
                &SymbolicLink,
                KeyValuePartialInformation,
                NULL,
                0,
                &Size);
            if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL)
            {
                DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status);
                goto cleanup;
            }
            bip = ExAllocatePool(PagedPool, Size);
            if (!bip)
            {
                DPRINT("ExAllocatePool() failed\n");
                Status = STATUS_INSUFFICIENT_RESOURCES;
                goto cleanup;
            }
            Status = ZwQueryValueKey(
                ReferenceKey,
                &SymbolicLink,
                KeyValuePartialInformation,
                bip,
                Size,
                &Size);
            if (!NT_SUCCESS(Status))
            {
                DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status);
                goto cleanup;
            }
            else if (bip->Type != REG_SZ)
            {
                DPRINT("Unexpected registry type 0x%lx (expected 0x%lx)\n", bip->Type, REG_SZ);
                Status = STATUS_UNSUCCESSFUL;
                goto cleanup;
            }
            else if (bip->DataLength < 5 * sizeof(WCHAR))
            {
                DPRINT("Registry string too short (length %lu, expected %lu at least)\n", bip->DataLength, 5 * sizeof(WCHAR));
                Status = STATUS_UNSUCCESSFUL;
                goto cleanup;
            }
            KeyName.Length = KeyName.MaximumLength = (USHORT)bip->DataLength;
            KeyName.Buffer = (PWSTR)bip->Data;

            /* Fixup the prefix (from "\\?\") */
            RtlCopyMemory(KeyName.Buffer, L"\\??\\", 4 * sizeof(WCHAR));

            /* Add new symbolic link to symbolic link list */
            if (ReturnBuffer.Length + KeyName.Length + sizeof(WCHAR) > ReturnBuffer.MaximumLength)
            {
                PWSTR NewBuffer;
                ReturnBuffer.MaximumLength = (USHORT)max(2 * ReturnBuffer.MaximumLength,
                                                         (USHORT)(ReturnBuffer.Length +
                                                         KeyName.Length +
                                                         2 * sizeof(WCHAR)));
                NewBuffer = ExAllocatePool(PagedPool, ReturnBuffer.MaximumLength);
                if (!NewBuffer)
                {
                    DPRINT("ExAllocatePool() failed\n");
                    Status = STATUS_INSUFFICIENT_RESOURCES;
                    goto cleanup;
                }
                if (ReturnBuffer.Buffer)
                {
                    RtlCopyMemory(NewBuffer, ReturnBuffer.Buffer, ReturnBuffer.Length);
                    ExFreePool(ReturnBuffer.Buffer);
                }
                ReturnBuffer.Buffer = NewBuffer;
            }
            DPRINT("Adding symbolic link %wZ\n", &KeyName);
            Status = RtlAppendUnicodeStringToString(&ReturnBuffer, &KeyName);
            if (!NT_SUCCESS(Status))
            {
                DPRINT("RtlAppendUnicodeStringToString() failed with status 0x%08lx\n", Status);
                goto cleanup;
            }
            /* RtlAppendUnicodeStringToString added a NULL at the end of the
             * destination string, but didn't increase the Length field.
             * Do it for it.
             */
            ReturnBuffer.Length += sizeof(WCHAR);

NextReferenceString:
            ExFreePool(ReferenceBi);
            ReferenceBi = NULL;
            if (bip)
                ExFreePool(bip);
            bip = NULL;
            if (ReferenceKey != INVALID_HANDLE_VALUE)
            {
                ZwClose(ReferenceKey);
                ReferenceKey = INVALID_HANDLE_VALUE;
            }
            if (ControlKey != INVALID_HANDLE_VALUE)
            {
                ZwClose(ControlKey);
                ControlKey = INVALID_HANDLE_VALUE;
            }
        }
        if (FoundRightPDO)
        {
            /* No need to go further, as we already have found what we searched */
            break;
        }

        ExFreePool(DeviceBi);
        DeviceBi = NULL;
        ZwClose(DeviceKey);
        DeviceKey = INVALID_HANDLE_VALUE;
    }

    /* Add final NULL to ReturnBuffer */
    NT_ASSERT(ReturnBuffer.Length <= ReturnBuffer.MaximumLength);
    if (ReturnBuffer.Length >= ReturnBuffer.MaximumLength)
    {
        PWSTR NewBuffer;
        ReturnBuffer.MaximumLength += sizeof(WCHAR);
        NewBuffer = ExAllocatePool(PagedPool, ReturnBuffer.MaximumLength);
        if (!NewBuffer)
        {
            DPRINT("ExAllocatePool() failed\n");
            Status = STATUS_INSUFFICIENT_RESOURCES;
            goto cleanup;
        }
        if (ReturnBuffer.Buffer)
        {
            RtlCopyMemory(NewBuffer, ReturnBuffer.Buffer, ReturnBuffer.Length);
            ExFreePool(ReturnBuffer.Buffer);
        }
        ReturnBuffer.Buffer = NewBuffer;
    }
    ReturnBuffer.Buffer[ReturnBuffer.Length / sizeof(WCHAR)] = UNICODE_NULL;
    *SymbolicLinkList = ReturnBuffer.Buffer;
    Status = STATUS_SUCCESS;

cleanup:
    if (!NT_SUCCESS(Status) && ReturnBuffer.Buffer)
        ExFreePool(ReturnBuffer.Buffer);
    if (InterfaceKey != INVALID_HANDLE_VALUE)
        ZwClose(InterfaceKey);
    if (DeviceKey != INVALID_HANDLE_VALUE)
        ZwClose(DeviceKey);
    if (ReferenceKey != INVALID_HANDLE_VALUE)
        ZwClose(ReferenceKey);
    if (ControlKey != INVALID_HANDLE_VALUE)
        ZwClose(ControlKey);
    if (DeviceBi)
        ExFreePool(DeviceBi);
    if (ReferenceBi)
        ExFreePool(ReferenceBi);
    if (bip)
        ExFreePool(bip);
    return Status;
}
Ejemplo n.º 9
0
NTSTATUS
RegistryEnumerateSubKeys(
    IN  HANDLE              Key,
    IN  NTSTATUS            (*Callback)(PVOID, HANDLE, PCHAR),
    IN  PVOID               Context
    )
{
    ULONG                   Size;
    NTSTATUS                status;
    PKEY_FULL_INFORMATION   Full;
    PKEY_BASIC_INFORMATION  Basic;
    ULONG                   Index;

    status = ZwQueryKey(Key,
                        KeyFullInformation,
                        NULL,
                        0,
                        &Size);
    if (status != STATUS_BUFFER_OVERFLOW &&
        status != STATUS_BUFFER_TOO_SMALL)
        goto fail1;

#pragma prefast(suppress:6102)
    Full = __RegistryAllocate(Size);

    status = STATUS_NO_MEMORY;
    if (Full == NULL)
        goto fail2;

    status = ZwQueryKey(Key,
                        KeyFullInformation,
                        Full,
                        Size,
                        &Size);
    if (!NT_SUCCESS(status))
        goto fail3;

    Size = FIELD_OFFSET(KEY_BASIC_INFORMATION, Name) +
           Full->MaxNameLen;

    Basic = __RegistryAllocate(Size);
    status = STATUS_NO_MEMORY;
    if (Basic == NULL)
        goto fail4;

    for (Index = 0; Index < Full->SubKeys; Index++) {
        UNICODE_STRING  Unicode;
        ANSI_STRING     Ansi;

        status = ZwEnumerateKey(Key,
                                Index,
                                KeyBasicInformation,
                                Basic,
                                Size,
                                &Size);
        if (!NT_SUCCESS(status))
            goto fail5;

        Unicode.MaximumLength = (USHORT)Basic->NameLength;
        Unicode.Buffer = Basic->Name;
        Unicode.Length = (USHORT)Basic->NameLength;

        Ansi.MaximumLength = (USHORT)((Basic->NameLength / sizeof (WCHAR)) + sizeof (CHAR));
        Ansi.Buffer = __RegistryAllocate(Ansi.MaximumLength);

        status = STATUS_NO_MEMORY;
        if (Ansi.Buffer == NULL)
            goto fail6;

        status = RtlUnicodeStringToAnsiString(&Ansi, &Unicode, FALSE);
        ASSERT(NT_SUCCESS(status));

        Ansi.Length = (USHORT)(strlen(Ansi.Buffer) * sizeof (CHAR));        

        status = Callback(Context, Key, Ansi.Buffer);

        __RegistryFree(Ansi.Buffer);
        Ansi.Buffer = NULL;

        if (!NT_SUCCESS(status))
            goto fail7;
    }

    __RegistryFree(Basic);

    __RegistryFree(Full);

    return STATUS_SUCCESS;

fail7:
fail6:
fail5:
    __RegistryFree(Basic);

fail4:
fail3:
    __RegistryFree(Full);
    
fail2:
fail1:
    return status;
}
Ejemplo n.º 10
0
///////////////////////////////////////////////////////////////////////////////////////////////////
//  testdrvRegEnumerateKeys
//      Enumerates and print names of subkeys using a given registry key handle.
//
//  Arguments:
//      IN  RegKeyHandle
//              Handle to root key
//
//  Return Value:
//      none
//
VOID testdrvRegEnumerateKeys(
    IN  HANDLE RegKeyHandle
    )
{
    NTSTATUS                status;
    ULONG                   index;
    PKEY_BASIC_INFORMATION  regBuffer;
    PWCHAR                  nameBuffer;
    ULONG                   length;

    status = STATUS_SUCCESS;
    index = 0;
    regBuffer = NULL;
    nameBuffer = NULL;

    while (status != STATUS_NO_MORE_ENTRIES)
    {
        // Get the buffer size necessary
        status = ZwEnumerateKey(
                    RegKeyHandle,
                    index,
                    KeyBasicInformation,
                    NULL,
                    0,
                    &length
                    );

        if ((status != STATUS_BUFFER_TOO_SMALL) && (status != STATUS_BUFFER_OVERFLOW))
        {
            if (status != STATUS_NO_MORE_ENTRIES)
            {
                testdrvDebugPrint(DBG_PNP, DBG_INFO, __FUNCTION__ ": ZwEnumerateKey failed %x", status);
            }
            else
            {
                testdrvDebugPrint(DBG_PNP, DBG_INFO, __FUNCTION__ ": Enumerated %d keys", index);
            }

            break;
        }

        regBuffer = 
            (PKEY_BASIC_INFORMATION)ExAllocatePoolWithTag(NonPagedPool, length, TESTDRV_POOL_TAG);

        if (regBuffer == NULL)
        {
            continue;
        }

        // Now actually attempt to get subkey info
        status = ZwEnumerateKey(
                    RegKeyHandle,
                    index,
                    KeyBasicInformation,
                    regBuffer,
                    length,
                    &length
                    );

        if (!NT_SUCCESS(status))
        {
            testdrvDebugPrint(DBG_PNP, DBG_INFO, __FUNCTION__ ": ZwEnumerateKey failed %x", status);

            // Free our temporary storage
            ExFreePool(regBuffer);

            continue;
        }

        // Allocate a buffer for the display name
        nameBuffer = (PWCHAR)ExAllocatePoolWithTag(
                                    PagedPool, 
                                    regBuffer->NameLength + sizeof(WCHAR), 
                                    TESTDRV_POOL_TAG
                                    );

        if (nameBuffer == NULL)
        {
            // Free our temporary storage
            ExFreePool(regBuffer);

            continue;
        }

        // NULL terminate the string
        RtlZeroMemory(nameBuffer, regBuffer->NameLength + sizeof(WCHAR));

        // Copy the name over
        RtlCopyMemory(nameBuffer, regBuffer->Name, regBuffer->NameLength);
        
        testdrvDebugPrint(DBG_PNP, DBG_INFO, __FUNCTION__ ": ZwEnumerateKey returned %S", nameBuffer);

        // Free both buffers
        ExFreePool(regBuffer);
        ExFreePool(nameBuffer);

        // Increment our index
        ++index;
    }

    return;
}
Ejemplo n.º 11
0
NTSTATUS
DrDeleteAllSubKeys(
		HANDLE				ParentKey
	) {

	NTSTATUS					status;
	PKEY_BASIC_INFORMATION		keyInfo;
	ULONG						outLength;
	ULONG						idxKey;
	OBJECT_ATTRIBUTES			objectAttributes;
	UNICODE_STRING				objectName;
	HANDLE						childKey;

	keyInfo = (PKEY_BASIC_INFORMATION)ExAllocatePoolWithTag(PagedPool, 512, DEVREG_POOTAG_KEYINFO);
	if(!keyInfo) {
		KDPrint(1, ("ExAllocatePoolWithTag(KEY_BASIC_INFORMATION) failed.\n"));
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	status = STATUS_SUCCESS;
	for(idxKey = 0 ; idxKey < DEVREG_MAX_REGISTRY_KEY; idxKey ++) {
		status = ZwEnumerateKey(
						ParentKey,
						idxKey,
						KeyBasicInformation,
						keyInfo,
						512,
						&outLength
						);

		if(status == STATUS_NO_MORE_ENTRIES) {
			KDPrint(1, ("No more entries.\n"));
			status = STATUS_SUCCESS;
			break;
		}
		if(status != STATUS_SUCCESS) {
			ASSERT(status != STATUS_BUFFER_OVERFLOW && status != STATUS_BUFFER_TOO_SMALL);
			KDPrint(1, ("ZwEnumerateKey() failed. NTSTATUS:%08lx\n", status));
			ExFreePool(keyInfo);
			return STATUS_SUCCESS;
		}


		//
		//	Open a sub key
		//
		objectName.Length = objectName.MaximumLength = (USHORT)keyInfo->NameLength;
		objectName.Buffer = keyInfo->Name;
		InitializeObjectAttributes(		&objectAttributes,
										&objectName,
										OBJ_KERNEL_HANDLE,
										ParentKey,
										NULL
								);
		status = ZwOpenKey(&childKey, KEY_ALL_ACCESS, &objectAttributes);
		if(!NT_SUCCESS(status)) {
			KDPrint(1, ("ZwOpenKey() failed. NTSTATUS:%08lx\n", status));
			continue;
		}

		//
		//	Delete all subkeys
		//
		status = DrDeleteAllSubKeys(childKey);
		if(!NT_SUCCESS(status)) {
			KDPrint(1, ("Recursive DrDeleteAllSubKeys() failed. NTSTATUS:%08lx\n", status));
			ZwClose(childKey);
			continue;
		}

		//
		//	Delete NDAS device instance.
		//
		status = ZwDeleteKey(childKey);
#if DBG
		if(!NT_SUCCESS(status)) {
			KDPrint(1, ("ZwDeleteKey() failed. NTSTATUS:%08lx\n", status));
		}
#endif
		ZwClose(childKey);

		//
		//	One key was deleted, decrement key index.
		//

		idxKey--;

	}

	ExFreePool(keyInfo);
	return STATUS_SUCCESS;
}
Ejemplo n.º 12
0
NTSTATUS NTAPI
IopQueryBusDescription(
   PIO_QUERY Query,
   UNICODE_STRING RootKey,
   HANDLE RootKeyHandle,
   PULONG Bus,
   BOOLEAN KeyIsRoot)
{
   NTSTATUS Status;
   ULONG BusLoop;
   UNICODE_STRING SubRootRegName;
   UNICODE_STRING BusString;
   UNICODE_STRING SubBusString;
   ULONG LenBasicInformation = 0;
   ULONG LenFullInformation;
   ULONG LenKeyFullInformation;
   ULONG LenKey;
   HANDLE SubRootKeyHandle;
   PKEY_FULL_INFORMATION FullInformation;
   PKEY_BASIC_INFORMATION BasicInformation = NULL;
   OBJECT_ATTRIBUTES ObjectAttributes;
   PKEY_VALUE_FULL_INFORMATION BusInformation[3] = {NULL, NULL, NULL};

   /* How much buffer space */
   Status = ZwQueryKey(RootKeyHandle, KeyFullInformation, NULL, 0, &LenFullInformation);

   if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL && Status != STATUS_BUFFER_OVERFLOW)
      return Status;

   /* Allocate it */
   FullInformation = ExAllocatePoolWithTag(PagedPool, LenFullInformation, TAG_IO_RESOURCE);

   if (!FullInformation)
     return STATUS_NO_MEMORY;

   /* Get the Information */
   Status = ZwQueryKey(RootKeyHandle, KeyFullInformation, FullInformation, LenFullInformation, &LenFullInformation);

   /* Everything was fine */
   if (NT_SUCCESS(Status))
   {
      /* Buffer needed for all the keys under this one */
      LenBasicInformation = FullInformation->MaxNameLen + sizeof(KEY_BASIC_INFORMATION);

      /* Allocate it */
      BasicInformation = ExAllocatePoolWithTag(PagedPool, LenBasicInformation, TAG_IO_RESOURCE);
   }

   /* Deallocate the old Buffer */
   ExFreePoolWithTag(FullInformation, TAG_IO_RESOURCE);

   /* Try to find a Bus */
   for (BusLoop = 0; NT_SUCCESS(Status); BusLoop++)
   {
      /* Bus parameter was passed and number was matched */
      if ((Query->BusNumber) && (*(Query->BusNumber)) == *Bus) break;

      /* Enumerate the Key */
      Status = ZwEnumerateKey(
         RootKeyHandle,
         BusLoop,
         KeyBasicInformation,
         BasicInformation,
         LenBasicInformation,
         &LenKey);

      /* Everything enumerated */
      if (!NT_SUCCESS(Status)) break;

      /* What Bus are we going to go down? (only check if this is a Root Key) */
      if (KeyIsRoot)
      {
         if (wcsncmp(BasicInformation->Name, L"MultifunctionAdapter", BasicInformation->NameLength / 2) &&
             wcsncmp(BasicInformation->Name, L"EisaAdapter", BasicInformation->NameLength / 2) &&
             wcsncmp(BasicInformation->Name, L"TcAdapter", BasicInformation->NameLength / 2))
         {
            /* Nothing found, check next */
            continue;
         }
      }

      /* Enumerate the Bus. */
      BusString.Buffer = BasicInformation->Name;
      BusString.Length = (USHORT)BasicInformation->NameLength;
      BusString.MaximumLength = (USHORT)BasicInformation->NameLength;

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

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

      /* Go on if we can't */
      if (!NT_SUCCESS(Status)) continue;

      /* Key opened. Create the path */
      SubRootRegName = RootKey;
      RtlAppendUnicodeToString(&SubRootRegName, L"\\");
      RtlAppendUnicodeStringToString(&SubRootRegName, &BusString);

      if (!KeyIsRoot)
      {
         /* Parsing a SubBus-key */
         int SubBusLoop;
         PWSTR Strings[3] = {
            L"Identifier",
            L"Configuration Data",
            L"Component Information"};

         for (SubBusLoop = 0; SubBusLoop < 3; SubBusLoop++)
         {
            /* Identifier String First */
            RtlInitUnicodeString(&SubBusString, Strings[SubBusLoop]);

            /* How much buffer space */
            ZwQueryValueKey(SubRootKeyHandle, &SubBusString, KeyValueFullInformation, NULL, 0, &LenKeyFullInformation);

            /* Allocate it */
            BusInformation[SubBusLoop] = ExAllocatePoolWithTag(PagedPool, LenKeyFullInformation, TAG_IO_RESOURCE);

            /* Get the Information */
            Status = ZwQueryValueKey(SubRootKeyHandle, &SubBusString, KeyValueFullInformation, BusInformation[SubBusLoop], LenKeyFullInformation, &LenKeyFullInformation);
         }

         if (NT_SUCCESS(Status))
         {
            /* Do we have something */
            if (BusInformation[1] != NULL &&
                BusInformation[1]->DataLength != 0 &&
                /* Does it match what we want? */
                (((PCM_FULL_RESOURCE_DESCRIPTOR)((ULONG_PTR)BusInformation[1] + BusInformation[1]->DataOffset))->InterfaceType == *(Query->BusType)))
            {
               /* Found a bus */
               (*Bus)++;

               /* Is it the bus we wanted */
               if (Query->BusNumber == NULL || *(Query->BusNumber) == *Bus)
               {
                  /* If we don't want Controller Information, we're done... call the callback */
                  if (Query->ControllerType == NULL)
                  {
                     Status = Query->CalloutRoutine(
                        Query->Context,
                        &SubRootRegName,
                        *(Query->BusType),
                        *Bus,
                        BusInformation,
                        0,
                        0,
                        NULL,
                        0,
                        0,
                        NULL);
                  } else {
                     /* We want Controller Info...get it */
                     Status = IopQueryDeviceDescription(Query, SubRootRegName, RootKeyHandle, *Bus, (PKEY_VALUE_FULL_INFORMATION*)BusInformation);
                  }
               }
            }
         }

         /* Free the allocated memory */
         for (SubBusLoop = 0; SubBusLoop < 3; SubBusLoop++)
         {
            if (BusInformation[SubBusLoop])
            {
               ExFreePoolWithTag(BusInformation[SubBusLoop], TAG_IO_RESOURCE);
               BusInformation[SubBusLoop] = NULL;
            }
         }

         /* Exit the Loop if we found the bus */
         if (Query->BusNumber != NULL && *(Query->BusNumber) == *Bus)
         {
            ZwClose(SubRootKeyHandle);
            SubRootKeyHandle = NULL;
            continue;
         }
      }

      /* Enumerate the buses below us recursively if we haven't found the bus yet */
      Status = IopQueryBusDescription(Query, SubRootRegName, SubRootKeyHandle, Bus, !KeyIsRoot);

      /* Everything enumerated */
      if (Status == STATUS_NO_MORE_ENTRIES) Status = STATUS_SUCCESS;

      ZwClose(SubRootKeyHandle);
      SubRootKeyHandle = NULL;
   }

   /* Free the last remaining Allocated Memory */
   if (BasicInformation)
      ExFreePoolWithTag(BasicInformation, TAG_IO_RESOURCE);

   return Status;
}
Ejemplo n.º 13
0
VOID
NdisOpenConfigurationKeyByIndex(
	OUT PNDIS_STATUS				Status,
	IN	PNDIS_HANDLE				ConfigurationHandle,
	IN	ULONG						Index,
	OUT	PNDIS_STRING				KeyName,
	OUT PNDIS_HANDLE				KeyHandle
	)
/*++

Routine Description:

	This routine is used to open a subkey relative to the configuration handle.

Arguments:

	Status - Returns the status of the request.

	ConfigurationHandle - Handle to an already open section of the registry

	Index - Index of the sub-key to open

	KeyName - Placeholder for the name of subkey being opened

	KeyHandle - Placeholder for the handle to the sub-key.

Return Value:

	None.

--*/
{
	PNDIS_CONFIGURATION_HANDLE			ConfigHandle = (PNDIS_CONFIGURATION_HANDLE)ConfigurationHandle;
	HANDLE								Handle;
	OBJECT_ATTRIBUTES					ObjAttr;
	UNICODE_STRING						KeyPath, Services, AbsolutePath;
	PKEY_BASIC_INFORMATION				InfoBuf = NULL;
	ULONG								Len;

	ASSERT (KeGetCurrentIrql() < DISPATCH_LEVEL);

	*KeyHandle = NULL;

	do
	{
		//
		// Open the current key and lookup the Nth subkey. But first conver the service relative
		// path to absolute since this is what ZwOpenKey expects.
		//
		RtlInitUnicodeString(&KeyPath, ConfigHandle->KeyQueryTable[3].Name);
		RtlInitUnicodeString(&Services, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
		AbsolutePath.MaximumLength = KeyPath.Length + Services.Length + sizeof(WCHAR);
		AbsolutePath.Buffer = (PWSTR)ALLOC_FROM_POOL(AbsolutePath.MaximumLength, NDIS_TAG_DEFAULT);
		if (AbsolutePath.Buffer == NULL)
		{
			break;
		}
		NdisMoveMemory(AbsolutePath.Buffer, Services.Buffer, Services.Length);
		AbsolutePath.Length = Services.Length;
		RtlAppendUnicodeStringToString(&AbsolutePath, &KeyPath);

		InitializeObjectAttributes(&ObjAttr,
								   &AbsolutePath,
								   OBJ_CASE_INSENSITIVE,
								   NULL,
								   NULL);
		*Status = ZwOpenKey(&Handle,
							GENERIC_READ | MAXIMUM_ALLOWED,
							&ObjAttr);
		if (*Status != STATUS_SUCCESS)
		{
			break;
		}

		//
		// Allocate memory for the call to ZwEnumerateKey
		//
		Len = sizeof(KEY_BASIC_INFORMATION) + 256;
		InfoBuf = (PKEY_BASIC_INFORMATION)ALLOC_FROM_POOL(Len, NDIS_TAG_DEFAULT);
		if (InfoBuf == NULL)
		{
			ZwClose(Handle);
			*Status = NDIS_STATUS_RESOURCES;
			break;
		}

		//
		// Get the Index(th) key, if it exists
		//
		*Status = ZwEnumerateKey(Handle,
								 Index,
								 KeyValueBasicInformation,
								 InfoBuf,
								 Len,
								 &Len);
		ZwClose(Handle);
		if (*Status == STATUS_SUCCESS)
		{
			//
			// This worked. Now simply pick up the name and do a NdisOpenConfigurationKeyByName on it.
			//
			KeyPath.Length = KeyPath.MaximumLength = (USHORT)InfoBuf->NameLength;
			KeyPath.Buffer = InfoBuf->Name;
			NdisOpenConfigurationKeyByName(Status,
										   ConfigurationHandle,
										   &KeyPath,
										   KeyHandle);
			if (*Status == NDIS_STATUS_SUCCESS)
			{
				PNDIS_CONFIGURATION_HANDLE		NewHandle = *(PNDIS_CONFIGURATION_HANDLE *)KeyHandle;

				//
				// The path in the new handle has the name of the key. Extract it and return to caller
				//
				RtlInitUnicodeString(KeyName, NewHandle->KeyQueryTable[3].Name);
				KeyName->Buffer = (PWSTR)((PUCHAR)KeyName->Buffer + KeyName->Length - KeyPath.Length);
				KeyName->Length = KeyPath.Length;
				KeyName->MaximumLength = KeyPath.MaximumLength;
			}
		}

	} while (FALSE);

	if (AbsolutePath.Buffer != NULL)
	{
		FREE_POOL(AbsolutePath.Buffer);
	}

	if (InfoBuf != NULL)
	{
		FREE_POOL(InfoBuf);
	}
}
Ejemplo n.º 14
0
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DriverParametersSubKeyDelete -.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
NTSTATUS  DriverParametersSubKeyDelete(
    WDFDRIVER  Driver,
    DtString*  pKeyName)
{
    NTSTATUS  NtStatus = STATUS_SUCCESS;
    DtStringChar*  pRegistryPath;
    DtString  RegistryPath;
    DtString  FullKeyName;
    UInt  PathLength;
    HANDLE  hKey;
    OBJECT_ATTRIBUTES  ObjectAttributes;
    KEY_BASIC_INFORMATION*  pKeyInfo;
    ULONG  Size;
    ULONG  ResultSize;
    Int  Index;
    
    DT_STRING_DECL(ParamItemName, "\\Parameters\\");

    DT_ASSERT(KeGetCurrentIrql()<=PASSIVE_LEVEL);

    // Build the full path
    pRegistryPath = WdfDriverGetRegistryPath(Driver);
    PathLength = wcslen(pRegistryPath); 

    DT_STRING_INIT_CONST(RegistryPath, pRegistryPath, PathLength);

    // Allocate struct for key information result
    Size = sizeof(KEY_BASIC_INFORMATION)+100;
    pKeyInfo = DtMemAllocPool(DtPoolNonPaged, Size, SAL_TAG);
    if (pKeyInfo == NULL)
        return STATUS_NO_MEMORY;

    // Allocate a new DtString buffer for the complete path inclusive a '\0' character
    // and extra '\\'
    if (!DT_SUCCESS(DtStringAlloc(&FullKeyName, PathLength+
                                                  DtStringGetStringLength(&ParamItemName)+
                                                  DtStringGetStringLength(pKeyName)+
                                                  100+1+1)))
    {
        DtMemFreePool(pKeyInfo, SAL_TAG);
        return STATUS_NO_MEMORY;
    }

    DtStringAppendDtString(&FullKeyName, &RegistryPath);
    DtStringAppendDtString(&FullKeyName, &ParamItemName);
    DtStringAppendDtString(&FullKeyName, pKeyName);

    // Initialize key to open
    InitializeObjectAttributes(&ObjectAttributes, &FullKeyName, OBJ_KERNEL_HANDLE, NULL,
                                                                                    NULL);
    
    NtStatus = ZwOpenKey(&hKey, KEY_ENUMERATE_SUB_KEYS , &ObjectAttributes);
    
    if (NT_SUCCESS(NtStatus)) 
    {
        Index = 0;
        NtStatus = STATUS_SUCCESS;
        // Enumerate all keys
        while (NtStatus != STATUS_NO_MORE_ENTRIES)
        {
            NtStatus = ZwEnumerateKey(hKey, Index, KeyBasicInformation, pKeyInfo, Size,
                                                                             &ResultSize);
            if (NT_SUCCESS(NtStatus))
            {
                DtString SubKey;

                // Build key to delete
                pKeyInfo->Name[pKeyInfo->NameLength/2] = L'\0';
                DT_STRING_INIT_CONST(SubKey, pKeyInfo->Name, ((USHORT)pKeyInfo->NameLength/2));

                DtStringClear(&FullKeyName);
                DtStringAppendDtString(&FullKeyName, pKeyName);
                DtStringAppendChars(&FullKeyName, "\\");
                DtStringAppendDtString(&FullKeyName, &SubKey);
                
                DtDbgOut(MAX, SAL, "Delete SubKey %S.", FullKeyName.Buffer);
                NtStatus = DriverParametersKeyDelete(Driver, &FullKeyName);
                if (!NT_SUCCESS(NtStatus))
                    DtDbgOut(ERR, SAL, "Error deleting SubKey %S. Error: %x", 
                                                            FullKeyName.Buffer, NtStatus);
            }
            // In case deletion failed, skip this entry
            if (!NT_SUCCESS(NtStatus)) 
                Index++;
        }
        NtStatus = ZwDeleteKey(hKey);
        ZwClose(hKey);
    }
    DtMemFreePool(pKeyInfo, SAL_TAG);
    DtStringFree(&FullKeyName);
    return NtStatus;
}
Ejemplo n.º 15
0
//////////////////////////////////////////////////////////////////////////
//如果提供的缓存区不够大,返回STATUS_BUFFER_TOO_SMALL
NTSTATUS GetAdapterInfo(ADAPTER_INFOEX *pAIEX,  PULONG Size2Take)
{

	NTSTATUS                status;
	HANDLE                    hAdapter = NULL;
	PKEY_FULL_INFORMATION    pKeyFullInfo = NULL;
	ULONG					uTmp;
	ULONG					 uCounter=0;

	do
	{
		//        UNICODE_STRING            ustrAdapter = UNICODE_STRING_CONST(L";\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}";);
		UNICODE_STRING            ustrAdapter = UNICODE_STRING_CONST(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Adapters");
		OBJECT_ATTRIBUTES        ObjAttrib;
		ULONG                    nSize;
		ULONG                    nIndex;


		InitializeObjectAttributes(&ObjAttrib, &ustrAdapter, OBJ_CASE_INSENSITIVE, NULL, NULL);
		status = ZwOpenKey(&hAdapter, KEY_READ, &ObjAttrib);
		if (!NT_SUCCESS(status))
		{
			//DbgPrintEx(DPFLTR_IHVBUS_ID ,DPFLTR_ERROR_LEVEL,"ZwOpenKey Error: %x\n", status);
			break;
		}
		ZwQueryKey(hAdapter, KeyFullInformation, NULL, 0, &nSize);
		pKeyFullInfo = (PKEY_FULL_INFORMATION)kmalloc( nSize);
		if (!pKeyFullInfo)
		{
			status = STATUS_INSUFFICIENT_RESOURCES;
			break;
		}
		status  = ZwQueryKey(hAdapter, KeyFullInformation, pKeyFullInfo, nSize, &nSize);
		if (!NT_SUCCESS(status))
		{
			//DbgPrintEx(DPFLTR_IHVBUS_ID ,DPFLTR_ERROR_LEVEL,";ZwQueryKey Error: %x\n", status);
			break;
		}
		if (pAIEX==NULL)
		{
			status	=	STATUS_BUFFER_TOO_SMALL;
			*Size2Take	=	pKeyFullInfo->SubKeys*sizeof(ADAPTER_INFO)+sizeof(ULONG);
			break;
		}

		for (nIndex = 0; nIndex< pKeyFullInfo->SubKeys; nIndex ++)
		{
			PKEY_BASIC_INFORMATION        pKeyBasicInfo = NULL;
			HANDLE                        hDev = NULL;
			pKeyBasicInfo = NULL;

			do
			{
				UNICODE_STRING        strKeyName;
				UNICODE_STRING        ustrDev ;// UNICODE_STRING_CONST(DEV_DOS_ROOT L"{F6ACFAC2-D39E-4A43-A320-0CDB9E22B15B}");
				IO_STATUS_BLOCK        IoStatusBlock;
				ULONG                nOid;

				ZwEnumerateKey(hAdapter, nIndex, KeyBasicInformation, NULL, 0, &nSize);
				pKeyBasicInfo = (PKEY_BASIC_INFORMATION) kmalloc(nSize);
				if (NULL == pKeyBasicInfo)
				{
					status = STATUS_INSUFFICIENT_RESOURCES;
					break;
				}
				status = ZwEnumerateKey(hAdapter, nIndex, KeyBasicInformation, pKeyBasicInfo, nSize, &nSize);
				if (!NT_SUCCESS(status))
				{
					kprintf("ZwEnumerateKey fail \n");
					break;
				}

				strKeyName.Buffer = pKeyBasicInfo->Name;
				strKeyName.MaximumLength = (USHORT)pKeyBasicInfo->NameLength;
				strKeyName.Length = (USHORT)pKeyBasicInfo->NameLength;

				ustrDev.Buffer	=	kmalloc(strKeyName.MaximumLength+sizeof(DEV_DOS_ROOT));
				ustrDev.MaximumLength	=	strKeyName.MaximumLength+sizeof(DEV_DOS_ROOT);
				ustrDev.Length = 0;

				if (NULL == ustrDev.Buffer)
				{
					status = STATUS_INSUFFICIENT_RESOURCES;
					break;
				}
				RtlAppendUnicodeToString(&ustrDev, DEV_DOS_ROOT);
				status = RtlAppendUnicodeStringToString(&ustrDev, &strKeyName);
				if (STATUS_SUCCESS != status)
				{
					//DbgPrintEx(DPFLTR_IHVBUS_ID ,DPFLTR_ERROR_LEVEL,";RtlAppendUnicodeStringToString Error: %x\n", status);
					kfree(ustrDev.Buffer);
					break;
				}
				InitializeObjectAttributes(&ObjAttrib, &ustrDev, OBJ_CASE_INSENSITIVE, NULL, NULL);
				status = ZwOpenFile(&hDev,
					GENERIC_READ,
					&ObjAttrib,
					&IoStatusBlock,
					FILE_SHARE_READ,
					FILE_NON_DIRECTORY_FILE);
				if (STATUS_SUCCESS != status)
				{
					//DbgPrintEx(DPFLTR_IHVBUS_ID ,DPFLTR_ERROR_LEVEL,";ZwOpenFile %wZ,Error: %x\n", &ustrDev, status);
					kfree(ustrDev.Buffer);
					break;
				}
				

				//	nOid = OID_GEN_MEDIA_IN_USE;
// 				nOid	=	OID_GEN_PHYSICAL_MEDIUM; //网卡类型
// 				uTmp	=	sizeof(uTmp);
// 				status = ZwDeviceIoControlFile(hDev,
// 					NULL,
// 					NULL,
// 					NULL,
// 					&IoStatusBlock,
// 					IOCTL_NDIS_QUERY_GLOBAL_STATS,
// 					&nOid,
// 					sizeof(nOid),
// 					&uTmp,
// 					uTmp);
// 				if (STATUS_SUCCESS != status)
// 				{
// 					DbgPrintEx(DPFLTR_IHVBUS_ID ,DPFLTR_ERROR_LEVEL,";ZwDeviceIoControlFile OID_GEN_PHYSICAL_MEDIUM Error: 0X%x\n", status);
// 					uTmp	=	-1;
// 					if (status==STATUS_INVALID_PARAMETER)
// 					{
// 						// NdisPhysicalMediumUnspecified
// 					}
// 					//	break;
// 				}
	//其实这里应该先发OID_GEN_MEDIA_IN_USE获取下media类型

				nOid	=	OID_GEN_MEDIA_CONNECT_STATUS; //网卡类型
				uTmp	=	sizeof(uTmp);
				status = ZwDeviceIoControlFile(hDev,
					NULL,
					NULL,
					NULL,
					&IoStatusBlock,
					IOCTL_NDIS_QUERY_GLOBAL_STATS,
					&nOid,
					sizeof(nOid),
					&uTmp,
					uTmp);
				if (STATUS_SUCCESS != status)
				{
					//DbgPrintEx(DPFLTR_IHVBUS_ID ,DPFLTR_ERROR_LEVEL,";ZwDeviceIoControlFile OID_GEN_MEDIA_CONNECT_STATUS Error: 0X%x\n", status);
					uTmp	=	NdisMediaStateDisconnected;
					//	break;
				}
				pAIEX->pAI[uCounter].status	=	uTmp;
				kprintf(" %wZ, OID_GEN_MEDIA_CONNECT_STATUS %s \n", &ustrDev, uTmp == NdisMediaStateConnected ? "Connected" : "Disconnected");
				kfree(ustrDev.Buffer);
				uTmp	=	sizeof(pAIEX->pAI[uCounter].macAddress);
				nOid = OID_802_3_CURRENT_ADDRESS;
				status = ZwDeviceIoControlFile(hDev,
					NULL,
					NULL,
					NULL,
					&IoStatusBlock,
					IOCTL_NDIS_QUERY_GLOBAL_STATS,
					&nOid,
					sizeof(nOid),
					pAIEX->pAI[uCounter].macAddress,
					uTmp);
				if (STATUS_SUCCESS != status)
				{
					//DbgPrintEx(DPFLTR_IHVBUS_ID ,DPFLTR_ERROR_LEVEL,";ZwDeviceIoControlFile OID_802_3_PERMANENT_ADDRESS Error: 0x%x\n", status);
					break;
				}
				//DbgPrintEx(DPFLTR_IHVBUS_ID ,DPFLTR_ERROR_LEVEL,"Mac: %02X:%02X:%02X:%02X:%02X:%02X\n", pAIEX->pAI[uCounter].macAddress[0], pAIEX->pAI[uCounter].macAddress[1], pAIEX->pAI[uCounter].macAddress[2], pAIEX->pAI[uCounter].macAddress[3], pAIEX->pAI[uCounter].macAddress[4], pAIEX->pAI[uCounter].macAddress[5]);


				pAIEX->pAI[uCounter].GUID.Buffer	=	kmalloc(pKeyBasicInfo->NameLength);

				pAIEX->pAI[uCounter].GUID.Length = pAIEX->pAI[uCounter].GUID.MaximumLength	=	(USHORT)pKeyBasicInfo->NameLength;
				RtlCopyMemory(pAIEX->pAI[uCounter].GUID.Buffer, pKeyBasicInfo->Name, pKeyBasicInfo->NameLength);
				if (1)
				{
					CHAR	IPAddress[48];
					ANSI_STRING	aniString;
					UNICODE_STRING	uniString;
					char *pTmp=NULL;
					UNICODE_STRING   ustrAdapterInfo = UNICODE_STRING_CONST(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\");
					WCHAR	*pPath	=kmalloc(ustrAdapterInfo.Length+pKeyBasicInfo->NameLength+2);
					RtlZeroMemory(pPath, ustrAdapterInfo.Length+pKeyBasicInfo->NameLength+2);
					RtlCopyMemory(pPath, ustrAdapterInfo.Buffer, ustrAdapterInfo.Length);
					pTmp	=	(char*)pPath;
					RtlCopyMemory(&pTmp[ustrAdapterInfo.Length], pKeyBasicInfo->Name, pKeyBasicInfo->NameLength);

					uTmp=0;
					uTmp	= sizeof(ULONG);
					status	=	KKGetKeyValue(pPath, L"EnableDHCP", &uTmp, &uTmp);
					if (NT_SUCCESS(status))
					{
						RtlZeroMemory(IPAddress, sizeof(IPAddress));
						//开启了DHCP情况
						if (uTmp==1)
						{
							pAIEX->pAI[uCounter].bDhcp	=	TRUE;

							//够长了,应该会自动截断
							RtlZeroMemory(IPAddress, sizeof(IPAddress));

							uTmp	=	sizeof(IPAddress);

							status = KKGetKeyValue(pPath, L"DhcpIPAddress", IPAddress, &uTmp);
							if (NT_SUCCESS(status))
							{

								RtlInitUnicodeString(&uniString, (WCHAR*)IPAddress);
								RtlUnicodeStringToAnsiString(&aniString, &uniString, TRUE);
								RtlZeroMemory(IPAddress, sizeof(IPAddress));
								RtlCopyMemory(IPAddress, aniString.Buffer, aniString.Length);
								pAIEX->pAI[uCounter].IPAddr	=	inet_addr(IPAddress);
								RtlFreeAnsiString(&aniString);
							}
							else
							{
								kprintf("fail 2 get DhcpIPAddress\n");
							}
							RtlZeroMemory(IPAddress, sizeof(IPAddress));

							uTmp	=	sizeof(IPAddress);

							status = KKGetKeyValue(pPath, L"DhcpDefaultGateway", IPAddress, &uTmp);
							if (NT_SUCCESS(status))
							{

								RtlInitUnicodeString(&uniString, (WCHAR*)IPAddress);
								RtlUnicodeStringToAnsiString(&aniString, &uniString, TRUE);
								RtlZeroMemory(IPAddress, sizeof(IPAddress));
								RtlCopyMemory(IPAddress, aniString.Buffer, aniString.Length);
								pAIEX->pAI[uCounter].GatewayIpAddr	=	inet_addr(IPAddress);
								RtlFreeAnsiString(&aniString);
							}
							else
							{
								kprintf("fail 2 get DhcpDefaultGateway\n");
							}
						}//if (uTmp==1)
						else
						{

							pAIEX->pAI[uCounter].bDhcp	=	FALSE;

							//够长了,应该会自动截断
							RtlZeroMemory(IPAddress, sizeof(IPAddress));
							uTmp	=	sizeof(IPAddress);

							status = KKGetKeyValue(pPath, L"IPAddress", IPAddress, &uTmp);
							if (NT_SUCCESS(status))
							{

								RtlInitUnicodeString(&uniString, (WCHAR*)IPAddress);
								RtlUnicodeStringToAnsiString(&aniString, &uniString, TRUE);
								RtlZeroMemory(IPAddress, sizeof(IPAddress));
								RtlCopyMemory(IPAddress, aniString.Buffer, aniString.Length);
								pAIEX->pAI[uCounter].IPAddr	=	inet_addr(IPAddress);
								RtlFreeAnsiString(&aniString);
							}
							else
							{
								kprintf("fail 2 get IPAddress\n");
							}
							RtlZeroMemory(IPAddress, sizeof(IPAddress));
							uTmp	=	sizeof(IPAddress);

							status = KKGetKeyValue(pPath, L"DefaultGateway", IPAddress, &uTmp);
							if (NT_SUCCESS(status))
							{

								RtlInitUnicodeString(&uniString, (WCHAR*)IPAddress);
								RtlUnicodeStringToAnsiString(&aniString, &uniString, TRUE);
								RtlZeroMemory(IPAddress, sizeof(IPAddress));
								RtlCopyMemory(IPAddress, aniString.Buffer, aniString.Length);
								pAIEX->pAI[uCounter].GatewayIpAddr	=	inet_addr(IPAddress);
								RtlFreeAnsiString(&aniString);
							}
							else
							{
								kprintf("fail 2 get DefaultGateway\n");
							}
						}
					}// end status = QueryRegistryValue(pPath, L"EnableDHCP

					if (pPath)
					{
						kfree(pPath);pPath=NULL;
					}


				}


				uCounter++;
				pAIEX->uNumber	=	uCounter;

			}while(0);
			if (hDev)
			{
				ZwClose(hDev);
			}

			if (pKeyBasicInfo)
			{
				kfree(pKeyBasicInfo);
			}
			if (STATUS_SUCCESS == status)
			{

				//                break;
			}
		}
	}while(0);

	if (pKeyFullInfo)
	{
		kfree(pKeyFullInfo);
	}
	if (hAdapter)
	{
		ZwClose(hAdapter);
	}


	return status;
}
Ejemplo n.º 16
0
NTSTATUS
NTAPI
IntCopyRegistryKey(
    _In_ HANDLE SourceKeyHandle,
    _In_ HANDLE DestKeyHandle)
{
    PVOID InfoBuffer;
    PKEY_BASIC_INFORMATION KeyInformation;
    PKEY_VALUE_FULL_INFORMATION KeyValueInformation;
    OBJECT_ATTRIBUTES ObjectAttributes;
    ULONG Index, InformationLength, RequiredLength;
    UNICODE_STRING NameString;
    NTSTATUS Status;
    HANDLE SourceSubKeyHandle, DestSubKeyHandle;

    /* Start with no buffer, set initial size */
    InfoBuffer = NULL;
    InformationLength = 256;

    /* Start looping with key index 0 */
    Index = 0;
    while (TRUE)
    {
        /* Check if we have no buffer */
        if (InfoBuffer == NULL)
        {
            /* Allocate a new buffer */
            InfoBuffer = ExAllocatePoolWithTag(PagedPool,
                                               InformationLength,
                                               TAG_VIDEO_PORT_BUFFER);
            if (InfoBuffer == NULL)
            {
                ERR_(VIDEOPRT, "Could not allocate buffer for key info\n");
                return Status;
            }
        }

        /* Enumerate the next sub-key */
        KeyInformation = InfoBuffer;
        Status = ZwEnumerateKey(SourceKeyHandle,
                                Index,
                                KeyBasicInformation,
                                KeyInformation,
                                InformationLength,
                                &RequiredLength);
        if ((Status == STATUS_BUFFER_OVERFLOW) ||
            (Status == STATUS_BUFFER_TOO_SMALL))
        {
            /* Free the buffer and remember the required size */
            ExFreePoolWithTag(InfoBuffer, TAG_VIDEO_PORT_BUFFER);
            InfoBuffer = NULL;
            InformationLength = RequiredLength;

            /* Try again */
            continue;
        }
        else if (Status == STATUS_NO_MORE_ENTRIES)
        {
            /* We are done with the sub-keys */
            break;
        }
        else if (!NT_SUCCESS(Status))
        {
            ERR_(VIDEOPRT, "ZwEnumerateKey failed, status 0x%lx\n", Status);
            goto Cleanup;
        }

        /* Initialize a unicode string from the key name */
        NameString.Buffer = KeyInformation->Name;
        NameString.Length = (USHORT)KeyInformation->NameLength;
        NameString.MaximumLength = NameString.Length;

        /* Initialize object attributes and open the source sub-key */
        InitializeObjectAttributes(&ObjectAttributes,
                                   &NameString,
                                   OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
                                   SourceKeyHandle,
                                   NULL);
        Status = ZwOpenKey(&SourceSubKeyHandle, KEY_READ, &ObjectAttributes);
        if (!NT_SUCCESS(Status))
        {
            ERR_(VIDEOPRT, "failed to open the source key.\n");
            goto Cleanup;
        }

        /* Initialize object attributes and create the dest sub-key */
        InitializeObjectAttributes(&ObjectAttributes,
                                   &NameString,
                                   OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
                                   DestKeyHandle,
                                   NULL);
        Status = ZwCreateKey(&DestSubKeyHandle,
                             KEY_WRITE,
                             &ObjectAttributes,
                             0,
                             NULL,
                             0,
                             NULL);
        if (!NT_SUCCESS(Status))
        {
            ERR_(VIDEOPRT, "failed to create the destination key.\n");
            ObCloseHandle(SourceSubKeyHandle, KernelMode);
            goto Cleanup;
        }

        /* Recursively copy the sub-key */
        Status = IntCopyRegistryKey(SourceSubKeyHandle, DestSubKeyHandle);
        if (!NT_SUCCESS(Status))
        {
            /* Just warn, but continue with the remaining sub-keys */
            WARN_(VIDEOPRT, "failed to copy subkey '%wZ'.\n", &NameString);
        }

        /* Close the sub-key handles */
        ObCloseHandle(SourceSubKeyHandle, KernelMode);
        ObCloseHandle(DestSubKeyHandle, KernelMode);

        /* Next sub-key */
        Index++;
    }

    /* Start looping with value index 0 */
    Index = 0;
    while (TRUE)
    {
        /* Check if we have no buffer */
        if (InfoBuffer == NULL)
        {
            /* Allocate a new buffer */
            InfoBuffer = ExAllocatePoolWithTag(PagedPool,
                                               InformationLength,
                                               TAG_VIDEO_PORT_BUFFER);
            if (InfoBuffer == NULL)
            {
                ERR_(VIDEOPRT, "Could not allocate buffer for key values\n");
                return Status;
            }
        }

        /* Enumerate the next value */
        KeyValueInformation = InfoBuffer;
        Status = ZwEnumerateValueKey(SourceKeyHandle,
                                     Index,
                                     KeyValueFullInformation,
                                     KeyValueInformation,
                                     InformationLength,
                                     &RequiredLength);
        if ((Status == STATUS_BUFFER_OVERFLOW) ||
            (Status == STATUS_BUFFER_TOO_SMALL))
        {
            /* Free the buffer and remember the required size */
            ExFreePoolWithTag(InfoBuffer, TAG_VIDEO_PORT_BUFFER);
            InfoBuffer = NULL;
            InformationLength = RequiredLength;

            /* Try again */
            continue;
        }
        else if (Status == STATUS_NO_MORE_ENTRIES)
        {
            /* We are done with the values */
            Status = STATUS_SUCCESS;
            break;
        }
        else if (!NT_SUCCESS(Status))
        {
            ERR_(VIDEOPRT, "ZwEnumerateValueKey failed, status 0x%lx\n", Status);
            goto Cleanup;
        }

        /* Initialize a unicode string from the value name */
        NameString.Buffer = KeyValueInformation->Name;
        NameString.Length = (USHORT)KeyValueInformation->NameLength;
        NameString.MaximumLength = NameString.Length;

        /* Create the key value in the destination key */
        Status = ZwSetValueKey(DestKeyHandle,
                               &NameString,
                               KeyValueInformation->TitleIndex,
                               KeyValueInformation->Type,
                               (PUCHAR)KeyValueInformation + KeyValueInformation->DataOffset,
                               KeyValueInformation->DataLength);
        if (!NT_SUCCESS(Status))
        {
            /* Just warn, but continue with the remaining sub-keys */
            WARN_(VIDEOPRT, "failed to set value '%wZ'.\n", NameString);
        }

        /* Next subkey */
        Index++;
    }

Cleanup:
    /* Free the buffer and return the failure code */
    if (InfoBuffer != NULL)
		ExFreePoolWithTag(InfoBuffer, TAG_VIDEO_PORT_BUFFER);
    return Status;
}
Ejemplo n.º 17
0
NTSTATUS NTAPI
IopDetectResourceConflict(
   IN PCM_RESOURCE_LIST ResourceList,
   IN BOOLEAN Silent,
   OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor)
{
   OBJECT_ATTRIBUTES ObjectAttributes;
   UNICODE_STRING KeyName;
   HANDLE ResourceMapKey = INVALID_HANDLE_VALUE, ChildKey2 = INVALID_HANDLE_VALUE, ChildKey3 = INVALID_HANDLE_VALUE;
   ULONG KeyInformationLength, RequiredLength, KeyValueInformationLength, KeyNameInformationLength;
   PKEY_BASIC_INFORMATION KeyInformation;
   PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation;
   PKEY_VALUE_BASIC_INFORMATION KeyNameInformation;
   ULONG ChildKeyIndex1 = 0, ChildKeyIndex2 = 0, ChildKeyIndex3 = 0;
   NTSTATUS Status;

   RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\HARDWARE\\RESOURCEMAP");
   InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, 0, NULL);
   Status = ZwOpenKey(&ResourceMapKey, KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, &ObjectAttributes);
   if (!NT_SUCCESS(Status))
   {
      /* The key is missing which means we are the first device */
      return STATUS_SUCCESS;
   }

   while (TRUE)
   {
      Status = ZwEnumerateKey(ResourceMapKey,
                              ChildKeyIndex1,
                              KeyBasicInformation,
                              NULL,
                              0,
                              &RequiredLength);
      if (Status == STATUS_NO_MORE_ENTRIES)
          break;
      else if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL)
      {
          KeyInformationLength = RequiredLength;
          KeyInformation = ExAllocatePool(PagedPool, KeyInformationLength);
          if (!KeyInformation)
          {
              Status = STATUS_INSUFFICIENT_RESOURCES;
              goto cleanup;
          }

          Status = ZwEnumerateKey(ResourceMapKey,
                                  ChildKeyIndex1,
                                  KeyBasicInformation,
                                  KeyInformation,
                                  KeyInformationLength,
                                  &RequiredLength);
      }
      else
         goto cleanup;
      ChildKeyIndex1++;
      if (!NT_SUCCESS(Status))
          goto cleanup;

      KeyName.Buffer = KeyInformation->Name;
      KeyName.MaximumLength = KeyName.Length = (USHORT)KeyInformation->NameLength;
      InitializeObjectAttributes(&ObjectAttributes,
                                 &KeyName,
                                 OBJ_CASE_INSENSITIVE,
                                 ResourceMapKey,
                                 NULL);
      Status = ZwOpenKey(&ChildKey2, KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, &ObjectAttributes);
      ExFreePool(KeyInformation);
      if (!NT_SUCCESS(Status))
          goto cleanup;

      while (TRUE)
      {
          Status = ZwEnumerateKey(ChildKey2,
                                  ChildKeyIndex2,
                                  KeyBasicInformation,
                                  NULL,
                                  0,
                                  &RequiredLength);
          if (Status == STATUS_NO_MORE_ENTRIES)
              break;
          else if (Status == STATUS_BUFFER_TOO_SMALL)
          {
              KeyInformationLength = RequiredLength;
              KeyInformation = ExAllocatePool(PagedPool, KeyInformationLength);
              if (!KeyInformation)
              {
                  Status = STATUS_INSUFFICIENT_RESOURCES;
                  goto cleanup;
              }

              Status = ZwEnumerateKey(ChildKey2,
                                      ChildKeyIndex2,
                                      KeyBasicInformation,
                                      KeyInformation,
                                      KeyInformationLength,
                                      &RequiredLength);
          }
          else
              goto cleanup;
          ChildKeyIndex2++;
          if (!NT_SUCCESS(Status))
              goto cleanup;

          KeyName.Buffer = KeyInformation->Name;
          KeyName.MaximumLength = KeyName.Length = (USHORT)KeyInformation->NameLength;
          InitializeObjectAttributes(&ObjectAttributes,
                                     &KeyName,
                                     OBJ_CASE_INSENSITIVE,
                                     ChildKey2,
                                     NULL);
          Status = ZwOpenKey(&ChildKey3, KEY_QUERY_VALUE, &ObjectAttributes);
          ExFreePool(KeyInformation);
          if (!NT_SUCCESS(Status))
              goto cleanup;

          while (TRUE)
          {
              Status = ZwEnumerateValueKey(ChildKey3,
                                           ChildKeyIndex3,
                                           KeyValuePartialInformation,
                                           NULL,
                                           0,
                                           &RequiredLength);
              if (Status == STATUS_NO_MORE_ENTRIES)
                  break;
              else if (Status == STATUS_BUFFER_TOO_SMALL)
              {
                  KeyValueInformationLength = RequiredLength;
                  KeyValueInformation = ExAllocatePool(PagedPool, KeyValueInformationLength);
                  if (!KeyValueInformation)
                  {
                      Status = STATUS_INSUFFICIENT_RESOURCES;
                      goto cleanup;
                  }

                  Status = ZwEnumerateValueKey(ChildKey3,
                                               ChildKeyIndex3,
                                               KeyValuePartialInformation,
                                               KeyValueInformation,
                                               KeyValueInformationLength,
                                               &RequiredLength);
              }
              else
                  goto cleanup;
              if (!NT_SUCCESS(Status))
                  goto cleanup;

              Status = ZwEnumerateValueKey(ChildKey3,
                                           ChildKeyIndex3,
                                           KeyValueBasicInformation,
                                           NULL,
                                           0,
                                           &RequiredLength);
              if (Status == STATUS_BUFFER_TOO_SMALL)
              {
                  KeyNameInformationLength = RequiredLength;
                  KeyNameInformation = ExAllocatePool(PagedPool, KeyNameInformationLength + sizeof(WCHAR));
                  if (!KeyNameInformation)
                  {
                      Status = STATUS_INSUFFICIENT_RESOURCES;
                      goto cleanup;
                  }

                  Status = ZwEnumerateValueKey(ChildKey3,
                                               ChildKeyIndex3,
                                               KeyValueBasicInformation,
                                               KeyNameInformation,
                                               KeyNameInformationLength,
                                               &RequiredLength);
              }
              else
                  goto cleanup;

              ChildKeyIndex3++;

              if (!NT_SUCCESS(Status))
                  goto cleanup;

              KeyNameInformation->Name[KeyNameInformation->NameLength / sizeof(WCHAR)] = UNICODE_NULL;

              /* Skip translated entries */
              if (wcsstr(KeyNameInformation->Name, L".Translated"))
              {
                  ExFreePool(KeyNameInformation);
                  continue;
              }

              ExFreePool(KeyNameInformation);

              if (IopCheckForResourceConflict(ResourceList,
                                              (PCM_RESOURCE_LIST)KeyValueInformation->Data,
                                              Silent,
                                              ConflictingDescriptor))
              {
                  ExFreePool(KeyValueInformation);
                  Status = STATUS_CONFLICTING_ADDRESSES;
                  goto cleanup;
              }

              ExFreePool(KeyValueInformation);
          }
      }
   }

cleanup:
   if (ResourceMapKey != INVALID_HANDLE_VALUE)
       ZwClose(ResourceMapKey);
   if (ChildKey2 != INVALID_HANDLE_VALUE)
       ZwClose(ChildKey2);
   if (ChildKey3 != INVALID_HANDLE_VALUE)
       ZwClose(ChildKey3);

   if (Status == STATUS_NO_MORE_ENTRIES)
       Status = STATUS_SUCCESS;

   return Status;
}
Ejemplo n.º 18
0
NTSTATUS vboxWddmRegQueryVideoGuidString(ULONG cbBuf, PWCHAR pBuf, PULONG pcbResult)
{
    HANDLE hKey;
    NTSTATUS Status = vboxWddmRegOpenKey(&hKey, VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY, GENERIC_READ);
    Assert(Status == STATUS_SUCCESS);
    if (Status == STATUS_SUCCESS)
    {
        struct
        {
            KEY_BASIC_INFORMATION Name;
            WCHAR Buf[256];
        } Buf;
        WCHAR KeyBuf[sizeof (VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY)/2 + 256 + 64];
        wcscpy(KeyBuf, VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY);
        ULONG ResultLength;
        BOOL bFound = FALSE;
        for (ULONG i = 0; !bFound; ++i)
        {
            RtlZeroMemory(&Buf, sizeof (Buf));
            Status = ZwEnumerateKey(hKey, i, KeyBasicInformation, &Buf, sizeof (Buf), &ResultLength);
            Assert(Status == STATUS_SUCCESS);
            /* we should not encounter STATUS_NO_MORE_ENTRIES here since this would mean we did not find our entry */
            if (Status != STATUS_SUCCESS)
                break;

            HANDLE hSubKey;
            PWCHAR pSubBuf = KeyBuf + (sizeof (VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY) - 2)/2;
            memcpy(pSubBuf, Buf.Name.Name, Buf.Name.NameLength);
            pSubBuf += Buf.Name.NameLength/2;
            memcpy(pSubBuf, VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY_SUBKEY, sizeof (VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY_SUBKEY));
            Status = vboxWddmRegOpenKey(&hSubKey, KeyBuf, GENERIC_READ);
            Assert(Status == STATUS_SUCCESS);
            if (Status == STATUS_SUCCESS)
            {
                struct
                {
                    KEY_VALUE_PARTIAL_INFORMATION Info;
                    UCHAR Buf[sizeof (L"VBoxVideoWddm")]; /* should be enough */
                } KeyData;
                ULONG cbResult;
                UNICODE_STRING RtlStr;
                RtlInitUnicodeString(&RtlStr, L"Service");
                Status = ZwQueryValueKey(hSubKey,
                                         &RtlStr,
                                         KeyValuePartialInformation,
                                         &KeyData.Info,
                                         sizeof(KeyData),
                                         &cbResult);
                Assert(Status == STATUS_SUCCESS || STATUS_BUFFER_TOO_SMALL || STATUS_BUFFER_OVERFLOW);
                if (Status == STATUS_SUCCESS)
                {
                    if (KeyData.Info.Type == REG_SZ)
                    {
                        if (KeyData.Info.DataLength == sizeof (L"VBoxVideoWddm"))
                        {
                            if (!wcscmp(L"VBoxVideoWddm", (PWCHAR)KeyData.Info.Data))
                            {
                                bFound = TRUE;
                                *pcbResult = Buf.Name.NameLength + 2;
                                if (cbBuf >= Buf.Name.NameLength + 2)
                                {
                                    memcpy(pBuf, Buf.Name.Name, Buf.Name.NameLength + 2);
                                }
                                else
                                {
                                    Status = STATUS_BUFFER_TOO_SMALL;
                                }
                            }
                        }
                    }
                }

                NTSTATUS tmpStatus = ZwClose(hSubKey);
                Assert(tmpStatus == STATUS_SUCCESS);
            }
            else
                break;
        }
        NTSTATUS tmpStatus = ZwClose(hKey);
        Assert(tmpStatus == STATUS_SUCCESS);
    }

    return Status;
}
Ejemplo n.º 19
0
NTSTATUS
NTAPI
PciAcpiFindRsdt(OUT PACPI_BIOS_MULTI_NODE *AcpiMultiNode)
{
    BOOLEAN Result;
    NTSTATUS Status;
    HANDLE KeyHandle, SubKey;
    ULONG NumberOfBytes, i, Length;
    PKEY_FULL_INFORMATION FullInfo;
    PKEY_BASIC_INFORMATION KeyInfo;
    PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
    PACPI_BIOS_MULTI_NODE NodeData;
    UNICODE_STRING ValueName;
    struct
    {
        CM_FULL_RESOURCE_DESCRIPTOR Descriptor;
        ACPI_BIOS_MULTI_NODE Node;
    } *Package;

    /* So we know what to free at the end of the body */
    ValueInfo = NULL;
    KeyInfo = NULL;
    KeyHandle = NULL;
    FullInfo = NULL;
    Package = NULL;
    do
    {
        /* Open the ACPI BIOS key */
        Result = PciOpenKey(L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\"
                            L"System\\MultiFunctionAdapter",
                            NULL,
                            KEY_QUERY_VALUE,
                            &KeyHandle,
                            &Status);
        if (!Result) break;

        /* Query how much space should be allocated for the key information */
        Status = ZwQueryKey(KeyHandle,
                            KeyFullInformation,
                            NULL,
                            sizeof(ULONG),
                            &NumberOfBytes);
        if (Status != STATUS_BUFFER_TOO_SMALL) break;

        /* Allocate the space required */
        Status = STATUS_INSUFFICIENT_RESOURCES;
        FullInfo = ExAllocatePoolWithTag(PagedPool, NumberOfBytes, PCI_POOL_TAG);
        if ( !FullInfo ) break;

        /* Now query the key information that's needed */
        Status = ZwQueryKey(KeyHandle,
                            KeyFullInformation,
                            FullInfo,
                            NumberOfBytes,
                            &NumberOfBytes);
        if (!NT_SUCCESS(Status)) break;

        /* Allocate enough space to hold the value information plus the name */
        Status = STATUS_INSUFFICIENT_RESOURCES;
        Length = FullInfo->MaxNameLen + 26;
        KeyInfo = ExAllocatePoolWithTag(PagedPool, Length, PCI_POOL_TAG);
        if ( !KeyInfo ) break;

        /* Allocate the value information and name we expect to find */
        ValueInfo = ExAllocatePoolWithTag(PagedPool,
                                          sizeof(KEY_VALUE_PARTIAL_INFORMATION) +
                                          sizeof(L"ACPI BIOS"),
                                          PCI_POOL_TAG);
        if (!ValueInfo) break;

        /* Loop each sub-key */
        i = 0;
        while (TRUE)
        {
            /* Query each sub-key */
            Status = ZwEnumerateKey(KeyHandle,
                                    i++,
                                    KeyBasicInformation,
                                    KeyInfo,
                                    Length,
                                    &NumberOfBytes);
            if (Status == STATUS_NO_MORE_ENTRIES) break;

            /* Null-terminate the keyname, because the kernel does not */
            KeyInfo->Name[KeyInfo->NameLength / sizeof(WCHAR)] = UNICODE_NULL;

            /* Open this subkey */
            Result = PciOpenKey(KeyInfo->Name,
                                KeyHandle,
                                KEY_QUERY_VALUE,
                                &SubKey,
                                &Status);
            if (Result)
            {
                /* Query the identifier value for this subkey */
                RtlInitUnicodeString(&ValueName, L"Identifier");
                Status = ZwQueryValueKey(SubKey,
                                         &ValueName,
                                         KeyValuePartialInformation,
                                         ValueInfo,
                                         sizeof(KEY_VALUE_PARTIAL_INFORMATION) +
                                         sizeof(L"ACPI BIOS"),
                                         &NumberOfBytes);
                if (NT_SUCCESS(Status))
                {
                    /* Check if this is the PCI BIOS subkey */
                    if (!wcsncmp((PWCHAR)ValueInfo->Data,
                                 L"ACPI BIOS",
                                 ValueInfo->DataLength))
                    {
                        /* It is, proceed to query the PCI IRQ routing table */
                        Status = PciGetRegistryValue(L"Configuration Data",
                                                     KeyInfo->Name,
                                                     KeyHandle,
                                                     REG_FULL_RESOURCE_DESCRIPTOR,
                                                     (PVOID*)&Package,
                                                     &NumberOfBytes);
                        ZwClose(SubKey);
                        break;
                    }
                }

                /* Close the subkey and try the next one */
                ZwClose(SubKey);
            }
        }

        /* Check if we got here because the routing table was found */
        if (!NT_SUCCESS(Status))
        {
            /* This should only fail if we're out of entries */
            ASSERT(Status == STATUS_NO_MORE_ENTRIES);
            break;
        }

        /* Check if a descriptor was found */
        if (!Package) break;

        /* The configuration data is a resource list, and the BIOS node follows */
        NodeData = &Package->Node;

        /* How many E820 memory entries are there? */
        Length = sizeof(ACPI_BIOS_MULTI_NODE) +
                 (NodeData->Count - 1) * sizeof(ACPI_E820_ENTRY);

        /* Allocate the buffer needed to copy the information */
        Status = STATUS_INSUFFICIENT_RESOURCES;
        *AcpiMultiNode = ExAllocatePoolWithTag(NonPagedPool, Length, PCI_POOL_TAG);
        if (!*AcpiMultiNode) break;

        /* Copy the data */
        RtlCopyMemory(*AcpiMultiNode, NodeData, Length);
        Status = STATUS_SUCCESS;
    } while (FALSE);

    /* Close any opened keys, free temporary allocations, and return status */
    if (Package) ExFreePoolWithTag(Package, 0);
    if (ValueInfo) ExFreePoolWithTag(ValueInfo, 0);
    if (KeyInfo) ExFreePoolWithTag(KeyInfo, 0);
    if (FullInfo) ExFreePoolWithTag(FullInfo, 0);
    if (KeyHandle) ZwClose(KeyHandle);
    return Status;
}
Ejemplo n.º 20
0
NTSTATUS
NTAPI
PciGetIrqRoutingTableFromRegistry(OUT PPCI_IRQ_ROUTING_TABLE *PciRoutingTable)
{
    BOOLEAN Result;
    NTSTATUS Status;
    HANDLE KeyHandle, SubKey;
    ULONG NumberOfBytes, i, Length;
    PKEY_FULL_INFORMATION FullInfo;
    PKEY_BASIC_INFORMATION KeyInfo;
    PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
    UNICODE_STRING ValueName;
    struct
    {
        CM_FULL_RESOURCE_DESCRIPTOR Descriptor;
        PCI_IRQ_ROUTING_TABLE Table;
    } *Package;

    /* So we know what to free at the end of the body */
    Package = NULL;
    ValueInfo = NULL;
    KeyInfo = NULL;
    KeyHandle = NULL;
    FullInfo = NULL;
    do
    {
        /* Open the BIOS key */
        Result = PciOpenKey(L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\"
                            L"System\\MultiFunctionAdapter",
                            NULL,
                            KEY_QUERY_VALUE,
                            &KeyHandle,
                            &Status);
        if (!Result) break;

        /* Query how much space should be allocated for the key information */
        Status = ZwQueryKey(KeyHandle,
                            KeyFullInformation,
                            NULL,
                            sizeof(ULONG),
                            &NumberOfBytes);
        if (Status != STATUS_BUFFER_TOO_SMALL) break;

        /* Allocate the space required */
        Status = STATUS_INSUFFICIENT_RESOURCES;
        FullInfo = ExAllocatePoolWithTag(PagedPool, NumberOfBytes, PCI_POOL_TAG);
        if ( !FullInfo ) break;

        /* Now query the key information that's needed */
        Status = ZwQueryKey(KeyHandle,
                            KeyFullInformation,
                            FullInfo,
                            NumberOfBytes,
                            &NumberOfBytes);
        if (!NT_SUCCESS(Status)) break;

        /* Allocate enough space to hold the value information plus the name */
        Status = STATUS_INSUFFICIENT_RESOURCES;
        Length = FullInfo->MaxNameLen + 26;
        KeyInfo = ExAllocatePoolWithTag(PagedPool, Length, PCI_POOL_TAG);
        if (!KeyInfo) break;

        /* Allocate the value information and name we expect to find */
        ValueInfo = ExAllocatePoolWithTag(PagedPool,
                                          sizeof(KEY_VALUE_PARTIAL_INFORMATION) +
                                          sizeof(L"PCI BIOS"),
                                          PCI_POOL_TAG);
        if (!ValueInfo) break;

        /* Loop each sub-key */
        i = 0;
        while (TRUE)
        {
            /* Query each sub-key */
            Status = ZwEnumerateKey(KeyHandle,
                                    i++,
                                    KeyBasicInformation,
                                    KeyInfo,
                                    Length,
                                    &NumberOfBytes);
            if (Status == STATUS_NO_MORE_ENTRIES) break;

            /* Null-terminate the keyname, because the kernel does not */
            KeyInfo->Name[KeyInfo->NameLength / sizeof(WCHAR)] = UNICODE_NULL;

            /* Open this subkey */
            Result = PciOpenKey(KeyInfo->Name,
                                KeyHandle,
                                KEY_QUERY_VALUE,
                                &SubKey,
                                &Status);
            if (Result)
            {
                /* Query the identifier value for this subkey */
                RtlInitUnicodeString(&ValueName, L"Identifier");
                Status = ZwQueryValueKey(SubKey,
                                         &ValueName,
                                         KeyValuePartialInformation,
                                         ValueInfo,
                                         sizeof(KEY_VALUE_PARTIAL_INFORMATION) +
                                         sizeof(L"PCI BIOS"),
                                         &NumberOfBytes);
                if (NT_SUCCESS(Status))
                {
                    /* Check if this is the PCI BIOS subkey */
                    if (!wcsncmp((PWCHAR)ValueInfo->Data,
                                 L"PCI BIOS",
                                 ValueInfo->DataLength))
                    {
                        /* It is, proceed to query the PCI IRQ routing table */
                        Status = PciGetRegistryValue(L"Configuration Data",
                                                     L"RealModeIrqRoutingTable"
                                                     L"\\0",
                                                     SubKey,
                                                     REG_FULL_RESOURCE_DESCRIPTOR,
                                                     (PVOID*)&Package,
                                                     &NumberOfBytes);
                        ZwClose(SubKey);
                        break;
                    }
                }

                /* Close the subkey and try the next one */
                ZwClose(SubKey);
            }
        }

        /* Check if we got here because the routing table was found */
        if (!NT_SUCCESS(Status)) break;

        /* Check if a descriptor was found */
        if (!Package) break;

        /* Make sure the buffer is large enough to hold the table */
        if ((NumberOfBytes < sizeof(*Package)) ||
            (Package->Table.TableSize >
             (NumberOfBytes - sizeof(CM_FULL_RESOURCE_DESCRIPTOR))))
        {
            /* Invalid package size */
            Status = STATUS_UNSUCCESSFUL;
            break;
        }

        /* Allocate space for the table */
        Status = STATUS_INSUFFICIENT_RESOURCES;
        *PciRoutingTable = ExAllocatePoolWithTag(PagedPool,
                                                 NumberOfBytes,
                                                 PCI_POOL_TAG);
        if (!*PciRoutingTable) break;

        /* Copy the registry data */
        RtlCopyMemory(*PciRoutingTable,
                      &Package->Table,
                      NumberOfBytes - sizeof(CM_FULL_RESOURCE_DESCRIPTOR));
        Status = STATUS_SUCCESS;
    } while (FALSE);

    /* Close any opened keys, free temporary allocations, and return status */
    if (Package) ExFreePoolWithTag(Package, 0);
    if (ValueInfo) ExFreePoolWithTag(ValueInfo, 0);
    if (KeyInfo) ExFreePoolWithTag(KeyInfo, 0);
    if (FullInfo) ExFreePoolWithTag(FullInfo, 0);
    if (KeyHandle) ZwClose(KeyHandle);
    return Status;
}
Ejemplo n.º 21
0
NTSTATUS NTAPI EnumDeviceKeys(
    IN PUNICODE_STRING RegistryPath,
    IN PWSTR SubKey,
    IN PREGISTRY_CALLBACK_ROUTINE Callback,
    IN PVOID Context)
/*
    Description:
        Enumerate the device subkeys in the driver's registry entry, and
        call the specified callback routine for each device.

    Parameters:
        RegistryPath    The location of the registry entry
        Subkey          The device's subkey
        Callback        A routine called for each device
        Context         ???

    Return Value:
        NT status STATUS_SUCCESS if successful
*/
{
    NTSTATUS s;
    OBJECT_ATTRIBUTES oa;
    HANDLE hKey, hSubKey;
    UNICODE_STRING SubkeyName;
    ULONG i;

    // Attempt to open the key

    InitializeObjectAttributes(&oa, RegistryPath, OBJ_CASE_INSENSITIVE,
                                NULL, (PSECURITY_DESCRIPTOR)NULL);

    s = ZwOpenKey(&hKey, KEY_READ, &oa);

        TEST_STATUS(s); // debugging

    if (! NT_SUCCESS(s))
        return s;   // Problem

    RtlInitUnicodeString(&SubkeyName, SubKey);

    DPRINT("Subkey: %wZ\n", &SubkeyName);

    InitializeObjectAttributes(&oa, &SubkeyName, OBJ_CASE_INSENSITIVE,
                                hKey, (PSECURITY_DESCRIPTOR)NULL);

    s = ZwOpenKey(&hSubKey, KEY_ENUMERATE_SUB_KEYS, &oa);

    ZwClose(hKey);

        TEST_STATUS(s); // debugging

    if (! NT_SUCCESS(s))
        return s;


    // And now, the enumeration

    for (i = 0;; i ++)
    {
        KEY_BASIC_INFORMATION Info;
        PKEY_BASIC_INFORMATION pInfo;
        ULONG ResultLength = 0;
        ULONG Size = 0;
        PWSTR Pos;
        PWSTR Name;

        // Find the length of the subkey data

//        Info.NameLength = 0;    // TEMPORARY!

        s = ZwEnumerateKey(hSubKey, i, KeyBasicInformation, &Info,
                            sizeof(Info), &ResultLength);

        if (s == STATUS_NO_MORE_ENTRIES)
            break;

        DPRINT("Found an entry, allocating memory...\n");

//        Size = Info.NameLength + FIELD_OFFSET(KEY_BASIC_INFORMATION, Name[0]);
        Size = ResultLength + FIELD_OFFSET(KEY_BASIC_INFORMATION, Name[0]);

        DPRINT("Size is %d\n", Size);

        pInfo = (PKEY_BASIC_INFORMATION) ExAllocatePool(PagedPool, Size);

        if (pInfo == NULL)
        {
            DPRINT("INSUFFICIENT RESOURCES!\n");
            s = STATUS_INSUFFICIENT_RESOURCES;
            break;
        }

        DPRINT("Re-enumerating...\n");

        s = ZwEnumerateKey(hSubKey, i, KeyBasicInformation, pInfo, Size,
                            &ResultLength);

//        TEST_STATUS(s); // debugging

        if (! NT_SUCCESS(s))
        {
            ExFreePool((PVOID) pInfo);
            s = STATUS_INTERNAL_ERROR;
            break;
        }

        DPRINT("Allocating memory for name...\n");

        Name = ExAllocatePool(PagedPool,
                          RegistryPath->Length + sizeof(WCHAR) +
                          SubkeyName.Length + sizeof(WCHAR) +
                          pInfo->NameLength + sizeof(UNICODE_NULL));

        if (Name == NULL)
        {
            DPRINT("INSUFFICIENT RESOURCES!");
            ExFreePool((PVOID) pInfo);
            return STATUS_INSUFFICIENT_RESOURCES;
        }

        // Copy the key name
        RtlCopyMemory((PVOID)Name, (PVOID)RegistryPath->Buffer, RegistryPath->Length);
        Pos = Name + (RegistryPath->Length / sizeof(WCHAR));
        Pos[0] = '\\';
        Pos++;

        // Copy the parameters sub key name
        RtlCopyMemory((PVOID)Pos, (PVOID)SubKey, SubkeyName.Length);    //SubkeyName?
        Pos += SubkeyName.Length / sizeof(WCHAR);
        Pos[0] = '\\';
        Pos ++;

        // Copy the device sub key name
        RtlCopyMemory((PVOID)Pos, (PVOID)pInfo->Name, pInfo->NameLength);
        Pos += pInfo->NameLength / sizeof(WCHAR);
        Pos[0] = UNICODE_NULL;

        ExFreePool((PVOID)pInfo);

        DPRINT("Calling callback...\n");

        s = (*Callback)(Name, Context);

        if (! NT_SUCCESS(s))
        {   DPRINT("Callback FAILED\n");
            break;}
    }

    ZwClose(hSubKey);

    DPRINT("%d device registry keys found\n", i);

    if ((i == 0) && (s == STATUS_NO_MORE_ENTRIES))
        return STATUS_DEVICE_CONFIGURATION_ERROR;

    return s == STATUS_NO_MORE_ENTRIES ? STATUS_SUCCESS : s;
}