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-2024 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, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21#ifdef HAVE_CONFIG_H
22#include <config.h>
23#endif
24
25#include "msica_arg.h"
26#include "../tapctl/error.h"
27#include "../tapctl/tap.h"
28
29#include <windows.h>
30#include <malloc.h>
31
32
33void
35{
36 seq->head = NULL;
37 seq->tail = NULL;
38}
39
40
41void
43{
44 while (seq->head)
45 {
46 struct msica_arg *p = seq->head;
47 seq->head = seq->head->next;
48 free(p);
49 }
50 seq->tail = NULL;
51}
52
53
54void
56 _Inout_ struct msica_arg_seq *seq,
57 _In_z_ LPCTSTR argument)
58{
59 size_t argument_size = (_tcslen(argument) + 1) * sizeof(TCHAR);
60 struct msica_arg *p = malloc(sizeof(struct msica_arg) + argument_size);
61 if (p == NULL)
62 {
63 msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, sizeof(struct msica_arg) + argument_size);
64 }
65 memcpy(p->val, argument, argument_size);
66 p->next = seq->head;
67 seq->head = p;
68 if (seq->tail == NULL)
69 {
70 seq->tail = p;
71 }
72}
73
74
75void
77 _Inout_ struct msica_arg_seq *seq,
78 _Inout_ LPCTSTR argument)
79{
80 size_t argument_size = (_tcslen(argument) + 1) * sizeof(TCHAR);
81 struct msica_arg *p = malloc(sizeof(struct msica_arg) + argument_size);
82 if (p == NULL)
83 {
84 msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, sizeof(struct msica_arg) + argument_size);
85 }
86 memcpy(p->val, argument, argument_size);
87 p->next = NULL;
88 *(seq->tail ? &seq->tail->next : &seq->head) = p;
89 seq->tail = p;
90}
91
92
93LPTSTR
95{
96 /* Count required space. */
97 size_t size = 2 /*x + zero-terminator*/;
98 for (struct msica_arg *p = seq->head; p != NULL; p = p->next)
99 {
100 size += _tcslen(p->val) + 1 /*space delimiter|zero-terminator*/;
101 }
102 size *= sizeof(TCHAR);
103
104 /* Allocate. */
105 LPTSTR str = malloc(size);
106 if (str == NULL)
107 {
108 msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, size);
109 return NULL;
110 }
111
112#ifdef _MSC_VER
113#pragma warning(push)
114#pragma warning(disable: 4996) /* Using unsafe string functions: The space in s and termination of p->val has been implicitly verified at the beginning of this function. */
115#endif
116
117 /* Dummy argv[0] (i.e. executable name), for CommandLineToArgvW to work correctly when parsing this string. */
118 _tcscpy(str, TEXT("x"));
119
120 /* Join. */
121 LPTSTR 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] = TEXT(' ');
126 s++;
127 /* Append argument. */
128 _tcscpy(s, p->val);
129 s += _tcslen(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:42
void msica_arg_seq_add_tail(_Inout_ struct msica_arg_seq *seq, _Inout_ LPCTSTR argument)
Appends argument to the end of the argument sequence.
Definition msica_arg.c:76
void msica_arg_seq_init(_Inout_ struct msica_arg_seq *seq)
Initializes argument sequence.
Definition msica_arg.c:34
void msica_arg_seq_add_head(_Inout_ struct msica_arg_seq *seq, _In_z_ LPCTSTR argument)
Inserts argument to the beginning of the argument sequence.
Definition msica_arg.c:55
LPTSTR 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:94
#define M_FATAL
Definition error.h:89
#define msg(flags,...)
Definition error.h:144
Argument sequence.
Definition msica_arg.h:49
Argument list.
Definition msica_arg.h:39
struct msica_arg * next
Pointer to the next argument in the sequence.
Definition msica_arg.h:40
TCHAR val[]
Zero terminated argument string.
Definition msica_arg.h:41
#define _Inout_
Definition basic.h:51
#define _In_z_
Definition basic.h:48
#define _In_
Definition basic.h:42