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