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-2021 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 #elif defined(_MSC_VER)
24 #include <config-msvc.h>
25 #endif
26 
27 #include "msica_arg.h"
28 #include "../tapctl/error.h"
29 #include "../tapctl/tap.h"
30 
31 #include <windows.h>
32 #include <malloc.h>
33 
34 
35 void
37 {
38  seq->head = NULL;
39  seq->tail = NULL;
40 }
41 
42 
43 void
45 {
46  while (seq->head)
47  {
48  struct msica_arg *p = seq->head;
49  seq->head = seq->head->next;
50  free(p);
51  }
52  seq->tail = NULL;
53 }
54 
55 
56 void
58  _Inout_ struct msica_arg_seq *seq,
59  _In_z_ LPCTSTR argument)
60 {
61  size_t argument_size = (_tcslen(argument) + 1) * sizeof(TCHAR);
62  struct msica_arg *p = malloc(sizeof(struct msica_arg) + argument_size);
63  if (p == NULL)
64  {
65  msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, sizeof(struct msica_arg) + argument_size);
66  }
67  memcpy(p->val, argument, argument_size);
68  p->next = seq->head;
69  seq->head = p;
70  if (seq->tail == NULL)
71  {
72  seq->tail = p;
73  }
74 }
75 
76 
77 void
79  _Inout_ struct msica_arg_seq *seq,
80  _Inout_ LPCTSTR argument)
81 {
82  size_t argument_size = (_tcslen(argument) + 1) * sizeof(TCHAR);
83  struct msica_arg *p = malloc(sizeof(struct msica_arg) + argument_size);
84  if (p == NULL)
85  {
86  msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, sizeof(struct msica_arg) + argument_size);
87  }
88  memcpy(p->val, argument, argument_size);
89  p->next = NULL;
90  *(seq->tail ? &seq->tail->next : &seq->head) = p;
91  seq->tail = p;
92 }
93 
94 
95 LPTSTR
97 {
98  /* Count required space. */
99  size_t size = 2 /*x + zero-terminator*/;
100  for (struct msica_arg *p = seq->head; p != NULL; p = p->next)
101  {
102  size += _tcslen(p->val) + 1 /*space delimiter|zero-terminator*/;
103  }
104  size *= sizeof(TCHAR);
105 
106  /* Allocate. */
107  LPTSTR str = malloc(size);
108  if (str == NULL)
109  {
110  msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, size);
111  return NULL;
112  }
113 
114 #ifdef _MSC_VER
115 #pragma warning(push)
116 #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. */
117 #endif
118 
119  /* Dummy argv[0] (i.e. executable name), for CommandLineToArgvW to work correctly when parsing this string. */
120  _tcscpy(str, TEXT("x"));
121 
122  /* Join. */
123  LPTSTR s = str + 1 /*x*/;
124  for (struct msica_arg *p = seq->head; p != NULL; p = p->next)
125  {
126  /* Convert zero-terminator into space delimiter. */
127  s[0] = TEXT(' ');
128  s++;
129  /* Append argument. */
130  _tcscpy(s, p->val);
131  s += _tcslen(p->val);
132  }
133 
134 #ifdef _MSC_VER
135 #pragma warning(pop)
136 #endif
137 
138  return str;
139 }
Argument sequence.
Definition: msica_arg.h:48
TCHAR val[]
Pointer to the next argument in the sequence.
Definition: msica_arg.h:41
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:57
void msica_arg_seq_free(_Inout_ struct msica_arg_seq *seq)
Frees argument sequence.
Definition: msica_arg.c:44
#define malloc
Definition: cmocka.c:1795
struct msica_arg * next
Definition: msica_arg.h:40
#define _In_
Definition: basic.h:42
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:96
void msica_arg_seq_init(_Inout_ struct msica_arg_seq *seq)
Initializes argument sequence.
Definition: msica_arg.c:36
#define _Inout_
Definition: basic.h:51
Argument list.
Definition: msica_arg.h:38
#define msg(flags,...)
Definition: error.h:153
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:78
#define _In_z_
Definition: basic.h:48
#define M_FATAL
Definition: error.h:98
#define free
Definition: cmocka.c:1850