From: Grigory Vasilyev h0tc0d3@gmail.com
--- dlls/ntdll/unix/system.c | 59 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+)
diff --git a/dlls/ntdll/unix/system.c b/dlls/ntdll/unix/system.c index f47925018b8..0d3a4f403ef 100644 --- a/dlls/ntdll/unix/system.c +++ b/dlls/ntdll/unix/system.c @@ -30,6 +30,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #include <errno.h> @@ -3682,9 +3683,67 @@ NTSTATUS WINAPI NtQuerySystemEnvironmentValue( UNICODE_STRING *name, WCHAR *buff NTSTATUS WINAPI NtQuerySystemEnvironmentValueEx( UNICODE_STRING *name, GUID *vendor, void *buffer, ULONG *retlen, ULONG *attrib ) { +#if defined(__linux__) || defined(__gnu_linux__) + int fd, rc; + size_t bytes, pos = 0; + ssize_t ssz; + char filename[128]; + char *cname; + struct stat sb = { 0 }; + + cname = (char *)malloc( name->Length ); + ntdll_wcstoumbs( name->Buffer, name->Length, cname, name->Length, FALSE ); + + snprintf( filename, sizeof(filename), "/sys/firmware/efi/efivars/%s-%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", + cname, vendor->Data1, vendor->Data2, vendor->Data3, + vendor->Data4[0], vendor->Data4[1], vendor->Data4[2], vendor->Data4[3], + vendor->Data4[4], vendor->Data4[5], vendor->Data4[6], vendor->Data4[7]); + + fd = open( filename, O_RDONLY | O_NONBLOCK ); + if (fd < 0) + goto done; + + rc = fstat( fd, &sb ); + if ( rc < 0 || sb.st_size == 0 ) + goto done; + + if ( sb.st_size - 4 < *retlen ) + bytes = sb.st_size - 4; + else + bytes = *retlen; + +try_read_attributes: + ssz = read( fd, attrib, 4 ); + if ( ssz < 0 ) { + if ( errno == EAGAIN || errno == EINTR ) + goto try_read_attributes; + goto done; + } + + while ( pos < bytes ) { + ssz = read( fd, (char *) buffer + pos, bytes - pos ); + if ( ssz < 0 ) { + if ( errno == EAGAIN || errno == EINTR ) + continue; + goto done; + } + pos += ssz; + } + + close( fd ); + *retlen = ssz & 0xFFFFFFFF; + return STATUS_SUCCESS; + +done: + if ( fd >= 0 ) + close( fd ); + *retlen = 0; + return STATUS_UNSUCCESSFUL; +#else FIXME( "(%s, %s, %p, %p, %p), stub\n", debugstr_us(name), debugstr_guid(vendor), buffer, retlen, attrib ); return STATUS_NOT_IMPLEMENTED; +#endif }