+
+
+#if DEPLOYMENT_TARGET_WINDOWS
+ // This is a replacement for 'dirent' below, and also uses wchar_t to support unicode paths
+ wchar_t extBuff[CFMaxPathSize];
+
+ if (extLen > 0) {
+ CFStringGetBytes(extension, CFRangeMake(0, extLen), kCFStringEncodingUTF16, 0, false, (uint8_t *)extBuff, CFMaxPathLength, &extLen);
+ extBuff[extLen] = '\0';
+ }
+
+ wchar_t pathBuf[CFMaxPathSize];
+
+ if (!dirPath) {
+ if (!_CFURLGetWideFileSystemRepresentation(dirURL, true, pathBuf, CFMaxPathLength)) {
+ if (extension) CFRelease(extension);
+ return NULL;
+ }
+
+ pathLength = wcslen(pathBuf);
+
+ } else {
+ // Convert dirPath to a wide representation and put it into our pathBuf
+ // Get the real length of the string in UTF16 characters
+ CFStringRef dirPathStr = CFStringCreateWithCString(kCFAllocatorSystemDefault, dirPath, kCFStringEncodingUTF8);
+ CFIndex strLen = CFStringGetLength(dirPathStr);
+
+ // Copy the string into the buffer and terminate
+ CFStringGetCharacters(dirPathStr, CFRangeMake(0, strLen), (UniChar *)pathBuf);
+ pathBuf[strLen] = 0;
+
+ CFRelease(dirPathStr);
+ }
+
+ WIN32_FIND_DATAW file;
+ HANDLE handle;
+
+ if (pathLength + 2 >= CFMaxPathLength) {
+ if (extension) {
+ CFRelease(extension);
+ }
+ return NULL;
+ }
+
+ pathBuf[pathLength] = '\\';
+ pathBuf[pathLength + 1] = '*';
+ pathBuf[pathLength + 2] = '\0';
+ handle = FindFirstFileW(pathBuf, (LPWIN32_FIND_DATAW)&file);
+ if (INVALID_HANDLE_VALUE == handle) {
+ pathBuf[pathLength] = '\0';
+ if (extension) {
+ CFRelease(extension);
+ }
+ return NULL;
+ }
+
+ files = CFArrayCreateMutable(alloc, 0, &kCFTypeArrayCallBacks);
+
+ do {
+ CFURLRef fileURL;
+ CFIndex namelen = wcslen(file.cFileName);
+ if (file.cFileName[0] == '.' && (namelen == 1 || (namelen == 2 && file.cFileName[1] == '.'))) {
+ continue;
+ }
+
+ if (extLen > namelen) continue; // if the extension is the same length or longer than the name, it can't possibly match.
+
+ if (extLen > 0) {
+ // Check to see if it matches the extension we're looking for.
+ if (_wcsicmp(&(file.cFileName[namelen - extLen]), (const wchar_t *)extBuff) != 0) {
+ continue;
+ }
+ }
+ if (dirURL == NULL) {
+ CFStringRef dirURLStr = CFStringCreateWithBytes(alloc, (const uint8_t *)pathBuf, pathLength, kCFStringEncodingUTF16, NO);
+ dirURL = CFURLCreateWithFileSystemPath(alloc, dirURLStr, kCFURLWindowsPathStyle, true);
+ CFRelease(dirURLStr);
+ releaseBase = true;
+ }
+ // MF:!!! What about the trailing slash?
+ CFStringRef fileURLStr = CFStringCreateWithBytes(alloc, (const uint8_t *)file.cFileName, namelen, kCFStringEncodingUTF16, NO);
+ fileURL = CFURLCreateWithFileSystemPathRelativeToBase(alloc, fileURLStr, kCFURLWindowsPathStyle, (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? true : false, dirURL);
+ CFArrayAppendValue(files, fileURL);
+ CFRelease(fileURL);
+ CFRelease(fileURLStr);
+ } while (FindNextFileW(handle, &file));
+ FindClose(handle);
+ pathBuf[pathLength] = '\0';
+
+#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD