Coverage Report

Created: 2024-05-20 06:11

/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
    sprintf_s(binaryAppender->FileName, MAX_PATH, "%" PRIu32 ".wlog", GetCurrentProcessId());
54
0
  }
55
56
0
  if (!binaryAppender->FilePath)
57
0
  {
58
0
    binaryAppender->FilePath = GetKnownSubPath(KNOWN_PATH_TEMP, "wlog");
59
0
    if (!binaryAppender->FilePath)
60
0
      return FALSE;
61
0
  }
62
63
0
  if (!binaryAppender->FullFileName)
64
0
  {
65
0
    binaryAppender->FullFileName =
66
0
        GetCombinedPath(binaryAppender->FilePath, binaryAppender->FileName);
67
0
    if (!binaryAppender->FullFileName)
68
0
      return FALSE;
69
0
  }
70
71
0
  if (!winpr_PathFileExists(binaryAppender->FilePath))
72
0
  {
73
0
    if (!winpr_PathMakePath(binaryAppender->FilePath, 0))
74
0
      return FALSE;
75
0
    UnixChangeFileMode(binaryAppender->FilePath, 0xFFFF);
76
0
  }
77
78
0
  binaryAppender->FileDescriptor = winpr_fopen(binaryAppender->FullFileName, "a+");
79
80
0
  if (!binaryAppender->FileDescriptor)
81
0
    return FALSE;
82
83
0
  return TRUE;
84
0
}
85
86
static BOOL WLog_BinaryAppender_Close(wLog* log, wLogAppender* appender)
87
0
{
88
0
  wLogBinaryAppender* binaryAppender = NULL;
89
90
0
  if (!appender)
91
0
    return FALSE;
92
93
0
  binaryAppender = (wLogBinaryAppender*)appender;
94
0
  if (!binaryAppender->FileDescriptor)
95
0
    return TRUE;
96
97
0
  if (binaryAppender->FileDescriptor)
98
0
    fclose(binaryAppender->FileDescriptor);
99
100
0
  binaryAppender->FileDescriptor = NULL;
101
102
0
  return TRUE;
103
0
}
104
105
static BOOL WLog_BinaryAppender_WriteMessage(wLog* log, wLogAppender* appender,
106
                                             wLogMessage* message)
107
0
{
108
0
  FILE* fp = NULL;
109
0
  wStream* s = NULL;
110
0
  size_t MessageLength = 0;
111
0
  size_t FileNameLength = 0;
112
0
  size_t FunctionNameLength = 0;
113
0
  size_t TextStringLength = 0;
114
0
  BOOL ret = TRUE;
115
0
  wLogBinaryAppender* binaryAppender = NULL;
116
117
0
  if (!log || !appender || !message)
118
0
    return FALSE;
119
120
0
  binaryAppender = (wLogBinaryAppender*)appender;
121
122
0
  fp = binaryAppender->FileDescriptor;
123
124
0
  if (!fp)
125
0
    return FALSE;
126
127
0
  FileNameLength = strnlen(message->FileName, INT_MAX);
128
0
  FunctionNameLength = strnlen(message->FunctionName, INT_MAX);
129
0
  TextStringLength = strnlen(message->TextString, INT_MAX);
130
131
0
  MessageLength =
132
0
      16 + (4 + FileNameLength + 1) + (4 + FunctionNameLength + 1) + (4 + TextStringLength + 1);
133
134
0
  if ((MessageLength > UINT32_MAX) || (FileNameLength > UINT32_MAX) ||
135
0
      (FunctionNameLength > UINT32_MAX) || (TextStringLength > UINT32_MAX))
136
0
    return FALSE;
137
138
0
  s = Stream_New(NULL, MessageLength);
139
0
  if (!s)
140
0
    return FALSE;
141
142
0
  Stream_Write_UINT32(s, (UINT32)MessageLength);
143
144
0
  Stream_Write_UINT32(s, message->Type);
145
0
  Stream_Write_UINT32(s, message->Level);
146
147
0
  WINPR_ASSERT(message->LineNumber <= UINT32_MAX);
148
0
  Stream_Write_UINT32(s, (UINT32)message->LineNumber);
149
150
0
  Stream_Write_UINT32(s, (UINT32)FileNameLength);
151
0
  Stream_Write(s, message->FileName, FileNameLength + 1);
152
153
0
  Stream_Write_UINT32(s, (UINT32)FunctionNameLength);
154
0
  Stream_Write(s, message->FunctionName, FunctionNameLength + 1);
155
156
0
  Stream_Write_UINT32(s, (UINT32)TextStringLength);
157
0
  Stream_Write(s, message->TextString, TextStringLength + 1);
158
159
0
  Stream_SealLength(s);
160
161
0
  if (fwrite(Stream_Buffer(s), MessageLength, 1, fp) != 1)
162
0
    ret = FALSE;
163
164
0
  Stream_Free(s, TRUE);
165
166
0
  return ret;
167
0
}
168
169
static BOOL WLog_BinaryAppender_WriteDataMessage(wLog* log, wLogAppender* appender,
170
                                                 wLogMessage* message)
171
0
{
172
0
  return TRUE;
173
0
}
174
175
static BOOL WLog_BinaryAppender_WriteImageMessage(wLog* log, wLogAppender* appender,
176
                                                  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 = NULL;
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(wLog* log)
221
0
{
222
0
  wLogBinaryAppender* BinaryAppender = NULL;
223
224
0
  BinaryAppender = (wLogBinaryAppender*)calloc(1, sizeof(wLogBinaryAppender));
225
0
  if (!BinaryAppender)
226
0
    return NULL;
227
228
0
  BinaryAppender->Type = WLOG_APPENDER_BINARY;
229
0
  BinaryAppender->Open = WLog_BinaryAppender_Open;
230
0
  BinaryAppender->Close = WLog_BinaryAppender_Close;
231
0
  BinaryAppender->WriteMessage = WLog_BinaryAppender_WriteMessage;
232
0
  BinaryAppender->WriteDataMessage = WLog_BinaryAppender_WriteDataMessage;
233
0
  BinaryAppender->WriteImageMessage = WLog_BinaryAppender_WriteImageMessage;
234
0
  BinaryAppender->Free = WLog_BinaryAppender_Free;
235
0
  BinaryAppender->Set = WLog_BinaryAppender_Set;
236
237
0
  return (wLogAppender*)BinaryAppender;
238
0
}