X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=programs%2Fimagex-win32.c;h=6ff838ca63e845a7053dbc7a2a984b9fafb9a491;hp=3c449a7733b108129503a32b4fbad682e2c2eeae;hb=a4123fea556d6c362318212127e25846981ea190;hpb=cc1b289394f993fa1a75b845553eea44e85e5051 diff --git a/programs/imagex-win32.c b/programs/imagex-win32.c index 3c449a77..6ff838ca 100644 --- a/programs/imagex-win32.c +++ b/programs/imagex-win32.c @@ -1,96 +1,101 @@ - -/* Replacements for functions needed specifically by the 'imagex' program in - * Windows native builds */ +/* Windows-specific code for wimlib-imagex. */ #ifndef __WIN32__ # error "This file contains Windows code" #endif #include "imagex-win32.h" +#include +#include +#include #include -#include -#include -#include - -/* Replacement for glob() in Windows native builds. */ -int glob(const char *pattern, int flags, - int (*errfunc)(const char *epath, int eerrno), - glob_t *pglob) +/* Convert a string from the "current Windows codepage" to UTF-16LE. */ +wchar_t * +win32_mbs_to_wcs(const char *mbs, size_t mbs_nbytes, size_t *num_wchars_ret) { - WIN32_FIND_DATA dat; - DWORD err; - HANDLE hFind; - int ret; - size_t nspaces; + if (mbs_nbytes > INT_MAX) { + fwprintf(stderr, L"ERROR: too much data (%zu bytes)!\n", + mbs_nbytes); + return NULL; + } + if (mbs_nbytes == 0) { + *num_wchars_ret = 0; + return (wchar_t*)mbs; + } + int len = MultiByteToWideChar(CP_ACP, + MB_ERR_INVALID_CHARS, + mbs, + mbs_nbytes, + NULL, + 0); + if (len <= 0) + goto out_invalid; + wchar_t *wcs = malloc(len * sizeof(wchar_t)); + if (!wcs) { + fwprintf(stderr, L"ERROR: out of memory!\n"); + return NULL; + } + int len2 = MultiByteToWideChar(CP_ACP, + MB_ERR_INVALID_CHARS, + mbs, + mbs_nbytes, + wcs, + len); + if (len2 != len) { + free(wcs); + goto out_invalid; + } + *num_wchars_ret = len; + return wcs; +out_invalid: + fwprintf(stderr, +L"ERROR: Invalid multi-byte string in the text file you provided as input!\n" +L" Maybe try converting your text file to UTF-16LE?\n" + ); + return NULL; +} - /* This function does not support all functionality of the POSIX glob(), - * so make sure the parameters are consistent with supported - * functionality. */ - assert(errfunc == NULL); - assert((flags & GLOB_ERR) == GLOB_ERR); - assert((flags & ~(GLOB_NOSORT | GLOB_ERR)) == 0); +/* Set a file descriptor to binary mode. */ +void set_fd_to_binary_mode(int fd) +{ + _setmode(fd, _O_BINARY); +} - hFind = FindFirstFileA(pattern, &dat); - if (hFind == INVALID_HANDLE_VALUE) { - err = GetLastError(); - if (err == ERROR_FILE_NOT_FOUND) { - errno = 0; - return GLOB_NOMATCH; - } else { - /* The other possible error codes for FindFirstFile() - * are undocumented. */ - errno = EIO; - return GLOB_ABORTED; - } - } - pglob->gl_pathc = 0; - pglob->gl_pathv = NULL; - nspaces = 0; - do { - char *filename; - if (pglob->gl_pathc == nspaces) { - size_t new_nspaces; - char **pathv; +#include - new_nspaces = nspaces * 2 + 1; - pathv = realloc(pglob->gl_pathv, - new_nspaces * sizeof(pglob->gl_pathv[0])); - if (!pathv) - goto oom; - pglob->gl_pathv = pathv; - nspaces = new_nspaces; - } - filename = strdup(dat.cFileName); - if (!filename) - goto oom; - pglob->gl_pathv[pglob->gl_pathc++] = filename; - } while (FindNextFileA(hFind, &dat)); - err = GetLastError(); - CloseHandle(hFind); - if (err == ERROR_NO_MORE_FILES) { - errno = 0; - return 0; - } else { - /* Other possible error codes for FindNextFile() are - * undocumented */ - errno = EIO; - ret = GLOB_ABORTED; - goto fail_globfree; - } -oom: - CloseHandle(hFind); - errno = ENOMEM; - ret = GLOB_NOSPACE; -fail_globfree: - globfree(pglob); - return ret; +static wchar_t * +get_security_descriptor_string(PSECURITY_DESCRIPTOR desc) +{ + wchar_t *str = NULL; + /* 52 characters!!! */ + ConvertSecurityDescriptorToStringSecurityDescriptorW( + desc, + SDDL_REVISION_1, + OWNER_SECURITY_INFORMATION | + GROUP_SECURITY_INFORMATION | + DACL_SECURITY_INFORMATION | + SACL_SECURITY_INFORMATION, + &str, + NULL); + return str; } -void globfree(glob_t *pglob) +void +win32_print_security_descriptor(const uint8_t *sd, size_t size) { - size_t i; - for (i = 0; i < pglob->gl_pathc; i++) - free(pglob->gl_pathv[i]); - free(pglob->gl_pathv[i]); + wchar_t *str; + const wchar_t *printstr; + + /* 'size' is ignored here due to the crappy Windows APIs. Oh well, this + * is just for debugging anyway. */ + str = get_security_descriptor_string((PSECURITY_DESCRIPTOR)sd); + if (str) + printstr = str; + else + printstr = L"(invalid)"; + + wprintf(L"Security Descriptor = %ls\n", printstr); + + LocalFree(str); }