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