diff a/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.c b/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.c
|
a
|
b
|
sfprov_readdir(
|
| 623 | 623 | SHFLSTRING *mask_str = NULL; /* must be path with "/*" appended */ |
| 624 | 624 | int mask_size; |
| 625 | 625 | sfp_file_t *fp; |
| 626 | | static char infobuff[2 * MAXNAMELEN]; /* not on stack!! */ |
| 627 | | SHFLDIRINFO *info = (SHFLDIRINFO *)&infobuff; |
| | 626 | uint32_t infobuff_alloc = 16384; |
| | 627 | SHFLDIRINFO *infobuff = NULL, *info; |
| 628 | 628 | uint32_t numbytes; |
| 629 | | uint32_t justone; |
| | 629 | uint32_t nents; |
| | 630 | uint32_t size; |
| 630 | 631 | uint32_t cnt; |
| 631 | 632 | sffs_dirents_t *cur_buf; |
| 632 | 633 | struct dirent64 *dirent; |
| … |
… |
sfprov_readdir(
|
| 666 | 667 | kmem_free(cp, len); |
| 667 | 668 | |
| 668 | 669 | /* |
| 669 | | * Now loop using vboxCallDirInfo to get one file name at a time |
| | 670 | * Now loop using vboxCallDirInfo |
| 670 | 671 | */ |
| | 672 | infobuff = kmem_alloc(infobuff_alloc, KM_SLEEP); |
| | 673 | if (infobuff == NULL) { |
| | 674 | error = (ENOSPC); |
| | 675 | goto done; |
| | 676 | } |
| | 677 | |
| 671 | 678 | cnt = 0; |
| 672 | 679 | for (;;) { |
| 673 | | justone = 1; |
| 674 | | numbytes = sizeof (infobuff); |
| | 680 | numbytes = infobuff_alloc; |
| 675 | 681 | error = vboxCallDirInfo(&vbox_client, &fp->map, fp->handle, |
| 676 | | mask_str, SHFL_LIST_RETURN_ONE, 0, &numbytes, info, |
| 677 | | &justone); |
| 678 | | if (error == VERR_NO_MORE_FILES) { |
| 679 | | break; |
| 680 | | } |
| 681 | | else if (error == VERR_NO_TRANSLATION) { |
| 682 | | continue; /* ?? just skip this one */ |
| 683 | | } |
| 684 | | else if (error != VINF_SUCCESS || justone != 1) { |
| 685 | | error = EINVAL; |
| 686 | | goto done; |
| | 682 | mask_str, 0, 0, &numbytes, infobuff, &nents); |
| | 683 | switch (error) { |
| | 684 | case VINF_SUCCESS: |
| | 685 | /* fallthrough */ |
| | 686 | case VERR_NO_MORE_FILES: |
| | 687 | break; |
| | 688 | |
| | 689 | case VERR_NO_TRANSLATION: |
| | 690 | /* XXX ??? */ |
| | 691 | break; |
| | 692 | |
| | 693 | default: |
| | 694 | error = RTErrConvertToErrno(error); |
| | 695 | goto done; |
| 687 | 696 | } |
| 688 | 697 | |
| 689 | 698 | /* |
| 690 | | * Put this name in the buffer, expand if we run out of room. |
| | 699 | * Create the dirent_t's for each name |
| 691 | 700 | */ |
| 692 | | reclen = DIRENT64_RECLEN(strlen(info->name.String.utf8)); |
| 693 | | if (SFFS_DIRENTS_OFF + cur_buf->sf_len + reclen > SFFS_DIRENTS_SIZE) { |
| 694 | | cur_buf->sf_next = kmem_alloc(SFFS_DIRENTS_SIZE, KM_SLEEP); |
| 695 | | if (cur_buf->sf_next == NULL) { |
| 696 | | error = ENOSPC; |
| 697 | | goto done; |
| | 701 | for (info = infobuff; (char *) info < (char *) infobuff + numbytes; nents--) { |
| | 702 | /* expand buffer if we need more space */ |
| | 703 | reclen = DIRENT64_RECLEN(strlen(info->name.String.utf8)); |
| | 704 | if (SFFS_DIRENTS_OFF + cur_buf->sf_len + reclen > SFFS_DIRENTS_SIZE) { |
| | 705 | cur_buf->sf_next = kmem_alloc(SFFS_DIRENTS_SIZE, KM_SLEEP); |
| | 706 | if (cur_buf->sf_next == NULL) { |
| | 707 | error = ENOSPC; |
| | 708 | goto done; |
| | 709 | } |
| | 710 | cur_buf = cur_buf->sf_next; |
| | 711 | cur_buf->sf_next = NULL; |
| | 712 | cur_buf->sf_len = 0; |
| 698 | 713 | } |
| 699 | | cur_buf = cur_buf->sf_next; |
| 700 | | cur_buf->sf_next = NULL; |
| 701 | | cur_buf->sf_len = 0; |
| 702 | | } |
| 703 | 714 | |
| 704 | | dirent = (dirent64_t *) |
| 705 | | (((char *) &cur_buf->sf_entries[0]) + cur_buf->sf_len); |
| 706 | | strcpy(&dirent->d_name[0], info->name.String.utf8); |
| 707 | | dirent->d_reclen = reclen; |
| 708 | | dirent->d_off = cnt; |
| | 715 | /* create the dirent with the name, offset, and len */ |
| | 716 | dirent = (dirent64_t *) |
| | 717 | (((char *) &cur_buf->sf_entries[0]) + cur_buf->sf_len); |
| | 718 | strcpy(&dirent->d_name[0], info->name.String.utf8); |
| | 719 | dirent->d_reclen = reclen; |
| | 720 | dirent->d_off = cnt; |
| | 721 | |
| | 722 | cur_buf->sf_len += reclen; |
| | 723 | ++cnt; |
| 709 | 724 | |
| 710 | | cur_buf->sf_len += reclen; |
| 711 | | ++cnt; |
| | 725 | size = offsetof (SHFLDIRINFO, name.String) + info->name.u16Size; |
| | 726 | info = (SHFLDIRINFO *) ((uintptr_t) info + size); |
| | 727 | } |
| | 728 | ASSERT(nents == 0); |
| | 729 | ASSERT((char *) info == (char *) infobuff + numbytes); |
| | 730 | |
| | 731 | if (error == VERR_NO_MORE_FILES) |
| | 732 | break; |
| 712 | 733 | } |
| 713 | 734 | error = 0; |
| 714 | 735 | |
| … |
… |
done:
|
| 720 | 741 | *dirents = cur_buf; |
| 721 | 742 | } |
| 722 | 743 | } |
| | 744 | if (infobuff != NULL) |
| | 745 | kmem_free(infobuff, infobuff_alloc); |
| 723 | 746 | if (mask_str != NULL) |
| 724 | 747 | kmem_free(mask_str, mask_size); |
| 725 | 748 | sfprov_close(fp); |