1 /**
2 * WinPR: Windows Portable Runtime
3 * Print Utils
4 *
5 * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include <stdio.h>
25 #include <string.h>
26 #include <stdarg.h>
27 #include <errno.h>
28
29 #include <winpr/crt.h>
30 #include <winpr/print.h>
31
32 #include "trio.h"
33
34 #include "../log.h"
35
winpr_HexDump(const char * tag,UINT32 level,const BYTE * data,size_t length)36 void winpr_HexDump(const char* tag, UINT32 level, const BYTE* data, size_t length)
37 {
38 wLog* log = WLog_Get(tag);
39 winpr_HexLogDump(log, level, data, length);
40 }
41
winpr_HexLogDump(wLog * log,UINT32 lvl,const BYTE * data,size_t length)42 void winpr_HexLogDump(wLog* log, UINT32 lvl, const BYTE* data, size_t length)
43 {
44 const BYTE* p = data;
45 size_t i, line, offset = 0;
46 const int maxlen = 20; /* 64bit SIZE_MAX as decimal */
47 /* String line length:
48 * prefix '[1234] '
49 * hexdump '01 02 03 04'
50 * separator ' '
51 * ASIC line 'ab..cd'
52 * zero terminator '\0'
53 */
54 const size_t blen =
55 ((size_t)maxlen + 3) + (WINPR_HEXDUMP_LINE_LENGTH * 3) + 3 + WINPR_HEXDUMP_LINE_LENGTH + 1;
56 size_t pos = 0;
57
58 char* buffer;
59
60 if (!log || (maxlen < 0))
61 return;
62
63 buffer = malloc(blen);
64
65 if (!buffer)
66 {
67 WLog_Print(log, WLOG_ERROR, "malloc(%" PRIuz ") failed with [%" PRIuz "] %s", blen, errno,
68 strerror(errno));
69 return;
70 }
71
72 while (offset < length)
73 {
74 int rc = trio_snprintf(&buffer[pos], blen - pos, "%04" PRIuz " ", offset);
75
76 if (rc < 0)
77 goto fail;
78
79 pos += (size_t)rc;
80 line = length - offset;
81
82 if (line > WINPR_HEXDUMP_LINE_LENGTH)
83 line = WINPR_HEXDUMP_LINE_LENGTH;
84
85 for (i = 0; i < line; i++)
86 {
87 rc = trio_snprintf(&buffer[pos], blen - pos, "%02" PRIx8 " ", p[i]);
88
89 if (rc < 0)
90 goto fail;
91
92 pos += (size_t)rc;
93 }
94
95 for (; i < WINPR_HEXDUMP_LINE_LENGTH; i++)
96 {
97 rc = trio_snprintf(&buffer[pos], blen - pos, " ");
98
99 if (rc < 0)
100 goto fail;
101
102 pos += (size_t)rc;
103 }
104
105 for (i = 0; i < line; i++)
106 {
107 rc = trio_snprintf(&buffer[pos], blen - pos, "%c",
108 (p[i] >= 0x20 && p[i] < 0x7F) ? (char)p[i] : '.');
109
110 if (rc < 0)
111 goto fail;
112
113 pos += (size_t)rc;
114 }
115
116 WLog_Print(log, lvl, "%s", buffer);
117 offset += line;
118 p += line;
119 pos = 0;
120 }
121
122 WLog_Print(log, lvl, "[length=%" PRIuz "] ", length);
123 fail:
124 free(buffer);
125 }
126
winpr_CArrayDump(const char * tag,UINT32 level,const BYTE * data,int length,int width)127 void winpr_CArrayDump(const char* tag, UINT32 level, const BYTE* data, int length, int width)
128 {
129 const BYTE* p = data;
130 int i, line, offset = 0;
131 const size_t llen = ((length > width) ? width : length) * 4 + 1;
132 size_t pos;
133 char* buffer = malloc(llen);
134
135 if (!buffer)
136 {
137 WLog_ERR(tag, "malloc(%" PRIuz ") failed with [%d] %s", llen, errno, strerror(errno));
138 return;
139 }
140
141 while (offset < length)
142 {
143 line = length - offset;
144
145 if (line > width)
146 line = width;
147
148 pos = 0;
149
150 for (i = 0; i < line; i++)
151 pos += trio_snprintf(&buffer[pos], llen - pos, "\\x%02" PRIX8 "", p[i]);
152
153 WLog_LVL(tag, level, "%s", buffer);
154 offset += line;
155 p += line;
156 }
157
158 free(buffer);
159 }
160
winpr_BinToHexString(const BYTE * data,int length,BOOL space)161 char* winpr_BinToHexString(const BYTE* data, int length, BOOL space)
162 {
163 size_t i;
164 int n;
165 char* p;
166 const char bin2hex[] = "0123456789ABCDEF";
167 n = space ? 3 : 2;
168 p = (char*)malloc((length + 1ULL) * n);
169
170 if (!p)
171 return NULL;
172
173 for (i = 0; i < length; i++)
174 {
175 int ln = data[i] & 0xF;
176 int hn = (data[i] >> 4) & 0xF;
177 p[i * n] = bin2hex[hn];
178 p[(i * n) + 1] = bin2hex[ln];
179
180 if (space)
181 p[(i * n) + 2] = ' ';
182 }
183
184 p[length * n] = '\0';
185 return p;
186 }
187
wvprintfx(const char * fmt,va_list args)188 int wvprintfx(const char* fmt, va_list args)
189 {
190 return trio_vprintf(fmt, args);
191 }
192
wprintfx(const char * fmt,...)193 int wprintfx(const char* fmt, ...)
194 {
195 va_list args;
196 int status;
197 va_start(args, fmt);
198 status = trio_vprintf(fmt, args);
199 va_end(args);
200 return status;
201 }
202
wvsnprintfx(char * buffer,size_t bufferSize,const char * fmt,va_list args)203 int wvsnprintfx(char* buffer, size_t bufferSize, const char* fmt, va_list args)
204 {
205 return trio_vsnprintf(buffer, bufferSize, fmt, args);
206 }
207