-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreg.c
154 lines (125 loc) · 2.51 KB
/
reg.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/** fcom: Windows Registry utils
2023, Simon Zolin */
static const char* reg_help()
{
return "\
Windows Registry utils: search.\n\
Usage:\n\
fcom reg search [HKEY...] TEXT... [-o OUTPUT]\n\
\n\
HKEY: HKEY_CLASSES_ROOT | HKEY_CURRENT_USER | HKEY_LOCAL_MACHINE | HKEY_USERS\n\
Default: HKEY_CURRENT_USER and HKEY_LOCAL_MACHINE\n\
";
}
#include <fcom.h>
#include <ffsys/winreg.h>
#include <ffsys/globals.h>
#include <ffbase/list.h>
static const fcom_core *core;
struct reg {
fcom_cominfo cominfo;
uint st;
fcom_cominfo *cmd;
fcom_file_obj *out;
uint oper;
uint stop;
ffvec buf;
// search:
ffvec values; // ffstr[]
ffwinreg_enum e;
ffwinreg key;
fflist blocks;
fflist keys;
ffchain_item *lr, *lw;
uint search_state;
struct {
uint subkeys
, subkeys_all
, vals
, vals_all;
} stat;
};
#include <windows/reg-search.h>
static int args_parse(struct reg *g, fcom_cominfo *cmd)
{
static const struct ffarg args[] = {
{}
};
if (0 != core->com->args_parse(cmd, args, g, FCOM_COM_AP_INOUT))
return -1;
if (0 != reg_search_args(g))
return -1;
return 0;
}
static void reg_close(fcom_op *op)
{
struct reg *g = op;
reg_search_close(g);
core->file->destroy(g->out);
ffvec_free(&g->buf);
ffmem_free(g);
}
static fcom_op* reg_create(fcom_cominfo *cmd)
{
struct reg *g = ffmem_new(struct reg);
g->cmd = cmd;
if (0 != args_parse(g, cmd))
goto end;
struct fcom_file_conf fc = {};
fc.buffer_size = cmd->buffer_size;
g->out = core->file->create(&fc);
return g;
end:
reg_close(g);
return NULL;
}
static void reg_run(fcom_op *op)
{
struct reg *g = op;
int r, rc = 1;
enum { I_OUT_OPEN, I_FIND, };
while (!FFINT_READONCE(g->stop)) {
switch (g->st) {
case I_OUT_OPEN: {
uint oflags = FCOM_FILE_WRITE;
oflags |= fcom_file_cominfo_flags_o(g->cmd);
r = core->file->open(g->out, g->cmd->output.ptr, oflags);
if (r == FCOM_FILE_ERR) goto end;
g->st = I_FIND;
continue;
}
case I_FIND: {
ffstr kv;
r = reg_search_next(g, &kv);
switch (r) {
case 'data':
r = core->file->write(g->out, kv, -1);
if (r == FCOM_FILE_ERR) goto end;
continue;
case 'erro': goto end;
case 'done':
rc = 0;
goto end;
}
continue;
}
}
}
end:
{
fcom_cominfo *cmd = g->cmd;
reg_close(g);
core->com->complete(cmd, rc);
}
}
static void reg_signal(fcom_op *op, uint signal)
{
struct reg *g = op;
FFINT_WRITEONCE(g->stop, 1);
}
static const fcom_operation fcom_op_reg = {
reg_create, reg_close,
reg_run, reg_signal,
reg_help,
};
FCOM_MOD_DEFINE(reg, fcom_op_reg, core)