| 84 | } |
| 85 | |
| 86 | cbm_dirent_t *cbm_readdir(cbm_dir_t *d) { |
| 87 | if (!d || d->done) { |
| 88 | return NULL; |
| 89 | } |
| 90 | if (!d->first) { |
| 91 | if (!FindNextFileW(d->find_handle, &d->find_data)) { |
| 92 | d->done = true; |
| 93 | return NULL; |
| 94 | } |
| 95 | } |
| 96 | d->first = false; |
| 97 | |
| 98 | while (d->find_data.cFileName[0] == L'.' && |
| 99 | (d->find_data.cFileName[1] == L'\0' || |
| 100 | (d->find_data.cFileName[1] == L'.' && d->find_data.cFileName[2] == L'\0'))) { |
| 101 | if (!FindNextFileW(d->find_handle, &d->find_data)) { |
| 102 | d->done = true; |
| 103 | return NULL; |
| 104 | } |
| 105 | } |
| 106 | |
| 107 | char *u8 = cbm_wide_to_utf8(d->find_data.cFileName); |
| 108 | if (!u8) { |
| 109 | d->done = true; |
| 110 | return NULL; |
| 111 | } |
| 112 | size_t nlen = strlen(u8); |
| 113 | if (nlen >= CBM_DIRENT_NAME_MAX) { |
| 114 | nlen = CBM_DIRENT_NAME_MAX - SKIP_ONE; |
| 115 | } |
| 116 | memcpy(d->entry.name, u8, nlen); |
| 117 | d->entry.name[nlen] = '\0'; |
| 118 | free(u8); |
| 119 | d->entry.is_dir = (d->find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; |
| 120 | d->entry.d_type = 0; |
| 121 | return &d->entry; |
| 122 | } |
| 123 | |
| 124 | int cbm_path_info_utf8(const char *path, cbm_path_info_t *out) { |
| 125 | if (!path || !out) { |