OpenVPN
msica_arg.c
Go to the documentation of this file.
1/*
2 * openvpnmsica -- Custom Action DLL to provide OpenVPN-specific support to MSI packages
3 * https://community.openvpn.net/openvpn/wiki/OpenVPNMSICA
4 *
5 * Copyright (C) 2018-2025 Simon Rozman <simon@rozman.si>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2
9 * as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, see <https://www.gnu.org/licenses/>.
18 */
19
20#ifdef HAVE_CONFIG_H
21#include <config.h>
22#endif
23
24#include "msica_arg.h"
25#include "../tapctl/error.h"
26#include "../tapctl/tap.h"
27
28#include <windows.h>
29#include <malloc.h>
30
31
32void
34{
35 seq->head = NULL;
36 seq->tail = NULL;
37}
38
39
40void
42{
43 while (seq->head)
44 {
45 struct msica_arg *p = seq->head;
46 seq->head = seq->head->next;
47 free(p);
48 }
49 seq->tail = NULL;
50}
51
52
53void
54msica_arg_seq_add_head(_Inout_ struct msica_arg_seq *seq, _In_z_ LPCWSTR argument)
55{
56 size_t argument_size = (wcslen(argument) + 1) * sizeof(WCHAR);
57 struct msica_arg *p = malloc(sizeof(struct msica_arg) + argument_size);
58 if (p == NULL)
59 {
60 msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__,
61 sizeof(struct msica_arg) + argument_size);
62 }
63 memcpy(p->val, argument, argument_size);
64 p->next = seq->head;
65 seq->head = p;
66 if (seq->tail == NULL)
67 {
68 seq->tail = p;
69 }
70}
71
72
73void
75{
76 size_t argument_size = (wcslen(argument) + 1) * sizeof(WCHAR);
77 struct msica_arg *p = malloc(sizeof(struct msica_arg) + argument_size);
78 if (p == NULL)
79 {
80 msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__,
81 sizeof(struct msica_arg) + argument_size);
82 }
83 memcpy(p->val, argument, argument_size);
84 p->next = NULL;
85 *(seq->tail ? &seq->tail->next : &seq->head) = p;
86 seq->tail = p;
87}
88
89
90LPWSTR
92{
93 /* Count required space. */
94 size_t size = 2 /*x + zero-terminator*/;
95 for (struct msica_arg *p = seq->head; p != NULL; p = p->next)
96 {
97 size += wcslen(p->val) + 1 /*space delimiter|zero-terminator*/;
98 }
99 size *= sizeof(WCHAR);
100
101 /* Allocate. */
102 LPWSTR str = malloc(size);
103 if (str == NULL)
104 {
105 msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, size);
106 return NULL;
107 }
108
109#ifdef _MSC_VER
110#pragma warning(push)
111#pragma warning( \
112 disable : 4996) /* Using unsafe string functions: The space in s and termination of p->val has \
113 been implicitly verified at the beginning of this function. */
114#endif
115
116 /* Dummy argv[0] (i.e. executable name), for CommandLineToArgvW to work correctly when parsing
117 * this string. */
118 wcscpy(str, L"x");
119
120 /* Join. */
121 LPWSTR s = str + 1 /*x*/;
122 for (struct msica_arg *p = seq->head; p != NULL; p = p->next)
123 {
124 /* Convert zero-terminator into space delimiter. */
125 s[0] = L' ';
126 s++;
127 /* Append argument. */
128 wcscpy(s, p->val);
129 s += wcslen(p->val);
130 }
131
132#ifdef _MSC_VER
133#pragma warning(pop)
134#endif
135
136 return str;
137}
void msica_arg_seq_free(_Inout_ struct msica_arg_seq *seq)
Frees argument sequence.
Definition msica_arg.c:41
void msica_arg_seq_init(_Inout_ struct msica_arg_seq *seq)
Initializes argument sequence.
Definition msica_arg.c:33
void msica_arg_seq_add_tail(_Inout_ struct msica_arg_seq *seq, _Inout_ LPCWSTR argument)
Appends argument to the end of the argument sequence.
Definition msica_arg.c:74
void msica_arg_seq_add_head(_Inout_ struct msica_arg_seq *seq, _In_z_ LPCWSTR argument)
Inserts argument to the beginning of the argument sequence.
Definition msica_arg.c:54
LPWSTR msica_arg_seq_join(_In_ const struct msica_arg_seq *seq)
Join arguments of the argument sequence into a space delimited string.
Definition msica_arg.c:91
#define M_FATAL
Definition error.h:88
#define msg(flags,...)
Definition error.h:150
Argument sequence.
Definition msica_arg.h:48
Argument list.
Definition msica_arg.h:38
struct msica_arg * next
Pointer to the next argument in the sequence.
Definition msica_arg.h:39
WCHAR val[]
Zero terminated argument string.
Definition msica_arg.h:40
#define _Inout_
Definition basic.h:50
#define _In_z_
Definition basic.h:47
#define _In_
Definition basic.h:41