Coverage Report

Created: 2026-03-04 06:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/FreeRDP/winpr/libwinpr/utils/wlog/BinaryAppender.c
Line
Count
Source
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
  wLogAppender 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 = nullptr;
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, nullptr))
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
  return binaryAppender->FileDescriptor != nullptr;
82
0
}
83
84
static BOOL WLog_BinaryAppender_Close(WINPR_ATTR_UNUSED wLog* log, wLogAppender* appender)
85
0
{
86
0
  wLogBinaryAppender* binaryAppender = nullptr;
87
88
0
  if (!appender)
89
0
    return FALSE;
90
91
0
  binaryAppender = (wLogBinaryAppender*)appender;
92
0
  if (!binaryAppender->FileDescriptor)
93
0
    return TRUE;
94
95
0
  if (binaryAppender->FileDescriptor)
96
0
    (void)fclose(binaryAppender->FileDescriptor);
97
98
0
  binaryAppender->FileDescriptor = nullptr;
99
100
0
  return TRUE;
101
0
}
102
103
static BOOL WLog_BinaryAppender_WriteMessage(wLog* log, wLogAppender* appender,
104
                                             const wLogMessage* message)
105
0
{
106
0
  FILE* fp = nullptr;
107
0
  wStream* s = nullptr;
108
0
  size_t MessageLength = 0;
109
0
  size_t FileNameLength = 0;
110
0
  size_t FunctionNameLength = 0;
111
0
  size_t TextStringLength = 0;
112
0
  BOOL ret = TRUE;
113
0
  wLogBinaryAppender* binaryAppender = nullptr;
114
115
0
  if (!log || !appender || !message)
116
0
    return FALSE;
117
118
0
  binaryAppender = (wLogBinaryAppender*)appender;
119
120
0
  fp = binaryAppender->FileDescriptor;
121
122
0
  if (!fp)
123
0
    return FALSE;
124
125
0
  FileNameLength = strnlen(message->FileName, INT_MAX);
126
0
  FunctionNameLength = strnlen(message->FunctionName, INT_MAX);
127
0
  TextStringLength = strnlen(message->TextString, INT_MAX);
128
129
0
  MessageLength =
130
0
      16 + (4 + FileNameLength + 1) + (4 + FunctionNameLength + 1) + (4 + TextStringLength + 1);
131
132
0
  if ((MessageLength > UINT32_MAX) || (FileNameLength > UINT32_MAX) ||
133
0
      (FunctionNameLength > UINT32_MAX) || (TextStringLength > UINT32_MAX))
134
0
    return FALSE;
135
136
0
  s = Stream_New(nullptr, MessageLength);
137
0
  if (!s)
138
0
    return FALSE;
139
140
0
  Stream_Write_UINT32(s, (UINT32)MessageLength);
141
142
0
  Stream_Write_UINT32(s, message->Type);
143
0
  Stream_Write_UINT32(s, message->Level);
144
145
0
  WINPR_ASSERT(message->LineNumber <= UINT32_MAX);
146
0
  Stream_Write_UINT32(s, (UINT32)message->LineNumber);
147
148
0
  Stream_Write_UINT32(s, (UINT32)FileNameLength);
149
0
  Stream_Write(s, message->FileName, FileNameLength + 1);
150
151
0
  Stream_Write_UINT32(s, (UINT32)FunctionNameLength);
152
0
  Stream_Write(s, message->FunctionName, FunctionNameLength + 1);
153
154
0
  Stream_Write_UINT32(s, (UINT32)TextStringLength);
155
0
  Stream_Write(s, message->TextString, TextStringLength + 1);
156
157
0
  Stream_SealLength(s);
158
159
0
  if (fwrite(Stream_Buffer(s), MessageLength, 1, fp) != 1)
160
0
    ret = FALSE;
161
162
0
  Stream_Free(s, TRUE);
163
164
0
  return ret;
165
0
}
166
167
static BOOL WLog_BinaryAppender_WriteDataMessage(WINPR_ATTR_UNUSED wLog* log,
168
                                                 WINPR_ATTR_UNUSED wLogAppender* appender,
169
                                                 WINPR_ATTR_UNUSED const wLogMessage* message)
170
0
{
171
0
  return TRUE;
172
0
}
173
174
static BOOL WLog_BinaryAppender_WriteImageMessage(WINPR_ATTR_UNUSED wLog* log,
175
                                                  WINPR_ATTR_UNUSED wLogAppender* appender,
176
                                                  WINPR_ATTR_UNUSED const wLogMessage* message)
177
0
{
178
0
  return TRUE;
179
0
}
180
181
static BOOL WLog_BinaryAppender_Set(wLogAppender* appender, const char* setting, void* value)
182
0
{
183
0
  wLogBinaryAppender* binaryAppender = (wLogBinaryAppender*)appender;
184
185
  /* Just check if the value string is longer than 0 */
186
0
  if (!value || (strnlen(value, 2) == 0))
187
0
    return FALSE;
188
189
0
  if (!strcmp("outputfilename", setting))
190
0
  {
191
0
    binaryAppender->FileName = _strdup((const char*)value);
192
0
    if (!binaryAppender->FileName)
193
0
      return FALSE;
194
0
  }
195
0
  else if (!strcmp("outputfilepath", setting))
196
0
  {
197
0
    binaryAppender->FilePath = _strdup((const char*)value);
198
0
    if (!binaryAppender->FilePath)
199
0
      return FALSE;
200
0
  }
201
0
  else
202
0
    return FALSE;
203
204
0
  return TRUE;
205
0
}
206
207
static void WLog_BinaryAppender_Free(wLogAppender* appender)
208
0
{
209
0
  wLogBinaryAppender* binaryAppender = nullptr;
210
0
  if (appender)
211
0
  {
212
0
    binaryAppender = (wLogBinaryAppender*)appender;
213
0
    free(binaryAppender->FileName);
214
0
    free(binaryAppender->FilePath);
215
0
    free(binaryAppender->FullFileName);
216
0
    free(binaryAppender);
217
0
  }
218
0
}
219
220
wLogAppender* WLog_BinaryAppender_New(WINPR_ATTR_UNUSED wLog* log)
221
0
{
222
0
  wLogBinaryAppender* BinaryAppender = (wLogBinaryAppender*)calloc(1, sizeof(wLogBinaryAppender));
223
0
  if (!BinaryAppender)
224
0
    return nullptr;
225
226
0
  BinaryAppender->common.Type = WLOG_APPENDER_BINARY;
227
0
  BinaryAppender->common.Open = WLog_BinaryAppender_Open;
228
0
  BinaryAppender->common.Close = WLog_BinaryAppender_Close;
229
0
  BinaryAppender->common.WriteMessage = WLog_BinaryAppender_WriteMessage;
230
0
  BinaryAppender->common.WriteDataMessage = WLog_BinaryAppender_WriteDataMessage;
231
0
  BinaryAppender->common.WriteImageMessage = WLog_BinaryAppender_WriteImageMessage;
232
0
  BinaryAppender->common.Free = WLog_BinaryAppender_Free;
233
0
  BinaryAppender->common.Set = WLog_BinaryAppender_Set;
234
235
0
  return &BinaryAppender->common;
236
0
}