blob: 2b925a18f6926ed526b1df669c0814c176fbeb94 [file] [log] [blame]
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001// Copyright 2014 PDFium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07004
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07005// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
Lei Zhange5b0bd12015-06-19 17:15:41 -07007#include "../../../core/include/fdrm/fx_crypt.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07008#include "../../include/javascript/JavaScript.h"
9#include "../../include/javascript/IJavaScript.h"
10#include "../../include/javascript/JS_GlobalData.h"
11
12#define JS_MAXGLOBALDATA (1024 * 4 - 8)
13
14/* --------------------- CJS_GlobalVariableArray --------------------- */
15
16CJS_GlobalVariableArray::CJS_GlobalVariableArray()
17{
18}
19
20CJS_GlobalVariableArray::~CJS_GlobalVariableArray()
21{
22 Empty();
23}
24
25void CJS_GlobalVariableArray::Copy(const CJS_GlobalVariableArray& array)
26{
27 Empty();
28 for (int i=0,sz=array.Count(); i<sz; i++)
29 {
30 CJS_KeyValue* pOldObjData = array.GetAt(i);
31 ASSERT(pOldObjData != NULL);
32
33 switch (pOldObjData->nType)
34 {
35 case JS_GLOBALDATA_TYPE_NUMBER:
36 {
37 CJS_KeyValue* pNewObjData = new CJS_KeyValue;
38 pNewObjData->sKey = pOldObjData->sKey;
39 pNewObjData->nType = pOldObjData->nType;
40 pNewObjData->dData = pOldObjData->dData;
41 Add(pNewObjData);
42 }
43 break;
44 case JS_GLOBALDATA_TYPE_BOOLEAN:
45 {
46 CJS_KeyValue* pNewObjData = new CJS_KeyValue;
47 pNewObjData->sKey = pOldObjData->sKey;
48 pNewObjData->nType = pOldObjData->nType;
49 pNewObjData->bData = pOldObjData->bData;
50 Add(pNewObjData);
51 }
52 break;
53 case JS_GLOBALDATA_TYPE_STRING:
54 {
55 CJS_KeyValue* pNewObjData = new CJS_KeyValue;
56 pNewObjData->sKey = pOldObjData->sKey;
57 pNewObjData->nType = pOldObjData->nType;
58 pNewObjData->sData = pOldObjData->sData;
59 Add(pNewObjData);
60 }
61 break;
62 case JS_GLOBALDATA_TYPE_OBJECT:
63 {
64 CJS_KeyValue* pNewObjData = new CJS_KeyValue;
65 pNewObjData->sKey = pOldObjData->sKey;
66 pNewObjData->nType = pOldObjData->nType;
67 pNewObjData->objData.Copy(pOldObjData->objData);
68 Add(pNewObjData);
69 }
70 case JS_GLOBALDATA_TYPE_NULL:
71 {
72 CJS_KeyValue* pNewObjData = new CJS_KeyValue;
73 pNewObjData->sKey = pOldObjData->sKey;
74 pNewObjData->nType = pOldObjData->nType;
75 Add(pNewObjData);
76 }
77 }
78 }
79}
80
81void CJS_GlobalVariableArray::Add(CJS_KeyValue* p)
82{
83 array.Add(p);
84}
85
86int CJS_GlobalVariableArray::Count() const
87{
88 return array.GetSize();
89}
90
91CJS_KeyValue* CJS_GlobalVariableArray::GetAt(int index) const
92{
93 return array.GetAt(index);
94}
95
96void CJS_GlobalVariableArray::Empty()
97{
98 for (int i=0,sz=array.GetSize(); i<sz; i++)
99 delete array.GetAt(i);
100 array.RemoveAll();
101}
102
103/* -------------------------- CJS_GlobalData -------------------------- */
104
105#define READER_JS_GLOBALDATA_FILENAME L"Reader_JsGlobal.Data"
106#define PHANTOM_JS_GLOBALDATA_FILENAME L"Phantom_JsGlobal.Data"
107#define SDK_JS_GLOBALDATA_FILENAME L"SDK_JsGlobal.Data"
108
Tom Sepezbfa9a822015-06-09 13:24:12 -0700109static const uint8_t JS_RC4KEY[] = {0x19,0xa8,0xe8,0x01,0xf6,0xa8,0xb6,0x4d,0x82,0x04,
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700110 0x45,0x6d,0xb4,0xcf,0xd7,0x77,0x67,0xf9,0x75,0x9f,
111 0xf0,0xe0,0x1e,0x51,0xee,0x46,0xfd,0x0b,0xc9,0x93,
112 0x25,0x55,0x4a,0xee,0xe0,0x16,0xd0,0xdf,0x8c,0xfa,
113 0x2a,0xa9,0x49,0xfd,0x97,0x1c,0x0e,0x22,0x13,0x28,
114 0x7c,0xaf,0xc4,0xfc,0x9c,0x12,0x65,0x8c,0x4e,0x5b,
115 0x04,0x75,0x89,0xc9,0xb1,0xed,0x50,0xca,0x96,0x6f,
116 0x1a,0x7a,0xfe,0x58,0x5d,0xec,0x19,0x4a,0xf6,0x35,
117 0x6a,0x97,0x14,0x00,0x0e,0xd0,0x6b,0xbb,0xd5,0x75,
118 0x55,0x8b,0x6e,0x6b,0x19,0xa0,0xf8,0x77,0xd5,0xa3
119 };
120
Bo Xufdc00a72014-10-28 23:03:33 -0700121CJS_GlobalData::CJS_GlobalData(CPDFDoc_Environment* pApp) : m_pApp(pApp)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700122{
123// IBaseAnnot* pBaseAnnot = IBaseAnnot::GetBaseAnnot(m_pApp);
124// ASSERT(pBaseAnnot != NULL);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700125//
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700126// m_sFilePath = pBaseAnnot->GetUserPath();
127 m_sFilePath += SDK_JS_GLOBALDATA_FILENAME;
128
129 LoadGlobalPersistentVariables();
130}
131
132CJS_GlobalData::~CJS_GlobalData()
133{
134 SaveGlobalPersisitentVariables();
135
136 for (int i=0,sz=m_arrayGlobalData.GetSize(); i<sz; i++)
137 delete m_arrayGlobalData.GetAt(i);
138
139 m_arrayGlobalData.RemoveAll();
140}
141
Tom Sepezd7e5cc72015-06-10 14:33:37 -0700142int CJS_GlobalData::FindGlobalVariable(const FX_CHAR* propname)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700143{
144 ASSERT(propname != NULL);
145
146 int nRet = -1;
147
148 for (int i=0,sz=m_arrayGlobalData.GetSize(); i<sz; i++)
149 {
150 CJS_GlobalData_Element* pTemp = m_arrayGlobalData.GetAt(i);
151 if (pTemp->data.sKey[0] == *propname && pTemp->data.sKey == propname)
152 {
153 nRet = i;
154 break;
155 }
156 }
157
158 return nRet;
159}
160
Tom Sepezd7e5cc72015-06-10 14:33:37 -0700161CJS_GlobalData_Element* CJS_GlobalData::GetGlobalVariable(const FX_CHAR* propname)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700162{
163 ASSERT(propname != NULL);
164
165 int nFind = FindGlobalVariable(propname);
166
167 if (nFind >= 0)
168 return m_arrayGlobalData.GetAt(nFind);
169 else
170 return NULL;
171}
172
Tom Sepezd7e5cc72015-06-10 14:33:37 -0700173void CJS_GlobalData::SetGlobalVariableNumber(const FX_CHAR* propname, double dData)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700174{
175 ASSERT(propname != NULL);
176 CFX_ByteString sPropName = propname;
177
178 sPropName.TrimLeft();
179 sPropName.TrimRight();
180
181 if (sPropName.GetLength() == 0) return;
182
183 if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName))
184 {
185 pData->data.nType = JS_GLOBALDATA_TYPE_NUMBER;
186 pData->data.dData = dData;
187 }
188 else
189 {
190 CJS_GlobalData_Element* pNewData = new CJS_GlobalData_Element;
191 pNewData->data.sKey = sPropName;
192 pNewData->data.nType = JS_GLOBALDATA_TYPE_NUMBER;
193 pNewData->data.dData = dData;
194
195 m_arrayGlobalData.Add(pNewData);
196 }
197}
198
Tom Sepezd7e5cc72015-06-10 14:33:37 -0700199void CJS_GlobalData::SetGlobalVariableBoolean(const FX_CHAR* propname, bool bData)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700200{
201 ASSERT(propname != NULL);
202 CFX_ByteString sPropName = propname;
203
204 sPropName.TrimLeft();
205 sPropName.TrimRight();
206
207 if (sPropName.GetLength() == 0) return;
208
209 if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName))
210 {
211 pData->data.nType = JS_GLOBALDATA_TYPE_BOOLEAN;
212 pData->data.bData = bData;
213 }
214 else
215 {
216 CJS_GlobalData_Element* pNewData = new CJS_GlobalData_Element;
217 pNewData->data.sKey = sPropName;
218 pNewData->data.nType = JS_GLOBALDATA_TYPE_BOOLEAN;
219 pNewData->data.bData = bData;
220
221 m_arrayGlobalData.Add(pNewData);
222 }
223}
224
Tom Sepezd7e5cc72015-06-10 14:33:37 -0700225void CJS_GlobalData::SetGlobalVariableString(const FX_CHAR* propname, const CFX_ByteString& sData)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700226{
227 ASSERT(propname != NULL);
228 CFX_ByteString sPropName = propname;
229
230 sPropName.TrimLeft();
231 sPropName.TrimRight();
232
233 if (sPropName.GetLength() == 0) return;
234
235 if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName))
236 {
237 pData->data.nType = JS_GLOBALDATA_TYPE_STRING;
238 pData->data.sData = sData;
239 }
240 else
241 {
242 CJS_GlobalData_Element* pNewData = new CJS_GlobalData_Element;
243 pNewData->data.sKey = sPropName;
244 pNewData->data.nType = JS_GLOBALDATA_TYPE_STRING;
245 pNewData->data.sData = sData;
246
247 m_arrayGlobalData.Add(pNewData);
248 }
249}
250
Tom Sepezd7e5cc72015-06-10 14:33:37 -0700251void CJS_GlobalData::SetGlobalVariableObject(const FX_CHAR* propname, const CJS_GlobalVariableArray& array)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700252{
253 ASSERT(propname != NULL);
254 CFX_ByteString sPropName = propname;
255
256 sPropName.TrimLeft();
257 sPropName.TrimRight();
258
259 if (sPropName.GetLength() == 0) return;
260
261 if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName))
262 {
263 pData->data.nType = JS_GLOBALDATA_TYPE_OBJECT;
264 pData->data.objData.Copy(array);
265 }
266 else
267 {
268 CJS_GlobalData_Element* pNewData = new CJS_GlobalData_Element;
269 pNewData->data.sKey = sPropName;
270 pNewData->data.nType = JS_GLOBALDATA_TYPE_OBJECT;
271 pNewData->data.objData.Copy(array);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700272
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700273 m_arrayGlobalData.Add(pNewData);
274 }
275}
276
Tom Sepezd7e5cc72015-06-10 14:33:37 -0700277void CJS_GlobalData::SetGlobalVariableNull(const FX_CHAR* propname)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700278{
279 ASSERT(propname != NULL);
280 CFX_ByteString sPropName = propname;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700281
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700282 sPropName.TrimLeft();
283 sPropName.TrimRight();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700284
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700285 if (sPropName.GetLength() == 0) return;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700286
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700287 if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName))
288 {
289 pData->data.nType = JS_GLOBALDATA_TYPE_NULL;
290 }
291 else
292 {
293 CJS_GlobalData_Element* pNewData = new CJS_GlobalData_Element;
294 pNewData->data.sKey = sPropName;
295 pNewData->data.nType = JS_GLOBALDATA_TYPE_NULL;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700296
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700297 m_arrayGlobalData.Add(pNewData);
298 }
299}
300
Tom Sepezd7e5cc72015-06-10 14:33:37 -0700301FX_BOOL CJS_GlobalData::SetGlobalVariablePersistent(const FX_CHAR* propname, FX_BOOL bPersistent)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700302{
303 ASSERT(propname != NULL);
304 CFX_ByteString sPropName = propname;
305
306 sPropName.TrimLeft();
307 sPropName.TrimRight();
308
309 if (sPropName.GetLength() == 0) return FALSE;
310
311 if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName))
312 {
313 pData->bPersistent = bPersistent;
314 return TRUE;
315 }
316
317 return FALSE;
318}
319
Tom Sepezd7e5cc72015-06-10 14:33:37 -0700320FX_BOOL CJS_GlobalData::DeleteGlobalVariable(const FX_CHAR* propname)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700321{
322 ASSERT(propname != NULL);
323 CFX_ByteString sPropName = propname;
324
325 sPropName.TrimLeft();
326 sPropName.TrimRight();
327
328 if (sPropName.GetLength() == 0) return FALSE;
329
330 int nFind = FindGlobalVariable(sPropName);
331
332 if (nFind >= 0)
333 {
334 delete m_arrayGlobalData.GetAt(nFind);
335 m_arrayGlobalData.RemoveAt(nFind);
336 return TRUE;
337 }
338
339 return FALSE;
340}
341
Tom Sepezbfa9a822015-06-09 13:24:12 -0700342int32_t CJS_GlobalData::GetSize() const
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700343{
344 return m_arrayGlobalData.GetSize();
345}
346
347CJS_GlobalData_Element* CJS_GlobalData::GetAt(int index) const
348{
349 return m_arrayGlobalData.GetAt(index);
350}
351
352void CJS_GlobalData::LoadGlobalPersistentVariables()
353{
Tom Sepezd7e5cc72015-06-10 14:33:37 -0700354 uint8_t* pBuffer = NULL;
Tom Sepezbfa9a822015-06-09 13:24:12 -0700355 int32_t nLength = 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700356
Tom Sepez4f7bc042015-04-27 12:06:58 -0700357 LoadFileBuffer(m_sFilePath.c_str(), pBuffer, nLength);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700358 CRYPT_ArcFourCryptBlock(pBuffer, nLength, JS_RC4KEY, sizeof(JS_RC4KEY));
359
360 if (pBuffer)
361 {
Tom Sepezd7e5cc72015-06-10 14:33:37 -0700362 uint8_t* p = pBuffer;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700363 FX_WORD wType = *((FX_WORD*)p);
364 p += sizeof(FX_WORD);
365
366 //FX_WORD wTemp = (FX_WORD)(('X' << 8) | 'F');
367
368 if (wType == (FX_WORD)(('X' << 8) | 'F'))
369 {
370 FX_WORD wVersion = *((FX_WORD*)p);
371 p += sizeof(FX_WORD);
372
373 ASSERT(wVersion <= 2);
374
375 FX_DWORD dwCount = *((FX_DWORD*)p);
376 p += sizeof(FX_DWORD);
377
378 FX_DWORD dwSize = *((FX_DWORD*)p);
379 p += sizeof(FX_DWORD);
380
381 if (dwSize == nLength - sizeof(FX_WORD) * 2 - sizeof(FX_DWORD)* 2)
382 {
Tom Sepezbfa9a822015-06-09 13:24:12 -0700383 for (int32_t i=0,sz=dwCount; i<sz; i++)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700384 {
385 if (p > pBuffer + nLength)
386 break;
387
388 FX_DWORD dwNameLen = *((FX_DWORD*)p);
389 p += sizeof(FX_DWORD);
390
391 if (p + dwNameLen > pBuffer + nLength)
392 break;
393
394 CFX_ByteString sEntry = CFX_ByteString(p, dwNameLen);
395 p += sizeof(char) * dwNameLen;
396
397 FX_WORD wDataType = *((FX_WORD*)p);
398 p += sizeof(FX_WORD);
399
400 switch (wDataType)
401 {
402 case JS_GLOBALDATA_TYPE_NUMBER:
403 {
404 double dData = 0;
405 switch (wVersion)
406 {
407 case 1:
408 {
409 FX_DWORD dwData = *((FX_DWORD*)p);
410 p += sizeof(FX_DWORD);
411 dData = dwData;
412 }
413 break;
414 case 2:
415 {
416 dData = *((double*)p);
417 p += sizeof(double);
418 }
419 break;
420 }
421 SetGlobalVariableNumber(sEntry, dData);
422 SetGlobalVariablePersistent(sEntry, TRUE);
423 }
424 break;
425 case JS_GLOBALDATA_TYPE_BOOLEAN:
426 {
427 FX_WORD wData = *((FX_WORD*)p);
428 p += sizeof(FX_WORD);
429 SetGlobalVariableBoolean(sEntry, (bool)(wData == 1));
430 SetGlobalVariablePersistent(sEntry, TRUE);
431 }
432 break;
433 case JS_GLOBALDATA_TYPE_STRING:
434 {
435 FX_DWORD dwLength = *((FX_DWORD*)p);
436 p += sizeof(FX_DWORD);
437
438 if (p + dwLength > pBuffer + nLength)
439 break;
440
441 SetGlobalVariableString(sEntry, CFX_ByteString(p, dwLength));
442 SetGlobalVariablePersistent(sEntry, TRUE);
443 p += sizeof(char) * dwLength;
444 }
445 break;
446 case JS_GLOBALDATA_TYPE_NULL:
447 {
448 SetGlobalVariableNull(sEntry);
449 SetGlobalVariablePersistent(sEntry, TRUE);
450 }
451 }
452 }
453 }
454 }
455 FX_Free(pBuffer);
456 }
457}
458
459/*
460struct js_global_datafile_header
461{
462 FX_WORD type; //FX ('X' << 8) | 'F'
463 FX_WORD version; //1.0
464 FX_DWORD datacount;
465};
466struct js_global_datafile_data
467{
468 FX_WORD type;
469 FX_DWORD nData;
470 FX_WORD bData;
471 FX_DWORD nStrLen;
472 char* pStr;
473};
474*/
475
476void CJS_GlobalData::SaveGlobalPersisitentVariables()
477{
478 FX_DWORD nCount = 0;
479 CFX_BinaryBuf sData;
480
481 for (int i=0,sz=m_arrayGlobalData.GetSize(); i<sz; i++)
482 {
483 CJS_GlobalData_Element* pElement = m_arrayGlobalData.GetAt(i);
484 ASSERT(pElement != NULL);
485
486 if (pElement->bPersistent)
487 {
488 CFX_BinaryBuf sElement;
489 MakeByteString(pElement->data.sKey, &pElement->data, sElement);
490
491 if (sData.GetSize() + sElement.GetSize() > JS_MAXGLOBALDATA)
492 break;
493
494 sData.AppendBlock(sElement.GetBuffer(), sElement.GetSize());
495 nCount++;
496 }
497 }
498
499 CFX_BinaryBuf sFile;
500
501 FX_WORD wType = (FX_WORD)(('X' << 8) | 'F');
502 sFile.AppendBlock(&wType, sizeof(FX_WORD));
503 FX_WORD wVersion = 2;
504 sFile.AppendBlock(&wVersion, sizeof(FX_WORD));
505 sFile.AppendBlock(&nCount, sizeof(FX_DWORD));
506 FX_DWORD dwSize = sData.GetSize();
507 sFile.AppendBlock(&dwSize, sizeof(FX_DWORD));
508
509 sFile.AppendBlock(sData.GetBuffer(), sData.GetSize());
510
511 CRYPT_ArcFourCryptBlock(sFile.GetBuffer(), sFile.GetSize(), JS_RC4KEY, sizeof(JS_RC4KEY));
Tom Sepezd7e5cc72015-06-10 14:33:37 -0700512 WriteFileBuffer(m_sFilePath.c_str(), (const FX_CHAR*)sFile.GetBuffer(), sFile.GetSize());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700513}
514
Tom Sepezd7e5cc72015-06-10 14:33:37 -0700515void CJS_GlobalData::LoadFileBuffer(const FX_WCHAR* sFilePath, uint8_t*& pBuffer, int32_t& nLength)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700516{
517//UnSupport.
518}
519
Tom Sepezd7e5cc72015-06-10 14:33:37 -0700520void CJS_GlobalData::WriteFileBuffer(const FX_WCHAR* sFilePath, const FX_CHAR* pBuffer, int32_t nLength)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700521{
522//UnSupport.
523}
524
525void CJS_GlobalData::MakeByteString(const CFX_ByteString& name, CJS_KeyValue* pData, CFX_BinaryBuf& sData)
526{
527 ASSERT(pData != NULL);
528
529 FX_WORD wType = (FX_WORD)pData->nType;
530
531 switch (wType)
532 {
533 case JS_GLOBALDATA_TYPE_NUMBER:
534 {
535 FX_DWORD dwNameLen = (FX_DWORD)name.GetLength();
536 sData.AppendBlock(&dwNameLen, sizeof(FX_DWORD));
537 sData.AppendString(name);
538
539 sData.AppendBlock(&wType, sizeof(FX_WORD));
540 double dData = pData->dData;
541 sData.AppendBlock(&dData, sizeof(double));
542 }
543 break;
544 case JS_GLOBALDATA_TYPE_BOOLEAN:
545 {
546 FX_DWORD dwNameLen = (FX_DWORD)name.GetLength();
547 sData.AppendBlock(&dwNameLen, sizeof(FX_DWORD));
548 sData.AppendString(name);
549
550 sData.AppendBlock(&wType, sizeof(FX_WORD));
551 FX_WORD wData = (FX_WORD)pData->bData;
552 sData.AppendBlock(&wData, sizeof(FX_WORD));
553 }
554 break;
555 case JS_GLOBALDATA_TYPE_STRING:
556 {
557 FX_DWORD dwNameLen = (FX_DWORD)name.GetLength();
558 sData.AppendBlock(&dwNameLen, sizeof(FX_DWORD));
559 sData.AppendString(name);
560
561 sData.AppendBlock(&wType, sizeof(FX_WORD));
562
563 FX_DWORD dwDataLen = (FX_DWORD)pData->sData.GetLength();
564 sData.AppendBlock(&dwDataLen, sizeof(FX_DWORD));
565 sData.AppendString(pData->sData);
566 }
567 break;
568 case JS_GLOBALDATA_TYPE_NULL:
569 {
570 FX_DWORD dwNameLen = (FX_DWORD)name.GetLength();
571 sData.AppendBlock(&dwNameLen, sizeof(FX_DWORD));
572 sData.AppendString(name);
573
574 sData.AppendBlock(&wType, sizeof(FX_DWORD));
575 }
576 break;
577 default:
578 break;
579 }
580}
581