+static int cstr2wstr(wchar_t *dst, const char *src)\r
+{\r
+ int i, len;\r
+ for (i = len = strlen(src); i >= 0; i--)\r
+ dst[i] = src[i];\r
+ return len;\r
+}\r
+\r
+static void wstr2cstr(char *dst, const wchar_t *src)\r
+{\r
+ int i;\r
+ for (i = wcslen(src); i >= 0; i--)\r
+ dst[i] = src[i];\r
+}\r
+\r
+static int my_scandir(const char *dir, struct my_dirent ***namelist_out,\r
+ int(*filter)(const struct my_dirent *),\r
+ int(*compar)(const void *, const void *))\r
+{\r
+ wchar_t *wdir;\r
+ int i, len, ret = -1, name_alloc = 4, name_count = 0;\r
+ struct my_dirent **namelist = NULL, *ent;\r
+ WIN32_FIND_DATA finddata;\r
+ HANDLE fh = INVALID_HANDLE_VALUE;\r
+ BOOL bRet;\r
+\r
+ wdir = malloc(sizeof(wdir[0]) * MAX_PATH);\r
+ if (wdir == NULL) { lprintf_al("%s:%i: OOM\n", __FILE__, __LINE__); goto fail; }\r
+\r
+ namelist = malloc(sizeof(*namelist) * name_alloc);\r
+ if (namelist == NULL) { lprintf_al("%s:%i: OOM\n", __FILE__, __LINE__); goto fail; }\r
+\r
+ // try to read first..\r
+ len = cstr2wstr(wdir, dir);\r
+ for (i = 0; i < len; i++)\r
+ if (wdir[i] == '/') wdir[i] = '\\';\r
+ if (wdir[len-1] != '\\') wdir[len++] = '\\';\r
+ wdir[len++] = '*';\r
+ wdir[len++] = 0;\r
+ /*if (wdir[len-1] == '\\') wdir[len-1] = 0;*/\r
+\r
+ bRet = 1;\r
+ fh = FindFirstFile(wdir, &finddata);\r
+ if (fh == INVALID_HANDLE_VALUE)\r
+ {\r
+ if (GetLastError() != ERROR_NO_MORE_FILES)\r
+ {\r
+ lprintf("FindFirstFile(\"%s\") failed with %lu\n", dir, GetLastError());\r
+ goto fail;\r
+ }\r
+ bRet = 0;\r
+ }\r
+\r
+ // add "." and ".."\r
+ ent = malloc(sizeof(*ent) + 3);\r
+ ent->d_type = DT_DIR; strcpy(ent->d_name, ".");\r
+ namelist[name_count++] = ent;\r
+ ent = malloc(sizeof(*ent) + 3);\r
+ ent->d_type = DT_DIR; strcpy(ent->d_name, "..");\r
+ namelist[name_count++] = ent;\r
+\r
+ while (bRet)\r
+ {\r
+ ent = malloc(sizeof(*ent) + wcslen(finddata.cFileName) + 1);\r
+ ent->d_type = (finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? DT_DIR : DT_REG;\r
+ wstr2cstr(ent->d_name, finddata.cFileName);\r
+ if (filter == NULL || filter(ent))\r
+ namelist[name_count++] = ent;\r
+ else free(ent);\r
+\r
+ if (name_count >= name_alloc)\r
+ {\r
+ void *tmp;\r
+ name_alloc *= 2;\r
+ tmp = realloc(namelist, sizeof(*namelist) * name_alloc);\r
+ if (tmp == NULL) { lprintf_al("%s:%i: OOM\n", __FILE__, __LINE__); goto fail; }\r
+ namelist = tmp;\r
+ }\r
+\r
+ bRet = FindNextFile(fh, &finddata);\r
+ }\r
+\r
+ // sort\r
+ if (compar != NULL && name_count > 3) qsort(&namelist[2], name_count - 2, sizeof(namelist[0]), compar);\r
+\r
+ // all done.\r
+ ret = name_count;\r
+ *namelist_out = namelist;\r
+ goto end;\r
+\r
+fail:\r
+ if (namelist != NULL)\r
+ {\r
+ while (name_count--)\r
+ free(namelist[name_count]);\r
+ free(namelist);\r
+ }\r
+end:\r
+ if (fh != INVALID_HANDLE_VALUE) FindClose(fh);\r
+ if (wdir != NULL) free(wdir);\r
+ return ret;\r
+}\r
+\r
+\r