| 41 | }; |
| 42 | |
| 43 | cbm_dir_t *cbm_opendir(const char *path) { |
| 44 | if (!path) { |
| 45 | return NULL; |
| 46 | } |
| 47 | wchar_t *wpath = cbm_path_to_wide(path); |
| 48 | if (!wpath) { |
| 49 | return NULL; |
| 50 | } |
| 51 | |
| 52 | size_t wlen = wcslen(wpath); |
| 53 | if (wlen == 0 || wlen + 2 >= CBM_PATH_MAX) { |
| 54 | free(wpath); |
| 55 | return NULL; |
| 56 | } |
| 57 | |
| 58 | cbm_dir_t *d = (cbm_dir_t *)calloc(CBM_ALLOC_ONE, sizeof(cbm_dir_t)); |
| 59 | if (!d) { |
| 60 | free(wpath); |
| 61 | return NULL; |
| 62 | } |
| 63 | |
| 64 | wmemcpy(d->wide_pattern, wpath, wlen + 1); |
| 65 | wchar_t *p = d->wide_pattern + wlen - SKIP_ONE; |
| 66 | if (*p != L'\\' && *p != L'/') { |
| 67 | ++p; |
| 68 | *p++ = L'\\'; |
| 69 | } else { |
| 70 | ++p; |
| 71 | } |
| 72 | *p++ = L'*'; |
| 73 | *p = L'\0'; |
| 74 | free(wpath); |
| 75 | |
| 76 | d->find_handle = FindFirstFileW(d->wide_pattern, &d->find_data); |
| 77 | if (d->find_handle == INVALID_HANDLE_VALUE) { |
| 78 | free(d); |
| 79 | return NULL; |
| 80 | } |
| 81 | d->first = true; |
| 82 | d->done = false; |
| 83 | return d; |
| 84 | } |
| 85 | |
| 86 | cbm_dirent_t *cbm_readdir(cbm_dir_t *d) { |
| 87 | if (!d || d->done) { |