Ejemplo n.º 1
0
static VOID Test_guid(
    VOID
    )
{
    GUID guid;
    GUID ns;
    UNICODE_STRING dnsNamespace = RTL_CONSTANT_STRING(L"{6ba7b810-9dad-11d1-80b4-00c04fd430c8}");
    UNICODE_STRING urlNamespace = RTL_CONSTANT_STRING(L"{6ba7b811-9dad-11d1-80b4-00c04fd430c8}");
    UNICODE_STRING oidNamespace = RTL_CONSTANT_STRING(L"{6ba7b812-9dad-11d1-80b4-00c04fd430c8}");
    UNICODE_STRING x500Namespace = RTL_CONSTANT_STRING(L"{6ba7b814-9dad-11d1-80b4-00c04fd430c8}");

    // Taken from http://svn.python.org/projects/python/branches/py3k/Lib/test/test_uuid.py

    RtlGUIDFromString(&dnsNamespace, &ns);
    PhGenerateGuidFromName(&guid, &ns, "python.org", 10, GUID_VERSION_MD5);
    assert(AreGuidsEqual(&guid, L"{6fa459ea-ee8a-3ca4-894e-db77e160355e}"));

    RtlGUIDFromString(&urlNamespace, &ns);
    PhGenerateGuidFromName(&guid, &ns, "http://python.org/", 18, GUID_VERSION_MD5);
    assert(AreGuidsEqual(&guid, L"{9fe8e8c4-aaa8-32a9-a55c-4535a88b748d}"));

    RtlGUIDFromString(&oidNamespace, &ns);
    PhGenerateGuidFromName(&guid, &ns, "1.3.6.1", 7, GUID_VERSION_SHA1);
    assert(AreGuidsEqual(&guid, L"{1447fa61-5277-5fef-a9b3-fbc6e44f4af3}"));

    RtlGUIDFromString(&x500Namespace, &ns);
    PhGenerateGuidFromName(&guid, &ns, "c=ca", 4, GUID_VERSION_SHA1);
    assert(AreGuidsEqual(&guid, L"{cc957dd1-a972-5349-98cd-874190002798}"));
}
Ejemplo n.º 2
0
NTSTATUS kuhl_m_sysenv_del(int argc, wchar_t * argv[])
{
	NTSTATUS status;
	LPCWSTR szName, szGuid, szAttributes;
	UNICODE_STRING uName, uGuid;
	GUID guid;
	DWORD attributes;

	kull_m_string_args_byName(argc, argv, L"name", &szName, MIMIKATZ);
	kull_m_string_args_byName(argc, argv, L"guid", &szGuid, L"{b16b00b5-cafe-babe-0ee0-dabadabad000}");
	kull_m_string_args_byName(argc, argv, L"attributes", &szAttributes, L"1");

	RtlInitUnicodeString(&uName, szName);
	RtlInitUnicodeString(&uGuid, szGuid);
	attributes = wcstoul(szAttributes, NULL, 0);

	status = RtlGUIDFromString(&uGuid, &guid);
	if(NT_SUCCESS(status))
	{
		kprintf(L"Name       : %wZ\nVendor GUID: ", &uName);
		kuhl_m_sysenv_display_vendorGuid(&guid);
		kprintf(L"\nAttributes : %08x (", attributes);
		kuhl_m_sysenv_display_attributes(attributes);
		kprintf(L")\n");

		status = NtSetSystemEnvironmentValueEx(&uName, &guid, NULL, 0, attributes);
		if(NT_SUCCESS(status))
			kprintf(L"> OK!\n");
		else if(status == STATUS_VARIABLE_NOT_FOUND)
			PRINT_ERROR(L"System Environment Variable not found.\n");
		else PRINT_ERROR(L"NtSetSystemEnvironmentValueEx(data): 0x%08x\n", status);
	}
	else PRINT_ERROR(L"RtlGUIDFromString: 0x%08x\n", status);
	return STATUS_SUCCESS;
}
Ejemplo n.º 3
0
static GUID *parse_uuid( GUID *guid, const char *str )
{
    /* standard uuid format */
    if (strlen(str) == 36)
    {
        UNICODE_STRING strW;
        WCHAR buffer[39];

        if (MultiByteToWideChar( CP_UNIXCP, 0, str, 36, buffer + 1, 36 ))
        {
            buffer[0] = '{';
            buffer[37] = '}';
            buffer[38] = 0;
            RtlInitUnicodeString( &strW, buffer );
            if (!RtlGUIDFromString( &strW, guid )) return guid;
        }
    }

    /* check for xxxx-xxxx format (FAT serial number) */
    if (strlen(str) == 9 && str[4] == '-')
    {
        memset( guid, 0, sizeof(*guid) );
        if (sscanf( str, "%hx-%hx", &guid->Data2, &guid->Data3 ) == 2) return guid;
    }
    return NULL;
}
Ejemplo n.º 4
0
NTSTATUS GUIDFromWdfString(__in WDFSTRING guidString, __out PGUID guid)
{
    UNICODE_STRING guidStringW;

    WdfStringGetUnicodeString(guidString, &guidStringW);

    return RtlGUIDFromString (&guidStringW, guid);
}
Ejemplo n.º 5
0
NTSTATUS kuhl_m_kernel_sysenv_set(int argc, wchar_t * argv[])
{
	NTSTATUS status;
	LPCWSTR szName, szGuid, szAttributes, szData;
	UNICODE_STRING uName, uGuid;
	GUID guid;
	LPBYTE hex = NULL;
	DWORD size, attributes, nameLen, structSize;
	PMIMIDRV_VARIABLE_NAME_AND_VALUE vnv;

	kull_m_string_args_byName(argc, argv, L"name", &szName, L"Kernel_Lsa_Ppl_Config");
	kull_m_string_args_byName(argc, argv, L"guid", &szGuid, L"{77fa9abd-0359-4d32-bd60-28f4e78f784b}");
	kull_m_string_args_byName(argc, argv, L"attributes", &szAttributes, L"1");
	kull_m_string_args_byName(argc, argv, L"data", &szData, L"00000000");

	RtlInitUnicodeString(&uName, szName);
	RtlInitUnicodeString(&uGuid, szGuid);
	attributes = wcstoul(szAttributes, NULL, 0);

	status = RtlGUIDFromString(&uGuid, &guid);
	if(NT_SUCCESS(status))
	{
		kprintf(L"Name       : %wZ\nVendor GUID: ", &uName);
		kuhl_m_sysenv_display_vendorGuid(&guid);
		kprintf(L"\nAttributes : %08x (", attributes);
		kuhl_m_sysenv_display_attributes(attributes);
		kprintf(L")\n");
		if(kull_m_string_stringToHexBuffer(szData, &hex, &size))
		{
			kprintf(L"Length     : %u\nData       : ", size);
			kull_m_string_wprintf_hex(hex, size, 1);
			kprintf(L"\n\n");
			nameLen = ((DWORD) wcslen(szName) + 1) * sizeof(wchar_t);
			structSize = FIELD_OFFSET(MIMIDRV_VARIABLE_NAME_AND_VALUE, Name) + nameLen  + size;
			if(vnv = (PMIMIDRV_VARIABLE_NAME_AND_VALUE) LocalAlloc(LPTR, structSize))
			{
				vnv->Attributes = attributes;
				RtlCopyMemory(&vnv->VendorGuid, &guid, sizeof(GUID));
				vnv->ValueLength = size;
				vnv->ValueOffset = FIELD_OFFSET(MIMIDRV_VARIABLE_NAME_AND_VALUE, Name) + nameLen;
				RtlCopyMemory(vnv->Name, szName, nameLen);
				RtlCopyMemory((PBYTE) vnv + vnv->ValueOffset, hex, size);
				if(kull_m_kernel_mimidrv_simple_output(IOCTL_MIMIDRV_SYSENVSET, vnv, structSize))
					kprintf(L"> OK!\n");
				LocalFree(vnv);
			}
			LocalFree(hex);
		}
	}
	else PRINT_ERROR(L"RtlGUIDFromString: 0x%08x\n", status);
	return STATUS_SUCCESS;
}
Ejemplo n.º 6
0
static BOOLEAN AreGuidsEqual(
    __in PGUID Guid1,
    __in PWSTR Guid2
    )
{
    GUID guid2;
    UNICODE_STRING us;

    RtlInitUnicodeString(&us, Guid2);
    RtlGUIDFromString(&us, &guid2);

    return memcmp(Guid1, &guid2, sizeof(GUID)) == 0;
}
Ejemplo n.º 7
0
static PPH_STRING NetworkAdapterQueryName(
    _Inout_ PPH_NETADAPTER_SYSINFO_CONTEXT Context
    )
{
    NDIS_OID opcode;
    IO_STATUS_BLOCK isb;
    WCHAR adapterNameBuffer[MAX_PATH] = L"";

    // https://msdn.microsoft.com/en-us/library/windows/hardware/ff569584.aspx
    opcode = OID_GEN_FRIENDLY_NAME;

    if (NT_SUCCESS(NtDeviceIoControlFile(
        Context->DeviceHandle,
        NULL,
        NULL,
        NULL,
        &isb,
        IOCTL_NDIS_QUERY_GLOBAL_STATS,
        &opcode,
        sizeof(NDIS_OID),
        adapterNameBuffer,
        sizeof(adapterNameBuffer)
        )))
    {
        return PhCreateString(adapterNameBuffer);
    }

    // HACK: Query adapter description using undocumented function.
    if (Context->GetInterfaceDescriptionFromGuid_I)
    {
        GUID deviceGuid = GUID_NULL;
        UNICODE_STRING guidStringUs;

        PhStringRefToUnicodeString(&Context->AdapterEntry->InterfaceGuid->sr, &guidStringUs);

        if (NT_SUCCESS(RtlGUIDFromString(&guidStringUs, &deviceGuid)))
        {
            SIZE_T adapterDescriptionLength = 0;
            WCHAR adapterDescription[NDIS_IF_MAX_STRING_SIZE + 1] = L"";

            adapterDescriptionLength = sizeof(adapterDescription); // This is what the API expects apparently... 

            if (SUCCEEDED(Context->GetInterfaceDescriptionFromGuid_I(&deviceGuid, adapterDescription, &adapterDescriptionLength, NULL, NULL)))
            {
                return PhCreateString(adapterDescription);
            }
        }
    }

    return PhCreateString(L"Unknown");
}
Ejemplo n.º 8
0
NTSTATUS kuhl_m_sysenv_get(int argc, wchar_t * argv[])
{
	NTSTATUS status;
	LPCWSTR szName, szGuid;
	UNICODE_STRING uName, uGuid;
	GUID guid;
	DWORD bufferLen = 0, attributes;
	PVOID buffer;

	kull_m_string_args_byName(argc, argv, L"name", &szName, L"Kernel_Lsa_Ppl_Config");
	kull_m_string_args_byName(argc, argv, L"guid", &szGuid, L"{77fa9abd-0359-4d32-bd60-28f4e78f784b}");
	RtlInitUnicodeString(&uName, szName);
	RtlInitUnicodeString(&uGuid, szGuid);

	status = RtlGUIDFromString(&uGuid, &guid);
	if(NT_SUCCESS(status))
	{
		kprintf(L"Name       : %wZ\nVendor GUID: ", &uName);
		kuhl_m_sysenv_display_vendorGuid(&guid);
		kprintf(L"\n");
		status = NtQuerySystemEnvironmentValueEx(&uName, &guid, NULL, &bufferLen, &attributes);
		if((status == STATUS_BUFFER_TOO_SMALL) && bufferLen)
		{
			if(buffer = LocalAlloc(LPTR, bufferLen))
			{
				status = NtQuerySystemEnvironmentValueEx(&uName, &guid, buffer, &bufferLen, &attributes);
				if(NT_SUCCESS(status))
				{
					kprintf(L"Attributes : %08x (", attributes);
					kuhl_m_sysenv_display_attributes(attributes);
					kprintf(L")\nLength     : %u\nData       : ", bufferLen);
					kull_m_string_wprintf_hex(buffer, bufferLen, 1);
					kprintf(L"\n");
				}
				else PRINT_ERROR(L"NtQuerySystemEnvironmentValueEx(data): 0x%08x\n", status);
				LocalFree(buffer);
			}
		}
		else if(status == STATUS_VARIABLE_NOT_FOUND)
			PRINT_ERROR(L"System Environment Variable not found.\n");
		else PRINT_ERROR(L"NtQuerySystemEnvironmentValueEx(size): 0x%08x\n", status);
	}
	else PRINT_ERROR(L"RtlGUIDFromString: 0x%08x\n", status);
	return STATUS_SUCCESS;
}
Ejemplo n.º 9
0
NTSTATUS kuhl_m_sysenv_set(int argc, wchar_t * argv[])
{
	NTSTATUS status;
	LPCWSTR szName, szGuid, szAttributes, szData;
	UNICODE_STRING uName, uGuid;
	GUID guid;
	LPBYTE hex;
	DWORD size, attributes;

	kull_m_string_args_byName(argc, argv, L"name", &szName, MIMIKATZ);
	kull_m_string_args_byName(argc, argv, L"guid", &szGuid, L"{b16b00b5-cafe-babe-0ee0-dabadabad000}");
	kull_m_string_args_byName(argc, argv, L"attributes", &szAttributes, L"1");
	kull_m_string_args_byName(argc, argv, L"data", &szData, L"410020004c00610020005600690065002c002000410020004c00270041006d006f00750072000000");

	RtlInitUnicodeString(&uName, szName);
	RtlInitUnicodeString(&uGuid, szGuid);
	attributes = wcstoul(szAttributes, NULL, 0);

	status = RtlGUIDFromString(&uGuid, &guid);
	if(NT_SUCCESS(status))
	{
		kprintf(L"Name       : %wZ\nVendor GUID: ", &uName);
		kuhl_m_sysenv_display_vendorGuid(&guid);
		kprintf(L"\nAttributes : %08x (", attributes);
		kuhl_m_sysenv_display_attributes(attributes);
		kprintf(L")\n");
		if(kull_m_string_stringToHexBuffer(szData, &hex, &size))
		{
			kprintf(L"Length     : %u\nData       : ", size);
			kull_m_string_wprintf_hex(hex, size, 1);
			kprintf(L"\n\n");
			status = NtSetSystemEnvironmentValueEx(&uName, &guid, hex, size, attributes);
			if(NT_SUCCESS(status))
				kprintf(L"> OK!\n");
			else PRINT_ERROR(L"NtSetSystemEnvironmentValueEx(data): 0x%08x\n", status);
			LocalFree(hex);
		}
	}
	else PRINT_ERROR(L"RtlGUIDFromString: 0x%08x\n", status);
	return STATUS_SUCCESS;
}
Ejemplo n.º 10
0
/*++
 * @name IoSetDeviceInterfaceState
 * @implemented
 *
 * Enables or disables an instance of a previously registered device
 * interface class.
 * Documented in WDK.
 *
 * @param SymbolicLinkName
 *        Pointer to the string identifying instance to enable or disable
 *
 * @param Enable
 *        TRUE = enable, FALSE = disable
 *
 * @return Usual NTSTATUS
 *
 * @remarks Must be called at IRQL = PASSIVE_LEVEL in the context of a
 *          system thread
 *
 *--*/
NTSTATUS
NTAPI
IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName,
                          IN BOOLEAN Enable)
{
    PDEVICE_OBJECT PhysicalDeviceObject;
    PFILE_OBJECT FileObject;
    UNICODE_STRING GuidString;
    UNICODE_STRING SymLink;
    PWCHAR StartPosition;
    PWCHAR EndPosition;
    NTSTATUS Status;
    LPCGUID EventGuid;
    HANDLE InstanceHandle, ControlHandle;
    UNICODE_STRING KeyName;
    OBJECT_ATTRIBUTES ObjectAttributes;
    ULONG LinkedValue;
    GUID DeviceGuid;

    if (SymbolicLinkName == NULL)
        return STATUS_INVALID_PARAMETER_1;

    DPRINT("IoSetDeviceInterfaceState('%wZ', %u)\n", SymbolicLinkName, Enable);

    /* Symbolic link name is \??\ACPI#PNP0501#1#{GUID}\ReferenceString */
    /* Get GUID from SymbolicLinkName */
    StartPosition = wcschr(SymbolicLinkName->Buffer, L'{');
    EndPosition = wcschr(SymbolicLinkName->Buffer, L'}');
    if (!StartPosition ||!EndPosition || StartPosition > EndPosition)
    {
        DPRINT1("IoSetDeviceInterfaceState() returning STATUS_INVALID_PARAMETER_1\n");
        return STATUS_INVALID_PARAMETER_1;
    }
    GuidString.Buffer = StartPosition;
    GuidString.MaximumLength = GuidString.Length = (USHORT)((ULONG_PTR)(EndPosition + 1) - (ULONG_PTR)StartPosition);

    SymLink.Buffer = SymbolicLinkName->Buffer;
    SymLink.MaximumLength = SymLink.Length = (USHORT)((ULONG_PTR)(EndPosition + 1) - (ULONG_PTR)SymLink.Buffer);
    DPRINT("IoSetDeviceInterfaceState('%wZ', %u)\n", SymbolicLinkName, Enable);

    Status = OpenRegistryHandlesFromSymbolicLink(SymbolicLinkName,
                                                 KEY_CREATE_SUB_KEY,
                                                 NULL,
                                                 NULL,
                                                 &InstanceHandle);
    if (!NT_SUCCESS(Status))
        return Status;

    RtlInitUnicodeString(&KeyName, L"Control");
    InitializeObjectAttributes(&ObjectAttributes,
                               &KeyName,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               InstanceHandle,
                               NULL);
    Status = ZwCreateKey(&ControlHandle,
                         KEY_SET_VALUE,
                         &ObjectAttributes,
                         0,
                         NULL,
                         REG_OPTION_VOLATILE,
                         NULL);
    ZwClose(InstanceHandle);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Failed to create the Control subkey\n");
        return Status;
    }

    LinkedValue = (Enable ? 1 : 0);

    RtlInitUnicodeString(&KeyName, L"Linked");
    Status = ZwSetValueKey(ControlHandle,
                           &KeyName,
                           0,
                           REG_DWORD,
                           &LinkedValue,
                           sizeof(ULONG));
    ZwClose(ControlHandle);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Failed to write the Linked value\n");
        return Status;
    }

    /* Get pointer to the PDO */
    Status = IoGetDeviceObjectPointer(
        &SymLink,
        0, /* DesiredAccess */
        &FileObject,
        &PhysicalDeviceObject);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("IoGetDeviceObjectPointer() failed with status 0x%08lx\n", Status);
        return Status;
    }

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

    EventGuid = Enable ? &GUID_DEVICE_INTERFACE_ARRIVAL : &GUID_DEVICE_INTERFACE_REMOVAL;
    IopNotifyPlugPlayNotification(
        PhysicalDeviceObject,
        EventCategoryDeviceInterfaceChange,
        EventGuid,
        &DeviceGuid,
        (PVOID)SymbolicLinkName);

    ObDereferenceObject(FileObject);
    DPRINT("Status %x\n", Status);
    return STATUS_SUCCESS;
}
Ejemplo n.º 11
0
Archivo: crypt.c Proyecto: dvdhoo/wine
/***********************************************************************
 *      CryptCATEnumerateMember  (WINTRUST.@)
 */
CRYPTCATMEMBER * WINAPI CryptCATEnumerateMember(HANDLE hCatalog, CRYPTCATMEMBER *prev)
{
    struct cryptcat *cc = hCatalog;
    CRYPTCATMEMBER *member = prev;
    CTL_ENTRY *entry;
    DWORD size, i;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

error:
    HeapFree(GetProcessHeap(), 0, member->pIndirectData);
    HeapFree(GetProcessHeap(), 0, member->pwszReferenceTag);
    HeapFree(GetProcessHeap(), 0, member);
    return NULL;
}
Ejemplo n.º 12
0
BOOL kull_m_rpc_drsr_getDomainAndUserInfos(RPC_BINDING_HANDLE *hBinding, LPCWSTR ServerName, LPCWSTR Domain, GUID *DomainGUID, LPCWSTR User, LPCWSTR Guid, GUID *UserGuid)
{
	BOOL DomainGUIDfound = FALSE, ObjectGUIDfound = FALSE;
	DWORD i;
	ULONG drsStatus;
	DRS_HANDLE hDrs = NULL;
	DRS_EXTENSIONS_INT DrsExtensionsInt = {0};
	DRS_EXTENSIONS *pDrsExtensionsOutput = NULL;
	DRS_MSG_DCINFOREQ dcInfoReq = {0};
	DWORD dcOutVersion = 0;
	DRS_MSG_DCINFOREPLY dcInfoRep = {0};
	LPWSTR sGuid;
	UNICODE_STRING uGuid;

	RpcTryExcept
	{
		DrsExtensionsInt.cb = sizeof(DRS_EXTENSIONS_INT) - sizeof(DWORD);
		drsStatus = IDL_DRSBind(*hBinding, &DRSUAPI_DS_BIND_GUID_Standard, (DRS_EXTENSIONS *) &DrsExtensionsInt, &pDrsExtensionsOutput, &hDrs);
		if(drsStatus == 0)
		{
			dcInfoReq.V1.InfoLevel = 2;
			dcInfoReq.V1.Domain = (LPWSTR) Domain;
			drsStatus = IDL_DRSDomainControllerInfo(hDrs, 1, &dcInfoReq, &dcOutVersion, &dcInfoRep);
			if(drsStatus == 0)
			{
				if(dcOutVersion == 2)
				{
					for(i = 0; i < dcInfoRep.V2.cItems; i++)
					{
						if(!DomainGUIDfound && ((_wcsicmp(ServerName, dcInfoRep.V2.rItems[i].DnsHostName) == 0) || (_wcsicmp(ServerName, dcInfoRep.V2.rItems[i].NetbiosName) == 0)))
						{
							DomainGUIDfound = TRUE;
							*DomainGUID = dcInfoRep.V2.rItems[i].NtdsDsaObjectGuid;
						}
					}
					if(!DomainGUIDfound)
						PRINT_ERROR(L"DomainControllerInfo: DC \'%s\' not found\n", ServerName);
				}
				else PRINT_ERROR(L"DomainControllerInfo: bad version (%u)\n", dcOutVersion);
				kull_m_rpc_drsr_free_DRS_MSG_DCINFOREPLY_data(dcOutVersion, &dcInfoRep);
			}
			else PRINT_ERROR(L"DomainControllerInfo: 0x%08x (%u)\n", drsStatus, drsStatus);
			
			if(Guid)
			{
				RtlInitUnicodeString(&uGuid, Guid);
				ObjectGUIDfound = NT_SUCCESS(RtlGUIDFromString(&uGuid, UserGuid));
			}
			else if(User)
			{
				if(kull_m_rpc_drsr_CrackName(hDrs, wcschr(User, L'\\') ? DS_NT4_ACCOUNT_NAME : wcschr(User, L'=') ? DS_FQDN_1779_NAME : wcschr(User, L'@') ? DS_USER_PRINCIPAL_NAME : DS_NT4_ACCOUNT_NAME_SANS_DOMAIN, User, DS_UNIQUE_ID_NAME, &sGuid, NULL))
				{
					RtlInitUnicodeString(&uGuid, sGuid);
					ObjectGUIDfound = NT_SUCCESS(RtlGUIDFromString(&uGuid, UserGuid));
				}
			}
			drsStatus = IDL_DRSUnbind(&hDrs);
			MIDL_user_free(pDrsExtensionsOutput);
		}
	}
	RpcExcept(DRS_EXCEPTION)
		PRINT_ERROR(L"RPC Exception 0x%08x (%u)\n", RpcExceptionCode(), RpcExceptionCode());
	RpcEndExcept
	return (DomainGUIDfound && (ObjectGUIDfound || !(Guid || User)));
}
Ejemplo n.º 13
0
BOOLEAN PhaGetProcessKnownCommandLine(
    __in PPH_STRING CommandLine,
    __in PH_KNOWN_PROCESS_TYPE KnownProcessType,
    __out PPH_KNOWN_PROCESS_COMMAND_LINE KnownCommandLine
    )
{
    switch (KnownProcessType & KnownProcessTypeMask)
    {
    case ServiceHostProcessType:
        {
            // svchost.exe -k <GroupName>

            static PH_COMMAND_LINE_OPTION options[] =
            {
                { 1, L"k", MandatoryArgumentType }
            };

            KnownCommandLine->ServiceHost.GroupName = NULL;

            PhParseCommandLine(
                &CommandLine->sr,
                options,
                sizeof(options) / sizeof(PH_COMMAND_LINE_OPTION),
                PH_COMMAND_LINE_IGNORE_UNKNOWN_OPTIONS,
                PhpSvchostCommandLineCallback,
                KnownCommandLine
                );

            if (KnownCommandLine->ServiceHost.GroupName)
            {
                PhaDereferenceObject(KnownCommandLine->ServiceHost.GroupName);
                return TRUE;
            }
            else
            {
                return FALSE;
            }
        }
        break;
    case RunDllAsAppProcessType:
        {
            // rundll32.exe <DllName>,<ProcedureName> ...

            SIZE_T i;
            ULONG_PTR lastIndexOfComma;
            PPH_STRING dllName;
            PPH_STRING procedureName;

            i = 0;

            // Get the rundll32.exe part.

            dllName = PhParseCommandLinePart(&CommandLine->sr, &i);

            if (!dllName)
                return FALSE;

            PhDereferenceObject(dllName);

            // Get the DLL name part.

            while (i < CommandLine->Length / 2 && CommandLine->Buffer[i] == ' ')
                i++;

            dllName = PhParseCommandLinePart(&CommandLine->sr, &i);

            if (!dllName)
                return FALSE;

            PhaDereferenceObject(dllName);

            // The procedure name begins after the last comma.

            lastIndexOfComma = PhFindLastCharInString(dllName, 0, ',');

            if (lastIndexOfComma == -1)
                return FALSE;

            procedureName = PhaSubstring(
                dllName,
                lastIndexOfComma + 1,
                dllName->Length / 2 - lastIndexOfComma - 1
                );
            dllName = PhaSubstring(dllName, 0, lastIndexOfComma);

            // If the DLL name isn't an absolute path, assume it's in system32.
            // TODO: Use a proper search function.

            if (RtlDetermineDosPathNameType_U(dllName->Buffer) == RtlPathTypeRelative)
            {
                dllName = PhaConcatStrings(
                    3,
                    ((PPH_STRING)PHA_DEREFERENCE(PhGetSystemDirectory()))->Buffer,
                    L"\\",
                    dllName->Buffer
                    );
            }

            KnownCommandLine->RunDllAsApp.FileName = dllName;
            KnownCommandLine->RunDllAsApp.ProcedureName = procedureName;
        }
        break;
    case ComSurrogateProcessType:
        {
            // dllhost.exe /processid:<Guid>

            static PH_STRINGREF inprocServer32Name = PH_STRINGREF_INIT(L"InprocServer32");

            SIZE_T i;
            ULONG_PTR indexOfProcessId;
            PPH_STRING argPart;
            PPH_STRING guidString;
            UNICODE_STRING guidStringUs;
            GUID guid;
            HANDLE clsidKeyHandle;
            HANDLE inprocServer32KeyHandle;
            PPH_STRING fileName;

            i = 0;

            // Get the dllhost.exe part.

            argPart = PhParseCommandLinePart(&CommandLine->sr, &i);

            if (!argPart)
                return FALSE;

            PhDereferenceObject(argPart);

            // Get the argument part.

            while (i < (ULONG)CommandLine->Length / 2 && CommandLine->Buffer[i] == ' ')
                i++;

            argPart = PhParseCommandLinePart(&CommandLine->sr, &i);

            if (!argPart)
                return FALSE;

            PhaDereferenceObject(argPart);

            // Find "/processid:"; the GUID is just after that.

            PhUpperString(argPart);
            indexOfProcessId = PhFindStringInString(argPart, 0, L"/PROCESSID:");

            if (indexOfProcessId == -1)
                return FALSE;

            guidString = PhaSubstring(
                argPart,
                indexOfProcessId + 11,
                (ULONG)argPart->Length / 2 - indexOfProcessId - 11
                );
            PhStringRefToUnicodeString(&guidString->sr, &guidStringUs);

            if (!NT_SUCCESS(RtlGUIDFromString(
                &guidStringUs,
                &guid
                )))
                return FALSE;

            KnownCommandLine->ComSurrogate.Guid = guid;
            KnownCommandLine->ComSurrogate.Name = NULL;
            KnownCommandLine->ComSurrogate.FileName = NULL;

            // Lookup the GUID in the registry to determine the name and file name.

            if (NT_SUCCESS(PhOpenKey(
                &clsidKeyHandle,
                KEY_READ,
                PH_KEY_CLASSES_ROOT,
                &PhaConcatStrings2(L"CLSID\\", guidString->Buffer)->sr,
                0
                )))
            {
                KnownCommandLine->ComSurrogate.Name =
                    PHA_DEREFERENCE(PhQueryRegistryString(clsidKeyHandle, NULL));

                if (NT_SUCCESS(PhOpenKey(
                    &inprocServer32KeyHandle,
                    KEY_READ,
                    clsidKeyHandle,
                    &inprocServer32Name,
                    0
                    )))
                {
                    KnownCommandLine->ComSurrogate.FileName =
                        PHA_DEREFERENCE(PhQueryRegistryString(inprocServer32KeyHandle, NULL));

                    if (fileName = PHA_DEREFERENCE(PhExpandEnvironmentStrings(
                        &KnownCommandLine->ComSurrogate.FileName->sr
                        )))
                    {
                        KnownCommandLine->ComSurrogate.FileName = fileName;
                    }

                    NtClose(inprocServer32KeyHandle);
                }

                NtClose(clsidKeyHandle);
            }
        }
        break;
    default:
        return FALSE;
    }

    return TRUE;
}
Ejemplo n.º 14
0
_Use_decl_annotations_
NDIS_STATUS
FilterAttach(
    NDIS_HANDLE                     NdisFilterHandle,
    NDIS_HANDLE                     FilterDriverContext,
    PNDIS_FILTER_ATTACH_PARAMETERS  AttachParameters
    )
/*++

Routine Description:

    Filter attach routine.
    Create filter's context, allocate NetBufferLists and NetBuffer pools and any
    other resources, and read configuration if needed.

Arguments:

    NdisFilterHandle - Specify a handle identifying this instance of the filter. FilterAttach
                       should save this handle. It is a required  parameter in subsequent calls
                       to NdisFxxx functions.
    FilterDriverContext - Filter driver context passed to NdisFRegisterFilterDriver.

    AttachParameters - attach parameters

Return Value:

    NDIS_STATUS_SUCCESS: FilterAttach successfully allocated and initialize data structures
                         for this filter instance.
    NDIS_STATUS_RESOURCES: FilterAttach failed due to insufficient resources.
    NDIS_STATUS_FAILURE: FilterAttach could not set up this instance of this filter and it has called
                         NdisWriteErrorLogEntry with parameters specifying the reason for failure.

N.B.:  FILTER can use NdisRegisterDeviceEx to create a device, so the upper 
    layer can send Irps to the filter.

--*/
{
    PMS_FILTER              pFilter = NULL;
    NDIS_STATUS             Status = NDIS_STATUS_SUCCESS;
    NTSTATUS                NtStatus;
    NDIS_FILTER_ATTRIBUTES  FilterAttributes;
    ULONG                   Size;
    COMPARTMENT_ID          OriginalCompartmentID;
    OBJECT_ATTRIBUTES       ObjectAttributes = {0};

    const ULONG RegKeyOffset = ARRAYSIZE(L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\otlwf\\Parameters\\NdisAdapters\\") - 1;
    DECLARE_CONST_UNICODE_STRING(RegKeyPath, L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\otlwf\\Parameters\\NdisAdapters\\{00000000-0000-0000-0000-000000000000}");
    RtlCopyMemory(RegKeyPath.Buffer + RegKeyOffset, AttachParameters->BaseMiniportName->Buffer + 8, sizeof(L"{00000000-0000-0000-0000-000000000000}"));

    LogFuncEntry(DRIVER_DEFAULT);

    do
    {
        ASSERT(FilterDriverContext == (NDIS_HANDLE)FilterDriverObject);
        if (FilterDriverContext != (NDIS_HANDLE)FilterDriverObject)
        {
            Status = NDIS_STATUS_INVALID_PARAMETER;
            break;
        }

        // Verify the media type is supported.  This is a last resort; the
        // the filter should never have been bound to an unsupported miniport
        // to begin with.
        if (AttachParameters->MiniportMediaType != NdisMediumIP)
        {
            LogError(DRIVER_DEFAULT, "Unsupported media type, 0x%x.", (ULONG)AttachParameters->MiniportMediaType);
            Status = NDIS_STATUS_INVALID_PARAMETER;
            break;
        }

        Size = sizeof(MS_FILTER) +  AttachParameters->BaseMiniportInstanceName->Length;

        pFilter = (PMS_FILTER)FILTER_ALLOC_MEM(NdisFilterHandle, Size);
        if (pFilter == NULL)
        {
            LogWarning(DRIVER_DEFAULT, "Failed to allocate context structure, 0x%x bytes", Size);
            Status = NDIS_STATUS_RESOURCES;
            break;
        }

        NdisZeroMemory(pFilter, sizeof(MS_FILTER));

        LogVerbose(DRIVER_DEFAULT, "Opening interface registry key %S", RegKeyPath.Buffer);

        InitializeObjectAttributes(
            &ObjectAttributes,
            (PUNICODE_STRING)&RegKeyPath,
            OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
            NULL,
            NULL);

        // Open the registry key
        NtStatus = ZwOpenKey(&pFilter->InterfaceRegKey, KEY_ALL_ACCESS, &ObjectAttributes);
        if (!NT_SUCCESS(NtStatus))
        {
            LogError(DRIVER_DEFAULT, "ZwOpenKey failed to open %S, %!STATUS!", RegKeyPath.Buffer, NtStatus);
            Status = NDIS_STATUS_FAILURE;
            break;
        }

        // Format of "\DEVICE\{5BA90C49-0D7E-455B-8D3B-614F6714A212}"
        AttachParameters->BaseMiniportName->Buffer += 8;
        AttachParameters->BaseMiniportName->Length -= 8 * sizeof(WCHAR);
        NtStatus = RtlGUIDFromString(AttachParameters->BaseMiniportName, &pFilter->InterfaceGuid);
        AttachParameters->BaseMiniportName->Buffer -= 8;
        AttachParameters->BaseMiniportName->Length += 8 * sizeof(WCHAR);
        if (!NT_SUCCESS(NtStatus))
        {
            LogError(DRIVER_DEFAULT, "Failed to convert FilterModuleGuidName to a GUID, %!STATUS!", NtStatus);
            Status = NDIS_STATUS_FAILURE;
            break;
        }

        pFilter->InterfaceFriendlyName.Length = pFilter->InterfaceFriendlyName.MaximumLength = AttachParameters->BaseMiniportInstanceName->Length;
        pFilter->InterfaceFriendlyName.Buffer = (PWSTR)((PUCHAR)pFilter + sizeof(MS_FILTER));
        NdisMoveMemory(pFilter->InterfaceFriendlyName.Buffer,
                        AttachParameters->BaseMiniportInstanceName->Buffer,
                        pFilter->InterfaceFriendlyName.Length);

        pFilter->InterfaceIndex = AttachParameters->BaseMiniportIfIndex;
        pFilter->InterfaceLuid = AttachParameters->BaseMiniportNetLuid;
        pFilter->InterfaceCompartmentID = UNSPECIFIED_COMPARTMENT_ID;
        pFilter->FilterHandle = NdisFilterHandle;

        NdisZeroMemory(&FilterAttributes, sizeof(NDIS_FILTER_ATTRIBUTES));
        FilterAttributes.Header.Revision = NDIS_FILTER_ATTRIBUTES_REVISION_1;
        FilterAttributes.Header.Size = sizeof(NDIS_FILTER_ATTRIBUTES);
        FilterAttributes.Header.Type = NDIS_OBJECT_TYPE_FILTER_ATTRIBUTES;
        FilterAttributes.Flags = 0;

        NDIS_DECLARE_FILTER_MODULE_CONTEXT(MS_FILTER);
        Status = NdisFSetAttributes(NdisFilterHandle, pFilter, &FilterAttributes);
        if (Status != NDIS_STATUS_SUCCESS)
        {
            LogError(DRIVER_DEFAULT, "Failed to set attributes, %!NDIS_STATUS!", Status);
            break;
        }

        // Filter initially in Paused state
        pFilter->State = FilterPaused;

        // Initialize rundowns to disabled with no active references
        pFilter->ExternalRefs.Count = EX_RUNDOWN_ACTIVE;
        pFilter->cmdRundown.Count = EX_RUNDOWN_ACTIVE;

        // Query the compartment ID for this interface to use for the IP stack
        pFilter->InterfaceCompartmentID = GetInterfaceCompartmentID(&pFilter->InterfaceLuid);
        LogVerbose(DRIVER_DEFAULT, "Interface %!GUID! is in Compartment %u", &pFilter->InterfaceGuid, (ULONG)pFilter->InterfaceCompartmentID);

        // Make sure we are in the right compartment
        (VOID)otLwfSetCompartment(pFilter, &OriginalCompartmentID);

        // Register for address changed notifications
        NtStatus = 
            NotifyUnicastIpAddressChange(
                AF_INET6,
                otLwfAddressChangeCallback,
                pFilter,
                FALSE,
                &pFilter->AddressChangeHandle
                );

        // Revert the compartment, now that we have the table
        otLwfRevertCompartment(OriginalCompartmentID);

        if (!NT_SUCCESS(NtStatus))
        {
            LogError(DRIVER_DEFAULT, "NotifyUnicastIpAddressChange failed, %!STATUS!", NtStatus);
            Status = NDIS_STATUS_FAILURE;
            break;
        }

        // Add Filter to global list of Thread Filters
        NdisAcquireSpinLock(&FilterListLock);
        InsertTailList(&FilterModuleList, &pFilter->FilterModuleLink);
        NdisReleaseSpinLock(&FilterListLock);

        LogVerbose(DRIVER_DEFAULT, "Created Filter: %p", pFilter);

    } while (FALSE);

    // Clean up on failure
    if (Status != NDIS_STATUS_SUCCESS)
    {
        if (pFilter != NULL)
        {
            if (pFilter->AddressChangeHandle != NULL)
            {
                CancelMibChangeNotify2(pFilter->AddressChangeHandle);
                pFilter->AddressChangeHandle = NULL;
            }

            NdisFreeMemory(pFilter, 0, 0);
        }
    }

    LogFuncExitNDIS(DRIVER_DEFAULT, Status);

    return Status;
}
Ejemplo n.º 15
0
static
VOID
test_GetInterfaceName(VOID)
{
    PIP_INTERFACE_INFO pInfo = NULL;
    ULONG ulOutBufLen = 0;
    DWORD ApiReturn;
    WCHAR Name[MAX_ADAPTER_NAME];
    UNICODE_STRING GuidString;
    GUID AdapterGUID;
    HINSTANCE hIpHlpApi;

    ApiReturn = GetInterfaceInfo(pInfo, &ulOutBufLen);
    ok(ApiReturn == ERROR_INSUFFICIENT_BUFFER,
       "GetInterfaceInfo(pInfo, &ulOutBufLen) returned %ld, expected ERROR_INSUFFICIENT_BUFFER\n",
       ApiReturn);
    if (ApiReturn != ERROR_INSUFFICIENT_BUFFER)
    {
        skip("Can't determine size of IP_INTERFACE_INFO. Can't proceed\n");
        return;
    }

    pInfo = (IP_INTERFACE_INFO *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ulOutBufLen);
    if (pInfo == NULL)
    {
        skip("pInfo is NULL. Can't proceed\n");
        return;
    }

    ApiReturn = GetInterfaceInfo(pInfo, &ulOutBufLen);
    ok(ApiReturn == NO_ERROR,
        "GetInterfaceInfo(pInfo, &ulOutBufLen) returned %ld, expected NO_ERROR\n",
        ApiReturn);
    if (ApiReturn != NO_ERROR || ulOutBufLen == 0)
    {
        skip("GetInterfaceInfo failed with error %ld. Can't proceed\n", ApiReturn);
        return;
    }

    if (pInfo->NumAdapters > 0)
        CopyMemory(&Name, &pInfo->Adapter[0].Name, sizeof(Name));

    if (pInfo->NumAdapters == 0)
    {
        HeapFree(GetProcessHeap(), 0, pInfo);
        skip("pInfo->NumAdapters = 0. Can't proceed\n");
        return;
    }
    trace("pInfo->NumAdapters: %lu\n", pInfo->NumAdapters);

    HeapFree(GetProcessHeap(), 0, pInfo);

    ApiReturn = wcsncmp(Name, L"\\DEVICE\\TCPIP_", 14);
    ok(ApiReturn == 0,
       "wcsncmp(Name, L\"\\DEVICE\\TCPIP_\", 14) returned %ld, expected 0\n",
       ApiReturn);
    if (ApiReturn != 0)
    {
        if (wcslen(Name) == 0)
        {
            skip("pInfo->Adapter[0].Name is empty. Can't proceed\n");
            return;
        }
        else
        {
            // workaround for ReactOS
            trace("pInfo->Adapter[0].Name = \"%ls\" is incorrect.\n", Name);
            RtlInitUnicodeString(&GuidString, &Name[0]);
        }
    }
    else
    {
        RtlInitUnicodeString(&GuidString, &Name[14]);
    }

    ApiReturn = RtlGUIDFromString(&GuidString, &AdapterGUID);
    if (ApiReturn != 0)
    {
        skip("RtlGUIDFromString failed. Can't proceed\n");
        return;
    }

    hIpHlpApi = GetModuleHandleW(L"iphlpapi.dll");
    if (!hIpHlpApi)
    {
        skip("Failed to load iphlpapi.dll. Can't proceed\n");
        return;
    }

    pNhGetInterfaceNameFromGuid = (void *)GetProcAddress(hIpHlpApi, "NhGetInterfaceNameFromGuid");

    if (!pNhGetInterfaceNameFromGuid)
        skip("NhGetInterfaceNameFromGuid not found. Can't proceed\n");
    else
        test_NhGetInterfaceNameFromGuid(AdapterGUID, 0, 0);

    pNhGetInterfaceNameFromDeviceGuid = (void *)GetProcAddress(hIpHlpApi, "NhGetInterfaceNameFromDeviceGuid");

    if (!pNhGetInterfaceNameFromDeviceGuid)
        skip("NhGetInterfaceNameFromDeviceGuid not found. Can't proceed\n");
    else
        test_NhGetInterfaceNameFromDeviceGuid(AdapterGUID, 1, 0);
}
Ejemplo n.º 16
0
/*++
 * @name EfiInitpCreateApplicationEntry
 *
 *     The EfiInitpCreateApplicationEntry routine 
 *
 * @param  SystemTable
 *         UEFI Image Handle for the current loaded application.
 *
 * @param  Entry
 *         Pointer to the UEFI System Table.
 *
 * @param  MaximumLength
 *         Pointer to the UEFI System Table.
 *
 * @param  DevicePath
 *         Pointer to the UEFI System Table.
 *
 * @param  FilePath
 *         Pointer to the UEFI System Table.
 *
 * @param  LoadOptions
 *         Pointer to the UEFI System Table.
 *
 * @param  LoadOptionsSize
 *         Pointer to the UEFI System Table.
 *
 * @param  Flags
 *         Pointer to the UEFI System Table.
 *
 * @param  ResultLength
 *         Pointer to the UEFI System Table.
 *
 * @param  AppEntryDevice
 *         Pointer to the UEFI System Table.
 *
 * @return None
 *
 *--*/
VOID
EfiInitpCreateApplicationEntry (
    __in EFI_SYSTEM_TABLE *SystemTable,
    __in PBL_APPLICATION_ENTRY Entry,
    __in ULONG MaximumLength,
    __in EFI_DEVICE_PATH *DevicePath,
    __in EFI_DEVICE_PATH *FilePath,
    __in PWCHAR LoadOptions,
    __in ULONG LoadOptionsSize,
    __in ULONG Flags,
    __out PULONG ResultLength,
    __out PBL_DEVICE_DESCRIPTOR *AppEntryDevice
    )
{
    PBL_WINDOWS_LOAD_OPTIONS WindowsOptions;
    PWCHAR ObjectString, CommandLine;
    PBL_BCD_OPTION Option, PreviousOption;
    ULONG HeaderSize, TotalOptionSize, Size, CommandLineSize, RemainingSize;
    NTSTATUS Status;
    UNICODE_STRING GuidString;
    GUID ObjectGuid;
    PBCD_DEVICE_OPTION BcdDevice;
    BOOLEAN HaveBinaryOptions, HaveGuid;
    PBL_FILE_PATH_DESCRIPTOR OsPath;
    EFI_DEVICE_PATH *OsDevicePath;

    /* Initialize everything */
    TotalOptionSize = 0;
    *AppEntryDevice = NULL;
    HeaderSize = 0;

    /* Check if the load options are in binary Windows format */
    WindowsOptions = (PBL_WINDOWS_LOAD_OPTIONS)LoadOptions;
    if ((WindowsOptions != NULL) &&
        (LoadOptionsSize >= sizeof(BL_WINDOWS_LOAD_OPTIONS)) &&
        (WindowsOptions->Length >= sizeof(BL_WINDOWS_LOAD_OPTIONS)) &&
        !(strncmp(WindowsOptions->Signature, "WINDOWS", 7)))
    {
        /* They are, so firmware must have loaded us -- extract arguments */
        CommandLine = WindowsOptions->LoadOptions;
        CommandLineSize = LoadOptionsSize - FIELD_OFFSET(BL_WINDOWS_LOAD_OPTIONS,
                                                         LoadOptions);

        /* Remember that we used binary options */
        HaveBinaryOptions = TRUE;
    }
    else
    {
        /* Nope -- so treat them as raw command-line options */
        CommandLine = LoadOptions;
        CommandLineSize = LoadOptionsSize;

        /* No binary options */
        HaveBinaryOptions = FALSE;
    }

    /* EFI uses UTF-16LE, like NT, so convert to characters */
    CommandLineSize /= sizeof(WCHAR);
    if (CommandLineSize != 0)
    {
        /* And check if the options are not NULL-terminated */
        if (wcsnlen(CommandLine, CommandLineSize) == CommandLineSize)
        {
            /* NULL-terminate them */
            CommandLine[CommandLineSize - 1] = UNICODE_NULL;
        }
    }

    /* Begin by making sure we at least have space for the app entry header */
    RemainingSize = MaximumLength;
    if (RemainingSize < sizeof(BL_APPLICATION_ENTRY))
    {
        Status = STATUS_INVALID_PARAMETER;
        goto Quickie;
    }

    /* On exit, return that we've at least consumed this much */
    HeaderSize = FIELD_OFFSET(BL_APPLICATION_ENTRY, BcdData);

    /* Zero out the header, and write down the signature */
    RtlZeroMemory(Entry, sizeof(BL_APPLICATION_ENTRY));
    RtlCopyMemory(Entry->Signature, BL_APP_ENTRY_SIGNATURE, 7);

    /* Check if a BCD object was passed on the command-line */
    ObjectString = wcsstr(CommandLine, L"BCDOBJECT=");
    if (ObjectString != NULL)
    {
        /* Convert the BCD object to a GUID */
        RtlInitUnicodeString(&GuidString, ObjectString + 10);
        RtlGUIDFromString(&GuidString, &ObjectGuid);

        /* Store it in the application entry */
        Entry->Guid = ObjectGuid;

        /* Remember one was passed */
        HaveGuid = TRUE;
    }
    else
    {
        /* Remember that no identifier was passed */
        Entry->Flags |= BL_APPLICATION_ENTRY_FLAG_NO_GUID;
        HaveGuid = FALSE;
    }

    /* At this point, the header is consumed, and we must now handle BCD options */
    RemainingSize -= FIELD_OFFSET(BL_APPLICATION_ENTRY, BcdData);

    /* Convert the device path into a BCD option */
    Status = EfiInitpConvertEfiDevicePath(DevicePath,
                                          BcdLibraryDevice_ApplicationDevice,
                                          &Entry->BcdData,
                                          RemainingSize);
    if (!NT_SUCCESS(Status))
    {
        /* We failed, so mark the option as such and return an empty one */
        Entry->BcdData.Empty = TRUE;
        TotalOptionSize = sizeof(BL_BCD_OPTION);
        goto Quickie;
    }

    /* Extract the device descriptor and return it */
    BcdDevice = (PVOID)((ULONG_PTR)&Entry->BcdData + Entry->BcdData.DataOffset);
    *AppEntryDevice = &BcdDevice->DeviceDescriptor;

    /* Calculate how big this option was and consume that from the buffer */
    TotalOptionSize = BlGetBootOptionSize(&Entry->BcdData);
    RemainingSize -= TotalOptionSize;

    /* Calculate where the next option should go */
    Option = (PVOID)((ULONG_PTR)&Entry->BcdData + TotalOptionSize);

    /* Check if we're PXE booting or not */
    if ((*AppEntryDevice)->DeviceType == UdpDevice)
    {
        /* lol */
        Status = STATUS_NOT_IMPLEMENTED;
    }
    else
    {
        /* Convert the local file path into a BCD option */
        Status = EfiInitpConvertEfiFilePath(FilePath,
                                            BcdLibraryString_ApplicationPath,
                                            Option,
                                            RemainingSize);
    }

    /* Bail out on failure */
    if (!NT_SUCCESS(Status))
    {
        goto Quickie;
    }

    /* The next option is right after this one */
    Entry->BcdData.NextEntryOffset = TotalOptionSize;

    /* Now compute the size of the next option, and add to the rolling sum */
    Size = BlGetBootOptionSize(Option);
    TotalOptionSize += Size;

    /* Remember the previous option so we can update its next offset */
    PreviousOption = Option;

    /* Consume the option from the buffer */
    RemainingSize -= Size;

    /* Calculate where the next option should go */
    Option = (PVOID)((ULONG_PTR)Option + Size);

    /* Check if we were using binary options without a BCD GUID */
    if ((HaveBinaryOptions) && !(HaveGuid))
    {
        /* Then this means we have to convert the OS paths to BCD too */
        WindowsOptions = (PBL_WINDOWS_LOAD_OPTIONS)LoadOptions;
        OsPath = (PVOID)((ULONG_PTR)WindowsOptions + WindowsOptions->OsPathOffset);

        /* IS the OS path in EFI format? */
        if ((OsPath->Length > (ULONG)FIELD_OFFSET(BL_FILE_PATH_DESCRIPTOR, Path)) &&
            (OsPath->PathType == EfiPath))
        {
            /* Convert the device portion  */
            OsDevicePath = (EFI_DEVICE_PATH*)OsPath->Path;
            Status = EfiInitpConvertEfiDevicePath(OsDevicePath,
                                                  BcdOSLoaderDevice_OSDevice,
                                                  Option,
                                                  RemainingSize);
            if (!NT_SUCCESS(Status))
            {
                goto Quickie;
            }

            /* Update the offset of the previous option */
            PreviousOption->NextEntryOffset = (ULONG_PTR)Option - (ULONG_PTR)&Entry->BcdData;

            /* Now compute the size of the next option, and add to the rolling sum */
            Size = BlGetBootOptionSize(Option);
            TotalOptionSize += Size;

            /* Remember the previous option so we can update its next offset */
            PreviousOption = Option;

            /* Consume the option from the buffer */
            RemainingSize -= Size;

            /* Calculate where the next option should go */
            Option = (PVOID)((ULONG_PTR)Option + Size);

            /* Convert the path option */
            Status = EfiInitpConvertEfiFilePath(OsDevicePath,
                                                BcdOSLoaderString_SystemRoot,
                                                Option,
                                                RemainingSize);
            if (!NT_SUCCESS(Status))
            {
                goto Quickie;
            }

            /* Update the offset of the previous option */
            PreviousOption->NextEntryOffset = (ULONG_PTR)Option - (ULONG_PTR)&Entry->BcdData;

            /* Now compute the size of the next option, and add to the rolling sum */
            Size = BlGetBootOptionSize(Option);
            TotalOptionSize += Size;

            /* Remember the previous option so we can update its next offset */
            PreviousOption = Option;

            /* Consume the option from the buffer */
            RemainingSize -= Size;

            /* Calculate where the next option should go */
            Option = (PVOID)((ULONG_PTR)Option + Size);
        }
    }

    /* Now convert everything else */
    AhCreateLoadOptionsList(CommandLine,
                            &Entry->BcdData,
                            RemainingSize,
                            &TotalOptionSize,
                            &PreviousOption,
                            &Size);

Quickie:
    /* Return the final size */
    *ResultLength = HeaderSize + TotalOptionSize;
}
Ejemplo n.º 17
0
NTSTATUS
BiConvertRegistryDataToElement (
    _In_ HANDLE ObjectHandle,
    _In_ PVOID Data,
    _In_ ULONG DataLength,
    _In_ BcdElementType ElementType,
    _Out_ PVOID Element,
    _Out_ PULONG ElementSize
    )
{
    NTSTATUS Status;
    ULONG Length, Size, ReturnedLength;
    PBL_DEVICE_DESCRIPTOR Device;
    BOOLEAN NullTerminate;
    PBCD_DEVICE_OPTION BcdDevice, ElementDevice;
    PWCHAR BcdString, ElementString;
    PGUID ElementGuid; UNICODE_STRING GuidString;
    PULONGLONG ElementInteger;
    PUSHORT ElementWord; PBOOLEAN BcdBoolean;

    /* Assume failure */
    ReturnedLength = 0;

    /* Check what type of format we are dealing with */
    switch (ElementType.Format)
    {
        /* Devices -- they are in a binary format */
        case BCD_TYPE_DEVICE:

            /* First, make sure it's at least big enough for an empty descriptor */
            if (DataLength < FIELD_OFFSET(BCD_DEVICE_OPTION, 
                                          DeviceDescriptor.Unknown))
            {
                return STATUS_OBJECT_TYPE_MISMATCH;
            }

            /* Both the registry and BCD format are the same */
            BcdDevice = (PBCD_DEVICE_OPTION)Data;
            ElementDevice = (PBCD_DEVICE_OPTION)Element;

            /* Make sure the device fits in the registry data */
            Device = &BcdDevice->DeviceDescriptor;
            Size = Device->Size;
            if ((Size + sizeof(BcdDevice->AssociatedEntry)) != DataLength)
            {
                return STATUS_OBJECT_TYPE_MISMATCH;
            }

            /* Check if this is a locate device */
            if (Device->DeviceType == LocateDevice)
            {
                EfiPrintf(L"Locates not yet supported\r\n");
                return STATUS_NOT_SUPPORTED;
            }

            /* Make sure the caller's buffer can fit the device */
            ReturnedLength = Size + sizeof(BcdDevice->AssociatedEntry);
            if (ReturnedLength > *ElementSize)
            {
                Status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            /* It'll fit -- copy it in */
            RtlCopyMemory(&ElementDevice->DeviceDescriptor, Device, Size);
            ElementDevice->AssociatedEntry = BcdDevice->AssociatedEntry;
            Status = STATUS_SUCCESS;
            break;

        /* Strings -- they are stored as is */
        case BCD_TYPE_STRING:

            /* Make sure the string isn't empty or misaligned */
            if (!(DataLength) || (DataLength & 1))
            {
                return STATUS_OBJECT_TYPE_MISMATCH;
            }

            /* Both the registry and BCD format are the same */
            BcdString = (PWCHAR)Data;
            ElementString = (PWCHAR)Element;

            /* We'll need as much data as the string has to offer */
            ReturnedLength = DataLength;

            /* If the string isn't NULL-terminated, do it now */
            NullTerminate = FALSE;
            if (BcdString[(DataLength / sizeof(WCHAR)) - 1] != UNICODE_NULL)
            {
                ReturnedLength += sizeof(UNICODE_NULL);
                NullTerminate = TRUE;
            }

            /* Will we fit in the caller's buffer? */
            if (ReturnedLength > *ElementSize)
            {
                Status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            /* Yep -- copy it in, and NULL-terminate if needed */
            RtlCopyMemory(Element, Data, DataLength);
            if (NullTerminate)
            {
                ElementString[DataLength / sizeof(WCHAR)] = UNICODE_NULL;
            }

            Status = STATUS_SUCCESS;
            break;

        /* Objects -- they are stored as GUID Strings */
        case BCD_TYPE_OBJECT:

            /* Registry data is a string, BCD data is a GUID */
            BcdString = (PWCHAR)Data;
            ElementGuid = (PGUID)Element;

            /* We need a GUID-sized buffer, does the caller have one? */
            ReturnedLength = sizeof(*ElementGuid);
            if (*ElementSize < ReturnedLength)
            {
                Status = STATUS_BUFFER_TOO_SMALL;
                break;
            }
            
            /* Yep, copy the GUID */
            RtlInitUnicodeString(&GuidString, BcdString);
            Status = RtlGUIDFromString(&GuidString, ElementGuid);
            break;

        /* Object Lists -- they are stored as arrays of GUID strings */
        case BCD_TYPE_OBJECT_LIST:

            /* Assume an empty list*/
            ReturnedLength = 0;
            Length = 0;
            Status = STATUS_SUCCESS;

            /* Registry data is an array of strings, BCD data is array of GUIDs */
            BcdString = (PWCHAR)Data;
            ElementGuid = (PGUID)Element;

            /* Loop as long as the array still has strings */
            while (*BcdString)
            {
                /* Don't read beyond the registry data */
                if (Length >= DataLength)
                {
                    break;
                }

                /* One more GUID -- does the caller have space? */
                ReturnedLength += sizeof(GUID);
                if (ReturnedLength <= *ElementSize)
                {
                    /* Convert and add it in */
                    RtlInitUnicodeString(&GuidString, BcdString);
                    Status = RtlGUIDFromString(&GuidString, ElementGuid);
                    if (!NT_SUCCESS(Status))
                    {
                        break;
                    }

                    /* Move to the next GUID in the caller's buffer */
                    ElementGuid++;
                }

                /* Move to the next string in the registry array */
                Size = (wcslen(BcdString) * sizeof(WCHAR)) + sizeof(UNICODE_NULL);
                Length += Size;
                BcdString = (PWCHAR)((ULONG_PTR)BcdString + Length);
            }

            /* Check if we failed anywhere */
            if (!NT_SUCCESS(Status))
            {
                break;
            }

            /* Check if we consumed more space than we have */
            if (ReturnedLength > *ElementSize)
            {
                Status = STATUS_BUFFER_TOO_SMALL;
            }

            /* All good here */
            break;

        /* Integer -- stored as binary */
        case BCD_TYPE_INTEGER:

            /* BCD data is a ULONGLONG, registry data is 8 bytes binary */
            ElementInteger = (PULONGLONG)Element;
            ReturnedLength = sizeof(*ElementInteger);

            /* Make sure the registry data makes sense */
            if (DataLength > ReturnedLength)
            {
                return STATUS_OBJECT_TYPE_MISMATCH;
            }

            /* Make sure the caller has space */
            if (*ElementSize < ReturnedLength)
            {
                Status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            /* Write the integer result */
            *ElementInteger = 0;
            RtlCopyMemory(ElementInteger, Data, DataLength);
            Status = STATUS_SUCCESS;
            break;

        /* Boolean -- stored as binary */
        case BCD_TYPE_BOOLEAN:

            /* BCD data is a BOOLEAN, registry data is 2 bytes binary */
            ElementWord = (PUSHORT)Element;
            BcdBoolean = (PBOOLEAN)Data;
            ReturnedLength = sizeof(ElementWord);

            /* Make sure the registry data makes sense */
            if (DataLength != sizeof(*BcdBoolean))
            {
                return STATUS_OBJECT_TYPE_MISMATCH;
            }

            /* Make sure the caller has space */
            if (*ElementSize < ReturnedLength)
            {
                Status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            /* Write the boolean result */
            *ElementWord = 0;
            *ElementWord = *BcdBoolean != 0;
            Status = STATUS_SUCCESS;
            break;

        /* Integer list --stored as binary */
        case BCD_TYPE_INTEGER_LIST:

            /* BCD Data is n ULONGLONGs, registry data is n*8 bytes binary */
            ReturnedLength = DataLength;
            if (!(DataLength) || (DataLength & 7))
            {
                return STATUS_OBJECT_TYPE_MISMATCH;
            }

            /* Make sure the caller has space */
            if (*ElementSize < ReturnedLength)
            {
                Status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            /* Write the integer list result */
            RtlCopyMemory(Element, Data, DataLength);
            Status = STATUS_SUCCESS;
            break;

        /* Arbitrary data */
        default:

            /* Registry data is copied binary as-is */
            ReturnedLength = DataLength;

            /* Make sure it's not empty */
            if (!DataLength)
            {
                return STATUS_OBJECT_TYPE_MISMATCH;
            }

            /* Make sure the caller has space */
            if (*ElementSize < ReturnedLength)
            {
                Status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            /* Write the result */
            RtlCopyMemory(Element, Data, DataLength);
            Status = STATUS_SUCCESS;
            break;
    }

    /* If we got here due to success or space issues, write the size */
    if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_TOO_SMALL))
    {
        *ElementSize = ReturnedLength;
    }

    /* All done, return our conversion result */
    return Status;
}