Coverage Report

Created: 2025-07-01 06:46

/src/FreeRDP/winpr/libwinpr/utils/wlog/BinaryAppender.c
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * WinPR: Windows Portable Runtime
3
 * WinPR Logger
4
 *
5
 * Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6
 * Copyright 2015 Thincast Technologies GmbH
7
 * Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
8
 *
9
 * Licensed under the Apache License, Version 2.0 (the "License");
10
 * you may not use this file except in compliance with the License.
11
 * You may obtain a copy of the License at
12
 *
13
 *     http://www.apache.org/licenses/LICENSE-2.0
14
 *
15
 * Unless required by applicable law or agreed to in writing, software
16
 * distributed under the License is distributed on an "AS IS" BASIS,
17
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
 * See the License for the specific language governing permissions and
19
 * limitations under the License.
20
 */
21
22
#include <winpr/config.h>
23
24
#include "BinaryAppender.h"
25
#include <winpr/crt.h>
26
#include <winpr/assert.h>
27
#include <winpr/file.h>
28
#include <winpr/path.h>
29
#include <winpr/stream.h>
30
31
typedef struct
32
{
33
  WLOG_APPENDER_COMMON();
34
35
  char* FileName;
36
  char* FilePath;
37
  char* FullFileName;
38
  FILE* FileDescriptor;
39
} wLogBinaryAppender;
40
41
static BOOL WLog_BinaryAppender_Open(wLog* log, wLogAppender* appender)
42
0
{
43
0
  wLogBinaryAppender* binaryAppender = NULL;
44
0
  if (!log || !appender)
45
0
    return FALSE;
46
47
0
  binaryAppender = (wLogBinaryAppender*)appender;
48
0
  if (!binaryAppender->FileName)
49
0
  {
50
0
    binaryAppender->FileName = (char*)malloc(MAX_PATH);
51
0
    if (!binaryAppender->FileName)
52
0
      return FALSE;
53
0
    (void)sprintf_s(binaryAppender->FileName, MAX_PATH, "%" PRIu32 ".wlog",
54
0
                    GetCurrentProcessId());
55
0
  }
56
57
0
  if (!binaryAppender->FilePath)
58
0
  {
59
0
    binaryAppender->FilePath = GetKnownSubPath(KNOWN_PATH_TEMP, "wlog");
60
0
    if (!binaryAppender->FilePath)
61
0
      return FALSE;
62
0
  }
63
64
0
  if (!binaryAppender->FullFileName)
65
0
  {
66
0
    binaryAppender->FullFileName =
67
0
        GetCombinedPath(binaryAppender->FilePath, binaryAppender->FileName);
68
0
    if (!binaryAppender->FullFileName)
69
0
      return FALSE;
70
0
  }
71
72
0
  if (!winpr_PathFileExists(binaryAppender->FilePath))
73
0
  {
74
0
    if (!winpr_PathMakePath(binaryAppender->FilePath, 0))
75
0
      return FALSE;
76
0
    UnixChangeFileMode(binaryAppender->FilePath, 0xFFFF);
77
0
  }
78
79
0
  binaryAppender->FileDescriptor = winpr_fopen(binaryAppender->FullFileName, "a+");
80
81
0
  if (!binaryAppender->FileDescriptor)
82
0
    return FALSE;
83
84
0
  return TRUE;
85
0
}
86
87
static BOOL WLog_BinaryAppender_Close(WINPR_ATTR_UNUSED wLog* log, wLogAppender* appender)
88
0
{
89
0
  wLogBinaryAppender* binaryAppender = NULL;
90
91
0
  if (!appender)
92
0
    return FALSE;
93
94
0
  binaryAppender = (wLogBinaryAppender*)appender;
95
0
  if (!binaryAppender->FileDescriptor)
96
0
    return TRUE;
97
98
0
  if (binaryAppender->FileDescriptor)
99
0
    (void)fclose(binaryAppender->FileDescriptor);
100
101
0
  binaryAppender->FileDescriptor = NULL;
102
103
0
  return TRUE;
104
0
}
105
106
static BOOL WLog_BinaryAppender_WriteMessage(wLog* log, wLogAppender* appender,
107
                                             wLogMessage* message)
108
0
{
109
0
  FILE* fp = NULL;
110
0
  wStream* s = NULL;
111
0
  size_t MessageLength = 0;
112
0
  size_t FileNameLength = 0;
113
0
  size_t FunctionNameLength = 0;
114
0
  size_t TextStringLength = 0;
115
0
  BOOL ret = TRUE;
116
0
  wLogBinaryAppender* binaryAppender = NULL;
117
118
0
  if (!log || !appender || !message)
119
0
    return FALSE;
120
121
0
  binaryAppender = (wLogBinaryAppender*)appender;
122
123
0
  fp = binaryAppender->FileDescriptor;
124
125
0
  if (!fp)
126
0
    return FALSE;
127
128
0
  FileNameLength = strnlen(message->FileName, INT_MAX);
129
0
  FunctionNameLength = strnlen(message->FunctionName, INT_MAX);
130
0
  TextStringLength = strnlen(message->TextString, INT_MAX);
131
132
0
  MessageLength =
133
0
      16 + (4 + FileNameLength + 1) + (4 + FunctionNameLength + 1) + (4 + TextStringLength + 1);
134
135
0
  if ((MessageLength > UINT32_MAX) || (FileNameLength > UINT32_MAX) ||
136
0
      (FunctionNameLength > UINT32_MAX) || (TextStringLength > UINT32_MAX))
137
0
    return FALSE;
138
139
0
  s = Stream_New(NULL, MessageLength);
140
0
  if (!s)
141
0
    return FALSE;
142
143
0
  Stream_Write_UINT32(s, (UINT32)MessageLength);
144
145
0
  Stream_Write_UINT32(s, message->Type);
146
0
  Stream_Write_UINT32(s, message->Level);
147
148
0
  WINPR_ASSERT(message->LineNumber <= UINT32_MAX);
149
0
  Stream_Write_UINT32(s, (UINT32)message->LineNumber);
150
151
0
  Stream_Write_UINT32(s, (UINT32)FileNameLength);
152
0
  Stream_Write(s, message->FileName, FileNameLength + 1);
153
154
0
  Stream_Write_UINT32(s, (UINT32)FunctionNameLength);
155
0
  Stream_Write(s, message->FunctionName, FunctionNameLength + 1);
156
157
0
  Stream_Write_UINT32(s, (UINT32)TextStringLength);
158
0
  Stream_Write(s, message->TextString, TextStringLength + 1);
159
160
0
  Stream_SealLength(s);
161
162
0
  if (fwrite(Stream_Buffer(s), MessageLength, 1, fp) != 1)
163
0
    ret = FALSE;
164
165
0
  Stream_Free(s, TRUE);
166
167
0
  return ret;
168
0
}
169
170
static BOOL WLog_BinaryAppender_WriteDataMessage(WINPR_ATTR_UNUSED wLog* log,
171
                                                 WINPR_ATTR_UNUSED wLogAppender* appender,
172
                                                 WINPR_ATTR_UNUSED wLogMessage* message)
173
0
{
174
0
  return TRUE;
175
0
}
176
177
static BOOL WLog_BinaryAppender_WriteImageMessage(WINPR_ATTR_UNUSED wLog* log,
178
                                                  WINPR_ATTR_UNUSED wLogAppender* appender,
179
                                                  WINPR_ATTR_UNUSED wLogMessage* message)
180
0
{
181
0
  return TRUE;
182
0
}
183
184
static BOOL WLog_BinaryAppender_Set(wLogAppender* appender, const char* setting, void* value)
185
0
{
186
0
  wLogBinaryAppender* binaryAppender = (wLogBinaryAppender*)appender;
187
188
  /* Just check if the value string is longer than 0 */
189
0
  if (!value || (strnlen(value, 2) == 0))
190
0
    return FALSE;
191
192
0
  if (!strcmp("outputfilename", setting))
193
0
  {
194
0
    binaryAppender->FileName = _strdup((const char*)value);
195
0
    if (!binaryAppender->FileName)
196
0
      return FALSE;
197
0
  }
198
0
  else if (!strcmp("outputfilepath", setting))
199
0
  {
200
0
    binaryAppender->FilePath = _strdup((const char*)value);
201
0
    if (!binaryAppender->FilePath)
202
0
      return FALSE;
203
0
  }
204
0
  else
205
0
    return FALSE;
206
207
0
  return TRUE;
208
0
}
209
210
static void WLog_BinaryAppender_Free(wLogAppender* appender)
211
0
{
212
0
  wLogBinaryAppender* binaryAppender = NULL;
213
0
  if (appender)
214
0
  {
215
0
    binaryAppender = (wLogBinaryAppender*)appender;
216
0
    free(binaryAppender->FileName);
217
0
    free(binaryAppender->FilePath);
218
0
    free(binaryAppender->FullFileName);
219
0
    free(binaryAppender);
220
0
  }
221
0
}
222
223
wLogAppender* WLog_BinaryAppender_New(WINPR_ATTR_UNUSED wLog* log)
224
0
{
225
0
  wLogBinaryAppender* BinaryAppender = NULL;
226
227
0
  BinaryAppender = (wLogBinaryAppender*)calloc(1, sizeof(wLogBinaryAppender));
228
0
  if (!BinaryAppender)
229
0
    return NULL;
230
231
0
  BinaryAppender->Type = WLOG_APPENDER_BINARY;
232
0
  BinaryAppender->Open = WLog_BinaryAppender_Open;
233
0
  BinaryAppender->Close = WLog_BinaryAppender_Close;
234
0
  BinaryAppender->WriteMessage = WLog_BinaryAppender_WriteMessage;
235
0
  BinaryAppender->WriteDataMessage = WLog_BinaryAppender_WriteDataMessage;
236
0
  BinaryAppender->WriteImageMessage = WLog_BinaryAppender_WriteImageMessage;
237
0
  BinaryAppender->Free = WLog_BinaryAppender_Free;
238
0
  BinaryAppender->Set = WLog_BinaryAppender_Set;
239
240
0
  return (wLogAppender*)BinaryAppender;
241
0
}