1 // SoftEther VPN Source Code - Stable Edition Repository
2 // Mayaqua Kernel
3 //
4 // SoftEther VPN Server, Client and Bridge are free software under the Apache License, Version 2.0.
5 //
6 // Copyright (c) Daiyuu Nobori.
7 // Copyright (c) SoftEther VPN Project, University of Tsukuba, Japan.
8 // Copyright (c) SoftEther Corporation.
9 // Copyright (c) all contributors on SoftEther VPN project in GitHub.
10 //
11 // All Rights Reserved.
12 //
13 // http://www.softether.org/
14 //
15 // This stable branch is officially managed by Daiyuu Nobori, the owner of SoftEther VPN Project.
16 // Pull requests should be sent to the Developer Edition Master Repository on https://github.com/SoftEtherVPN/SoftEtherVPN
17 //
18 // License: The Apache License, Version 2.0
19 // https://www.apache.org/licenses/LICENSE-2.0
20 //
21 // DISCLAIMER
22 // ==========
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 // SOFTWARE.
31 //
32 // THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN, UNDER
33 // JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY, MERGE, PUBLISH,
34 // DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS SOFTWARE, THAT ANY
35 // JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS SOFTWARE OR ITS CONTENTS,
36 // AGAINST US (SOFTETHER PROJECT, SOFTETHER CORPORATION, DAIYUU NOBORI OR OTHER
37 // SUPPLIERS), OR ANY JURIDICAL DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND
38 // OF USING, COPYING, MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING,
39 // AND/OR SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
40 // CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO EXCLUSIVE
41 // JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO, JAPAN. YOU MUST WAIVE
42 // ALL DEFENSES OF LACK OF PERSONAL JURISDICTION AND FORUM NON CONVENIENS.
43 // PROCESS MAY BE SERVED ON EITHER PARTY IN THE MANNER AUTHORIZED BY APPLICABLE
44 // LAW OR COURT RULE.
45 //
46 // USE ONLY IN JAPAN. DO NOT USE THIS SOFTWARE IN ANOTHER COUNTRY UNLESS YOU HAVE
47 // A CONFIRMATION THAT THIS SOFTWARE DOES NOT VIOLATE ANY CRIMINAL LAWS OR CIVIL
48 // RIGHTS IN THAT PARTICULAR COUNTRY. USING THIS SOFTWARE IN OTHER COUNTRIES IS
49 // COMPLETELY AT YOUR OWN RISK. THE SOFTETHER VPN PROJECT HAS DEVELOPED AND
50 // DISTRIBUTED THIS SOFTWARE TO COMPLY ONLY WITH THE JAPANESE LAWS AND EXISTING
51 // CIVIL RIGHTS INCLUDING PATENTS WHICH ARE SUBJECTS APPLY IN JAPAN. OTHER
52 // COUNTRIES' LAWS OR CIVIL RIGHTS ARE NONE OF OUR CONCERNS NOR RESPONSIBILITIES.
53 // WE HAVE NEVER INVESTIGATED ANY CRIMINAL REGULATIONS, CIVIL LAWS OR
54 // INTELLECTUAL PROPERTY RIGHTS INCLUDING PATENTS IN ANY OF OTHER 200+ COUNTRIES
55 // AND TERRITORIES. BY NATURE, THERE ARE 200+ REGIONS IN THE WORLD, WITH
56 // DIFFERENT LAWS. IT IS IMPOSSIBLE TO VERIFY EVERY COUNTRIES' LAWS, REGULATIONS
57 // AND CIVIL RIGHTS TO MAKE THE SOFTWARE COMPLY WITH ALL COUNTRIES' LAWS BY THE
58 // PROJECT. EVEN IF YOU WILL BE SUED BY A PRIVATE ENTITY OR BE DAMAGED BY A
59 // PUBLIC SERVANT IN YOUR COUNTRY, THE DEVELOPERS OF THIS SOFTWARE WILL NEVER BE
60 // LIABLE TO RECOVER OR COMPENSATE SUCH DAMAGES, CRIMINAL OR CIVIL
61 // RESPONSIBILITIES. NOTE THAT THIS LINE IS NOT LICENSE RESTRICTION BUT JUST A
62 // STATEMENT FOR WARNING AND DISCLAIMER.
63 //
64 // READ AND UNDERSTAND THE 'WARNING.TXT' FILE BEFORE USING THIS SOFTWARE.
65 // SOME SOFTWARE PROGRAMS FROM THIRD PARTIES ARE INCLUDED ON THIS SOFTWARE WITH
66 // LICENSE CONDITIONS WHICH ARE DESCRIBED ON THE 'THIRD_PARTY.TXT' FILE.
67 //
68 //
69 // SOURCE CODE CONTRIBUTION
70 // ------------------------
71 //
72 // Your contribution to SoftEther VPN Project is much appreciated.
73 // Please send patches to us through GitHub.
74 // Read the SoftEther VPN Patch Acceptance Policy in advance:
75 // http://www.softether.org/5-download/src/9.patch
76 //
77 //
78 // DEAR SECURITY EXPERTS
79 // ---------------------
80 //
81 // If you find a bug or a security vulnerability please kindly inform us
82 // about the problem immediately so that we can fix the security problem
83 // to protect a lot of users around the world as soon as possible.
84 //
85 // Our e-mail address for security reports is:
86 // softether-vpn-security [at] softether.org
87 //
88 // Please note that the above e-mail address is not a technical support
89 // inquiry address. If you need technical assistance, please visit
90 // http://www.softether.org/ and ask your question on the users forum.
91 //
92 // Thank you for your cooperation.
93 //
94 //
95 // NO MEMORY OR RESOURCE LEAKS
96 // ---------------------------
97 //
98 // The memory-leaks and resource-leaks verification under the stress
99 // test has been passed before release this source code.
100 
101 
102 // Pack.c
103 // Data package code
104 
105 #include <GlobalConst.h>
106 
107 #include <stdio.h>
108 #include <stdlib.h>
109 #include <string.h>
110 #include <wchar.h>
111 #include <stdarg.h>
112 #include <time.h>
113 #include <errno.h>
114 #include <Mayaqua/Mayaqua.h>
115 
116 // Get a list of the element names in the PACK
GetPackElementNames(PACK * p)117 TOKEN_LIST *GetPackElementNames(PACK *p)
118 {
119 	TOKEN_LIST *ret;
120 	UINT i;
121 	// Validate arguments
122 	if (p == NULL)
123 	{
124 		return NULL;
125 	}
126 
127 	ret = ZeroMalloc(sizeof(TOKEN_LIST));
128 
129 	ret->NumTokens = LIST_NUM(p->elements);
130 	ret->Token = ZeroMalloc(sizeof(char *) * ret->NumTokens);
131 
132 	for (i = 0;i < ret->NumTokens;i++)
133 	{
134 		ELEMENT *e = LIST_DATA(p->elements, i);
135 
136 		ret->Token[i] = CopyStr(e->name);
137 	}
138 
139 	return ret;
140 }
141 
142 // Convert the BUF to a PACK
BufToPack(BUF * b)143 PACK *BufToPack(BUF *b)
144 {
145 	PACK *p;
146 	// Validate arguments
147 	if (b == NULL)
148 	{
149 		return NULL;
150 	}
151 
152 	p = NewPack();
153 	if (ReadPack(b, p) == false)
154 	{
155 		FreePack(p);
156 		return NULL;
157 	}
158 
159 	return p;
160 }
161 
162 // Convert the PACK to the BUF
PackToBuf(PACK * p)163 BUF *PackToBuf(PACK *p)
164 {
165 	BUF *b;
166 	// Validate arguments
167 	if (p == NULL)
168 	{
169 		return NULL;
170 	}
171 
172 	b = NewBuf();
173 	WritePack(b, p);
174 
175 	return b;
176 }
177 
178 // Read the PACK
ReadPack(BUF * b,PACK * p)179 bool ReadPack(BUF *b, PACK *p)
180 {
181 	UINT i, num;
182 	// Validate arguments
183 	if (b == NULL || p == NULL)
184 	{
185 		return false;
186 	}
187 
188 	// The number of ELEMENTs
189 	num = ReadBufInt(b);
190 	if (num > MAX_ELEMENT_NUM)
191 	{
192 		// Number exceeds
193 		return false;
194 	}
195 
196 	// Read the ELEMENT
197 	for (i = 0;i < num;i++)
198 	{
199 		ELEMENT *e;
200 		e = ReadElement(b);
201 		if (AddElement(p, e) == false)
202 		{
203 			// Adding error
204 			return false;
205 		}
206 	}
207 
208 	return true;
209 }
210 
211 // Write down the PACK
WritePack(BUF * b,PACK * p)212 void WritePack(BUF *b, PACK *p)
213 {
214 	UINT i;
215 	// Validate arguments
216 	if (b == NULL || p == NULL)
217 	{
218 		return;
219 	}
220 
221 	// The number of ELEMENTs
222 	WriteBufInt(b, LIST_NUM(p->elements));
223 
224 	// Write the ELEMENT
225 	for (i = 0;i < LIST_NUM(p->elements);i++)
226 	{
227 		ELEMENT *e = LIST_DATA(p->elements, i);
228 		WriteElement(b, e);
229 	}
230 }
231 
232 // Read the ELEMENT
ReadElement(BUF * b)233 ELEMENT *ReadElement(BUF *b)
234 {
235 	UINT i;
236 	char name[MAX_ELEMENT_NAME_LEN + 1];
237 	UINT type, num_value;
238 	VALUE **values;
239 	ELEMENT *e;
240 	// Validate arguments
241 	if (b == NULL)
242 	{
243 		return NULL;
244 	}
245 
246 	// Name
247 	if (ReadBufStr(b, name, sizeof(name)) == false)
248 	{
249 		return NULL;
250 	}
251 
252 	// Type of item
253 	type = ReadBufInt(b);
254 
255 	// Number of items
256 	num_value = ReadBufInt(b);
257 	if (num_value > MAX_VALUE_NUM)
258 	{
259 		// Number exceeds
260 		return NULL;
261 	}
262 
263 	// VALUE
264 	values = (VALUE **)Malloc(sizeof(VALUE *) * num_value);
265 	for (i = 0;i < num_value;i++)
266 	{
267 		values[i] = ReadValue(b, type);
268 	}
269 
270 	// Create a ELEMENT
271 	e = NewElement(name, type, num_value, values);
272 
273 	Free(values);
274 
275 	return e;
276 }
277 
278 // Write the ELEMENT
WriteElement(BUF * b,ELEMENT * e)279 void WriteElement(BUF *b, ELEMENT *e)
280 {
281 	UINT i;
282 	// Validate arguments
283 	if (b == NULL || e == NULL)
284 	{
285 		return;
286 	}
287 
288 	// Name
289 	WriteBufStr(b, e->name);
290 	// Type of item
291 	WriteBufInt(b, e->type);
292 	// Number of items
293 	WriteBufInt(b, e->num_value);
294 	// VALUE
295 	for (i = 0;i < e->num_value;i++)
296 	{
297 		VALUE *v = e->values[i];
298 		WriteValue(b, v, e->type);
299 	}
300 }
301 
302 // Read the VALUE
ReadValue(BUF * b,UINT type)303 VALUE *ReadValue(BUF *b, UINT type)
304 {
305 	UINT len;
306 	BYTE *u;
307 	void *data;
308 	char *str;
309 	wchar_t *unistr;
310 	UINT unistr_size;
311 	UINT size;
312 	UINT u_size;
313 	VALUE *v = NULL;
314 	// Validate arguments
315 	if (b == NULL)
316 	{
317 		return NULL;
318 	}
319 
320 	// Data item
321 	switch (type)
322 	{
323 	case VALUE_INT:			// Integer
324 		v = NewIntValue(ReadBufInt(b));
325 		break;
326 	case VALUE_INT64:
327 		v = NewInt64Value(ReadBufInt64(b));
328 		break;
329 	case VALUE_DATA:		// Data
330 		size = ReadBufInt(b);
331 		if (size > MAX_VALUE_SIZE)
332 		{
333 			// Size over
334 			break;
335 		}
336 		data = Malloc(size);
337 		if (ReadBuf(b, data, size) != size)
338 		{
339 			// Read failure
340 			Free(data);
341 			break;
342 		}
343 		v = NewDataValue(data, size);
344 		Free(data);
345 		break;
346 	case VALUE_STR:			// ANSI string
347 		len = ReadBufInt(b);
348 		if (len > (MAX_VALUE_SIZE - 1))
349 		{
350 			// Size over
351 			break;
352 		}
353 		str = Malloc(len + 1);
354 		// String body
355 		if (ReadBuf(b, str, len) != len)
356 		{
357 			// Read failure
358 			Free(str);
359 			break;
360 		}
361 		str[len] = 0;
362 		v = NewStrValue(str);
363 		Free(str);
364 		break;
365 	case VALUE_UNISTR:		// Unicode string
366 		u_size = ReadBufInt(b);
367 		if (u_size > MAX_VALUE_SIZE)
368 		{
369 			// Size over
370 			break;
371 		}
372 		// Reading an UTF-8 string
373 		u = ZeroMalloc(u_size + 1);
374 		if (ReadBuf(b, u, u_size) != u_size)
375 		{
376 			// Read failure
377 			Free(u);
378 			break;
379 		}
380 		// Convert to a Unicode string
381 		unistr_size = CalcUtf8ToUni(u, u_size);
382 		if (unistr_size == 0)
383 		{
384 			Free(u);
385 			break;
386 		}
387 		unistr = Malloc(unistr_size);
388 		Utf8ToUni(unistr, unistr_size, u, u_size);
389 		Free(u);
390 		v = NewUniStrValue(unistr);
391 		Free(unistr);
392 		break;
393 	}
394 
395 	return v;
396 }
397 
398 // Write the VALUE
WriteValue(BUF * b,VALUE * v,UINT type)399 void WriteValue(BUF *b, VALUE *v, UINT type)
400 {
401 	UINT len;
402 	BYTE *u;
403 	UINT u_size;
404 	// Validate arguments
405 	if (b == NULL || v == NULL)
406 	{
407 		return;
408 	}
409 
410 	// Data item
411 	switch (type)
412 	{
413 	case VALUE_INT:			// Integer
414 		WriteBufInt(b, v->IntValue);
415 		break;
416 	case VALUE_INT64:		// 64 bit integer
417 		WriteBufInt64(b, v->Int64Value);
418 		break;
419 	case VALUE_DATA:		// Data
420 		// Size
421 		WriteBufInt(b, v->Size);
422 		// Body
423 		WriteBuf(b, v->Data, v->Size);
424 		break;
425 	case VALUE_STR:			// ANSI string
426 		len = StrLen(v->Str);
427 		// Length
428 		WriteBufInt(b, len);
429 		// String body
430 		WriteBuf(b, v->Str, len);
431 		break;
432 	case VALUE_UNISTR:		// Unicode string
433 		// Convert to UTF-8
434 		u_size = CalcUniToUtf8(v->UniStr) + 1;
435 		u = ZeroMalloc(u_size);
436 		UniToUtf8(u, u_size, v->UniStr);
437 		// Size
438 		WriteBufInt(b, u_size);
439 		// UTF-8 string body
440 		WriteBuf(b, u, u_size);
441 		Free(u);
442 		break;
443 	}
444 }
445 
446 // Get data size
GetDataValueSize(ELEMENT * e,UINT index)447 UINT GetDataValueSize(ELEMENT *e, UINT index)
448 {
449 	// Validate arguments
450 	if (e == NULL)
451 	{
452 		return 0;
453 	}
454 	if (e->values == NULL)
455 	{
456 		return 0;
457 	}
458 	if (index >= e->num_value)
459 	{
460 		return 0;
461 	}
462 	if (e->values[index] == NULL)
463 	{
464 		return 0;
465 	}
466 
467 	return e->values[index]->Size;
468 }
469 
470 // Get the data
GetDataValue(ELEMENT * e,UINT index)471 void *GetDataValue(ELEMENT *e, UINT index)
472 {
473 	// Validate arguments
474 	if (e == NULL)
475 	{
476 		return NULL;
477 	}
478 	if (e->values == NULL)
479 	{
480 		return NULL;
481 	}
482 	if (index >= e->num_value)
483 	{
484 		return NULL;
485 	}
486 	if (e->values[index] == NULL)
487 	{
488 		return NULL;
489 	}
490 
491 	return e->values[index]->Data;
492 }
493 
494 // Get the Unicode string type
GetUniStrValue(ELEMENT * e,UINT index)495 wchar_t *GetUniStrValue(ELEMENT *e, UINT index)
496 {
497 	// Validate arguments
498 	if (e == NULL)
499 	{
500 		return 0;
501 	}
502 	if (index >= e->num_value)
503 	{
504 		return 0;
505 	}
506 	if (e->values[index] == NULL)
507 	{
508 		return NULL;
509 	}
510 
511 	return e->values[index]->UniStr;
512 }
513 
514 // Get the ANSI string type
GetStrValue(ELEMENT * e,UINT index)515 char *GetStrValue(ELEMENT *e, UINT index)
516 {
517 	// Validate arguments
518 	if (e == NULL)
519 	{
520 		return 0;
521 	}
522 	if (index >= e->num_value)
523 	{
524 		return 0;
525 	}
526 	if (e->values[index] == NULL)
527 	{
528 		return NULL;
529 	}
530 
531 	return e->values[index]->Str;
532 }
533 
534 // Get the 64 bit integer value
GetInt64Value(ELEMENT * e,UINT index)535 UINT64 GetInt64Value(ELEMENT *e, UINT index)
536 {
537 	// Validate arguments
538 	if (e == NULL)
539 	{
540 		return 0;
541 	}
542 	if (index >= e->num_value)
543 	{
544 		return 0;
545 	}
546 	if (e->values[index] == NULL)
547 	{
548 		return 0;
549 	}
550 
551 	return e->values[index]->Int64Value;
552 }
553 
554 // Get the integer value
GetIntValue(ELEMENT * e,UINT index)555 UINT GetIntValue(ELEMENT *e, UINT index)
556 {
557 	// Validate arguments
558 	if (e == NULL)
559 	{
560 		return 0;
561 	}
562 	if (index >= e->num_value)
563 	{
564 		return 0;
565 	}
566 	if (e->values[index] == NULL)
567 	{
568 		return 0;
569 	}
570 
571 	return e->values[index]->IntValue;
572 }
573 
574 // Function of sort for PACK
ComparePackName(void * p1,void * p2)575 int ComparePackName(void *p1, void *p2)
576 {
577 	ELEMENT *o1, *o2;
578 	if (p1 == NULL || p2 == NULL)
579 	{
580 		return 0;
581 	}
582 	o1 = *(ELEMENT **)p1;
583 	o2 = *(ELEMENT **)p2;
584 	if (o1 == NULL || o2 == NULL)
585 	{
586 		return 0;
587 	}
588 
589 	return StrCmpi(o1->name, o2->name);
590 }
591 
592 // Delete the VALUE
FreeValue(VALUE * v,UINT type)593 void FreeValue(VALUE *v, UINT type)
594 {
595 	// Validate arguments
596 	if (v == NULL)
597 	{
598 		return;
599 	}
600 
601 	switch (type)
602 	{
603 	case VALUE_INT:
604 	case VALUE_INT64:
605 		break;
606 	case VALUE_DATA:
607 		Free(v->Data);
608 		break;
609 	case VALUE_STR:
610 		Free(v->Str);
611 		break;
612 	case VALUE_UNISTR:
613 		Free(v->UniStr);
614 		break;
615 	}
616 
617 	// Memory release
618 	Free(v);
619 }
620 
621 // Create a VALUE of Unicode String type
NewUniStrValue(wchar_t * str)622 VALUE *NewUniStrValue(wchar_t *str)
623 {
624 	VALUE *v;
625 	// Validate arguments
626 	if (str == NULL)
627 	{
628 		return NULL;
629 	}
630 
631 	// Memory allocation
632 	v = Malloc(sizeof(VALUE));
633 
634 	// String copy
635 	v->Size = UniStrSize(str);
636 	v->UniStr = Malloc(v->Size);
637 	UniStrCpy(v->UniStr, v->Size, str);
638 
639 	UniTrim(v->UniStr);
640 
641 	return v;
642 }
643 
644 // Creation of the VALUE of ANSI string type
NewStrValue(char * str)645 VALUE *NewStrValue(char *str)
646 {
647 	VALUE *v;
648 	// Validate arguments
649 	if (str == NULL)
650 	{
651 		return NULL;
652 	}
653 
654 	// Memory allocation
655 	v = Malloc(sizeof(VALUE));
656 
657 	// String copy
658 	v->Size = StrLen(str) + 1;
659 	v->Str = Malloc(v->Size);
660 	StrCpy(v->Str, v->Size, str);
661 
662 	Trim(v->Str);
663 
664 	return v;
665 }
666 
667 // Create the VALUE of the data type
NewDataValue(void * data,UINT size)668 VALUE *NewDataValue(void *data, UINT size)
669 {
670 	VALUE *v;
671 	// Validate arguments
672 	if (data == NULL)
673 	{
674 		return NULL;
675 	}
676 
677 	// Memory allocation
678 	v = Malloc(sizeof(VALUE));
679 
680 	// Data copy
681 	v->Size = size;
682 	v->Data = Malloc(v->Size);
683 	Copy(v->Data, data, size);
684 
685 	return v;
686 }
687 
688 // Create the VALUE of 64 bit integer type
NewInt64Value(UINT64 i)689 VALUE *NewInt64Value(UINT64 i)
690 {
691 	VALUE *v;
692 
693 	v = Malloc(sizeof(VALUE));
694 	v->Int64Value = i;
695 	v->Size = sizeof(UINT64);
696 
697 	return v;
698 }
699 
700 // Create the VALUE of integer type
NewIntValue(UINT i)701 VALUE *NewIntValue(UINT i)
702 {
703 	VALUE *v;
704 
705 	// Memory allocation
706 	v = Malloc(sizeof(VALUE));
707 	v->IntValue = i;
708 	v->Size = sizeof(UINT);
709 
710 	return v;
711 }
712 
713 // Delete the ELEMENT
FreeElement(ELEMENT * e)714 void FreeElement(ELEMENT *e)
715 {
716 	UINT i;
717 	// Validate arguments
718 	if (e == NULL)
719 	{
720 		return;
721 	}
722 
723 	for (i = 0;i < e->num_value;i++)
724 	{
725 		FreeValue(e->values[i], e->type);
726 	}
727 	Free(e->values);
728 
729 	Free(e);
730 }
731 
732 // Create a ELEMENT
NewElement(char * name,UINT type,UINT num_value,VALUE ** values)733 ELEMENT *NewElement(char *name, UINT type, UINT num_value, VALUE **values)
734 {
735 	ELEMENT *e;
736 	UINT i;
737 	// Validate arguments
738 	if (name == NULL || num_value == 0 || values == NULL)
739 	{
740 		return NULL;
741 	}
742 
743 	// Memory allocation
744 	e = ZeroMalloc(sizeof(ELEMENT));
745 	StrCpy(e->name, sizeof(e->name), name);
746 	e->num_value = num_value;
747 	e->type = type;
748 
749 	// Copy of the pointer list to the element
750 	e->values = (VALUE **)ZeroMalloc(sizeof(VALUE *) * num_value);
751 	for (i = 0;i < e->num_value;i++)
752 	{
753 		e->values[i] = values[i];
754 	}
755 
756 	return e;
757 }
758 
759 // Search and retrieve a ELEMENT from the PACK
GetElement(PACK * p,char * name,UINT type)760 ELEMENT *GetElement(PACK *p, char *name, UINT type)
761 {
762 	ELEMENT t;
763 	ELEMENT *e;
764 	// Validate arguments
765 	if (p == NULL || name == NULL)
766 	{
767 		return NULL;
768 	}
769 
770 	// Search
771 	StrCpy(t.name, sizeof(t.name), name);
772 	e = Search(p->elements, &t);
773 
774 	if (e == NULL)
775 	{
776 		return NULL;
777 	}
778 
779 	// Type checking
780 	if (type != INFINITE)
781 	{
782 		if (e->type != type)
783 		{
784 			return NULL;
785 		}
786 	}
787 
788 	return e;
789 }
790 
791 // Check whether the specified element exists
IsElement(PACK * p,char * name)792 bool IsElement(PACK *p, char *name)
793 {
794 	ELEMENT t;
795 	ELEMENT *e;
796 	// Validate arguments
797 	if (p == NULL || name == NULL)
798 	{
799 		return false;
800 	}
801 
802 	// Search
803 	StrCpy(t.name, sizeof(t.name), name);
804 	e = Search(p->elements, &t);
805 
806 	if (e == NULL)
807 	{
808 		return false;
809 	}
810 
811 	return true;
812 }
813 
814 // Remove the ELEMENT from the PACK
DelElement(PACK * p,char * name)815 void DelElement(PACK *p, char *name)
816 {
817 	ELEMENT *e;
818 	// Validate arguments
819 	if (p == NULL || name == NULL)
820 	{
821 		return;
822 	}
823 
824 	e = GetElement(p, name, INFINITE);
825 	if (e != NULL)
826 	{
827 		Delete(p->elements, e);
828 
829 		FreeElement(e);
830 	}
831 }
832 
833 // Add an ELEMENT to the PACK
AddElement(PACK * p,ELEMENT * e)834 bool AddElement(PACK *p, ELEMENT *e)
835 {
836 	// Validate arguments
837 	if (p == NULL || e == NULL)
838 	{
839 		return false;
840 	}
841 
842 	// Size Check
843 	if (LIST_NUM(p->elements) >= MAX_ELEMENT_NUM)
844 	{
845 		// Can not add any more
846 		FreeElement(e);
847 		return false;
848 	}
849 
850 	// Check whether there is another item which have same name
851 	if (GetElement(p, e->name, INFINITE))
852 	{
853 		// Exists
854 		FreeElement(e);
855 		return false;
856 	}
857 
858 	if (e->num_value == 0)
859 	{
860 		// VALUE without any items can not be added
861 		FreeElement(e);
862 		return false;
863 	}
864 
865 	// Adding
866 	Add(p->elements, e);
867 
868 	// Set JsonHint_GroupName
869 	StrCpy(e->JsonHint_GroupName, sizeof(e->JsonHint_GroupName), p->CurrentJsonHint_GroupName);
870 
871 	return true;
872 }
873 
874 // Release of the PACK object
FreePack(PACK * p)875 void FreePack(PACK *p)
876 {
877 	UINT i;
878 	ELEMENT **elements;
879 	// Validate arguments
880 	if (p == NULL)
881 	{
882 		return;
883 	}
884 
885 	elements = ToArray(p->elements);
886 	for (i = 0;i < LIST_NUM(p->elements);i++)
887 	{
888 		FreeElement(elements[i]);
889 	}
890 	Free(elements);
891 
892 	if (p->json_subitem_names != NULL)
893 	{
894 		FreeStrList(p->json_subitem_names);
895 	}
896 
897 	ReleaseList(p->elements);
898 	Free(p);
899 }
900 
901 // Create a PACK object
NewPack()902 PACK *NewPack()
903 {
904 	PACK *p;
905 
906 	// Memory allocation
907 	p = ZeroMallocEx(sizeof(PACK), true);
908 
909 	// Creating a List
910 	p->elements = NewListFast(ComparePackName);
911 
912 	return p;
913 }
914 
915 // Get the K from the PACK
PackGetK(PACK * p,char * name)916 K *PackGetK(PACK *p, char *name)
917 {
918 	K *k;
919 	BUF *b;
920 	// Validate arguments
921 	if (p == NULL || name == NULL)
922 	{
923 		return NULL;
924 	}
925 
926 	b = PackGetBuf(p, name);
927 	if (b == NULL)
928 	{
929 		return NULL;
930 	}
931 
932 	k = BufToK(b, true, false, NULL);
933 
934 	if (k == NULL)
935 	{
936 		k = BufToK(b, true, true, NULL);
937 	}
938 
939 	FreeBuf(b);
940 
941 	return k;
942 }
943 
944 // Get the X from the PACK
PackGetX(PACK * p,char * name)945 X *PackGetX(PACK *p, char *name)
946 {
947 	X *x;
948 	BUF *b;
949 	// Validate arguments
950 	if (p == NULL || name == NULL)
951 	{
952 		return NULL;
953 	}
954 
955 	b = PackGetBuf(p, name);
956 	if (b == NULL)
957 	{
958 		return NULL;
959 	}
960 
961 	x = BufToX(b, false);
962 
963 	if (x == NULL)
964 	{
965 		x = BufToX(b, true);
966 	}
967 
968 	FreeBuf(b);
969 
970 	return x;
971 }
972 
973 // Add the K to the PACK
PackAddK(PACK * p,char * name,K * k)974 ELEMENT *PackAddK(PACK *p, char *name, K *k)
975 {
976 	BUF *b;
977 	ELEMENT *e = NULL;
978 	// Validate arguments
979 	if (p == NULL || name == NULL || k == NULL)
980 	{
981 		return NULL;
982 	}
983 
984 	b = KToBuf(k, false, NULL);
985 	if (b == NULL)
986 	{
987 		return NULL;
988 	}
989 
990 	e = PackAddBuf(p, name, b);
991 	FreeBuf(b);
992 
993 	return e;
994 }
995 
996 // Add an X into the PACK
PackAddX(PACK * p,char * name,X * x)997 ELEMENT *PackAddX(PACK *p, char *name, X *x)
998 {
999 	BUF *b;
1000 	ELEMENT *e = NULL;
1001 	// Validate arguments
1002 	if (p == NULL || name == NULL || x == NULL)
1003 	{
1004 		return NULL;
1005 	}
1006 
1007 	b = XToBuf(x, false);
1008 	if (b == NULL)
1009 	{
1010 		return NULL;
1011 	}
1012 
1013 	e = PackAddBuf(p, name, b);
1014 	FreeBuf(b);
1015 
1016 	return e;
1017 }
1018 
1019 // Get a buffer from the PACK
PackGetBuf(PACK * p,char * name)1020 BUF *PackGetBuf(PACK *p, char *name)
1021 {
1022 	return PackGetBufEx(p, name, 0);
1023 }
PackGetBufEx(PACK * p,char * name,UINT index)1024 BUF *PackGetBufEx(PACK *p, char *name, UINT index)
1025 {
1026 	UINT size;
1027 	void *tmp;
1028 	BUF *b;
1029 	// Validate arguments
1030 	if (p == NULL || name == NULL)
1031 	{
1032 		return NULL;
1033 	}
1034 
1035 	size = PackGetDataSizeEx(p, name, index);
1036 	tmp = MallocEx(size, true);
1037 	if (PackGetDataEx(p, name, tmp, index) == false)
1038 	{
1039 		Free(tmp);
1040 		return NULL;
1041 	}
1042 
1043 	b = NewBuf();
1044 	WriteBuf(b, tmp, size);
1045 	SeekBuf(b, 0, 0);
1046 
1047 	Free(tmp);
1048 
1049 	return b;
1050 }
1051 
1052 // Get the data from the PACK
PackGetData(PACK * p,char * name,void * data)1053 bool PackGetData(PACK *p, char *name, void *data)
1054 {
1055 	return PackGetDataEx(p, name, data, 0);
1056 }
PackGetDataEx(PACK * p,char * name,void * data,UINT index)1057 bool PackGetDataEx(PACK *p, char *name, void *data, UINT index)
1058 {
1059 	ELEMENT *e;
1060 	// Validate arguments
1061 	if (p == NULL || name == NULL)
1062 	{
1063 		return false;
1064 	}
1065 
1066 	e = GetElement(p, name, VALUE_DATA);
1067 	if (e == NULL)
1068 	{
1069 		return false;
1070 	}
1071 	Copy(data, GetDataValue(e, index), GetDataValueSize(e, index));
1072 	return true;
1073 }
PackGetData2(PACK * p,char * name,void * data,UINT size)1074 bool PackGetData2(PACK *p, char *name, void *data, UINT size)
1075 {
1076 	return PackGetDataEx2(p, name, data, size, 0);
1077 }
PackGetDataEx2(PACK * p,char * name,void * data,UINT size,UINT index)1078 bool PackGetDataEx2(PACK *p, char *name, void *data, UINT size, UINT index)
1079 {
1080 	ELEMENT *e;
1081 	// Validate arguments
1082 	if (p == NULL || name == NULL)
1083 	{
1084 		return false;
1085 	}
1086 
1087 	e = GetElement(p, name, VALUE_DATA);
1088 	if (e == NULL)
1089 	{
1090 		return false;
1091 	}
1092 	if (GetDataValueSize(e, index) != size)
1093 	{
1094 		return false;
1095 	}
1096 	Copy(data, GetDataValue(e, index), GetDataValueSize(e, index));
1097 	return true;
1098 }
1099 
1100 // Get the data size from the PACK
PackGetDataSize(PACK * p,char * name)1101 UINT PackGetDataSize(PACK *p, char *name)
1102 {
1103 	return PackGetDataSizeEx(p, name, 0);
1104 }
PackGetDataSizeEx(PACK * p,char * name,UINT index)1105 UINT PackGetDataSizeEx(PACK *p, char *name, UINT index)
1106 {
1107 	ELEMENT *e;
1108 	// Validate arguments
1109 	if (p == NULL || name == NULL)
1110 	{
1111 		return 0;
1112 	}
1113 
1114 	e = GetElement(p, name, VALUE_DATA);
1115 	if (e == NULL)
1116 	{
1117 		return 0;
1118 	}
1119 	return GetDataValueSize(e, index);
1120 }
1121 
1122 // Get an integer from the PACK
PackGetInt64(PACK * p,char * name)1123 UINT64 PackGetInt64(PACK *p, char *name)
1124 {
1125 	return PackGetInt64Ex(p, name, 0);
1126 }
PackGetInt64Ex(PACK * p,char * name,UINT index)1127 UINT64 PackGetInt64Ex(PACK *p, char *name, UINT index)
1128 {
1129 	ELEMENT *e;
1130 	// Validate arguments
1131 	if (p == NULL || name == NULL)
1132 	{
1133 		return 0;
1134 	}
1135 
1136 	e = GetElement(p, name, VALUE_INT64);
1137 	if (e == NULL)
1138 	{
1139 		return 0;
1140 	}
1141 	return GetInt64Value(e, index);
1142 }
1143 
1144 // Get the index number from the PACK
PackGetIndexCount(PACK * p,char * name)1145 UINT PackGetIndexCount(PACK *p, char *name)
1146 {
1147 	ELEMENT *e;
1148 	// Validate arguments
1149 	if (p == NULL || name == NULL)
1150 	{
1151 		return 0;
1152 	}
1153 
1154 	e = GetElement(p, name, INFINITE);
1155 	if (e == NULL)
1156 	{
1157 		return 0;
1158 	}
1159 
1160 	return e->num_value;
1161 }
1162 
1163 // Get the number from the PACK
PackGetNum(PACK * p,char * name)1164 UINT PackGetNum(PACK *p, char *name)
1165 {
1166 	return MIN(PackGetInt(p, name), 65536);
1167 }
1168 
1169 // Get a bool type from the PACK
PackGetBool(PACK * p,char * name)1170 bool PackGetBool(PACK *p, char *name)
1171 {
1172 	return PackGetInt(p, name) == 0 ? false : true;
1173 }
PackGetBoolEx(PACK * p,char * name,UINT index)1174 bool PackGetBoolEx(PACK *p, char *name, UINT index)
1175 {
1176 	return PackGetIntEx(p, name, index) == 0 ? false : true;
1177 }
1178 
1179 // Set CurrentJsonHint_GroupName to PACK
PackSetCurrentJsonGroupName(PACK * p,char * json_group_name)1180 void PackSetCurrentJsonGroupName(PACK *p, char *json_group_name)
1181 {
1182 	if (p == NULL)
1183 	{
1184 		return;
1185 	}
1186 
1187 	if (json_group_name == NULL)
1188 	{
1189 		ClearStr(p->CurrentJsonHint_GroupName, sizeof(p->CurrentJsonHint_GroupName));
1190 	}
1191 	else
1192 	{
1193 		StrCpy(p->CurrentJsonHint_GroupName, sizeof(p->CurrentJsonHint_GroupName), json_group_name);
1194 
1195 		if (p->json_subitem_names == NULL)
1196 		{
1197 			p->json_subitem_names = NewStrList();
1198 		}
1199 
1200 		AddStrToStrListDistinct(p->json_subitem_names, json_group_name);
1201 	}
1202 }
1203 
1204 // Add a bool type into the PACK
PackAddBool(PACK * p,char * name,bool b)1205 ELEMENT *PackAddBool(PACK *p, char *name, bool b)
1206 {
1207 	ELEMENT *e = PackAddInt(p, name, b ? 1 : 0);
1208 	if (e != NULL)
1209 	{
1210 		e->JsonHint_IsBool = true;
1211 	}
1212 	return e;
1213 }
PackAddBoolEx(PACK * p,char * name,bool b,UINT index,UINT total)1214 ELEMENT *PackAddBoolEx(PACK *p, char *name, bool b, UINT index, UINT total)
1215 {
1216 	ELEMENT *e = PackAddIntEx(p, name, b ? 1 : 0, index, total);
1217 	if (e != NULL)
1218 	{
1219 		e->JsonHint_IsBool = true;
1220 	}
1221 	return e;
1222 }
1223 
1224 // Add the IPV6_ADDR to the PACK
PackAddIp6AddrEx(PACK * p,char * name,IPV6_ADDR * addr,UINT index,UINT total)1225 ELEMENT *PackAddIp6AddrEx(PACK *p, char *name, IPV6_ADDR *addr, UINT index, UINT total)
1226 {
1227 	// Validate arguments
1228 	if (p == NULL || name == NULL || addr == NULL)
1229 	{
1230 		return NULL;
1231 	}
1232 
1233 	return PackAddDataEx(p, name, addr, sizeof(IPV6_ADDR), index, total);
1234 }
PackAddIp6Addr(PACK * p,char * name,IPV6_ADDR * addr)1235 ELEMENT *PackAddIp6Addr(PACK *p, char *name, IPV6_ADDR *addr)
1236 {
1237 	return PackAddIp6AddrEx(p, name, addr, 0, 1);
1238 }
1239 
1240 // Get an IPV6_ADDR from the PACK
PackGetIp6AddrEx(PACK * p,char * name,IPV6_ADDR * addr,UINT index)1241 bool PackGetIp6AddrEx(PACK *p, char *name, IPV6_ADDR *addr, UINT index)
1242 {
1243 	// Validate arguments
1244 	if (p == NULL || name == NULL || addr == NULL)
1245 	{
1246 		Zero(addr, sizeof(IPV6_ADDR));
1247 		return false;
1248 	}
1249 
1250 	return PackGetDataEx2(p, name, addr, sizeof(IPV6_ADDR), index);
1251 }
PackGetIp6Addr(PACK * p,char * name,IPV6_ADDR * addr)1252 bool PackGetIp6Addr(PACK *p, char *name, IPV6_ADDR *addr)
1253 {
1254 	return PackGetIp6AddrEx(p, name, addr, 0);
1255 }
1256 
1257 // Add the IP to the PACK
PackAddIp32Ex(PACK * p,char * name,UINT ip32,UINT index,UINT total)1258 void PackAddIp32Ex(PACK *p, char *name, UINT ip32, UINT index, UINT total)
1259 {
1260 	PackAddIp32Ex2(p, name, ip32, index, total, false);
1261 }
PackAddIp32Ex2(PACK * p,char * name,UINT ip32,UINT index,UINT total,bool is_single)1262 void PackAddIp32Ex2(PACK *p, char *name, UINT ip32, UINT index, UINT total, bool is_single)
1263 {
1264 	IP ip;
1265 	// Validate arguments
1266 	if (p == NULL || name == NULL)
1267 	{
1268 		return;
1269 	}
1270 
1271 	UINTToIP(&ip, ip32);
1272 
1273 	PackAddIpEx2(p, name, &ip, index, total, is_single);
1274 }
PackAddIp32(PACK * p,char * name,UINT ip32)1275 void PackAddIp32(PACK *p, char *name, UINT ip32)
1276 {
1277 	PackAddIp32Ex2(p, name, ip32, 0, 1, true);
1278 }
PackAddIpEx(PACK * p,char * name,IP * ip,UINT index,UINT total)1279 void PackAddIpEx(PACK *p, char *name, IP *ip, UINT index, UINT total)
1280 {
1281 	PackAddIpEx2(p, name, ip, index, total, false);
1282 }
PackAddIpEx2(PACK * p,char * name,IP * ip,UINT index,UINT total,bool is_single)1283 void PackAddIpEx2(PACK *p, char *name, IP *ip, UINT index, UINT total, bool is_single)
1284 {
1285 	UINT i;
1286 	bool b = false;
1287 	char tmp[MAX_PATH];
1288 	ELEMENT *e;
1289 	// Validate arguments
1290 	if (p == NULL || name == NULL || ip == NULL)
1291 	{
1292 		return;
1293 	}
1294 	if (total >= 2)
1295 	{
1296 		is_single = false;
1297 	}
1298 
1299 	b = IsIP6(ip);
1300 
1301 	Format(tmp, sizeof(tmp), "%s@ipv6_bool", name);
1302 	e = PackAddBoolEx(p, tmp, b, index, total);
1303 	if (e != NULL && is_single) e->JsonHint_IsArray = false;
1304 	if (e != NULL) e->JsonHint_IsIP = true;
1305 
1306 	Format(tmp, sizeof(tmp), "%s@ipv6_array", name);
1307 	if (b)
1308 	{
1309 		e = PackAddDataEx(p, tmp, ip->ipv6_addr, sizeof(ip->ipv6_addr), index, total);
1310 		if (e != NULL && is_single) e->JsonHint_IsArray = false;
1311 		if (e != NULL) e->JsonHint_IsIP = true;
1312 	}
1313 	else
1314 	{
1315 		UCHAR dummy[16];
1316 
1317 		Zero(dummy, sizeof(dummy));
1318 
1319 		e = PackAddDataEx(p, tmp, dummy, sizeof(dummy), index, total);
1320 		if (e != NULL && is_single) e->JsonHint_IsArray = false;
1321 		if (e != NULL) e->JsonHint_IsIP = true;
1322 	}
1323 
1324 	Format(tmp, sizeof(tmp), "%s@ipv6_scope_id", name);
1325 	if (b)
1326 	{
1327 		e = PackAddIntEx(p, tmp, ip->ipv6_scope_id, index, total);
1328 		if (e != NULL && is_single) e->JsonHint_IsArray = false;
1329 		if (e != NULL) e->JsonHint_IsIP = true;
1330 	}
1331 	else
1332 	{
1333 		e = PackAddIntEx(p, tmp, 0, index, total);
1334 		if (e != NULL && is_single) e->JsonHint_IsArray = false;
1335 		if (e != NULL) e->JsonHint_IsIP = true;
1336 	}
1337 
1338 	i = IPToUINT(ip);
1339 
1340 	if (IsBigEndian())
1341 	{
1342 		i = Swap32(i);
1343 	}
1344 
1345 	e = PackAddIntEx(p, name, i, index, total);
1346 	if (e != NULL && is_single) e->JsonHint_IsArray = false;
1347 	if (e != NULL) e->JsonHint_IsIP = true;
1348 }
PackAddIp(PACK * p,char * name,IP * ip)1349 void PackAddIp(PACK *p, char *name, IP *ip)
1350 {
1351 	PackAddIpEx2(p, name, ip, 0, 1, true);
1352 }
1353 
1354 // Get an IP from the PACK
PackGetIp32Ex(PACK * p,char * name,UINT index)1355 UINT PackGetIp32Ex(PACK *p, char *name, UINT index)
1356 {
1357 	IP ip;
1358 	// Validate arguments
1359 	if (p == NULL || name == NULL)
1360 	{
1361 		return 0;
1362 	}
1363 
1364 	if (PackGetIpEx(p, name, &ip, index) == false)
1365 	{
1366 		return 0;
1367 	}
1368 
1369 	return IPToUINT(&ip);
1370 }
PackGetIp32(PACK * p,char * name)1371 UINT PackGetIp32(PACK *p, char *name)
1372 {
1373 	return PackGetIp32Ex(p, name, 0);
1374 }
PackGetIpEx(PACK * p,char * name,IP * ip,UINT index)1375 bool PackGetIpEx(PACK *p, char *name, IP *ip, UINT index)
1376 {
1377 	UINT i;
1378 	char tmp[MAX_PATH];
1379 	// Validate arguments
1380 	if (p == NULL || ip == NULL || name == NULL)
1381 	{
1382 		return false;
1383 	}
1384 
1385 	Format(tmp, sizeof(tmp), "%s@ipv6_bool", name);
1386 	if (PackGetBoolEx(p, tmp, index))
1387 	{
1388 		UCHAR data[16];
1389 		UINT scope_id;
1390 
1391 		Zero(data, sizeof(data));
1392 
1393 		Format(tmp, sizeof(tmp), "%s@ipv6_array", name);
1394 		PackGetDataEx2(p, tmp, data, sizeof(data), index);
1395 
1396 		Format(tmp, sizeof(tmp), "%s@ipv6_scope_id", name);
1397 		scope_id = PackGetIntEx(p, tmp, index);
1398 
1399 		SetIP6(ip, data);
1400 		ip->ipv6_scope_id = scope_id;
1401 	}
1402 	else
1403 	{
1404 		if (GetElement(p, name, VALUE_INT) == NULL)
1405 		{
1406 			Zero(ip, sizeof(IP));
1407 			return false;
1408 		}
1409 
1410 		i = PackGetIntEx(p, name, index);
1411 
1412 		if (IsBigEndian())
1413 		{
1414 			i = Swap32(i);
1415 		}
1416 
1417 		UINTToIP(ip, i);
1418 	}
1419 
1420 	return true;
1421 }
PackGetIp(PACK * p,char * name,IP * ip)1422 bool PackGetIp(PACK *p, char *name, IP *ip)
1423 {
1424 	return PackGetIpEx(p, name, ip, 0);
1425 }
1426 
1427 // Check whether the specified value is existing on the Pack
PackIsValueExists(PACK * p,char * name)1428 bool PackIsValueExists(PACK *p, char *name)
1429 {
1430 	// Validate arguments
1431 	if (p == NULL || name == NULL)
1432 	{
1433 		return false;
1434 	}
1435 
1436 	return IsElement(p, name);
1437 }
1438 
1439 // Get an integer from the PACK
PackGetInt(PACK * p,char * name)1440 UINT PackGetInt(PACK *p, char *name)
1441 {
1442 	return PackGetIntEx(p, name, 0);
1443 }
PackGetIntEx(PACK * p,char * name,UINT index)1444 UINT PackGetIntEx(PACK *p, char *name, UINT index)
1445 {
1446 	ELEMENT *e;
1447 	// Validate arguments
1448 	if (p == NULL || name == NULL)
1449 	{
1450 		return 0;
1451 	}
1452 
1453 	e = GetElement(p, name, VALUE_INT);
1454 	if (e == NULL)
1455 	{
1456 		return 0;
1457 	}
1458 	return GetIntValue(e, index);
1459 }
1460 
1461 // Get an Unicode string from the PACK
PackGetUniStr(PACK * p,char * name,wchar_t * unistr,UINT size)1462 bool PackGetUniStr(PACK *p, char *name, wchar_t *unistr, UINT size)
1463 {
1464 	return PackGetUniStrEx(p, name, unistr, size, 0);
1465 }
PackGetUniStrEx(PACK * p,char * name,wchar_t * unistr,UINT size,UINT index)1466 bool PackGetUniStrEx(PACK *p, char *name, wchar_t *unistr, UINT size, UINT index)
1467 {
1468 	ELEMENT *e;
1469 	// Validate arguments
1470 	if (p == NULL || name == NULL || unistr == NULL || size == 0)
1471 	{
1472 		return false;
1473 	}
1474 
1475 	unistr[0] = 0;
1476 
1477 	e = GetElement(p, name, VALUE_UNISTR);
1478 	if (e == NULL)
1479 	{
1480 		return false;
1481 	}
1482 	UniStrCpy(unistr, size, GetUniStrValue(e, index));
1483 	return true;
1484 }
1485 
1486 // Compare strings in the PACK
PackCmpStr(PACK * p,char * name,char * str)1487 bool PackCmpStr(PACK *p, char *name, char *str)
1488 {
1489 	char tmp[MAX_SIZE];
1490 
1491 	if (PackGetStr(p, name, tmp, sizeof(tmp)) == false)
1492 	{
1493 		return false;
1494 	}
1495 
1496 	if (StrCmpi(tmp, str) == 0)
1497 	{
1498 		return true;
1499 	}
1500 
1501 	return false;
1502 }
1503 
1504 // Get a string from the PACK
PackGetStr(PACK * p,char * name,char * str,UINT size)1505 bool PackGetStr(PACK *p, char *name, char *str, UINT size)
1506 {
1507 	return PackGetStrEx(p, name, str, size, 0);
1508 }
PackGetStrEx(PACK * p,char * name,char * str,UINT size,UINT index)1509 bool PackGetStrEx(PACK *p, char *name, char *str, UINT size, UINT index)
1510 {
1511 	ELEMENT *e;
1512 	// Validate arguments
1513 	if (p == NULL || name == NULL || str == NULL || size == 0)
1514 	{
1515 		return false;
1516 	}
1517 
1518 	str[0] = 0;
1519 
1520 	e = GetElement(p, name, VALUE_STR);
1521 	if (e == NULL)
1522 	{
1523 		return false;
1524 	}
1525 
1526 	StrCpy(str, size, GetStrValue(e, index));
1527 	return true;
1528 }
1529 
1530 // Add the buffer to the PACK (array)
PackAddBufEx(PACK * p,char * name,BUF * b,UINT index,UINT total)1531 ELEMENT *PackAddBufEx(PACK *p, char *name, BUF *b, UINT index, UINT total)
1532 {
1533 	// Validate arguments
1534 	if (p == NULL || name == NULL || b == NULL || total == 0)
1535 	{
1536 		return NULL;
1537 	}
1538 
1539 	return PackAddDataEx(p, name, b->Buf, b->Size, index, total);
1540 }
1541 
1542 // Add the data to the PACK (array)
PackAddDataEx(PACK * p,char * name,void * data,UINT size,UINT index,UINT total)1543 ELEMENT *PackAddDataEx(PACK *p, char *name, void *data, UINT size, UINT index, UINT total)
1544 {
1545 	VALUE *v;
1546 	ELEMENT *e;
1547 	// Validate arguments
1548 	if (p == NULL || data == NULL || name == NULL || total == 0)
1549 	{
1550 		return NULL;
1551 	}
1552 
1553 	v = NewDataValue(data, size);
1554 	e = GetElement(p, name, VALUE_DATA);
1555 	if (e != NULL)
1556 	{
1557 		if (e->num_value >= total)
1558 		{
1559 			FreeValue(e->values[index], VALUE_DATA);
1560 			e->values[index] = v;
1561 		}
1562 		else
1563 		{
1564 			FreeValue(v, VALUE_DATA);
1565 		}
1566 	}
1567 	else
1568 	{
1569 		e = ZeroMallocEx(sizeof(ELEMENT), true);
1570 		StrCpy(e->name, sizeof(e->name), name);
1571 		e->num_value = total;
1572 		e->type = VALUE_DATA;
1573 		e->values = ZeroMallocEx(sizeof(VALUE *) * total, true);
1574 		e->values[index] = v;
1575 		if (AddElement(p, e) == false)
1576 		{
1577 			return NULL;
1578 		}
1579 	}
1580 
1581 	e->JsonHint_IsArray = true;
1582 
1583 	return e;
1584 }
1585 
1586 // Add the buffer to the PACK
PackAddBuf(PACK * p,char * name,BUF * b)1587 ELEMENT *PackAddBuf(PACK *p, char *name, BUF *b)
1588 {
1589 	// Validate arguments
1590 	if (p == NULL || name == NULL || b == NULL)
1591 	{
1592 		return NULL;
1593 	}
1594 
1595 	return PackAddData(p, name, b->Buf, b->Size);
1596 }
1597 
1598 // Add the data to the PACK
PackAddData(PACK * p,char * name,void * data,UINT size)1599 ELEMENT *PackAddData(PACK *p, char *name, void *data, UINT size)
1600 {
1601 	VALUE *v;
1602 	ELEMENT *e;
1603 	// Validate arguments
1604 	if (p == NULL || data == NULL || name == NULL)
1605 	{
1606 		return NULL;
1607 	}
1608 
1609 	v = NewDataValue(data, size);
1610 	e = NewElement(name, VALUE_DATA, 1, &v);
1611 	if (AddElement(p, e) == false)
1612 	{
1613 		return NULL;
1614 	}
1615 
1616 	return e;
1617 }
1618 
1619 // Add a 64 bit integer (array) to the PACK
PackAddInt64Ex(PACK * p,char * name,UINT64 i,UINT index,UINT total)1620 ELEMENT *PackAddInt64Ex(PACK *p, char *name, UINT64 i, UINT index, UINT total)
1621 {
1622 	VALUE *v;
1623 	ELEMENT *e;
1624 	// Validate arguments
1625 	if (p == NULL || name == NULL || total == 0)
1626 	{
1627 		return NULL;
1628 	}
1629 
1630 	v = NewInt64Value(i);
1631 	e = GetElement(p, name, VALUE_INT64);
1632 	if (e != NULL)
1633 	{
1634 		if (e->num_value >= total)
1635 		{
1636 			FreeValue(e->values[index], VALUE_INT64);
1637 			e->values[index] = v;
1638 		}
1639 		else
1640 		{
1641 			FreeValue(v, VALUE_INT64);
1642 		}
1643 	}
1644 	else
1645 	{
1646 		e = ZeroMallocEx(sizeof(ELEMENT), true);
1647 		StrCpy(e->name, sizeof(e->name), name);
1648 		e->num_value = total;
1649 		e->type = VALUE_INT64;
1650 		e->values = ZeroMallocEx(sizeof(VALUE *) * total, true);
1651 		e->values[index] = v;
1652 
1653 		if (AddElement(p, e) == false)
1654 		{
1655 			return NULL;
1656 		}
1657 	}
1658 
1659 	e->JsonHint_IsArray = true;
1660 
1661 	return e;
1662 }
1663 
1664 // Add an integer to the PACK (array)
PackAddIntEx(PACK * p,char * name,UINT i,UINT index,UINT total)1665 ELEMENT *PackAddIntEx(PACK *p, char *name, UINT i, UINT index, UINT total)
1666 {
1667 	VALUE *v;
1668 	ELEMENT *e;
1669 	// Validate arguments
1670 	if (p == NULL || name == NULL || total == 0)
1671 	{
1672 		return NULL;
1673 	}
1674 
1675 	v = NewIntValue(i);
1676 	e = GetElement(p, name, VALUE_INT);
1677 	if (e != NULL)
1678 	{
1679 		if (e->num_value >= total)
1680 		{
1681 			FreeValue(e->values[index], VALUE_INT);
1682 			e->values[index] = v;
1683 		}
1684 		else
1685 		{
1686 			FreeValue(v, VALUE_INT);
1687 		}
1688 	}
1689 	else
1690 	{
1691 		e = ZeroMallocEx(sizeof(ELEMENT), true);
1692 		StrCpy(e->name, sizeof(e->name), name);
1693 		e->num_value = total;
1694 		e->type = VALUE_INT;
1695 		e->values = ZeroMallocEx(sizeof(VALUE *) * total, true);
1696 		e->values[index] = v;
1697 
1698 		if (AddElement(p, e) == false)
1699 		{
1700 			return NULL;
1701 		}
1702 	}
1703 
1704 	e->JsonHint_IsArray = true;
1705 
1706 	return e;
1707 }
1708 
1709 // Add 64 bit integer time value to the PACK
PackAddTime64(PACK * p,char * name,UINT64 i)1710 ELEMENT *PackAddTime64(PACK *p, char *name, UINT64 i)
1711 {
1712 	ELEMENT *e = PackAddInt64(p, name, i);
1713 	if (e != NULL)
1714 	{
1715 		e->JsonHint_IsDateTime = true;
1716 	}
1717 	return e;
1718 }
PackAddTime64Ex(PACK * p,char * name,UINT64 i,UINT index,UINT total)1719 ELEMENT *PackAddTime64Ex(PACK *p, char *name, UINT64 i, UINT index, UINT total)
1720 {
1721 	ELEMENT *e = PackAddInt64Ex(p, name, i, index, total);
1722 	if (e != NULL)
1723 	{
1724 		e->JsonHint_IsDateTime = true;
1725 	}
1726 	return e;
1727 }
1728 
1729 
1730 // Add a 64 bit integer to the PACK
PackAddInt64(PACK * p,char * name,UINT64 i)1731 ELEMENT *PackAddInt64(PACK *p, char *name, UINT64 i)
1732 {
1733 	VALUE *v;
1734 	ELEMENT *e;
1735 	// Validate arguments
1736 	if (p == NULL || name == NULL)
1737 	{
1738 		return NULL;
1739 	}
1740 
1741 	v = NewInt64Value(i);
1742 	e = NewElement(name, VALUE_INT64, 1, &v);
1743 	if (AddElement(p, e) == false)
1744 	{
1745 		return NULL;
1746 	}
1747 	return e;
1748 }
1749 
1750 // Add the number of items to the PACK
PackAddNum(PACK * p,char * name,UINT num)1751 ELEMENT *PackAddNum(PACK *p, char *name, UINT num)
1752 {
1753 	return PackAddInt(p, name, num);
1754 }
1755 
1756 // Add an integer to the PACK
PackAddInt(PACK * p,char * name,UINT i)1757 ELEMENT *PackAddInt(PACK *p, char *name, UINT i)
1758 {
1759 	VALUE *v;
1760 	ELEMENT *e = NULL;
1761 	// Validate arguments
1762 	if (p == NULL || name == NULL)
1763 	{
1764 		return NULL;
1765 	}
1766 
1767 	v = NewIntValue(i);
1768 	e = NewElement(name, VALUE_INT, 1, &v);
1769 	if (AddElement(p, e) == false)
1770 	{
1771 		return NULL;
1772 	}
1773 	return e;
1774 }
1775 
1776 // Add a Unicode string (array) to the PACK
PackAddUniStrEx(PACK * p,char * name,wchar_t * unistr,UINT index,UINT total)1777 ELEMENT *PackAddUniStrEx(PACK *p, char *name, wchar_t *unistr, UINT index, UINT total)
1778 {
1779 	VALUE *v;
1780 	ELEMENT *e;
1781 	// Validate arguments
1782 	if (p == NULL || name == NULL || unistr == NULL || total == 0)
1783 	{
1784 		return NULL;
1785 	}
1786 
1787 	v = NewUniStrValue(unistr);
1788 	e = GetElement(p, name, VALUE_UNISTR);
1789 	if (e != NULL)
1790 	{
1791 		if (e->num_value >= total)
1792 		{
1793 			FreeValue(e->values[index], VALUE_UNISTR);
1794 			e->values[index] = v;
1795 		}
1796 		else
1797 		{
1798 			FreeValue(v, VALUE_UNISTR);
1799 		}
1800 	}
1801 	else
1802 	{
1803 		e = ZeroMallocEx(sizeof(ELEMENT), true);
1804 		StrCpy(e->name, sizeof(e->name), name);
1805 		e->num_value = total;
1806 		e->type = VALUE_UNISTR;
1807 		e->values = ZeroMallocEx(sizeof(VALUE *) * total, true);
1808 		e->values[index] = v;
1809 		if (AddElement(p, e) == false)
1810 		{
1811 			return NULL;
1812 		}
1813 	}
1814 
1815 	e->JsonHint_IsArray = true;
1816 
1817 	return e;
1818 }
1819 
1820 // Add a Unicode string to the PACK
PackAddUniStr(PACK * p,char * name,wchar_t * unistr)1821 ELEMENT *PackAddUniStr(PACK *p, char *name, wchar_t *unistr)
1822 {
1823 	VALUE *v;
1824 	ELEMENT *e = NULL;
1825 	// Validate arguments
1826 	if (p == NULL || name == NULL || unistr == NULL)
1827 	{
1828 		return NULL;
1829 	}
1830 
1831 	v = NewUniStrValue(unistr);
1832 	e = NewElement(name, VALUE_UNISTR, 1, &v);
1833 	if (AddElement(p, e) == false)
1834 	{
1835 		return NULL;
1836 	}
1837 	return e;
1838 }
1839 
1840 // Add a string to the PACK (array)
PackAddStrEx(PACK * p,char * name,char * str,UINT index,UINT total)1841 ELEMENT *PackAddStrEx(PACK *p, char *name, char *str, UINT index, UINT total)
1842 {
1843 	VALUE *v;
1844 	ELEMENT *e;
1845 	// Validate arguments
1846 	if (p == NULL || name == NULL || str == NULL || total == 0)
1847 	{
1848 		return NULL;
1849 	}
1850 
1851 	v = NewStrValue(str);
1852 	e = GetElement(p, name, VALUE_STR);
1853 	if (e != NULL)
1854 	{
1855 		if (e->num_value >= total)
1856 		{
1857 			FreeValue(e->values[index], VALUE_STR);
1858 			e->values[index] = v;
1859 		}
1860 		else
1861 		{
1862 			FreeValue(v, VALUE_STR);
1863 		}
1864 	}
1865 	else
1866 	{
1867 		e = ZeroMallocEx(sizeof(ELEMENT), true);
1868 		StrCpy(e->name, sizeof(e->name), name);
1869 		e->num_value = total;
1870 		e->type = VALUE_STR;
1871 		e->values = ZeroMallocEx(sizeof(VALUE *) * total, true);
1872 		e->values[index] = v;
1873 		if (AddElement(p, e) == false)
1874 		{
1875 			return NULL;
1876 		}
1877 	}
1878 
1879 	e->JsonHint_IsArray = true;
1880 
1881 	return e;
1882 }
1883 
1884 // Add a string to the PACK
PackAddStr(PACK * p,char * name,char * str)1885 ELEMENT *PackAddStr(PACK *p, char *name, char *str)
1886 {
1887 	VALUE *v;
1888 	ELEMENT *e = NULL;
1889 	// Validate arguments
1890 	if (p == NULL || name == NULL || str == NULL)
1891 	{
1892 		return NULL;
1893 	}
1894 
1895 	v = NewStrValue(str);
1896 	e = NewElement(name, VALUE_STR, 1, &v);
1897 	if (AddElement(p, e) == false)
1898 	{
1899 		return NULL;
1900 	}
1901 	return e;
1902 }
1903 
1904 // Add an element of PACK array to JSON Array
PackArrayElementToJsonArray(JSON_ARRAY * ja,PACK * p,ELEMENT * e,UINT index)1905 void PackArrayElementToJsonArray(JSON_ARRAY *ja, PACK *p, ELEMENT *e, UINT index)
1906 {
1907 	if (ja == NULL || p == NULL || e == NULL || index >= e->num_value)
1908 	{
1909 		return;
1910 	}
1911 
1912 	switch (e->type)
1913 	{
1914 	case VALUE_INT:
1915 		if (e->JsonHint_IsIP)
1916 		{
1917 			if (InStr(e->name, "@") == false)
1918 			{
1919 				IP ip;
1920 				if (PackGetIpEx(p, e->name, &ip, index))
1921 				{
1922 					char ip_str[64];
1923 					IPToStr(ip_str, sizeof(ip_str), &ip);
1924 					JsonArrayAddStr(ja, ip_str);
1925 				}
1926 			}
1927 		}
1928 		else if (e->JsonHint_IsBool)
1929 		{
1930 			JsonArrayAddBool(ja, PackGetBoolEx(p, e->name, index));
1931 		}
1932 		else
1933 		{
1934 			JsonArrayAddNumber(ja, PackGetIntEx(p, e->name, index));
1935 		}
1936 		break;
1937 	case VALUE_INT64:
1938 		if (e->JsonHint_IsIP == false)
1939 		{
1940 			if (e->JsonHint_IsDateTime == false)
1941 			{
1942 				JsonArrayAddNumber(ja, PackGetInt64Ex(p, e->name, index));
1943 			}
1944 			else
1945 			{
1946 				char dtstr[64];
1947 
1948 				SystemTime64ToJsonStr(dtstr, sizeof(dtstr), PackGetInt64Ex(p, e->name, index));
1949 				JsonArrayAddStr(ja, dtstr);
1950 			}
1951 		}
1952 		break;
1953 	case VALUE_DATA:
1954 		if (e->JsonHint_IsIP == false)
1955 		{
1956 			BUF *buf = PackGetBufEx(p, e->name, index);
1957 			if (buf != NULL)
1958 			{
1959 				JsonArrayAddData(ja, buf->Buf, buf->Size);
1960 				FreeBuf(buf);
1961 			}
1962 			else
1963 			{
1964 				UCHAR zero = 0;
1965 				JsonArrayAddData(ja, &zero, 0);
1966 			}
1967 		}
1968 		break;
1969 	case VALUE_STR:
1970 		if (e->JsonHint_IsIP == false)
1971 		{
1972 			if (e->values[index] != NULL)
1973 			{
1974 				JsonArrayAddStr(ja, e->values[index]->Str);
1975 			}
1976 			else
1977 			{
1978 				JsonArrayAddStr(ja, "");
1979 			}
1980 		}
1981 		break;
1982 	case VALUE_UNISTR:
1983 		if (e->JsonHint_IsIP == false)
1984 		{
1985 			if (e->values[index] != NULL)
1986 			{
1987 				JsonArrayAddUniStr(ja, e->values[index]->UniStr);
1988 			}
1989 			else
1990 			{
1991 				JsonArrayAddUniStr(ja, L"");
1992 			}
1993 		}
1994 		break;
1995 	}
1996 }
1997 
1998 // Add an element of PACK to JSON Object
PackElementToJsonObject(JSON_OBJECT * o,PACK * p,ELEMENT * e,UINT index)1999 void PackElementToJsonObject(JSON_OBJECT *o, PACK *p, ELEMENT *e, UINT index)
2000 {
2001 	char *suffix;
2002 	char name[MAX_PATH];
2003 	if (o == NULL || p == NULL || e == NULL)
2004 	{
2005 		return;
2006 	}
2007 
2008 	suffix = DetermineJsonSuffixForPackElement(e);
2009 
2010 	if (suffix == NULL)
2011 	{
2012 		return;
2013 	}
2014 
2015 	StrCpy(name, sizeof(name), e->name);
2016 	StrCat(name, sizeof(name), suffix);
2017 
2018 	switch (e->type)
2019 	{
2020 	case VALUE_INT:
2021 		if (e->JsonHint_IsIP)
2022 		{
2023 			if (InStr(e->name, "@") == false)
2024 			{
2025 				IP ip;
2026 				if (PackGetIpEx(p, e->name, &ip, index))
2027 				{
2028 					char ip_str[64];
2029 					IPToStr(ip_str, sizeof(ip_str), &ip);
2030 					JsonSetStr(o, name, ip_str);
2031 				}
2032 			}
2033 		}
2034 		else if (e->JsonHint_IsBool)
2035 		{
2036 			JsonSetBool(o, name, PackGetBoolEx(p, e->name, index));
2037 		}
2038 		else
2039 		{
2040 			JsonSetNumber(o, name, PackGetIntEx(p, e->name, index));
2041 		}
2042 		break;
2043 	case VALUE_INT64:
2044 		if (e->JsonHint_IsIP == false)
2045 		{
2046 			if (e->JsonHint_IsDateTime == false)
2047 			{
2048 				JsonSetNumber(o, name, PackGetInt64Ex(p, e->name, index));
2049 			}
2050 			else
2051 			{
2052 				char dtstr[64];
2053 
2054 				SystemTime64ToJsonStr(dtstr, sizeof(dtstr), PackGetInt64Ex(p, e->name, index));
2055 				JsonSetStr(o, name, dtstr);
2056 			}
2057 		}
2058 		break;
2059 	case VALUE_DATA:
2060 		if (e->JsonHint_IsIP == false)
2061 		{
2062 			BUF *buf = PackGetBufEx(p, e->name, index);
2063 			if (buf != NULL)
2064 			{
2065 				JsonSetData(o, name, buf->Buf, buf->Size);
2066 				FreeBuf(buf);
2067 			}
2068 			else
2069 			{
2070 				UCHAR zero = 0;
2071 				JsonSetData(o, name, &zero, 0);
2072 			}
2073 		}
2074 		break;
2075 	case VALUE_STR:
2076 		if (e->JsonHint_IsIP == false)
2077 		{
2078 			if (e->values[index] != NULL)
2079 			{
2080 				JsonSetStr(o, name, e->values[index]->Str);
2081 			}
2082 			else
2083 			{
2084 				JsonSetStr(o, name, "");
2085 			}
2086 		}
2087 		break;
2088 	case VALUE_UNISTR:
2089 		if (e->JsonHint_IsIP == false)
2090 		{
2091 			if (e->values[index] != NULL)
2092 			{
2093 				JsonSetUniStr(o, name, e->values[index]->UniStr);
2094 			}
2095 			else
2096 			{
2097 				JsonSetUniStr(o, name, L"");
2098 			}
2099 		}
2100 		break;
2101 	}
2102 }
2103 
2104 // Determine JSON element suffix for PACK element
DetermineJsonSuffixForPackElement(ELEMENT * e)2105 char *DetermineJsonSuffixForPackElement(ELEMENT *e)
2106 {
2107 	switch (e->type)
2108 	{
2109 	case VALUE_INT:
2110 		if (e->JsonHint_IsIP)
2111 		{
2112 			if (InStr(e->name, "@") == false)
2113 			{
2114 				return "_ip";
2115 			}
2116 		}
2117 		else if (e->JsonHint_IsBool)
2118 		{
2119 			return "_bool";
2120 		}
2121 		else
2122 		{
2123 			return "_u32";
2124 		}
2125 		break;
2126 	case VALUE_INT64:
2127 		if (e->JsonHint_IsIP == false)
2128 		{
2129 			if (e->JsonHint_IsDateTime == false)
2130 			{
2131 				return "_u64";
2132 			}
2133 			else
2134 			{
2135 				return "_dt";
2136 			}
2137 		}
2138 		break;
2139 	case VALUE_DATA:
2140 		if (e->JsonHint_IsIP == false)
2141 		{
2142 			return "_bin";
2143 		}
2144 		break;
2145 	case VALUE_STR:
2146 		if (e->JsonHint_IsIP == false)
2147 		{
2148 			return "_str";
2149 		}
2150 		break;
2151 	case VALUE_UNISTR:
2152 		if (e->JsonHint_IsIP == false)
2153 		{
2154 			return "_utf";
2155 		}
2156 		break;
2157 	}
2158 
2159 	return NULL;
2160 }
2161 
2162 // Convert JSON to PACK
JsonToPack(JSON_VALUE * v)2163 PACK *JsonToPack(JSON_VALUE *v)
2164 {
2165 	PACK *p = NULL;
2166 	JSON_OBJECT *jo;
2167 	if (v == NULL)
2168 	{
2169 		return NULL;
2170 	}
2171 
2172 	p = NewPack();
2173 
2174 	jo = JsonValueGetObject(v);
2175 
2176 	if (jo != NULL)
2177 	{
2178 		UINT i;
2179 		for (i = 0;i < jo->count;i++)
2180 		{
2181 			char *name = jo->names[i];
2182 			JSON_VALUE *value = jo->values[i];
2183 
2184 			if (value->type == JSON_TYPE_ARRAY)
2185 			{
2186 				UINT j;
2187 				JSON_ARRAY *ja = value->value.array;
2188 
2189 				for (j = 0;j < ja->count;j++)
2190 				{
2191 					if (ja->items[j]->type != JSON_TYPE_OBJECT)
2192 					{
2193 						JsonTryParseValueAddToPack(p, ja->items[j], name, j, ja->count, false);
2194 					}
2195 					else
2196 					{
2197 						JSON_VALUE *v = ja->items[j];
2198 						JSON_OBJECT *o = v->value.object;
2199 						UINT k;
2200 
2201 						for (k = 0;k < o->count;k++)
2202 						{
2203 							char *name2 = o->names[k];
2204 							JSON_VALUE *value2 = o->values[k];
2205 
2206 							PackSetCurrentJsonGroupName(p, name);
2207 							JsonTryParseValueAddToPack(p, value2, name2, j, ja->count, false);
2208 							PackSetCurrentJsonGroupName(p, NULL);
2209 						}
2210 					}
2211 				}
2212 			}
2213 			else
2214 			{
2215 				JsonTryParseValueAddToPack(p, value, name, 0, 1, true);
2216 			}
2217 		}
2218 	}
2219 
2220 	return p;
2221 }
2222 
ElementNullSafe(ELEMENT * p)2223 ELEMENT *ElementNullSafe(ELEMENT *p)
2224 {
2225 	static ELEMENT dummy;
2226 	if (p == NULL)
2227 	{
2228 		Zero(&dummy, sizeof(dummy));
2229 		return &dummy;
2230 	}
2231 	return p;
2232 }
2233 
JsonTryParseValueAddToPack(PACK * p,JSON_VALUE * v,char * v_name,UINT index,UINT total,bool is_single)2234 bool JsonTryParseValueAddToPack(PACK *p, JSON_VALUE *v, char *v_name, UINT index, UINT total, bool is_single)
2235 {
2236 	char name[MAX_PATH];
2237 	bool ok = true;
2238 	if (p == NULL || v == NULL)
2239 	{
2240 		return false;
2241 	}
2242 
2243 	if (TrimEndWith(name, sizeof(name), v_name, "_bool"))
2244 	{
2245 		if (v->type == JSON_TYPE_BOOL)
2246 		{
2247 			ElementNullSafe(PackAddBoolEx(p, name, MAKEBOOL(v->value.boolean), index, total))->JsonHint_IsArray = !is_single;
2248 			ok = true;
2249 		}
2250 		else if (v->type == JSON_TYPE_NUMBER)
2251 		{
2252 			ElementNullSafe(PackAddBoolEx(p, name, MAKEBOOL(v->value.number), index, total))->JsonHint_IsArray = !is_single;
2253 			ok = true;
2254 		}
2255 		else if (v->type == JSON_TYPE_STRING)
2256 		{
2257 			ElementNullSafe(PackAddBoolEx(p, name, ToBool(v->value.string), index, total))->JsonHint_IsArray = !is_single;
2258 			ok = true;
2259 		}
2260 	}
2261 	else if (TrimEndWith(name, sizeof(name), v_name, "_u32"))
2262 	{
2263 		if (v->type == JSON_TYPE_BOOL)
2264 		{
2265 			ElementNullSafe(PackAddIntEx(p, name, MAKEBOOL(v->value.boolean), index, total))->JsonHint_IsArray = !is_single;
2266 			ok = true;
2267 		}
2268 		else if (v->type == JSON_TYPE_NUMBER)
2269 		{
2270 			ElementNullSafe(PackAddIntEx(p, name, (UINT)v->value.number, index, total))->JsonHint_IsArray = !is_single;
2271 			ok = true;
2272 		}
2273 		else if (v->type == JSON_TYPE_STRING)
2274 		{
2275 			ElementNullSafe(PackAddIntEx(p, name, ToInt(v->value.string), index, total))->JsonHint_IsArray = !is_single;
2276 			ok = true;
2277 		}
2278 	}
2279 	else if (TrimEndWith(name, sizeof(name), v_name, "_u64"))
2280 	{
2281 		if (v->type == JSON_TYPE_BOOL)
2282 		{
2283 			ElementNullSafe(PackAddInt64Ex(p, name, MAKEBOOL(v->value.boolean), index, total))->JsonHint_IsArray = !is_single;
2284 			ok = true;
2285 		}
2286 		else if (v->type == JSON_TYPE_NUMBER)
2287 		{
2288 			ElementNullSafe(PackAddInt64Ex(p, name, v->value.number, index, total))->JsonHint_IsArray = !is_single;
2289 			ok = true;
2290 		}
2291 		else if (v->type == JSON_TYPE_STRING)
2292 		{
2293 			ElementNullSafe(PackAddInt64Ex(p, name, ToInt64(v->value.string), index, total))->JsonHint_IsArray = !is_single;
2294 			ok = true;
2295 		}
2296 	}
2297 	else if (TrimEndWith(name, sizeof(name), v_name, "_str"))
2298 	{
2299 		if (v->type == JSON_TYPE_BOOL)
2300 		{
2301 			ElementNullSafe(PackAddStrEx(p, name, MAKEBOOL(v->value.boolean) ? "true" : "false", index, total))->JsonHint_IsArray = !is_single;
2302 			ok = true;
2303 		}
2304 		else if (v->type == JSON_TYPE_NUMBER)
2305 		{
2306 			char tmp[64];
2307 			ToStr64(tmp, v->value.number);
2308 			ElementNullSafe(PackAddStrEx(p, name, tmp, index, total))->JsonHint_IsArray = !is_single;
2309 			ok = true;
2310 		}
2311 		else if (v->type == JSON_TYPE_STRING)
2312 		{
2313 			ElementNullSafe(PackAddStrEx(p, name, v->value.string, index, total))->JsonHint_IsArray = !is_single;
2314 			ok = true;
2315 		}
2316 	}
2317 	else if (TrimEndWith(name, sizeof(name), v_name, "_utf"))
2318 	{
2319 		if (v->type == JSON_TYPE_BOOL)
2320 		{
2321 			ElementNullSafe(PackAddUniStrEx(p, name, MAKEBOOL(v->value.boolean) ? L"true" : L"false", index, total))->JsonHint_IsArray = !is_single;
2322 			ok = true;
2323 		}
2324 		else if (v->type == JSON_TYPE_NUMBER)
2325 		{
2326 			char tmp[64];
2327 			wchar_t tmp2[64];
2328 			ToStr64(tmp, v->value.number);
2329 			StrToUni(tmp2, sizeof(tmp2), tmp);
2330 			ElementNullSafe(PackAddUniStrEx(p, name, tmp2, index, total))->JsonHint_IsArray = !is_single;
2331 			ok = true;
2332 		}
2333 		else if (v->type == JSON_TYPE_STRING)
2334 		{
2335 			wchar_t *uni = CopyUtfToUni(v->value.string);
2336 			ElementNullSafe(PackAddUniStrEx(p, name, uni, index, total))->JsonHint_IsArray = !is_single;
2337 			Free(uni);
2338 			ok = true;
2339 		}
2340 	}
2341 	else if (TrimEndWith(name, sizeof(name), v_name, "_bin"))
2342 	{
2343 		if (v->type == JSON_TYPE_STRING)
2344 		{
2345 			UINT len = StrLen(v->value.string);
2346 			UCHAR *data = ZeroMalloc(len * 4 + 64);
2347 			UINT size = B64_Decode(data, v->value.string, len);
2348 			ElementNullSafe(PackAddDataEx(p, name, data, size, index, total))->JsonHint_IsArray = !is_single;
2349 			Free(data);
2350 			ok = true;
2351 		}
2352 	}
2353 	else if (TrimEndWith(name, sizeof(name), v_name, "_dt"))
2354 	{
2355 		if (v->type == JSON_TYPE_NUMBER)
2356 		{
2357 			ElementNullSafe(PackAddInt64Ex(p, name, v->value.number, index, total))->JsonHint_IsArray = !is_single;
2358 			ok = true;
2359 		}
2360 		else if (v->type == JSON_TYPE_STRING)
2361 		{
2362 			UINT64 time = DateTimeStrRFC3339ToSystemTime64(v->value.string);
2363 			ELEMENT *e = PackAddInt64Ex(p, name, time, index, total);
2364 			if (e != NULL)
2365 			{
2366 				e->JsonHint_IsArray = !is_single;
2367 				e->JsonHint_IsDateTime = true;
2368 			}
2369 			ok = true;
2370 		}
2371 	}
2372 	else if (TrimEndWith(name, sizeof(name), v_name, "_ip"))
2373 	{
2374 		if (v->type == JSON_TYPE_STRING)
2375 		{
2376 			IP ip;
2377 			if (StrToIP(&ip, v->value.string))
2378 			{
2379 				PackAddIpEx2(p, name, &ip, index, total, is_single);
2380 				ok = true;
2381 			}
2382 		}
2383 	}
2384 
2385 	return ok;
2386 }
2387 
2388 // Convert JSON string to PACK
JsonStrToPack(char * str)2389 PACK *JsonStrToPack(char *str)
2390 {
2391 	JSON_VALUE *v = StrToJson(str);
2392 	PACK *ret;
2393 
2394 	if (v == NULL)
2395 	{
2396 		return NULL;
2397 	}
2398 
2399 	ret = JsonToPack(v);
2400 
2401 	JsonFree(v);
2402 
2403 	return ret;
2404 }
2405 
2406 // Convert PACK to JSON string
PackToJsonStr(PACK * p)2407 char *PackToJsonStr(PACK *p)
2408 {
2409 	char *ret;
2410 	JSON_VALUE *json = PackToJson(p);
2411 
2412 	ret = JsonToStr(json);
2413 
2414 	JsonFree(json);
2415 
2416 	return ret;
2417 }
2418 
2419 // Convert PACK to JSON
PackToJson(PACK * p)2420 JSON_VALUE *PackToJson(PACK *p)
2421 {
2422 	JSON_VALUE *v;
2423 	JSON_OBJECT *o;
2424 	UINT i, j, k;
2425 	LIST *json_group_id_list;
2426 	if (p == NULL)
2427 	{
2428 		return JsonNewObject();
2429 	}
2430 
2431 	// suppress quick sort in the enumeration process
2432 	GetElement(p, "_dummy_", VALUE_INT);
2433 
2434 	json_group_id_list = NewStrList();
2435 
2436 	for (i = 0;i < LIST_NUM(p->elements);i++)
2437 	{
2438 		ELEMENT *e = LIST_DATA(p->elements, i);
2439 
2440 		if (e->num_value >= 2 || e->JsonHint_IsArray)
2441 		{
2442 			if (IsEmptyStr(e->JsonHint_GroupName) == false)
2443 			{
2444 				AddStrToStrListDistinct(json_group_id_list, e->JsonHint_GroupName);
2445 			}
2446 		}
2447 	}
2448 
2449 	for (i = 0;i < LIST_NUM(p->json_subitem_names);i++)
2450 	{
2451 		char *group_name = LIST_DATA(p->json_subitem_names, i);
2452 
2453 		if (IsEmptyStr(group_name) == false)
2454 		{
2455 			AddStrToStrListDistinct(json_group_id_list, group_name);
2456 		}
2457 	}
2458 
2459 	v = JsonNewObject();
2460 	o = JsonValueGetObject(v);
2461 
2462 	for (k = 0;k < LIST_NUM(json_group_id_list);k++)
2463 	{
2464 		char *group_name = LIST_DATA(json_group_id_list, k);
2465 		UINT array_count = INFINITE;
2466 		bool ok = true;
2467 
2468 		for (i = 0;i < LIST_NUM(p->elements);i++)
2469 		{
2470 			ELEMENT *e = LIST_DATA(p->elements, i);
2471 
2472 			if (e->num_value >= 2 || e->JsonHint_IsArray)
2473 			{
2474 				if (StrCmpi(e->JsonHint_GroupName, group_name) == 0)
2475 				{
2476 					if (array_count == INFINITE)
2477 					{
2478 						array_count = e->num_value;
2479 					}
2480 					else
2481 					{
2482 						if (array_count != e->num_value)
2483 						{
2484 							ok = false;
2485 						}
2486 					}
2487 				}
2488 			}
2489 		}
2490 
2491 		if (array_count == INFINITE)
2492 		{
2493 			array_count = 0;
2494 		}
2495 
2496 		if (ok)
2497 		{
2498 			JSON_VALUE **json_objects = ZeroMalloc(sizeof(void *) * array_count);
2499 			JSON_VALUE *jav = JsonNewArray();
2500 			JSON_ARRAY *ja = JsonArray(jav);
2501 
2502 			JsonSet(o, group_name, jav);
2503 
2504 			for (j = 0;j < array_count;j++)
2505 			{
2506 				json_objects[j] = JsonNewObject();
2507 
2508 				JsonArrayAdd(ja, json_objects[j]);
2509 			}
2510 
2511 			for (i = 0;i < LIST_NUM(p->elements);i++)
2512 			{
2513 				ELEMENT *e = LIST_DATA(p->elements, i);
2514 
2515 				if (e->num_value >= 2 || e->JsonHint_IsArray)
2516 				{
2517 					if (StrCmpi(e->JsonHint_GroupName, group_name) == 0)
2518 					{
2519 						for (j = 0;j < e->num_value;j++)
2520 						{
2521 							PackElementToJsonObject(JsonValueGetObject(json_objects[j]),
2522 								p, e, j);
2523 						}
2524 					}
2525 				}
2526 			}
2527 
2528 			Free(json_objects);
2529 		}
2530 	}
2531 
2532 	for (i = 0;i < LIST_NUM(p->elements);i++)
2533 	{
2534 		ELEMENT *e = LIST_DATA(p->elements, i);
2535 
2536 		if (e->num_value >= 2 || e->JsonHint_IsArray)
2537 		{
2538 			if (IsEmptyStr(e->JsonHint_GroupName))
2539 			{
2540 				char *suffix = DetermineJsonSuffixForPackElement(e);
2541 
2542 				if (suffix != NULL)
2543 				{
2544 					JSON_VALUE *jav = JsonNewArray();
2545 					JSON_ARRAY *ja = JsonArray(jav);
2546 					char name[MAX_PATH];
2547 
2548 					for (j = 0;j < e->num_value;j++)
2549 					{
2550 						PackArrayElementToJsonArray(ja, p, e, j);
2551 					}
2552 
2553 					StrCpy(name, sizeof(name), e->name);
2554 					StrCat(name, sizeof(name), suffix);
2555 
2556 					JsonSet(o, name, jav);
2557 				}
2558 			}
2559 		}
2560 		else if (e->num_value == 1)
2561 		{
2562 			PackElementToJsonObject(o, p, e, 0);
2563 		}
2564 	}
2565 
2566 	ReleaseStrList(json_group_id_list);
2567 
2568 	return v;
2569 }
2570 
2571 
2572 
2573 
2574