BOOL FindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData) { WIN32_FILE_SEARCH* pFileSearch; if (!hFindFile) return FALSE; if (hFindFile == INVALID_HANDLE_VALUE) return FALSE; pFileSearch = (WIN32_FILE_SEARCH*) hFindFile; while ((pFileSearch->pDirent = readdir(pFileSearch->pDir)) != NULL) { if (FilePatternMatchA(pFileSearch->pDirent->d_name, pFileSearch->lpPattern)) { strcpy(lpFindFileData->cFileName, pFileSearch->pDirent->d_name); return TRUE; } } return FALSE; }
BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYTE InitialQuery, const char* path, wStream* output) { int length; BOOL ret; WCHAR* ent_path; struct STAT st; struct dirent* ent; DEBUG_SVC("path %s FsInformationClass %d InitialQuery %d", path, FsInformationClass, InitialQuery); if (!file->dir) { Stream_Write_UINT32(output, 0); /* Length */ Stream_Write_UINT8(output, 0); /* Padding */ return FALSE; } if (InitialQuery != 0) { rewinddir(file->dir); free(file->pattern); if (path[0]) file->pattern = _strdup(strrchr(path, '\\') + 1); else file->pattern = NULL; } if (file->pattern) { do { ent = readdir(file->dir); if (ent == NULL) continue; if (FilePatternMatchA(ent->d_name, file->pattern)) break; } while (ent); } else { ent = readdir(file->dir); } if (ent == NULL) { DEBUG_SVC(" pattern %s not found.", file->pattern); Stream_Write_UINT32(output, 0); /* Length */ Stream_Write_UINT8(output, 0); /* Padding */ return FALSE; } memset(&st, 0, sizeof(struct STAT)); ent_path = (WCHAR*) malloc(strlen(file->fullpath) + strlen(ent->d_name) + 2); sprintf((char*) ent_path, "%s/%s", file->fullpath, ent->d_name); if (STAT((char*) ent_path, &st) != 0) { DEBUG_WARN("stat %s failed. errno = %d", (char*) ent_path, errno); } DEBUG_SVC(" pattern %s matched %s", file->pattern, ent_path); free(ent_path); ent_path = NULL; length = ConvertToUnicode(CP_UTF8, 0, ent->d_name, -1, &ent_path, 0) * 2; ret = TRUE; switch (FsInformationClass) { case FileDirectoryInformation: /* http://msdn.microsoft.com/en-us/library/cc232097.aspx */ Stream_Write_UINT32(output, 64 + length); /* Length */ Stream_EnsureRemainingCapacity(output, 64 + length); Stream_Write_UINT32(output, 0); /* NextEntryOffset */ Stream_Write_UINT32(output, 0); /* FileIndex */ Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* CreationTime */ Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_atime)); /* LastAccessTime */ Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* LastWriteTime */ Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* ChangeTime */ Stream_Write_UINT64(output, st.st_size); /* EndOfFile */ Stream_Write_UINT64(output, st.st_size); /* AllocationSize */ Stream_Write_UINT32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */ Stream_Write_UINT32(output, length); /* FileNameLength */ Stream_Write(output, ent_path, length); break; case FileFullDirectoryInformation: /* http://msdn.microsoft.com/en-us/library/cc232068.aspx */ Stream_Write_UINT32(output, 68 + length); /* Length */ Stream_EnsureRemainingCapacity(output, 68 + length); Stream_Write_UINT32(output, 0); /* NextEntryOffset */ Stream_Write_UINT32(output, 0); /* FileIndex */ Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* CreationTime */ Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_atime)); /* LastAccessTime */ Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* LastWriteTime */ Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* ChangeTime */ Stream_Write_UINT64(output, st.st_size); /* EndOfFile */ Stream_Write_UINT64(output, st.st_size); /* AllocationSize */ Stream_Write_UINT32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */ Stream_Write_UINT32(output, length); /* FileNameLength */ Stream_Write_UINT32(output, 0); /* EaSize */ Stream_Write(output, ent_path, length); break; case FileBothDirectoryInformation: /* http://msdn.microsoft.com/en-us/library/cc232095.aspx */ Stream_Write_UINT32(output, 93 + length); /* Length */ Stream_EnsureRemainingCapacity(output, 93 + length); Stream_Write_UINT32(output, 0); /* NextEntryOffset */ Stream_Write_UINT32(output, 0); /* FileIndex */ Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* CreationTime */ Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_atime)); /* LastAccessTime */ Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* LastWriteTime */ Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* ChangeTime */ Stream_Write_UINT64(output, st.st_size); /* EndOfFile */ Stream_Write_UINT64(output, st.st_size); /* AllocationSize */ Stream_Write_UINT32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */ Stream_Write_UINT32(output, length); /* FileNameLength */ Stream_Write_UINT32(output, 0); /* EaSize */ Stream_Write_UINT8(output, 0); /* ShortNameLength */ /* Reserved(1), MUST NOT be added! */ Stream_Zero(output, 24); /* ShortName */ Stream_Write(output, ent_path, length); break; case FileNamesInformation: /* http://msdn.microsoft.com/en-us/library/cc232077.aspx */ Stream_Write_UINT32(output, 12 + length); /* Length */ Stream_EnsureRemainingCapacity(output, 12 + length); Stream_Write_UINT32(output, 0); /* NextEntryOffset */ Stream_Write_UINT32(output, 0); /* FileIndex */ Stream_Write_UINT32(output, length); /* FileNameLength */ Stream_Write(output, ent_path, length); break; default: Stream_Write_UINT32(output, 0); /* Length */ Stream_Write_UINT8(output, 0); /* Padding */ DEBUG_WARN("invalid FsInformationClass %d", FsInformationClass); ret = FALSE; break; } free(ent_path); return ret; }
HANDLE FindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData) { char* p; int index; int length; struct stat fileStat; WIN32_FILE_SEARCH* pFileSearch; ZeroMemory(lpFindFileData, sizeof(WIN32_FIND_DATAA)); pFileSearch = (WIN32_FILE_SEARCH*) malloc(sizeof(WIN32_FILE_SEARCH)); ZeroMemory(pFileSearch, sizeof(WIN32_FILE_SEARCH)); /* Separate lpFileName into path and pattern components */ p = strrchr(lpFileName, '/'); if (!p) p = strrchr(lpFileName, '\\'); index = (p - lpFileName); length = (p - lpFileName); pFileSearch->lpPath = (LPSTR) malloc(length + 1); CopyMemory(pFileSearch->lpPath, lpFileName, length); pFileSearch->lpPath[length] = '\0'; length = strlen(lpFileName) - index; pFileSearch->lpPattern = (LPSTR) malloc(length + 1); CopyMemory(pFileSearch->lpPattern, &lpFileName[index + 1], length); pFileSearch->lpPattern[length] = '\0'; /* Check if the path is a directory */ if (lstat(pFileSearch->lpPath, &fileStat) < 0) { free(pFileSearch); return INVALID_HANDLE_VALUE; /* stat error */ } if (S_ISDIR(fileStat.st_mode) == 0) { free(pFileSearch); return INVALID_HANDLE_VALUE; /* not a directory */ } /* Open directory for reading */ pFileSearch->pDir = opendir(pFileSearch->lpPath); if (!pFileSearch->pDir) { free(pFileSearch); return INVALID_HANDLE_VALUE; /* failed to open directory */ } while ((pFileSearch->pDirent = readdir(pFileSearch->pDir)) != NULL) { if ((strcmp(pFileSearch->pDirent->d_name, ".") == 0) || (strcmp(pFileSearch->pDirent->d_name, "..") == 0)) { /* skip "." and ".." */ continue; } if (FilePatternMatchA(pFileSearch->pDirent->d_name, pFileSearch->lpPattern)) { strcpy(lpFindFileData->cFileName, pFileSearch->pDirent->d_name); return (HANDLE) pFileSearch; } } return INVALID_HANDLE_VALUE; }
int TestFilePatternMatch(int argc, char* argv[]) { /* '*' expression */ if (!FilePatternMatchA("document.txt", "*")) { printf("FilePatternMatchA error: FileName: %s Pattern: %s\n", "document.txt", "*"); return -1; } /* '*X' expression */ if (!FilePatternMatchA("document.txt", "*.txt")) { printf("FilePatternMatchA error: FileName: %s Pattern: %s\n", "document.txt", "*.txt"); return -1; } if (FilePatternMatchA("document.docx", "*.txt")) { printf("FilePatternMatchA error: FileName: %s Pattern: %s\n", "document.docx", "*.txt"); return -1; } if (FilePatternMatchA("document.txt.bak", "*.txt")) { printf("FilePatternMatchA error: FileName: %s Pattern: %s\n", "document.txt.bak", "*.txt"); return -1; } if (FilePatternMatchA("bak", "*.txt")) { printf("FilePatternMatchA error: FileName: %s Pattern: %s\n", "bak", "*.txt"); return -1; } /* 'X*' expression */ if (!FilePatternMatchA("document.txt", "document.*")) { printf("FilePatternMatchA error: FileName: %s Pattern: %s\n", "document.txt", "document.*"); return -1; } /* 'X?' expression */ if (!FilePatternMatchA("document.docx", "document.doc?")) { printf("FilePatternMatchA error: FileName: %s Pattern: %s\n", "document.docx", "document.doc?"); return -1; } if (FilePatternMatchA("document.doc", "document.doc?")) { printf("FilePatternMatchA error: FileName: %s Pattern: %s\n", "document.doc", "document.doc?"); return -1; } /* no wildcards expression */ if (!FilePatternMatchA("document.txt", "document.txt")) { printf("FilePatternMatchA error: FileName: %s Pattern: %s\n", "document.txt", "document.txt"); return -1; } /* 'X * Y' expression */ if (!FilePatternMatchA("X123Y.txt", "X*Y.txt")) { printf("FilePatternMatchA error: FileName: %s Pattern: %s\n", "X123Y.txt", "X*Y.txt"); return -1; } if (!FilePatternMatchA("XY.txt", "X*Y.txt")) { printf("FilePatternMatchA error: FileName: %s Pattern: %s\n", "XY.txt", "X*Y.txt"); return -1; } if (FilePatternMatchA("XZ.txt", "X*Y.txt")) { printf("FilePatternMatchA error: FileName: %s Pattern: %s\n", "XZ.txt", "X*Y.txt"); return -1; } if (FilePatternMatchA("X123Z.txt", "X*Y.txt")) { printf("FilePatternMatchA error: FileName: %s Pattern: %s\n", "X123Z.txt", "X*Y.txt"); return -1; } /* 'X * Y * Z' expression */ if (!FilePatternMatchA("X123Y456Z.txt", "X*Y*Z.txt")) { printf("FilePatternMatchA error: FileName: %s Pattern: %s\n", "X123Y456Z.txt", "X*Y*Z.txt"); return -1; } if (!FilePatternMatchA("XYZ.txt", "X*Y*Z.txt")) { printf("FilePatternMatchA error: FileName: %s Pattern: %s\n", "XYZ.txt", "X*Y*Z.txt"); return -1; } if (!FilePatternMatchA("X123Y456W.txt", "X*Y*Z.txt")) { printf("FilePatternMatchA error: FileName: %s Pattern: %s\n", "X123Y456W.txt", "X*Y*Z.txt"); return -1; } if (!FilePatternMatchA("XYW.txt", "X*Y*Z.txt")) { printf("FilePatternMatchA error: FileName: %s Pattern: %s\n", "XYW.txt", "X*Y*Z.txt"); return -1; } /* 'X ? Y' expression */ if (!FilePatternMatchA("X1Y.txt", "X?Y.txt")) { printf("FilePatternMatchA error: FileName: %s Pattern: %s\n", "X1Y.txt", "X?Y.txt"); return -1; } if (FilePatternMatchA("XY.txt", "X?Y.txt")) { printf("FilePatternMatchA error: FileName: %s Pattern: %s\n", "XY.txt", "X?Y.txt"); return -1; } if (FilePatternMatchA("XZ.txt", "X?Y.txt")) { printf("FilePatternMatchA error: FileName: %s Pattern: %s\n", "XZ.txt", "X?Y.txt"); return -1; } if (FilePatternMatchA("X123Z.txt", "X?Y.txt")) { printf("FilePatternMatchA error: FileName: %s Pattern: %s\n", "X123Z.txt", "X?Y.txt"); return -1; } /* 'X ? Y ? Z' expression */ if (!FilePatternMatchA("X123Y456Z.txt", "X?Y?Z.txt")) { printf("FilePatternMatchA error: FileName: %s Pattern: %s\n", "X123Y456Z.txt", "X?Y?Z.txt"); return -1; } if (FilePatternMatchA("XYZ.txt", "X?Y?Z.txt")) { printf("FilePatternMatchA error: FileName: %s Pattern: %s\n", "XYZ.txt", "X?Y?Z.txt"); return -1; } if (!FilePatternMatchA("X123Y456W.txt", "X?Y?Z.txt")) { printf("FilePatternMatchA error: FileName: %s Pattern: %s\n", "X123Y456W.txt", "X?Y?Z.txt"); return -1; } if (FilePatternMatchA("XYW.txt", "X?Y?Z.txt")) { printf("FilePatternMatchA error: FileName: %s Pattern: %s\n", "XYW.txt", "X?Y?Z.txt"); return -1; } return 0; }