diff --git a/nu/meson.build b/nu/meson.build index 5f5390e..771292e 100644 --- a/nu/meson.build +++ b/nu/meson.build @@ -9,5 +9,7 @@ nu_lib = static_library( ], sources : [ 'guid.c', + 'nvram.c', + 'nvram.h', ], ) diff --git a/nu/nvram.c b/nu/nvram.c new file mode 100644 index 0000000..2cb8b29 --- /dev/null +++ b/nu/nvram.c @@ -0,0 +1,80 @@ +#include + +#include +#include + +#include "util/dprintf.h" + +#include "nu/nvram.h" + +HRESULT nvram_open_file(HANDLE *out, wchar_t *path, size_t size) +{ + LARGE_INTEGER cur_size; + LARGE_INTEGER pos; + HANDLE file; + HRESULT hr; + BOOL ok; + + assert(out != NULL); + assert(path != NULL); + + *out = NULL; + + file = CreateFileW( + path, + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ, + NULL, + OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if (file == INVALID_HANDLE_VALUE) { + hr = HRESULT_FROM_WIN32(GetLastError()); + dprintf("%S: Error opening backing store: %x\n", path, (int) hr); + + goto end; + } + + ok = GetFileSizeEx(file, &cur_size); + + if (!ok) { + hr = HRESULT_FROM_WIN32(GetLastError()); + dprintf("%S: GetFileSizeEx failed: %x\n", path, (int) hr); + + goto end; + } + + if (cur_size.QuadPart != (uint64_t) size) { + pos.QuadPart = (uint64_t) size; + ok = SetFilePointerEx(file, pos, NULL, FILE_BEGIN); + + if (!ok) { + hr = HRESULT_FROM_WIN32(GetLastError()); + dprintf("%S: SetFilePointerEx failed: %x\n", path, (int) hr); + + goto end; + } + + ok = SetEndOfFile(file); + + if (!ok) { + hr = HRESULT_FROM_WIN32(GetLastError()); + dprintf("%S: SetEndOfFile failed: %x\n", path, (int) hr); + + goto end; + } + } + + *out = file; + file = INVALID_HANDLE_VALUE; + + hr = S_OK; + +end: + if (file != INVALID_HANDLE_VALUE) { + CloseHandle(file); + } + + return hr; +} diff --git a/nu/nvram.h b/nu/nvram.h new file mode 100644 index 0000000..e54f5cc --- /dev/null +++ b/nu/nvram.h @@ -0,0 +1,7 @@ +#pragma once + +#include + +#include + +HRESULT nvram_open_file(HANDLE *out, wchar_t *path, size_t size);