1 // 2 // 3 // Copyright 2023 gRPC authors. 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 // 17 // 18 19 #include <grpc/support/port_platform.h> 20 21 #if defined(GPR_WINDOWS) 22 23 #include <sys/stat.h> 24 #include <windows.h> 25 26 #include <string> 27 #include <vector> 28 29 #include "absl/status/statusor.h" 30 #include "absl/strings/str_cat.h" 31 #include "absl/strings/string_view.h" 32 33 #include <grpc/support/log.h> 34 35 #include "src/core/lib/gprpp/directory_reader.h" 36 namespace grpc_core { 37 38 namespace { 39 const char kSkipEntriesSelf[] = "."; 40 const char kSkipEntriesParent[] = ".."; 41 } // namespace 42 43 class DirectoryReaderImpl : public DirectoryReader { 44 public: DirectoryReaderImpl(absl::string_view directory_path)45 explicit DirectoryReaderImpl(absl::string_view directory_path) 46 : directory_path_(directory_path) {} Name() const47 absl::string_view Name() const override { return directory_path_; } 48 absl::Status ForEach(absl::FunctionRef<void(absl::string_view)>) override; 49 50 private: 51 const std::string directory_path_; 52 }; 53 MakeDirectoryReader(absl::string_view filename)54std::unique_ptr<DirectoryReader> MakeDirectoryReader( 55 absl::string_view filename) { 56 return std::make_unique<DirectoryReaderImpl>(filename); 57 } 58 59 // Reference for reading directory in Windows: 60 // https://stackoverflow.com/questions/612097/how-can-i-get-the-list-of-files-in-a-directory-using-c-or-c 61 // https://learn.microsoft.com/en-us/windows/win32/fileio/listing-the-files-in-a-directory ForEach(absl::FunctionRef<void (absl::string_view)> callback)62absl::Status DirectoryReaderImpl::ForEach( 63 absl::FunctionRef<void(absl::string_view)> callback) { 64 std::string search_path = absl::StrCat(directory_path_, "/*"); 65 WIN32_FIND_DATAA find_data; 66 HANDLE hFind = ::FindFirstFileA(search_path.c_str(), &find_data); 67 if (hFind == INVALID_HANDLE_VALUE) { 68 return absl::InternalError("Could not read crl directory."); 69 } 70 do { 71 if (!(find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { 72 callback(find_data.cFileName); 73 } 74 } while (::FindNextFileA(hFind, &find_data)); 75 ::FindClose(hFind); 76 return absl::OkStatus(); 77 } 78 79 } // namespace grpc_core 80 81 #endif // GPR_WINDOWS 82