From: Grigory Vasilyev h0tc0d3@gmail.com
--- dlls/kernel32/kernel32.spec | 2 + dlls/kernel32/process.c | 160 ++++++++++++++++++++++++++++++++++-- 2 files changed, 156 insertions(+), 6 deletions(-)
diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec index 7ed8048f5d0..5d3556a2078 100644 --- a/dlls/kernel32/kernel32.spec +++ b/dlls/kernel32/kernel32.spec @@ -695,7 +695,9 @@ @ stdcall -import GetFileType(long) @ stdcall -import GetFinalPathNameByHandleA(long ptr long long) @ stdcall -import GetFinalPathNameByHandleW(long ptr long long) +@ stdcall GetFirmwareEnvironmentVariableExA(str str ptr long ptr) @ stdcall GetFirmwareEnvironmentVariableA(str str ptr long) +@ stdcall GetFirmwareEnvironmentVariableExW(wstr wstr ptr long ptr) @ stdcall GetFirmwareEnvironmentVariableW(wstr wstr ptr long) @ stdcall GetFirmwareType(ptr) @ stdcall -import GetFullPathNameA(str long ptr ptr) diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c index ee5e3cf9164..a6c279ec3dc 100644 --- a/dlls/kernel32/process.c +++ b/dlls/kernel32/process.c @@ -718,14 +718,163 @@ WORD WINAPI GetMaximumProcessorGroupCount(void) return groups; }
+/*********************************************************************** + * __wine_string_to_guid (KERNEL32.@) + */ +static inline BOOL __wine_string_to_guid(LPCSTR s, GUID *id) +{ + int i; + if (!s || s[0] != '{') { + memset(id, 0, sizeof(*id)); + return FALSE; + } + + id->Data1 = 0; + for (i = 1; i < 9; ++i) { + if (!(((s[i] >= '0') && (s[i] <= '9')) + || ((s[i] >= 'a') && (s[i] <= 'f')) + || ((s[i] >= 'A') && (s[i] <= 'F')))) + return FALSE; + id->Data1 = (id->Data1 << 4) + | ((s[i] & 0xF) + (s[i] >> 6)) + | ((s[i] >> 3) & 0x8); + } + + if (s[9] != '-') + return FALSE; + + id->Data2 = 0; + for (i = 10; i < 14; ++i) { + if (!(((s[i] >= '0') && (s[i] <= '9')) + || ((s[i] >= 'a') && (s[i] <= 'f')) + || ((s[i] >= 'A') && (s[i] <= 'F')))) + return FALSE; + id->Data2 = (id->Data2 << 4) + | ((s[i] & 0xF) + (s[i] >> 6)) + | ((s[i] >> 3) & 0x8); + } + + if (s[14] != '-') + return FALSE; + + id->Data3 = 0; + for (i = 15; i < 19; ++i) { + if (!(((s[i] >= '0') && (s[i] <= '9')) + || ((s[i] >= 'a') && (s[i] <= 'f')) + || ((s[i] >= 'A') && (s[i] <= 'F')))) + return FALSE; + id->Data3 = (id->Data3 << 4) + | ((s[i] & 0xF) + (s[i] >> 6)) + | ((s[i] >> 3) & 0x8); + } + + if (s[19] != '-') + return FALSE; + + for (i = 20; i < 37; i += 2) { + if (i == 24) { + if (s[i] != '-') + return FALSE; + i++; + } + if (!(((s[i] >= '0') && (s[i] <= '9')) + || ((s[i] >= 'a') && (s[i] <= 'f')) + || ((s[i] >= 'A') && (s[i] <= 'F')) + || ((s[i + 1] >= '0') && (s[i + 1] <= '9')) + || ((s[i + 1] >= 'a') && (s[i + 1] <= 'f')) + || ((s[i + 1] >= 'A') && (s[i + 1] <= 'F')))) + return FALSE; + id->Data4[(i - 20) / 2] = ((((s[i] & 0xF) + (s[i] >> 6)) | ((s[i] >> 3) & 0x8)) << 4) + | (((s[i + 1] & 0xF) + (s[i + 1] >> 6)) | ((s[i + 1] >> 3) & 0x8)); + } + + if (s[37] == '}' && s[38] == '\0') + return TRUE; + + return FALSE; +} + +/*********************************************************************** + * GetFirmwareEnvironmentVariableExA (KERNEL32.@) + */ +DWORD WINAPI GetFirmwareEnvironmentVariableExA(LPCSTR name, LPCSTR guid, PVOID buffer, DWORD size, PDWORD attributes) +{ + int nsize; + GUID vendor = {0}; + LPWSTR wname; + UNICODE_STRING uname; + DWORD ret_size = size; + + if(!name || !guid || !attributes) + { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + + if (!__wine_string_to_guid(guid, &vendor)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + + nsize = MultiByteToWideChar(CP_ACP, 0, name, -1, NULL, 0); + + if (!(wname = HeapAlloc(GetProcessHeap(), 0, nsize * sizeof(wname)))) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return 0; + } + + MultiByteToWideChar(CP_ACP, 0, name, -1, wname, nsize); + + RtlInitUnicodeString(&uname, wname); + + if (!set_ntstatus(NtQuerySystemEnvironmentValueEx(&uname, &vendor, buffer, + &ret_size, attributes))) + ret_size = 0; + + HeapFree(GetProcessHeap(), 0, wname); + + return ret_size; +} + /*********************************************************************** * GetFirmwareEnvironmentVariableA (KERNEL32.@) */ DWORD WINAPI GetFirmwareEnvironmentVariableA(LPCSTR name, LPCSTR guid, PVOID buffer, DWORD size) { - FIXME("stub: %s %s %p %lu\n", debugstr_a(name), debugstr_a(guid), buffer, size); - SetLastError(ERROR_INVALID_FUNCTION); - return 0; + DWORD attributes; + return GetFirmwareEnvironmentVariableExA(name, guid, buffer, size, &attributes); +} + +/*********************************************************************** + * GetFirmwareEnvironmentVariableExW (KERNEL32.@) + */ +DWORD WINAPI GetFirmwareEnvironmentVariableExW(LPCWSTR name, LPCWSTR guid, PVOID buffer, DWORD size, PDWORD attributes) +{ + GUID vendor = {0}; + UNICODE_STRING uname; + UNICODE_STRING uguid; + DWORD ret_size = size; + + if(!name || !guid || !attributes) + { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + + RtlInitUnicodeString(&uguid, guid); + + if (!set_ntstatus(RtlGUIDFromString(&uguid, &vendor))) + return 0; + + RtlInitUnicodeString(&uname, name); + + if (!set_ntstatus(NtQuerySystemEnvironmentValueEx(&uname, &vendor, buffer, + &ret_size, attributes))) + return 0; + + return ret_size; }
/*********************************************************************** @@ -733,9 +882,8 @@ DWORD WINAPI GetFirmwareEnvironmentVariableA(LPCSTR name, LPCSTR guid, PVOID buf */ DWORD WINAPI GetFirmwareEnvironmentVariableW(LPCWSTR name, LPCWSTR guid, PVOID buffer, DWORD size) { - FIXME("stub: %s %s %p %lu\n", debugstr_w(name), debugstr_w(guid), buffer, size); - SetLastError(ERROR_INVALID_FUNCTION); - return 0; + DWORD attributes; + return GetFirmwareEnvironmentVariableExW(name, guid, buffer, size, &attributes); }
/***********************************************************************