1/** 2 * Copyright(c) 2011 Trusted Logic. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name Trusted Logic nor the names of its 15 * contributors may be used to endorse or promote products derived 16 * from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30#ifdef ANDROID 31#include <stddef.h> 32#endif 33 34#include <stdlib.h> 35#include <string.h> 36 37#define SST_EXPORTS 38#define EXCLUDE_SERVICE_SYSTEM_SST_BASIC_TYPES 39#include "sst.h" 40 41/* Included for the TEE management */ 42#include "pkcs11_internal.h" 43 44 45static TEEC_Session g_SSTSession; 46static bool g_bSSTInitialized = false; 47 48 49/* ------------------------------------------------------------------------ 50 TEEC -> SST error code translation 51 ------------------------------------------------------------------------- */ 52static SST_ERROR static_SSTConvertErrorCode(TEEC_Result nError) 53{ 54 switch (nError) 55 { 56 case TEEC_SUCCESS: 57 return SST_SUCCESS; 58 case SST_ERROR_BAD_PARAMETERS: 59 case SST_ERROR_ACCESS_DENIED: 60 case SST_ERROR_ACCESS_CONFLICT: 61 case SST_ERROR_CORRUPTED: 62 case SST_ERROR_NO_SPACE: 63 case SST_ERROR_ITEM_NOT_FOUND: 64 case SST_ERROR_OUT_OF_MEMORY: 65 case SST_ERROR_OVERFLOW: 66 return nError; 67 default: 68 return SST_ERROR_GENERIC; 69 } 70} 71 72static TEEC_Session* static_SSTGetSession(void) 73{ 74 if (g_bSSTInitialized) 75 { 76 return &g_SSTSession; 77 } 78 79 return NULL; 80} 81 82SST_ERROR SST_EXPORT_API SSTInit(void) 83{ 84 TEEC_Result nTeeError = TEEC_SUCCESS; 85 TEEC_Operation sOperation; 86 uint8_t nParamType3 = TEEC_NONE; 87 void* pSignatureFile = NULL; 88 uint32_t nSignatureFileLen = 0; 89 uint32_t nLoginType; 90 91 stubMutexLock(); 92 if (g_bSSTInitialized) 93 { 94 /* SST library already initialized */ 95 nTeeError = TEEC_SUCCESS; 96 goto end; 97 } 98 99 nTeeError = stubInitializeContext(); 100 if (nTeeError != TEEC_SUCCESS) 101 { 102 goto end; 103 } 104 105 /* Check if there is a signature file. 106 * If yes, send it in param3, otherwise use LOGIN_APPLICATION 107 */ 108 nTeeError = TEEC_ReadSignatureFile(&pSignatureFile, &nSignatureFileLen); 109 if (nTeeError == TEEC_ERROR_ITEM_NOT_FOUND) 110 { 111 nLoginType = TEEC_LOGIN_USER_APPLICATION; 112 } 113 else 114 { 115 if (nTeeError != TEEC_SUCCESS) 116 { 117 goto end; 118 } 119 sOperation.params[3].tmpref.buffer = pSignatureFile; 120 sOperation.params[3].tmpref.size = nSignatureFileLen; 121 nParamType3 = TEEC_MEMREF_TEMP_INPUT; 122 nLoginType = TEEC_LOGIN_AUTHENTICATION; 123 } 124 125 sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, nParamType3); 126 nTeeError = TEEC_OpenSession(&g_sContext, 127 &g_SSTSession, /* OUT session */ 128 &SERVICE_UUID, /* destination UUID */ 129 nLoginType, /* connectionMethod */ 130 NULL, /* connectionData */ 131 &sOperation, /* IN OUT operation */ 132 NULL /* OUT returnOrigin, optional */ 133 ); 134 if (nTeeError != TEEC_SUCCESS) 135 { 136 goto end_finalize_context; 137 } 138 139 g_bSSTInitialized = true; 140 stubMutexUnlock(); 141 return SST_SUCCESS; 142 143end_finalize_context: 144 stubFinalizeContext(); 145end: 146 stubMutexUnlock(); 147 return static_SSTConvertErrorCode(nTeeError); 148} 149 150SST_ERROR SST_EXPORT_API SSTTerminate(void) 151{ 152 stubMutexLock(); 153 if (g_bSSTInitialized) 154 { 155 TEEC_CloseSession(&g_SSTSession); 156 stubFinalizeContext(); 157 g_bSSTInitialized = false; 158 } 159 /* else if not intialized => success too */ 160 stubMutexUnlock(); 161 return SST_SUCCESS; 162} 163 164 165/* ------------------------------------------------------------------------ 166 Other API Functions 167------------------------------------------------------------------------- */ 168 169 170/* Check that the input filename is well-formed */ 171static SST_ERROR static_SSTCheckFileName(const char* pName) 172{ 173 uint32_t i; 174 char c; 175 176 if (pName == NULL) 177 { 178 return SST_ERROR_BAD_PARAMETERS; 179 } 180 181 for (i = 0; i <= SST_MAX_FILENAME; i++) 182 { 183 c = pName[i]; 184 if (c == 0) 185 { 186 /* End of the string */ 187 return SST_SUCCESS; 188 } 189 190 if (c == '/' || c == '\\') 191 { 192 /* Invalid character */ 193 return SST_ERROR_BAD_PARAMETERS; 194 } 195 196 if (c < 0x20 || c >= 0x7F) 197 { 198 /* Filename contains illegal characters */ 199 return SST_ERROR_BAD_PARAMETERS; 200 } 201 } 202 /* Filename is too long. Zero terminator not found */ 203 return SST_ERROR_BAD_PARAMETERS; 204} 205 206static SST_ERROR static_SSTCheckPattern( 207 const char* pFilenamePattern) 208{ 209 uint32_t i; 210 if(pFilenamePattern == NULL) 211 { 212 return S_SUCCESS; 213 } 214 215 /** 216 * Check Forbidden characters. 217 */ 218 for (i = 0; pFilenamePattern[i] != 0; i++) 219 { 220 if(pFilenamePattern[i] < 0x20 ) 221 { 222 return S_ERROR_BAD_PARAMETERS; 223 } 224 else if(pFilenamePattern[i] == 0x2F ) /* '/' */ 225 { 226 return S_ERROR_BAD_PARAMETERS; 227 } 228 else if(pFilenamePattern[i] == 0x5C ) /* '\' */ 229 { 230 /** 231 * Must be directly followed by asterisk character or question-mark 232 * character. 233 */ 234 if (! ((pFilenamePattern[i+1] == '*' || 235 pFilenamePattern[i+1] == '?'))) 236 { 237 return S_ERROR_BAD_PARAMETERS; 238 } 239 } 240 else if(pFilenamePattern[i] >= 0x7F ) 241 { 242 return S_ERROR_BAD_PARAMETERS; 243 } 244 } 245 246 return S_SUCCESS; 247} 248 249 250 251SST_ERROR SST_EXPORT_API SSTOpen(const char* pFilename, 252 uint32_t nFlags, 253 uint32_t nReserved, 254 SST_HANDLE* phFile) 255{ 256 TEEC_Session* pSession; 257 TEEC_Result nError; 258 TEEC_Operation sOperation; 259 uint32_t nReturnOrigin; 260 SST_ERROR nErrorCode = SST_SUCCESS; 261 262 if (phFile == NULL || nReserved != 0) 263 { 264 return SST_ERROR_BAD_PARAMETERS; 265 } 266 267 *phFile = SST_HANDLE_INVALID; 268 269 nErrorCode = static_SSTCheckFileName(pFilename); 270 if (nErrorCode != SST_SUCCESS) 271 { 272 return nErrorCode; 273 } 274 275 pSession = static_SSTGetSession(); 276 if (pSession == NULL) 277 { 278 return SST_ERROR_GENERIC; 279 } 280 281 sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_TEMP_INPUT, TEEC_NONE, TEEC_NONE); 282 sOperation.params[0].value.a = 1; /* Private storage */ 283 sOperation.params[0].value.b = nFlags; /* Access flags */ 284 sOperation.params[1].tmpref.buffer = (void*)pFilename; 285 sOperation.params[1].tmpref.size = strlen(pFilename); 286 nError = TEEC_InvokeCommand(pSession, 287 SERVICE_SYSTEM_SST_OPEN_COMMAND_ID, /* commandID */ 288 &sOperation, /* IN OUT operation */ 289 &nReturnOrigin /* OUT returnOrigin, optional */ 290 ); 291 if (nError == TEEC_SUCCESS) 292 { 293 *phFile = (SST_HANDLE)sOperation.params[0].value.a; 294 } 295 296 return static_SSTConvertErrorCode(nError); 297} 298 299SST_ERROR SST_EXPORT_API SSTCloseHandle(SST_HANDLE hFile) 300{ 301 TEEC_Session* pSession; 302 TEEC_Result nError; 303 TEEC_Operation sOperation; 304 uint32_t nReturnOrigin; 305 306 if (hFile == S_HANDLE_NULL) 307 { 308 return SST_SUCCESS; 309 } 310 311 pSession = static_SSTGetSession(); 312 if (pSession == NULL) 313 { 314 return SST_ERROR_GENERIC; 315 } 316 317 sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); 318 sOperation.params[0].value.a = hFile; 319 nError = TEEC_InvokeCommand(pSession, 320 SERVICE_SYSTEM_SST_CLOSE_COMMAND_ID, /* commandID */ 321 &sOperation, /* IN OUT operation */ 322 &nReturnOrigin /* OUT returnOrigin, optional */ 323 ); 324 325 return static_SSTConvertErrorCode(nError); 326} 327 328SST_ERROR SST_EXPORT_API SSTWrite(SST_HANDLE hFile, 329 const uint8_t* pBuffer, 330 uint32_t nSize) 331{ 332 TEEC_Session* pSession; 333 TEEC_Result nError; 334 TEEC_Operation sOperation; 335 uint32_t nReturnOrigin; 336 337 if (pBuffer == NULL) 338 { 339 return SST_ERROR_BAD_PARAMETERS; 340 } 341 342 if (nSize == 0) 343 { 344 return SST_SUCCESS; 345 } 346 347 pSession = static_SSTGetSession(); 348 if (pSession == NULL) 349 { 350 return SST_ERROR_GENERIC; 351 } 352 353 sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_MEMREF_TEMP_INPUT, TEEC_NONE, TEEC_NONE); 354 sOperation.params[0].value.a = hFile; 355 sOperation.params[1].tmpref.buffer = (void*)pBuffer; 356 sOperation.params[1].tmpref.size = nSize; 357 358 nError = TEEC_InvokeCommand(pSession, 359 SERVICE_SYSTEM_SST_WRITE_COMMAND_ID, /* commandID */ 360 &sOperation, /* IN OUT operation */ 361 &nReturnOrigin /* OUT returnOrigin, optional */ 362 ); 363 364 return static_SSTConvertErrorCode(nError); 365} 366 367 368SST_ERROR SST_EXPORT_API SSTRead(SST_HANDLE hFile, 369 uint8_t* pBuffer, 370 uint32_t nSize, 371 uint32_t* pnCount) 372{ 373 TEEC_Session* pSession; 374 TEEC_Result nError; 375 TEEC_Operation sOperation; 376 uint32_t nReturnOrigin; 377 378 if ((pBuffer == NULL) || (pnCount == NULL)) 379 { 380 return SST_ERROR_BAD_PARAMETERS; 381 } 382 *pnCount = 0; 383 384 pSession = static_SSTGetSession(); 385 if (pSession == NULL) 386 { 387 return SST_ERROR_GENERIC; 388 } 389 390 if (nSize == 0) 391 { 392 return SST_SUCCESS; 393 } 394 395 sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE, TEEC_NONE); 396 sOperation.params[0].value.a = hFile; 397 sOperation.params[1].tmpref.buffer = pBuffer; 398 sOperation.params[1].tmpref.size = nSize; 399 400 nError = TEEC_InvokeCommand(pSession, 401 SERVICE_SYSTEM_SST_READ_COMMAND_ID, /* commandID */ 402 &sOperation, /* IN OUT operation */ 403 &nReturnOrigin /* OUT returnOrigin, optional */ 404 ); 405 406 *pnCount = sOperation.params[1].tmpref.size; /* The returned buffer size */ 407 return static_SSTConvertErrorCode(nError); 408} 409 410SST_ERROR SST_EXPORT_API SSTSeek(SST_HANDLE hFile, 411 int32_t nOffset, 412 SST_WHENCE whence) 413{ 414 TEEC_Session* pSession; 415 TEEC_Result nError; 416 TEEC_Operation sOperation; 417 uint32_t nReturnOrigin; 418 419 switch(whence) 420 { 421 case SST_SEEK_SET: 422 case SST_SEEK_CUR: 423 case SST_SEEK_END: 424 break; 425 default: 426 return SST_ERROR_BAD_PARAMETERS; 427 } 428 429 pSession = static_SSTGetSession(); 430 if (pSession == NULL) 431 { 432 return SST_ERROR_GENERIC; 433 } 434 435 sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE); 436 sOperation.params[0].value.a = hFile; 437 sOperation.params[1].value.a = nOffset; 438 sOperation.params[1].value.b = (uint32_t)whence; 439 440 nError = TEEC_InvokeCommand(pSession, 441 SERVICE_SYSTEM_SST_SEEK_COMMAND_ID, /* commandID */ 442 &sOperation, /* IN OUT operation */ 443 &nReturnOrigin /* OUT returnOrigin, optional */ 444 ); 445 return static_SSTConvertErrorCode(nError); 446 447} 448 449static SST_ERROR SSTGetOffsetAndSize(SST_HANDLE hFile, uint32_t* pnOffset, uint32_t* pnSize) 450{ 451 TEEC_Session* pSession; 452 TEEC_Result nError; 453 TEEC_Operation sOperation; 454 uint32_t nReturnOrigin; 455 456 pSession = static_SSTGetSession(); 457 if (pSession == NULL) 458 { 459 return SST_ERROR_GENERIC; 460 } 461 462 if (pnOffset == NULL) 463 { 464 return SST_ERROR_BAD_PARAMETERS; 465 } 466 467 sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); 468 sOperation.params[0].value.a = (uint32_t)hFile; 469 470 nError = TEEC_InvokeCommand(pSession, 471 SERVICE_SYSTEM_SST_GET_OFFSET_AND_SIZE_COMMAND_ID, /* commandID */ 472 &sOperation, /* IN OUT operation */ 473 &nReturnOrigin /* OUT returnOrigin, optional */ 474 ); 475 476 if (pnOffset != NULL) 477 { 478 *pnOffset = sOperation.params[0].value.a; 479 } 480 if (pnSize != NULL) 481 { 482 *pnSize = sOperation.params[0].value.b; 483 } 484 return static_SSTConvertErrorCode(nError); 485 486} 487 488SST_ERROR SST_EXPORT_API SSTTell(SST_HANDLE hFile, 489 uint32_t* pnPos) 490{ 491 return SSTGetOffsetAndSize(hFile, pnPos, NULL); 492} 493 494SST_ERROR SST_EXPORT_API SSTGetSize(const char* pFilename, 495 uint32_t* pnSize) 496{ 497 TEEC_Session* pSession; 498 TEEC_Result nError; 499 TEEC_Operation sOperation; 500 uint32_t nReturnOrigin; 501 502 if ((pFilename == NULL) || (pnSize == NULL)) 503 { 504 return SST_ERROR_BAD_PARAMETERS; 505 } 506 507 nError = static_SSTCheckFileName(pFilename); 508 if (nError != SST_SUCCESS) 509 { 510 return nError; 511 } 512 513 pSession = static_SSTGetSession(); 514 if (pSession == NULL) 515 { 516 return SST_ERROR_GENERIC; 517 } 518 519 sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_TEMP_INPUT, TEEC_NONE, TEEC_NONE); 520 sOperation.params[0].value.a = 1; /* private storage */ 521 sOperation.params[0].value.b = 0; 522 sOperation.params[1].tmpref.buffer = (void*)pFilename; 523 sOperation.params[1].tmpref.size = strlen(pFilename); 524 525 nError = TEEC_InvokeCommand(pSession, 526 SERVICE_SYSTEM_SST_GET_SIZE_COMMAND_ID, /* commandID */ 527 &sOperation, /* IN OUT operation */ 528 &nReturnOrigin /* OUT returnOrigin, optional */ 529 ); 530 531 *pnSize = sOperation.params[0].value.a; 532 return static_SSTConvertErrorCode(nError); 533} 534 535 536SST_ERROR SST_EXPORT_API SSTEof( SST_HANDLE hFile, 537 bool* pbEof) 538{ 539 uint32_t nOffset; 540 uint32_t nSize; 541 SST_ERROR nError; 542 if (pbEof == NULL) 543 return SST_ERROR_BAD_PARAMETERS; 544 nError = SSTGetOffsetAndSize(hFile, &nOffset, &nSize); 545 if (nError == SST_SUCCESS) 546 { 547 if (nOffset >= nSize) 548 { 549 *pbEof = true; 550 } 551 else 552 { 553 *pbEof = false; 554 } 555 } 556 return nError; 557} 558 559SST_ERROR SST_EXPORT_API SSTCloseAndDelete(SST_HANDLE hFile) 560{ 561 TEEC_Session* pSession; 562 TEEC_Result nError; 563 TEEC_Operation sOperation; 564 uint32_t nReturnOrigin; 565 566 pSession = static_SSTGetSession(); 567 if (pSession == NULL) 568 { 569 return SST_ERROR_GENERIC; 570 } 571 572 sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); 573 sOperation.params[0].value.a = hFile; 574 575 nError = TEEC_InvokeCommand(pSession, 576 SERVICE_SYSTEM_SST_CLOSE_DELETE_COMMAND_ID, /* commandID */ 577 &sOperation, /* IN OUT operation */ 578 &nReturnOrigin /* OUT returnOrigin, optional */ 579 ); 580 return static_SSTConvertErrorCode(nError); 581} 582 583SST_ERROR SST_EXPORT_API SSTTruncate(SST_HANDLE hFile, uint32_t nLength) 584{ 585 TEEC_Session* pSession; 586 TEEC_Result nError; 587 TEEC_Operation sOperation; 588 uint32_t nReturnOrigin; 589 590 pSession = static_SSTGetSession(); 591 if (pSession == NULL) 592 { 593 return SST_ERROR_GENERIC; 594 } 595 596 sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); 597 sOperation.params[0].value.a = hFile; 598 sOperation.params[0].value.b = nLength; 599 600 nError = TEEC_InvokeCommand(pSession, 601 SERVICE_SYSTEM_SST_TRUNCATE_COMMAND_ID, /* commandID */ 602 &sOperation, /* IN OUT operation */ 603 &nReturnOrigin /* OUT returnOrigin, optional */ 604 ); 605 return static_SSTConvertErrorCode(nError); 606} 607 608SST_ERROR SST_EXPORT_API SSTRename(SST_HANDLE hFile, 609 const char* pNewFilename) 610{ 611 TEEC_Session* pSession; 612 TEEC_Result nError; 613 TEEC_Operation sOperation; 614 uint32_t nReturnOrigin; 615 616 pSession = static_SSTGetSession(); 617 if (pSession == NULL) 618 { 619 return SST_ERROR_GENERIC; 620 } 621 622 if (pNewFilename == NULL) 623 { 624 return SST_ERROR_BAD_PARAMETERS; 625 } 626 627 nError = static_SSTCheckFileName(pNewFilename); 628 if (nError != SST_SUCCESS) 629 { 630 return nError; 631 } 632 633 sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_MEMREF_TEMP_INPUT, TEEC_NONE, TEEC_NONE); 634 sOperation.params[0].value.a = hFile; 635 sOperation.params[1].tmpref.buffer = (void*)pNewFilename; 636 sOperation.params[1].tmpref.size = strlen(pNewFilename); 637 638 nError = TEEC_InvokeCommand(pSession, 639 SERVICE_SYSTEM_SST_RENAME_COMMAND_ID, /* commandID */ 640 &sOperation, /* IN OUT operation */ 641 &nReturnOrigin /* OUT returnOrigin, optional */ 642 ); 643 return static_SSTConvertErrorCode(nError); 644} 645 646SST_ERROR SST_EXPORT_API SSTEnumerationStart(const char* pFilenamePattern, 647 uint32_t nReserved1, 648 uint32_t nReserved2, 649 SST_HANDLE* phFileEnumeration) 650{ 651 TEEC_Session* pSession; 652 TEEC_Result nError; 653 TEEC_Operation sOperation; 654 uint32_t nReturnOrigin; 655 656 if (nReserved1!=0 || nReserved2!=0) 657 { 658 return SST_ERROR_BAD_PARAMETERS; 659 } 660 if (phFileEnumeration==NULL) 661 { 662 return SST_ERROR_BAD_PARAMETERS; 663 } 664 *phFileEnumeration = SST_HANDLE_INVALID; 665 666 nError = static_SSTCheckPattern(pFilenamePattern); 667 if (nError != SST_SUCCESS) 668 { 669 return nError; 670 } 671 672 pSession = static_SSTGetSession(); 673 if (pSession == NULL) 674 { 675 return SST_ERROR_GENERIC; 676 } 677 678 sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_TEMP_INPUT, TEEC_NONE, TEEC_NONE); 679 sOperation.params[0].value.a = 1; /* Private storage */ 680 sOperation.params[1].tmpref.buffer = (void*)pFilenamePattern; 681 if (pFilenamePattern != NULL) 682 { 683 sOperation.params[1].tmpref.size = strlen(pFilenamePattern); 684 } 685 else 686 { 687 sOperation.params[1].tmpref.size = 0; 688 } 689 690 nError = TEEC_InvokeCommand(pSession, 691 SERVICE_SYSTEM_SST_ENUM_START_COMMAND_ID, /* commandID */ 692 &sOperation, /* IN OUT operation */ 693 &nReturnOrigin /* OUT returnOrigin, optional */ 694 ); 695 696 *phFileEnumeration = (SST_HANDLE)sOperation.params[0].value.a; 697 return static_SSTConvertErrorCode(nError); 698} 699 700SST_ERROR SST_EXPORT_API SSTEnumerationCloseHandle(SST_HANDLE hFileEnumeration) 701{ 702 TEEC_Session* pSession; 703 TEEC_Result nError; 704 TEEC_Operation sOperation; 705 uint32_t nReturnOrigin; 706 707 pSession = static_SSTGetSession(); 708 if (pSession == NULL) 709 { 710 return SST_ERROR_GENERIC; 711 } 712 713 sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); 714 sOperation.params[0].value.a = hFileEnumeration; 715 716 nError = TEEC_InvokeCommand(pSession, 717 SERVICE_SYSTEM_SST_ENUM_CLOSE_COMMAND_ID, /* commandID */ 718 &sOperation, /* IN OUT operation */ 719 &nReturnOrigin /* OUT returnOrigin, optional */ 720 ); 721 722 return static_SSTConvertErrorCode(nError); 723} 724 725SST_ERROR SST_EXPORT_API SSTEnumerationGetNext(SST_HANDLE hFileEnumeration, 726 SST_FILE_INFO** ppFileInfo) 727 728{ 729 TEEC_Session* pSession; 730 TEEC_Result nError; 731 TEEC_Operation sOperation; 732 uint32_t nReturnOrigin; 733 SST_FILE_INFO* pInfo = NULL; 734 char sFilename[SST_MAX_FILENAME]; 735 736 if (ppFileInfo==NULL) 737 { 738 return SST_ERROR_BAD_PARAMETERS; 739 } 740 741 pSession = static_SSTGetSession(); 742 if (pSession == NULL) 743 { 744 return SST_ERROR_GENERIC; 745 } 746 747 sOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE, TEEC_NONE); 748 sOperation.params[0].value.a = hFileEnumeration; 749 sOperation.params[1].tmpref.buffer = sFilename; 750 sOperation.params[1].tmpref.size = SST_MAX_FILENAME; 751 752 nError = TEEC_InvokeCommand(pSession, 753 SERVICE_SYSTEM_SST_ENUM_GETNEXT_COMMAND_ID, /* commandID */ 754 &sOperation, /* IN OUT operation */ 755 &nReturnOrigin /* OUT returnOrigin, optional */ 756 ); 757 758 if (nError == TEEC_SUCCESS) 759 { 760 if (sOperation.params[1].tmpref.size <= SST_MAX_FILENAME) 761 { 762 pInfo = (SST_FILE_INFO*)malloc(sizeof(SST_FILE_INFO)); 763 if (pInfo == NULL) 764 { 765 return SST_ERROR_OUT_OF_MEMORY; 766 } 767 pInfo->pName = (char*)malloc(sOperation.params[1].tmpref.size+1); 768 if (pInfo->pName == NULL) 769 { 770 free(pInfo); 771 return SST_ERROR_OUT_OF_MEMORY; 772 } 773 memcpy(pInfo->pName, sFilename, sOperation.params[1].tmpref.size); 774 /* Add zero terminator */ 775 pInfo->pName[sOperation.params[1].tmpref.size] = 0; 776 pInfo->nSize = sOperation.params[0].value.b; 777 } 778 } 779 *ppFileInfo = pInfo; 780 return static_SSTConvertErrorCode(nError); 781 } 782 783SST_ERROR SST_EXPORT_API SSTDestroyFileInfo(SST_FILE_INFO* pFileInfo) 784{ 785 TEEC_Session* pSession; 786 787 pSession = static_SSTGetSession(); 788 if (pSession == NULL) 789 { 790 return SST_ERROR_GENERIC; 791 } 792 793 if (pFileInfo != NULL) 794 { 795 free(pFileInfo->pName); 796 free(pFileInfo); 797 } 798 return SST_SUCCESS; 799} 800