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 #include "src/core/util/directory_reader.h" 33 34 namespace grpc_core { 35 36 namespace { 37 const char kSkipEntriesSelf[] = "."; 38 const char kSkipEntriesParent[] = ".."; 39 } // namespace 40 41 class DirectoryReaderImpl : public DirectoryReader { 42 public: DirectoryReaderImpl(absl::string_view directory_path)43 explicit DirectoryReaderImpl(absl::string_view directory_path) 44 : directory_path_(directory_path) {} Name() const45 absl::string_view Name() const override { return directory_path_; } 46 absl::Status ForEach(absl::FunctionRef<void(absl::string_view)>) override; 47 48 private: 49 const std::string directory_path_; 50 }; 51 MakeDirectoryReader(absl::string_view filename)52std::unique_ptr<DirectoryReader> MakeDirectoryReader( 53 absl::string_view filename) { 54 return std::make_unique<DirectoryReaderImpl>(filename); 55 } 56 57 // Reference for reading directory in Windows: 58 // https://stackoverflow.com/questions/612097/how-can-i-get-the-list-of-files-in-a-directory-using-c-or-c 59 // https://learn.microsoft.com/en-us/windows/win32/fileio/listing-the-files-in-a-directory ForEach(absl::FunctionRef<void (absl::string_view)> callback)60absl::Status DirectoryReaderImpl::ForEach( 61 absl::FunctionRef<void(absl::string_view)> callback) { 62 std::string search_path = absl::StrCat(directory_path_, "/*"); 63 WIN32_FIND_DATAA find_data; 64 HANDLE hFind = ::FindFirstFileA(search_path.c_str(), &find_data); 65 if (hFind == INVALID_HANDLE_VALUE) { 66 return absl::InternalError("Could not read crl directory."); 67 } 68 do { 69 if (!(find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { 70 callback(find_data.cFileName); 71 } 72 } while (::FindNextFileA(hFind, &find_data)); 73 ::FindClose(hFind); 74 return absl::OkStatus(); 75 } 76 77 } // namespace grpc_core 78 79 #endif // GPR_WINDOWS 80