void uParserCustom::_customParserValidateFields(const std::vector<std::string>& fieldsNames) const
{
    /**< Must have at least 2 fields */
    if (fieldsNames.size() < 3)
    {
        customParser_missing_mandatory_values e;
        e << string_error("Custom file fields description is too short, must have at least 3 values: CHR and START_POS and a way to infer END_POS.\n");
        throw e;
    }

    /**< Check if mandatory fields are present */
    if (!_paramExists("CHR", fieldsNames))
    {
        customParser_missing_mandatory_values e;
        e << string_error("Mandatory field is missing: CHR\n");
        throw e;
    }
    if (!_paramExists("START_POS", fieldsNames))
    {
        customParser_missing_mandatory_values e;
        e << string_error("Mandatory field is missing: START_POS\n");
        throw e;
    }

    /**< We need to be able to infer END_POS either directly or indirectly (with a sequence or cigar score) */
    if (!_paramExists("END_POS", fieldsNames) && !_paramExists("SEQUENCE", fieldsNames) && !_paramExists("CIGAR", fieldsNames))
    {
        customParser_missing_mandatory_values e;
        e << string_error("We must be able to infer END_POS directly or indirectly (with SEQUENCE or CIGAR)\n");
        throw e;
    }
}
Exemple #2
0
    compiled_regex_t(const wchar_t *argv0, const wchar_t *pattern, bool ignore_case,
                     io_streams_t &streams)
        : code(0), match(0) {
        // Disable some sequences that can lead to security problems.
        uint32_t options = PCRE2_NEVER_UTF;
#if PCRE2_CODE_UNIT_WIDTH < 32
        options |= PCRE2_NEVER_BACKSLASH_C;
#endif

        int err_code = 0;
        PCRE2_SIZE err_offset = 0;

        code =
            pcre2_compile(PCRE2_SPTR(pattern), PCRE2_ZERO_TERMINATED,
                          options | (ignore_case ? PCRE2_CASELESS : 0), &err_code, &err_offset, 0);
        if (code == 0) {
            string_error(streams, _(L"%ls: Regular expression compile error: %ls\n"), argv0,
                         pcre2_strerror(err_code).c_str());
            string_error(streams, L"%ls: %ls\n", argv0, pattern);
            string_error(streams, L"%ls: %*ls\n", argv0, err_offset, L"^");
            return;
        }

        match = pcre2_match_data_create_from_pattern(code, 0);
        if (match == 0) {
            DIE_MEM();
        }
    }
Exemple #3
0
    int report_match(const wchar_t *arg, int pcre2_rc) {
        // Return values: -1 = error, 0 = no match, 1 = match.
        if (pcre2_rc == PCRE2_ERROR_NOMATCH) {
            if (opts.invert_match && !opts.quiet) {
                if (opts.index) {
                    streams.out.append_format(L"1 %lu\n", wcslen(arg));
                } else {
                    streams.out.append(arg);
                    streams.out.push_back(L'\n');
                }
            }

            return opts.invert_match ? 1 : 0;
        } else if (pcre2_rc < 0) {
            string_error(streams, _(L"%ls: Regular expression match error: %ls\n"), argv0,
                         pcre2_strerror(pcre2_rc).c_str());
            return -1;
        } else if (pcre2_rc == 0) {
            // The output vector wasn't big enough. Should not happen.
            string_error(streams, _(L"%ls: Regular expression internal error\n"), argv0);
            return -1;
        } else if (opts.invert_match) {
            return 0;
        }

        if (opts.entire) {
            streams.out.append(arg);
            streams.out.push_back(L'\n');
        }

        PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(regex.match);
        for (int j = (opts.entire ? 1 : 0); j < pcre2_rc; j++) {
            PCRE2_SIZE begin = ovector[2 * j];
            PCRE2_SIZE end = ovector[2 * j + 1];

            if (begin != PCRE2_UNSET && end != PCRE2_UNSET && !opts.quiet) {
                if (opts.index) {
                    streams.out.append_format(L"%lu %lu", (unsigned long)(begin + 1),
                                              (unsigned long)(end - begin));
                } else if (end > begin) {
                    // May have end < begin if \K is used.
                    streams.out.append(wcstring(&arg[begin], end - begin));
                }
                streams.out.push_back(L'\n');
            }
        }

        return opts.invert_match ? 0 : 1;
    }
Exemple #4
0
/// Parse the arguments for flags recognized by a specific string subcommand.
static int parse_opts(options_t *opts, int *optind, int n_req_args, int argc, wchar_t **argv,
                      parser_t &parser, io_streams_t &streams) {
    const wchar_t *cmd = argv[0];
    wcstring short_opts = construct_short_opts(opts);
    const wchar_t *short_options = short_opts.c_str();
    int opt;
    wgetopter_t w;
    while ((opt = w.wgetopt_long(argc, argv, short_options, long_options, NULL)) != -1) {
        auto fn = flag_to_function.find(opt);
        if (fn != flag_to_function.end()) {
            int retval = fn->second(argv, parser, streams, w, opts);
            if (retval != STATUS_CMD_OK) return retval;
        } else if (opt == ':') {
            string_error(streams, STRING_ERR_MISSING, cmd);
            return STATUS_INVALID_ARGS;
        } else if (opt == '?') {
            string_unknown_option(parser, streams, cmd, argv[w.woptind - 1]);
            return STATUS_INVALID_ARGS;
        } else {
            DIE("unexpected retval from wgetopt_long");
        }
    }

    *optind = w.woptind;

    // If the caller requires one or two mandatory args deal with that here.
    if (n_req_args) {
        opts->arg1 = string_get_arg_argv(optind, argv);
        if (!opts->arg1) {
            string_error(streams, STRING_ERR_MISSING, cmd);
            return STATUS_INVALID_ARGS;
        }
    }
    if (n_req_args > 1) {
        opts->arg2 = string_get_arg_argv(optind, argv);
        if (!opts->arg2) {
            string_error(streams, STRING_ERR_MISSING, cmd);
            return STATUS_INVALID_ARGS;
        }
    }

    // At this point we should not have optional args and be reading args from stdin.
    if (string_args_from_stdin(streams) && argc > *optind) {
        string_error(streams, BUILTIN_ERR_TOO_MANY_ARGUMENTS, cmd);
        return STATUS_INVALID_ARGS;
    }

    return STATUS_CMD_OK;
}
static int string_length(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv)
{
    const wchar_t *short_options = L"q";
    const struct woption long_options[] =
    {
        { L"quiet", no_argument, 0, 'q'},
        { 0, 0, 0, 0 }
    };

    bool quiet = false;
    wgetopter_t w;
    for (;;)
    {
        int c = w.wgetopt_long(argc, argv, short_options, long_options, 0);

        if (c == -1)
        {
            break;
        }
        switch (c)
        {
            case 0:
                break;

            case 'q':
                quiet = true;
                break;

            case '?':
                string_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
                return BUILTIN_STRING_ERROR;
        }
    }

    int i = w.woptind;
    if (string_args_from_stdin(streams) && argc > i)
    {
        string_error(streams, BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]);
        return BUILTIN_STRING_ERROR;
    }

    const wchar_t *arg;
    int nnonempty = 0;
    wcstring storage;
    while ((arg = string_get_arg(&i, argv, &storage, streams)) != 0)
    {
        size_t n = wcslen(arg);
        if (n > 0)
        {
            nnonempty++;
        }
        if (!quiet)
        {
            streams.out.append(to_string(n));
            streams.out.append(L'\n');
        }
    }

    return (nnonempty > 0) ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE;
}
Exemple #6
0
static int handle_flag_s(wchar_t **argv, parser_t &parser, io_streams_t &streams, wgetopter_t &w,
                         options_t *opts) {
    if (opts->start_valid) {
        opts->start = fish_wcstol(w.woptarg);
        if (opts->start == 0 || opts->start == LONG_MIN || errno == ERANGE) {
            string_error(streams, _(L"%ls: Invalid start value '%ls'\n"), argv[0], w.woptarg);
            return STATUS_INVALID_ARGS;
        } else if (errno) {
            string_error(streams, BUILTIN_ERR_NOT_NUMBER, argv[0], w.woptarg);
            return STATUS_INVALID_ARGS;
        }
        return STATUS_CMD_OK;
    }
    string_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
    return STATUS_INVALID_ARGS;
}
Exemple #7
0
void CALLBACK RemoveDeviceW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow) {
    try {
        WCHAR *s, *vol, *dev;
        uint64_t devid;
        win_handle h, token;
        TOKEN_PRIVILEGES tp;
        LUID luid;
        NTSTATUS Status;
        IO_STATUS_BLOCK iosb;

        set_dpi_aware();

        if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token))
            throw last_error(GetLastError());

        if (!LookupPrivilegeValueW(nullptr, L"SeManageVolumePrivilege", &luid))
            throw last_error(GetLastError());

        tp.PrivilegeCount = 1;
        tp.Privileges[0].Luid = luid;
        tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

        if (!AdjustTokenPrivileges(token, false, &tp, sizeof(TOKEN_PRIVILEGES), nullptr, nullptr))
            throw last_error(GetLastError());

        s = wcsstr(lpszCmdLine, L"|");
        if (!s)
            return;

        s[0] = 0;

        vol = lpszCmdLine;
        dev = &s[1];

        devid = _wtoi(dev);
        if (devid == 0)
            return;

        h = CreateFileW(vol, FILE_TRAVERSE | FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr,
                        OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, nullptr);

        if (h == INVALID_HANDLE_VALUE)
            throw last_error(GetLastError());

        Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_REMOVE_DEVICE, &devid, sizeof(uint64_t), nullptr, 0);
        if (!NT_SUCCESS(Status)) {
            if (Status == STATUS_CANNOT_DELETE)
                throw string_error(IDS_CANNOT_REMOVE_RAID);
            else
                throw ntstatus_error(Status);

            return;
        }

        BtrfsBalance bb(vol, true);
        bb.ShowBalance(hwnd);
    } catch (const exception& e) {
        error_message(hwnd, e.what());
    }
}
Exemple #8
0
/** \brief Set the fields name (only used for the Custom file)
  */
void uWriterBase::setFieldsNames(const std::vector<std::string>& fieldsNames)
{
    if (fieldsNames.size() == 0)
    {
        throw no_fields_names() << string_error("fieldsNames vector is empty");
    }
    m_fieldsNames = fieldsNames;
}
Exemple #9
0
void uParserBed::_validateColumnNumber(int numberOfColumn) const
{
    if (numberOfColumn < 3 || numberOfColumn > 6)
    {
        uParserBed_invalid_number_of_columns e;
        e << string_error("uParserBed: Invalid number of columns.");
        throw e;
    }
}
static int string_escape(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv)
{
    const wchar_t *short_options = L"n";
    const struct woption long_options[] =
    {
        { L"no-quoted", no_argument, 0, 'n' },
        { 0, 0, 0, 0 }
    };

    escape_flags_t flags = ESCAPE_ALL;
    wgetopter_t w;
    for (;;)
    {
        int c = w.wgetopt_long(argc, argv, short_options, long_options, 0);

        if (c == -1)
        {
            break;
        }
        switch (c)
        {
            case 0:
                break;

            case 'n':
                flags |= ESCAPE_NO_QUOTED;
                break;

            case '?':
                string_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
                return BUILTIN_STRING_ERROR;
        }
    }

    int i = w.woptind;
    if (string_args_from_stdin(streams) && argc > i)
    {
        string_error(streams, BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]);
        return BUILTIN_STRING_ERROR;
    }

    int nesc = 0;
    wcstring storage;
    const wchar_t *arg;
    while ((arg = string_get_arg(&i, argv, &storage, streams)) != 0)
    {
        streams.out.append(escape(arg, flags));
        streams.out.append(L'\n');
        nesc++;
    }

    return (nesc > 0) ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE;
}
Exemple #11
0
/// A return value of true means all is well (even if no replacements were performed), false
/// indicates an unrecoverable error.
bool regex_replacer_t::replace_matches(const wchar_t *arg) {
    if (regex.code == 0) {
        // pcre2_compile() failed
        return false;
    }

    uint32_t options = PCRE2_SUBSTITUTE_OVERFLOW_LENGTH | PCRE2_SUBSTITUTE_EXTENDED |
                       (opts.all ? PCRE2_SUBSTITUTE_GLOBAL : 0);
    size_t arglen = wcslen(arg);
    PCRE2_SIZE bufsize = (arglen == 0) ? 16 : 2 * arglen;
    wchar_t *output = (wchar_t *)malloc(sizeof(wchar_t) * bufsize);
    int pcre2_rc;

    bool done = false;
    while (!done) {
        if (output == NULL) {
            DIE_MEM();
        }
        PCRE2_SIZE outlen = bufsize;
        pcre2_rc = pcre2_substitute(regex.code, PCRE2_SPTR(arg), arglen,
                                    0,  // start offset
                                    options, regex.match,
                                    0,  // match context
                                    PCRE2_SPTR(replacement.c_str()), PCRE2_ZERO_TERMINATED,
                                    (PCRE2_UCHAR *)output, &outlen);

        if (pcre2_rc != PCRE2_ERROR_NOMEMORY || bufsize >= outlen) {
            done = true;
        } else {
            bufsize = outlen;
            // cppcheck-suppress memleakOnRealloc
            output = (wchar_t *)realloc(output, sizeof(wchar_t) * bufsize);
        }
    }

    bool rc = true;
    if (pcre2_rc < 0) {
        string_error(streams, _(L"%ls: Regular expression substitute error: %ls\n"), argv0,
                     pcre2_strerror(pcre2_rc).c_str());
        rc = false;
    } else {
        if (!opts.quiet) {
            streams.out.append(output);
            streams.out.append(L'\n');
        }
        total_replaced += pcre2_rc;
    }

    free(output);
    return rc;
}
Exemple #12
0
void uParserBed::_parseHeader()
{
    std::string unformatedHeader;
    /**< We parse a line at a time until we get a valid token, then we return the token back in the stream */
    do
    {
        char line[4096];
        if (m_pIostream->getline(line, 4096))
        {
            std::stringstream token_infos;
            _convertLineToTokenInfosBed(line, token_infos);
            try
            {
                uToken token(token_infos);
                /**< When we have a valid token, we consider that all the header have beed fetched */
                /**< We put token back into stream, and exit function */
                _pushBackLine(line);
                m_headerParsed = true;
            }
            /**< If there is a throw, we are not at the first valid token line, so we add line to header object */
            catch(invalid_uToken_throw& e) { }
            catch(invalid_value_throw& e) { }
            if (m_headerParsed == false)
            {
                std::string s(line);
                unformatedHeader += s;
                unformatedHeader += '\n';
            }
        }
        else
        {
            std::cout << "Reached end of file" << std::endl;
            #ifdef DEBUG
            std::cerr << "Reached end of file." << std::endl;
            #endif
            end_of_file_throw e;
            e << string_error("Reached end of file.");
            throw e;
        }
    } while(m_headerParsed == false);
    m_headerData.setUnformatedHeader(unformatedHeader);
}
Exemple #13
0
/** \brief Produce a token with next entry in the file/stream.
 * \return uToken containing the infos of the next entry.
 */
uToken uParserCustom::getNextEntry()
{
    char line[4096];
    if (m_pIostream->getline(line, 4096))
    {
        /**< We start by fetching the infos from the line */
        m_rawString=line;
        std::stringstream token_infos;

        _convertLineToTokenInfosCustom(line, token_infos);
        /**< We try to create a token with the infos that were fetched from the line */
        /**< If it doesn't work andit's the first token, we don't throw an error. Instead, we try again with another line */
        try
        {
            uToken token(token_infos, true);
            return token;
        }
        catch(invalid_uToken_throw& e)
        {
            throw e;
        }
        catch(invalid_value_throw& e)
        {
            throw e;
        }
    }
    else
    {
        #ifdef DEBUG
        std::cerr << "Reached end of file." << std::endl;
        #endif
        end_of_file_throw e;
        e << string_error("Reached end of file.");
        throw e;
    }
    std::cerr <<"Fatal error in getNextEntry() from Custom parser, should not reach here." <<std::endl;
    abort();
}
    bool replace_matches(const wchar_t *arg)
    {
        // A return value of true means all is well (even if no replacements
        // were performed), false indicates an unrecoverable error.
        if (regex.code == 0)
        {
            // pcre2_compile() failed
            return false;
        }

        uint32_t options = opts.all ? PCRE2_SUBSTITUTE_GLOBAL : 0;
        size_t arglen = wcslen(arg);
        PCRE2_SIZE bufsize = (arglen == 0) ? 16 : 2 * arglen;
        wchar_t *output = (wchar_t *)malloc(sizeof(wchar_t) * bufsize);
        if (output == 0)
        {
            DIE_MEM();
        }
        int pcre2_rc = 0;
        for (;;)
        {
            PCRE2_SIZE outlen = bufsize;
            pcre2_rc = pcre2_substitute(
                            regex.code,
                            PCRE2_SPTR(arg),
                            arglen,
                            0,  // start offset
                            options,
                            regex.match,
                            0,  // match context
                            PCRE2_SPTR(replacement.c_str()),
                            PCRE2_ZERO_TERMINATED,
                            (PCRE2_UCHAR *)output,
                            &outlen);

            if (pcre2_rc == PCRE2_ERROR_NOMEMORY)
            {
                if (bufsize < MAX_REPLACE_SIZE)
                {
                    bufsize = std::min(2 * bufsize, MAX_REPLACE_SIZE);
                    output = (wchar_t *)realloc(output, sizeof(wchar_t) * bufsize);
                    if (output == 0)
                    {
                        DIE_MEM();
                    }
                    continue;
                }
                string_error(streams, _(L"%ls: Replacement string too large\n"), argv0);
                free(output);
                return false;
            }
            break;
        }

        bool rc = true;
        if (pcre2_rc < 0)
        {
            string_error(streams, _(L"%ls: Regular expression substitute error: %ls\n"),
                    argv0, pcre2_strerror(pcre2_rc).c_str());
            rc = false;
        }
        else
        {
            if (!opts.quiet)
            {
                streams.out.append(output);
                streams.out.append(L'\n');
            }
            total_replaced += pcre2_rc;
        }

        free(output);
        return rc;
    }
Exemple #15
0
void BtrfsDeviceAdd::AddDevice(HWND hwndDlg) {
    wstring mess, title;
    NTSTATUS Status;
    UNICODE_STRING vn;
    OBJECT_ATTRIBUTES attr;
    IO_STATUS_BLOCK iosb;

    if (!sel) {
        EndDialog(hwndDlg, 0);
        return;
    }

    if (sel->fstype != L"") {
        wstring s;

        if (!load_string(module, IDS_ADD_DEVICE_CONFIRMATION_FS, s))
            throw last_error(GetLastError());

        wstring_sprintf(mess, s, sel->fstype.c_str());
    } else {
        if (!load_string(module, IDS_ADD_DEVICE_CONFIRMATION, mess))
            throw last_error(GetLastError());
    }

    if (!load_string(module, IDS_CONFIRMATION_TITLE, title))
        throw last_error(GetLastError());

    if (MessageBoxW(hwndDlg, mess.c_str(), title.c_str(), MB_YESNO) != IDYES)
        return;

    win_handle h = CreateFileW(cmdline, FILE_TRAVERSE | FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr,
                               OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, nullptr);

    if (h == INVALID_HANDLE_VALUE)
        throw last_error(GetLastError());

    {
        nt_handle h2;

        vn.Length = vn.MaximumLength = (uint16_t)(sel->pnp_name.length() * sizeof(WCHAR));
        vn.Buffer = (WCHAR*)sel->pnp_name.c_str();

        InitializeObjectAttributes(&attr, &vn, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, nullptr, nullptr);

        Status = NtOpenFile(&h2, FILE_GENERIC_READ | FILE_GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_ALERT);
        if (!NT_SUCCESS(Status))
            throw ntstatus_error(Status);

        if (!sel->is_disk) {
            Status = NtFsControlFile(h2, nullptr, nullptr, nullptr, &iosb, FSCTL_LOCK_VOLUME, nullptr, 0, nullptr, 0);
            if (!NT_SUCCESS(Status))
                throw string_error(IDS_LOCK_FAILED, Status);
        }

        Status = NtFsControlFile(h, nullptr, nullptr, nullptr, &iosb, FSCTL_BTRFS_ADD_DEVICE, &h2, sizeof(HANDLE), nullptr, 0);
        if (!NT_SUCCESS(Status))
            throw ntstatus_error(Status);

        if (!sel->is_disk) {
            Status = NtFsControlFile(h2, nullptr, nullptr, nullptr, &iosb, FSCTL_DISMOUNT_VOLUME, nullptr, 0, nullptr, 0);
            if (!NT_SUCCESS(Status))
                throw ntstatus_error(Status);

            Status = NtFsControlFile(h2, nullptr, nullptr, nullptr, &iosb, FSCTL_UNLOCK_VOLUME, nullptr, 0, nullptr, 0);
            if (!NT_SUCCESS(Status))
                throw ntstatus_error(Status);
        }
    }

    EndDialog(hwndDlg, 0);
}
Exemple #16
0
void BtrfsDeviceAdd::populate_device_tree(HWND tree) {
    HWND hwnd = GetParent(tree);
    unsigned int i;
    ULONG last_disk_num = 0xffffffff;
    HTREEITEM diskitem;
    NTSTATUS Status;
    OBJECT_ATTRIBUTES attr;
    UNICODE_STRING us;
    IO_STATUS_BLOCK iosb;
    btrfs_filesystem* bfs = nullptr;

    static WCHAR btrfs[] = L"\\Btrfs";

    device_list.clear();

    {
        nt_handle mountmgr;

        RtlInitUnicodeString(&us, MOUNTMGR_DEVICE_NAME);
        InitializeObjectAttributes(&attr, &us, 0, nullptr, nullptr);

        Status = NtOpenFile(&mountmgr, FILE_GENERIC_READ | FILE_GENERIC_WRITE, &attr, &iosb,
                            FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_ALERT);

        if (!NT_SUCCESS(Status))
            throw string_error(IDS_CANT_OPEN_MOUNTMGR);

        {
            nt_handle btrfsh;

            us.Length = us.MaximumLength = (uint16_t)(wcslen(btrfs) * sizeof(WCHAR));
            us.Buffer = btrfs;

            InitializeObjectAttributes(&attr, &us, 0, nullptr, nullptr);

            Status = NtOpenFile(&btrfsh, SYNCHRONIZE | FILE_READ_ATTRIBUTES, &attr, &iosb,
                                FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_ALERT);
            if (NT_SUCCESS(Status)) {
                ULONG bfssize = 0;

                do {
                    bfssize += 1024;

                    if (bfs) free(bfs);
                    bfs = (btrfs_filesystem*)malloc(bfssize);

                    Status = NtDeviceIoControlFile(btrfsh, nullptr, nullptr, nullptr, &iosb, IOCTL_BTRFS_QUERY_FILESYSTEMS, nullptr, 0, bfs, bfssize);
                    if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) {
                        free(bfs);
                        bfs = nullptr;
                        break;
                    }
                } while (Status == STATUS_BUFFER_OVERFLOW);

                if (bfs && bfs->num_devices == 0) { // no mounted filesystems found
                    free(bfs);
                    bfs = nullptr;
                }
            }
        }

        find_devices(hwnd, &GUID_DEVINTERFACE_DISK, mountmgr, device_list);
        find_devices(hwnd, &GUID_DEVINTERFACE_VOLUME, mountmgr, device_list);
        find_devices(hwnd, &GUID_DEVINTERFACE_HIDDEN_VOLUME, mountmgr, device_list);
    }

    sort(device_list.begin(), device_list.end(), sort_devices);

    for (i = 0; i < device_list.size(); i++) {
        if (!device_list[i].ignore) {
            TVINSERTSTRUCTW tis;
            HTREEITEM item;
            wstring name, size;

            if (device_list[i].disk_num != 0xffffffff && device_list[i].disk_num == last_disk_num)
                tis.hParent = diskitem;
            else
                tis.hParent = TVI_ROOT;

            tis.hInsertAfter = TVI_LAST;
            tis.itemex.mask = TVIF_TEXT | TVIF_STATE | TVIF_PARAM;
            tis.itemex.state = TVIS_EXPANDED;
            tis.itemex.stateMask = TVIS_EXPANDED;

            if (device_list[i].disk_num != 0xffffffff) {
                wstring t;

                if (!load_string(module, device_list[i].part_num != 0 ? IDS_PARTITION : IDS_DISK_NUM, t))
                    throw last_error(GetLastError());

                wstring_sprintf(name, t, device_list[i].part_num != 0 ? device_list[i].part_num : device_list[i].disk_num);
            } else
                name = device_list[i].pnp_name;

            // match child Btrfs devices to their parent
            if (bfs && device_list[i].drive == L"" && device_list[i].fstype == L"Btrfs") {
                btrfs_filesystem* bfs2 = bfs;

                while (true) {
                    if (RtlCompareMemory(&bfs2->uuid, &device_list[i].fs_uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
                        ULONG j, k;
                        btrfs_filesystem_device* dev;

                        for (j = 0; j < bfs2->num_devices; j++) {
                            if (j == 0)
                                dev = &bfs2->device;
                            else
                                dev = (btrfs_filesystem_device*)((uint8_t*)dev + offsetof(btrfs_filesystem_device, name[0]) + dev->name_length);

                            if (RtlCompareMemory(&device_list[i].dev_uuid, &device_list[i].dev_uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
                                for (k = 0; k < device_list.size(); k++) {
                                    if (k != i && device_list[k].fstype == L"Btrfs" && device_list[k].drive != L"" &&
                                        RtlCompareMemory(&device_list[k].fs_uuid, &device_list[i].fs_uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
                                        device_list[i].drive = device_list[k].drive;
                                        break;
                                    }
                                }

                                device_list[i].multi_device = bfs2->num_devices > 1;

                                break;
                            }
                        }

                        break;
                    }

                    if (bfs2->next_entry != 0)
                        bfs2 = (btrfs_filesystem*)((uint8_t*)bfs2 + bfs2->next_entry);
                    else
                        break;
                }
            }

            name += L" (";

            if (device_list[i].friendly_name != L"") {
                name += device_list[i].friendly_name;
                name += L", ";
            }

            if (device_list[i].drive != L"") {
                name += device_list[i].drive;
                name += L", ";
            }

            if (device_list[i].fstype != L"") {
                name += device_list[i].fstype;
                name += L", ";
            }

            format_size(device_list[i].size, size, false);
            name += size;

            name += L")";

            tis.itemex.pszText = (WCHAR*)name.c_str();
            tis.itemex.cchTextMax = name.length();
            tis.itemex.lParam = (LPARAM)&device_list[i];

            item = (HTREEITEM)SendMessageW(tree, TVM_INSERTITEMW, 0, (LPARAM)&tis);
            if (!item)
                throw string_error(IDS_TVM_INSERTITEM_FAILED);

            if (device_list[i].part_num == 0) {
                diskitem = item;
                last_disk_num = device_list[i].disk_num;
            }
        }
    }
}
Exemple #17
0
static int string_sub(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) {
    const wchar_t *short_options = L":l:qs:";
    const struct woption long_options[] = {{L"length", required_argument, 0, 'l'},
                                           {L"quiet", no_argument, 0, 'q'},
                                           {L"start", required_argument, 0, 's'},
                                           {0, 0, 0, 0}};

    long start = 0;
    long length = -1;
    bool quiet = false;
    wgetopter_t w;
    wchar_t *endptr = NULL;
    for (;;) {
        int c = w.wgetopt_long(argc, argv, short_options, long_options, 0);

        if (c == -1) {
            break;
        }
        switch (c) {
            case 0: {
                break;
            }
            case 'l': {
                errno = 0;
                length = wcstol(w.woptarg, &endptr, 10);
                if (*endptr != L'\0' || (errno != 0 && errno != ERANGE)) {
                    string_error(streams, BUILTIN_ERR_NOT_NUMBER, argv[0], w.woptarg);
                    return BUILTIN_STRING_ERROR;
                }
                if (length < 0 || errno == ERANGE) {
                    string_error(streams, _(L"%ls: Invalid length value '%ls'\n"), argv[0],
                                 w.woptarg);
                    return BUILTIN_STRING_ERROR;
                }
                break;
            }
            case 'q': {
                quiet = true;
                break;
            }
            case 's': {
                errno = 0;
                start = wcstol(w.woptarg, &endptr, 10);
                if (*endptr != L'\0' || (errno != 0 && errno != ERANGE)) {
                    string_error(streams, BUILTIN_ERR_NOT_NUMBER, argv[0], w.woptarg);
                    return BUILTIN_STRING_ERROR;
                }
                if (start == 0 || start == LONG_MIN || errno == ERANGE) {
                    string_error(streams, _(L"%ls: Invalid start value '%ls'\n"), argv[0],
                                 w.woptarg);
                    return BUILTIN_STRING_ERROR;
                }
                break;
            }
            case ':': {
                string_error(streams, STRING_ERR_MISSING, argv[0]);
                return BUILTIN_STRING_ERROR;
            }
            case '?': {
                string_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
                return BUILTIN_STRING_ERROR;
            }
            default: {
                DIE("unexpected opt");
                break;
            }
        }
    }

    int i = w.woptind;
    if (string_args_from_stdin(streams) && argc > i) {
        string_error(streams, BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]);
        return BUILTIN_STRING_ERROR;
    }

    int nsub = 0;
    const wchar_t *arg;
    wcstring storage;
    while ((arg = string_get_arg(&i, argv, &storage, streams)) != NULL) {
        typedef wcstring::size_type size_type;
        size_type pos = 0;
        size_type count = wcstring::npos;
        wcstring s(arg);
        if (start > 0) {
            pos = static_cast<size_type>(start - 1);
        } else if (start < 0) {
            assert(start != LONG_MIN);  // checked above
            size_type n = static_cast<size_type>(-start);
            pos = n > s.length() ? 0 : s.length() - n;
        }
        if (pos > s.length()) {
            pos = s.length();
        }

        if (length >= 0) {
            count = static_cast<size_type>(length);
        }

        // Note that std::string permits count to extend past end of string.
        if (!quiet) {
            streams.out.append(s.substr(pos, count));
            streams.out.append(L'\n');
        }
        nsub++;
    }

    return nsub > 0 ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE;
}
Exemple #18
0
static int string_split(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) {
    const wchar_t *short_options = L":m:qr";
    const struct woption long_options[] = {{L"max", required_argument, 0, 'm'},
                                           {L"quiet", no_argument, 0, 'q'},
                                           {L"right", no_argument, 0, 'r'},
                                           {0, 0, 0, 0}};

    long max = LONG_MAX;
    bool quiet = false;
    bool right = false;
    wgetopter_t w;
    for (;;) {
        int c = w.wgetopt_long(argc, argv, short_options, long_options, 0);

        if (c == -1) {
            break;
        }
        switch (c) {
            case 0: {
                break;
            }
            case 'm': {
                errno = 0;
                wchar_t *endptr = 0;
                max = wcstol(w.woptarg, &endptr, 10);
                if (*endptr != L'\0' || errno != 0) {
                    string_error(streams, BUILTIN_ERR_NOT_NUMBER, argv[0], w.woptarg);
                    return BUILTIN_STRING_ERROR;
                }
                break;
            }
            case 'q': {
                quiet = true;
                break;
            }
            case 'r': {
                right = true;
                break;
            }
            case ':': {
                string_error(streams, STRING_ERR_MISSING, argv[0]);
                return BUILTIN_STRING_ERROR;
            }
            case '?': {
                string_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
                return BUILTIN_STRING_ERROR;
            }
            default: {
                DIE("unexpected opt");
                break;
            }
        }
    }

    int i = w.woptind;
    const wchar_t *sep;
    if ((sep = string_get_arg_argv(&i, argv)) == NULL) {
        string_error(streams, STRING_ERR_MISSING, argv[0]);
        return BUILTIN_STRING_ERROR;
    }
    const wchar_t *sep_end = sep + wcslen(sep);

    if (string_args_from_stdin(streams) && argc > i) {
        string_error(streams, BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]);
        return BUILTIN_STRING_ERROR;
    }

    wcstring_list_t splits;
    size_t arg_count = 0;
    wcstring storage;
    const wchar_t *arg;
    while ((arg = string_get_arg(&i, argv, &storage, streams)) != 0) {
        const wchar_t *arg_end = arg + wcslen(arg);
        if (right) {
            typedef std::reverse_iterator<const wchar_t *> reverser;
            split_about(reverser(arg_end), reverser(arg), reverser(sep_end), reverser(sep), &splits,
                        max);
        } else {
            split_about(arg, arg_end, sep, sep_end, &splits, max);
        }
        arg_count++;
    }

    // If we are from the right, split_about gave us reversed strings, in reversed order!
    if (right) {
        for (size_t j = 0; j < splits.size(); j++) {
            std::reverse(splits[j].begin(), splits[j].end());
        }
        std::reverse(splits.begin(), splits.end());
    }

    if (!quiet) {
        for (wcstring_list_t::const_iterator si = splits.begin(); si != splits.end(); ++si) {
            streams.out.append(*si);
            streams.out.append(L'\n');
        }
    }

    // We split something if we have more split values than args.
    return splits.size() > arg_count ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE;
}
Exemple #19
0
static int string_replace(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) {
    const wchar_t *short_options = L"aiqr";
    const struct woption long_options[] = {{L"all", no_argument, 0, 'a'},
                                           {L"ignore-case", no_argument, 0, 'i'},
                                           {L"quiet", no_argument, 0, 'q'},
                                           {L"regex", no_argument, 0, 'r'},
                                           {0, 0, 0, 0}};

    replace_options_t opts;
    bool regex = false;
    wgetopter_t w;
    for (;;) {
        int opt = w.wgetopt_long(argc, argv, short_options, long_options, 0);

        if (opt == -1) {
            break;
        }
        switch (opt) {
            case 0: {
                break;
            }
            case 'a': {
                opts.all = true;
                break;
            }
            case 'i': {
                opts.ignore_case = true;
                break;
            }
            case 'q': {
                opts.quiet = true;
                break;
            }
            case 'r': {
                regex = true;
                break;
            }
            case '?': {
                string_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
                return BUILTIN_STRING_ERROR;
            }
            default: {
                DIE("unexpected opt");
                break;
            }
        }
    }

    int i = w.woptind;
    const wchar_t *pattern, *replacement;
    if ((pattern = string_get_arg_argv(&i, argv)) == 0) {
        string_error(streams, STRING_ERR_MISSING, argv[0]);
        return BUILTIN_STRING_ERROR;
    }
    if ((replacement = string_get_arg_argv(&i, argv)) == 0) {
        string_error(streams, STRING_ERR_MISSING, argv[0]);
        return BUILTIN_STRING_ERROR;
    }

    if (string_args_from_stdin(streams) && argc > i) {
        string_error(streams, BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]);
        return BUILTIN_STRING_ERROR;
    }

    string_replacer_t *replacer;
    if (regex) {
        replacer = new regex_replacer_t(argv[0], pattern, replacement, opts, streams);
    } else {
        replacer = new literal_replacer_t(argv[0], pattern, replacement, opts, streams);
    }

    const wchar_t *arg;
    wcstring storage;
    while ((arg = string_get_arg(&i, argv, &storage, streams)) != 0) {
        if (!replacer->replace_matches(arg)) {
            delete replacer;
            return BUILTIN_STRING_ERROR;
        }
    }

    int rc = replacer->replace_count() > 0 ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE;
    delete replacer;
    return rc;
}
Exemple #20
0
static void string_unknown_option(parser_t &parser, io_streams_t &streams, const wchar_t *subcmd,
                                  const wchar_t *opt) {
    string_error(streams, BUILTIN_ERR_UNKNOWN, subcmd, opt);
    builtin_print_help(parser, streams, L"string", streams.err);
}
Exemple #21
0
/** \brief Initialize the uParserCustom object (default initialization of uParserCustom is not valid).
 */
void uParserCustom::init(const std::string& filename, bool header)
{
    throw uParser_exception_base()<<string_error("Invalid constructor call for Custom Format");
}
Exemple #22
0
static int string_join(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) {
    const wchar_t *short_options = L"q";
    const struct woption long_options[] = {{L"quiet", no_argument, 0, 'q'}, {0, 0, 0, 0}};

    bool quiet = false;
    wgetopter_t w;
    for (;;) {
        int opt = w.wgetopt_long(argc, argv, short_options, long_options, 0);

        if (opt == -1) {
            break;
        }

        switch (opt) {
            case 0: {
                break;
            }
            case 'q': {
                quiet = true;
                break;
            }
            case '?': {
                string_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
                return BUILTIN_STRING_ERROR;
            }
            default: {
                DIE("unexpected opt");
                break;
            }
        }
    }

    int i = w.woptind;
    const wchar_t *sep;
    if ((sep = string_get_arg_argv(&i, argv)) == 0) {
        string_error(streams, STRING_ERR_MISSING, argv[0]);
        return BUILTIN_STRING_ERROR;
    }

    if (string_args_from_stdin(streams) && argc > i) {
        string_error(streams, BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]);
        return BUILTIN_STRING_ERROR;
    }

    int nargs = 0;
    const wchar_t *arg;
    wcstring storage;
    while ((arg = string_get_arg(&i, argv, &storage, streams)) != 0) {
        if (!quiet) {
            if (nargs > 0) {
                streams.out.append(sep);
            }
            streams.out.append(arg);
        }
        nargs++;
    }
    if (nargs > 0 && !quiet) {
        streams.out.push_back(L'\n');
    }

    return nargs > 1 ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE;
}
Exemple #23
0
static int string_trim(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) {
    const wchar_t *short_options = L":c:lqr";
    const struct woption long_options[] = {{L"chars", required_argument, 0, 'c'},
                                           {L"left", no_argument, 0, 'l'},
                                           {L"quiet", no_argument, 0, 'q'},
                                           {L"right", no_argument, 0, 'r'},
                                           {0, 0, 0, 0}};

    bool do_left = 0, do_right = 0;
    bool quiet = false;
    wcstring chars_to_trim = L" \f\n\r\t";
    wgetopter_t w;
    for (;;) {
        int c = w.wgetopt_long(argc, argv, short_options, long_options, 0);

        if (c == -1) {
            break;
        }
        switch (c) {
            case 0: {
                break;
            }
            case 'c': {
                chars_to_trim = w.woptarg;
                break;
            }
            case 'l': {
                do_left = true;
                break;
            }
            case 'q': {
                quiet = true;
                break;
            }
            case 'r': {
                do_right = true;
                break;
            }
            case ':': {
                string_error(streams, STRING_ERR_MISSING, argv[0]);
                return BUILTIN_STRING_ERROR;
            }
            case '?': {
                string_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
                return BUILTIN_STRING_ERROR;
            }
            default: {
                DIE("unexpected opt");
                break;
            }
        }
    }

    int i = w.woptind;
    if (string_args_from_stdin(streams) && argc > i) {
        string_error(streams, BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]);
        return BUILTIN_STRING_ERROR;
    }

    // If neither left or right is specified, we do both.
    if (!do_left && !do_right) {
        do_left = true;
        do_right = true;
    }

    const wchar_t *arg;
    size_t ntrim = 0;

    wcstring argstr;
    wcstring storage;
    while ((arg = string_get_arg(&i, argv, &storage, streams)) != 0) {
        argstr = arg;
        // Begin and end are respectively the first character to keep on the left, and first
        // character to trim on the right. The length is thus end - start.
        size_t begin = 0, end = argstr.size();
        if (do_right) {
            size_t last_to_keep = argstr.find_last_not_of(chars_to_trim);
            end = (last_to_keep == wcstring::npos) ? 0 : last_to_keep + 1;
        }
        if (do_left) {
            size_t first_to_keep = argstr.find_first_not_of(chars_to_trim);
            begin = (first_to_keep == wcstring::npos ? end : first_to_keep);
        }
        assert(begin <= end && end <= argstr.size());
        ntrim += argstr.size() - (end - begin);
        if (!quiet) {
            streams.out.append(wcstring(argstr, begin, end - begin));
            streams.out.append(L'\n');
        }
    }

    return ntrim > 0 ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE;
}
static int string_match(parser_t &parser, io_streams_t &streams, int argc, wchar_t **argv) {
    const wchar_t *short_options = L"ainvqr";
    const struct woption long_options[] = {{L"all", no_argument, 0, 'a'},
                                           {L"ignore-case", no_argument, 0, 'i'},
                                           {L"index", no_argument, 0, 'n'},
                                           {L"invert", no_argument, 0, 'v'},
                                           {L"quiet", no_argument, 0, 'q'},
                                           {L"regex", no_argument, 0, 'r'},
                                           {0, 0, 0, 0}};

    match_options_t opts;
    bool regex = false;
    wgetopter_t w;
    for (;;) {
        int opt = w.wgetopt_long(argc, argv, short_options, long_options, 0);

        if (opt == -1) {
            break;
        }
        switch (opt) {
            case 0: {
                break;
            }
            case 'a': {
                opts.all = true;
                break;
            }
            case 'i': {
                opts.ignore_case = true;
                break;
            }
            case 'n': {
                opts.index = true;
                break;
            }
            case 'v': {
                opts.invert_match = true;
                break;
            }
            case 'q': {
                opts.quiet = true;
                break;
            }
            case 'r': {
                regex = true;
                break;
            }
            case '?': {
                string_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
                return BUILTIN_STRING_ERROR;
            }
            default: {
                DIE("unexpected opt");
                break;
            }
        }
    }

    int i = w.woptind;
    const wchar_t *pattern;
    if ((pattern = string_get_arg_argv(&i, argv)) == 0) {
        string_error(streams, STRING_ERR_MISSING, argv[0]);
        return BUILTIN_STRING_ERROR;
    }

    if (string_args_from_stdin(streams) && argc > i) {
        string_error(streams, BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]);
        return BUILTIN_STRING_ERROR;
    }

    std::unique_ptr<string_matcher_t> matcher;
    if (regex) {
        matcher = make_unique<pcre2_matcher_t>(argv[0], pattern, opts, streams);
    } else {
        matcher = make_unique<wildcard_matcher_t>(argv[0], pattern, opts, streams);
    }

    const wchar_t *arg;
    wcstring storage;
    while ((arg = string_get_arg(&i, argv, &storage, streams)) != 0) {
        if (!matcher->report_matches(arg)) {
            return BUILTIN_STRING_ERROR;
        }
    }

    int rc = matcher->match_count() > 0 ? BUILTIN_STRING_OK : BUILTIN_STRING_NONE;
    return rc;
}
Exemple #25
0
/** \brief Initialize the uParserCustom object (default initialization of uParserCustom is not valid).
 */
void uParserCustom::init(std::istream* stream, bool header)
{
    throw uParser_exception_base()<<string_error("Invalid constructor call for Custom Format");
}