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}")); }
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; }
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; }
NTSTATUS GUIDFromWdfString(__in WDFSTRING guidString, __out PGUID guid) { UNICODE_STRING guidStringW; WdfStringGetUnicodeString(guidString, &guidStringW); return RtlGUIDFromString (&guidStringW, guid); }
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; }
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; }
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"); }
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; }
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; }
/*++ * @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; }
/*********************************************************************** * 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; }
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))); }
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; }
_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; }
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); }
/*++ * @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; }
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; }