@cetapod/react-native-smb 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +72 -0
  3. package/ReactNativeSmb.podspec +59 -0
  4. package/cpp/ios/OnLoad.mm +24 -0
  5. package/cpp/shared/HybridSMB.cpp +324 -0
  6. package/cpp/shared/HybridSMB.hpp +102 -0
  7. package/cpp/shared/ReactNativeSmb.hpp +428 -0
  8. package/cpp/shared/connection/ContextRequest.hpp +27 -0
  9. package/cpp/shared/connection/ContextRequestQueue.cpp +85 -0
  10. package/cpp/shared/connection/ContextRequestQueue.hpp +28 -0
  11. package/cpp/shared/connection/MetadataContextLease.hpp +33 -0
  12. package/cpp/shared/connection/PoolContextHandle.cpp +35 -0
  13. package/cpp/shared/connection/PoolContextHandle.hpp +44 -0
  14. package/cpp/shared/connection/PoolSlot.cpp +73 -0
  15. package/cpp/shared/connection/PoolSlot.hpp +46 -0
  16. package/cpp/shared/connection/PoolTypes.hpp +41 -0
  17. package/cpp/shared/connection/SmbConnection.cpp +385 -0
  18. package/cpp/shared/connection/SmbConnection.hpp +93 -0
  19. package/cpp/shared/connection/SmbConnectionPool.cpp +316 -0
  20. package/cpp/shared/connection/SmbConnectionPool.hpp +84 -0
  21. package/cpp/shared/core/CancellationToken.hpp +22 -0
  22. package/cpp/shared/core/OperatorContext.hpp +24 -0
  23. package/cpp/shared/core/SmbEnums.hpp +126 -0
  24. package/cpp/shared/core/SmbTask.cpp +131 -0
  25. package/cpp/shared/core/SmbTask.hpp +52 -0
  26. package/cpp/shared/core/SmbTaskCore.cpp +222 -0
  27. package/cpp/shared/core/SmbTaskCore.hpp +107 -0
  28. package/cpp/shared/core/SmbTypes.hpp +35 -0
  29. package/cpp/shared/core/TaskObserverHub.cpp +166 -0
  30. package/cpp/shared/core/TaskObserverHub.hpp +66 -0
  31. package/cpp/shared/core/TaskSnapshotCodec.cpp +32 -0
  32. package/cpp/shared/core/TaskSnapshotCodec.hpp +41 -0
  33. package/cpp/shared/io/SmbCopyTree.hpp +114 -0
  34. package/cpp/shared/io/SmbDirScan.hpp +80 -0
  35. package/cpp/shared/io/SmbFileIO.cpp +1355 -0
  36. package/cpp/shared/io/SmbFileIO.hpp +45 -0
  37. package/cpp/shared/io/SmbPathUtil.hpp +75 -0
  38. package/cpp/shared/io/SmbSecurity.cpp +308 -0
  39. package/cpp/shared/io/SmbSecurity.hpp +32 -0
  40. package/cpp/shared/io/SmbTreeOps.hpp +112 -0
  41. package/cpp/shared/operators/Operator.hpp +35 -0
  42. package/cpp/shared/operators/OperatorBase.cpp +57 -0
  43. package/cpp/shared/operators/OperatorBase.hpp +57 -0
  44. package/cpp/shared/operators/connection/ConnectOperator.cpp +19 -0
  45. package/cpp/shared/operators/connection/ConnectOperator.hpp +22 -0
  46. package/cpp/shared/operators/connection/ConnectShareOperator.cpp +19 -0
  47. package/cpp/shared/operators/connection/ConnectShareOperator.hpp +21 -0
  48. package/cpp/shared/operators/connection/DisconnectOperator.cpp +12 -0
  49. package/cpp/shared/operators/connection/DisconnectOperator.hpp +15 -0
  50. package/cpp/shared/operators/connection/InitializeOperator.cpp +12 -0
  51. package/cpp/shared/operators/connection/InitializeOperator.hpp +22 -0
  52. package/cpp/shared/operators/connection/ListSharesOperator.cpp +13 -0
  53. package/cpp/shared/operators/connection/ListSharesOperator.hpp +18 -0
  54. package/cpp/shared/operators/listing/GetPathInfoOperator.cpp +43 -0
  55. package/cpp/shared/operators/listing/GetPathInfoOperator.hpp +21 -0
  56. package/cpp/shared/operators/listing/GetSecurityDescriptorOperator.cpp +202 -0
  57. package/cpp/shared/operators/listing/GetSecurityDescriptorOperator.hpp +22 -0
  58. package/cpp/shared/operators/listing/ListDirectoryOperator.cpp +20 -0
  59. package/cpp/shared/operators/listing/ListDirectoryOperator.hpp +24 -0
  60. package/cpp/shared/operators/mutate/CopyItemOperator.cpp +19 -0
  61. package/cpp/shared/operators/mutate/CopyItemOperator.hpp +25 -0
  62. package/cpp/shared/operators/mutate/CreateDirectoryOperator.cpp +28 -0
  63. package/cpp/shared/operators/mutate/CreateDirectoryOperator.hpp +20 -0
  64. package/cpp/shared/operators/mutate/DeleteItemOperator.cpp +96 -0
  65. package/cpp/shared/operators/mutate/DeleteItemOperator.hpp +23 -0
  66. package/cpp/shared/operators/mutate/DuplicateItemOperator.cpp +48 -0
  67. package/cpp/shared/operators/mutate/DuplicateItemOperator.hpp +23 -0
  68. package/cpp/shared/operators/mutate/MoveItemOperator.cpp +32 -0
  69. package/cpp/shared/operators/mutate/MoveItemOperator.hpp +21 -0
  70. package/cpp/shared/operators/mutate/RenameItemOperator.cpp +37 -0
  71. package/cpp/shared/operators/mutate/RenameItemOperator.hpp +21 -0
  72. package/cpp/shared/operators/transfer/DownloadFileOperator.cpp +31 -0
  73. package/cpp/shared/operators/transfer/DownloadFileOperator.hpp +21 -0
  74. package/cpp/shared/operators/transfer/UploadFileOperator.cpp +27 -0
  75. package/cpp/shared/operators/transfer/UploadFileOperator.hpp +21 -0
  76. package/cpp/shared/util/SmbErrorMapper.hpp +229 -0
  77. package/cpp/shared/util/SmbLog.hpp +20 -0
  78. package/docs/API.md +105 -0
  79. package/docs/ARCHITECTURE.md +70 -0
  80. package/docs/TASK_MODEL.md +149 -0
  81. package/ios/include/smb2/libsmb2-dcerpc-lsa.h +172 -0
  82. package/ios/include/smb2/libsmb2-dcerpc-srvsvc.h +180 -0
  83. package/ios/include/smb2/libsmb2-dcerpc.h +155 -0
  84. package/ios/include/smb2/libsmb2-raw.h +497 -0
  85. package/ios/include/smb2/libsmb2.h +1384 -0
  86. package/ios/include/smb2/smb2-errors.h +549 -0
  87. package/ios/include/smb2/smb2.h +1251 -0
  88. package/ios/libs/device/libsmb2-device.a +0 -0
  89. package/ios/libs/libsmb2.xcframework/Info.plist +48 -0
  90. package/ios/libs/libsmb2.xcframework/ios-arm64/Headers/smb2/libsmb2-dcerpc-lsa.h +172 -0
  91. package/ios/libs/libsmb2.xcframework/ios-arm64/Headers/smb2/libsmb2-dcerpc-srvsvc.h +180 -0
  92. package/ios/libs/libsmb2.xcframework/ios-arm64/Headers/smb2/libsmb2-dcerpc.h +155 -0
  93. package/ios/libs/libsmb2.xcframework/ios-arm64/Headers/smb2/libsmb2-raw.h +497 -0
  94. package/ios/libs/libsmb2.xcframework/ios-arm64/Headers/smb2/libsmb2.h +1384 -0
  95. package/ios/libs/libsmb2.xcframework/ios-arm64/Headers/smb2/smb2-errors.h +549 -0
  96. package/ios/libs/libsmb2.xcframework/ios-arm64/Headers/smb2/smb2.h +1251 -0
  97. package/ios/libs/libsmb2.xcframework/ios-arm64/libsmb2.a +0 -0
  98. package/ios/libs/libsmb2.xcframework/ios-arm64_x86_64-simulator/Headers/smb2/libsmb2-dcerpc-lsa.h +172 -0
  99. package/ios/libs/libsmb2.xcframework/ios-arm64_x86_64-simulator/Headers/smb2/libsmb2-dcerpc-srvsvc.h +180 -0
  100. package/ios/libs/libsmb2.xcframework/ios-arm64_x86_64-simulator/Headers/smb2/libsmb2-dcerpc.h +155 -0
  101. package/ios/libs/libsmb2.xcframework/ios-arm64_x86_64-simulator/Headers/smb2/libsmb2-raw.h +497 -0
  102. package/ios/libs/libsmb2.xcframework/ios-arm64_x86_64-simulator/Headers/smb2/libsmb2.h +1384 -0
  103. package/ios/libs/libsmb2.xcframework/ios-arm64_x86_64-simulator/Headers/smb2/smb2-errors.h +549 -0
  104. package/ios/libs/libsmb2.xcframework/ios-arm64_x86_64-simulator/Headers/smb2/smb2.h +1251 -0
  105. package/ios/libs/libsmb2.xcframework/ios-arm64_x86_64-simulator/libsmb2.a +0 -0
  106. package/ios/libs/simulator/libsmb2-simulator.a +0 -0
  107. package/lib/ReactNativeSmb.d.ts +200 -0
  108. package/lib/ReactNativeSmb.js +1 -0
  109. package/lib/bridge/decode.d.ts +4 -0
  110. package/lib/bridge/decode.js +92 -0
  111. package/lib/core/SMB.d.ts +3 -0
  112. package/lib/core/SMB.js +4 -0
  113. package/lib/core/SmbClient.d.ts +35 -0
  114. package/lib/core/SmbClient.js +99 -0
  115. package/lib/core/SmbTask.d.ts +41 -0
  116. package/lib/core/SmbTask.js +74 -0
  117. package/lib/core/TransferStore.d.ts +22 -0
  118. package/lib/core/TransferStore.js +88 -0
  119. package/lib/core/ids.d.ts +1 -0
  120. package/lib/core/ids.js +3 -0
  121. package/lib/core/taskResult.d.ts +3 -0
  122. package/lib/core/taskResult.js +52 -0
  123. package/lib/hooks/useSubscribe.d.ts +20 -0
  124. package/lib/hooks/useSubscribe.js +36 -0
  125. package/lib/hooks/useTransfers.d.ts +7 -0
  126. package/lib/hooks/useTransfers.js +29 -0
  127. package/lib/index.d.ts +7 -0
  128. package/lib/index.js +7 -0
  129. package/lib/labels.d.ts +6 -0
  130. package/lib/labels.js +71 -0
  131. package/lib/types.d.ts +141 -0
  132. package/lib/types.js +59 -0
  133. package/lib/utils.d.ts +79 -0
  134. package/lib/utils.js +153 -0
  135. package/package.json +63 -0
  136. package/scripts/build-libsmb2.sh +143 -0
  137. package/scripts/create-xcframework.sh +84 -0
@@ -0,0 +1,57 @@
1
+ #pragma once
2
+
3
+ #include <any>
4
+ #include <cstdint>
5
+ #include <functional>
6
+ #include <memory>
7
+ #include <string>
8
+ #include <vector>
9
+
10
+ #include <jsi/jsi.h>
11
+
12
+ #include "../connection/MetadataContextLease.hpp"
13
+ #include "../connection/PoolContextHandle.hpp"
14
+ #include "../connection/PoolTypes.hpp"
15
+ #include "../core/CancellationToken.hpp"
16
+ #include "../core/OperatorContext.hpp"
17
+ #include "../core/SmbEnums.hpp"
18
+
19
+ namespace react_native_smb {
20
+
21
+ namespace jsi = facebook::jsi;
22
+
23
+ class SmbConnectionPool;
24
+ class SmbTask;
25
+
26
+ class OperatorBase {
27
+ public:
28
+ virtual ~OperatorBase() = default;
29
+
30
+ virtual void run() = 0;
31
+ virtual SmbOperatorKind kind() const = 0;
32
+
33
+ void setContext(const OperatorContext& ctx) { ctx_ = ctx; }
34
+ void start(SmbTask* task, SmbConnectionPool* pool, const CancellationToken& cancel, size_t opIndex);
35
+
36
+ protected:
37
+ void emitStatus(SmbTaskStatus s, const std::string& error = "", int code = 0);
38
+ void emitProgress(double done, double total);
39
+
40
+ bool isCancelled() const { return ctx_.cancel.cancelled(); }
41
+ const CancellationToken& cancelToken() const { return ctx_.cancel; }
42
+
43
+ SmbConnectionPool& pool() const { return *ctx_.pool; }
44
+ PoolContextHandle requestContext(AcquireMode mode);
45
+ MetadataContextLease makeMetadataLease();
46
+ std::string owningTaskId() const;
47
+
48
+ size_t spawn(std::vector<std::unique_ptr<OperatorBase>> moreOps);
49
+ void addExpectedBytes(int64_t bytes);
50
+ void setSourceDestination(const std::string& source, const std::string& destination);
51
+ void publishResult(std::any value, std::function<jsi::Value(jsi::Runtime&, const std::any&)> converter);
52
+
53
+ private:
54
+ OperatorContext ctx_{};
55
+ };
56
+
57
+ } // namespace react_native_smb
@@ -0,0 +1,19 @@
1
+ #include "ConnectOperator.hpp"
2
+
3
+ #include "../../connection/SmbConnectionPool.hpp"
4
+
5
+ namespace react_native_smb {
6
+
7
+ void ConnectOperator::run() {
8
+ pool().connect(url_, credentials_);
9
+ result_ = SmbConnectionInfo{
10
+ pool().getCurrentUrl(),
11
+ pool().getServerName(),
12
+ pool().getShareName(),
13
+ pool().isConnected(),
14
+ };
15
+ publishThisResult();
16
+ emitStatus(SmbTaskStatus::Success);
17
+ }
18
+
19
+ } // namespace react_native_smb
@@ -0,0 +1,22 @@
1
+ #pragma once
2
+
3
+ #include <string>
4
+
5
+ #include "../../ReactNativeSmb.hpp" // SmbCredentials, SmbConnectionInfo
6
+ #include "../Operator.hpp"
7
+
8
+ namespace react_native_smb {
9
+
10
+ class ConnectOperator : public Operator<SmbConnectionInfo> {
11
+ public:
12
+ ConnectOperator(std::string url, SmbCredentials credentials) : url_(std::move(url)), credentials_(std::move(credentials)) {}
13
+
14
+ SmbOperatorKind kind() const override { return SmbOperatorKind::Connect; }
15
+ void run() override;
16
+
17
+ private:
18
+ std::string url_;
19
+ SmbCredentials credentials_;
20
+ };
21
+
22
+ } // namespace react_native_smb
@@ -0,0 +1,19 @@
1
+ #include "ConnectShareOperator.hpp"
2
+
3
+ #include "../../connection/SmbConnectionPool.hpp"
4
+
5
+ namespace react_native_smb {
6
+
7
+ void ConnectShareOperator::run() {
8
+ pool().connectShare(share_);
9
+ result_ = SmbConnectionInfo{
10
+ pool().getCurrentUrl(),
11
+ pool().getServerName(),
12
+ pool().getShareName(),
13
+ pool().isConnected(),
14
+ };
15
+ publishThisResult();
16
+ emitStatus(SmbTaskStatus::Success);
17
+ }
18
+
19
+ } // namespace react_native_smb
@@ -0,0 +1,21 @@
1
+ #pragma once
2
+
3
+ #include <string>
4
+
5
+ #include "../../ReactNativeSmb.hpp" // SmbConnectionInfo
6
+ #include "../Operator.hpp"
7
+
8
+ namespace react_native_smb {
9
+
10
+ class ConnectShareOperator : public Operator<SmbConnectionInfo> {
11
+ public:
12
+ explicit ConnectShareOperator(std::string share) : share_(std::move(share)) {}
13
+
14
+ SmbOperatorKind kind() const override { return SmbOperatorKind::ConnectShare; }
15
+ void run() override;
16
+
17
+ private:
18
+ std::string share_;
19
+ };
20
+
21
+ } // namespace react_native_smb
@@ -0,0 +1,12 @@
1
+ #include "DisconnectOperator.hpp"
2
+
3
+ #include "../../connection/SmbConnectionPool.hpp"
4
+
5
+ namespace react_native_smb {
6
+
7
+ void DisconnectOperator::run() {
8
+ pool().disconnect();
9
+ emitStatus(SmbTaskStatus::Success);
10
+ }
11
+
12
+ } // namespace react_native_smb
@@ -0,0 +1,15 @@
1
+ #pragma once
2
+
3
+ #include "../OperatorBase.hpp"
4
+
5
+ namespace react_native_smb {
6
+
7
+ class DisconnectOperator : public OperatorBase {
8
+ public:
9
+ DisconnectOperator() = default;
10
+
11
+ SmbOperatorKind kind() const override { return SmbOperatorKind::Disconnect; }
12
+ void run() override;
13
+ };
14
+
15
+ } // namespace react_native_smb
@@ -0,0 +1,12 @@
1
+ #include "InitializeOperator.hpp"
2
+
3
+ #include "../../connection/SmbConnectionPool.hpp"
4
+
5
+ namespace react_native_smb {
6
+
7
+ void InitializeOperator::run() {
8
+ pool().initialize(url_, credentials_);
9
+ emitStatus(SmbTaskStatus::Success);
10
+ }
11
+
12
+ } // namespace react_native_smb
@@ -0,0 +1,22 @@
1
+ #pragma once
2
+
3
+ #include <string>
4
+
5
+ #include "../../ReactNativeSmb.hpp" // SmbCredentials
6
+ #include "../OperatorBase.hpp"
7
+
8
+ namespace react_native_smb {
9
+
10
+ class InitializeOperator : public OperatorBase {
11
+ public:
12
+ InitializeOperator(std::string url, SmbCredentials credentials) : url_(std::move(url)), credentials_(std::move(credentials)) {}
13
+
14
+ SmbOperatorKind kind() const override { return SmbOperatorKind::Initialize; }
15
+ void run() override;
16
+
17
+ private:
18
+ std::string url_;
19
+ SmbCredentials credentials_;
20
+ };
21
+
22
+ } // namespace react_native_smb
@@ -0,0 +1,13 @@
1
+ #include "ListSharesOperator.hpp"
2
+
3
+ #include "../../connection/SmbConnectionPool.hpp"
4
+
5
+ namespace react_native_smb {
6
+
7
+ void ListSharesOperator::run() {
8
+ result_ = pool().listShares(owningTaskId());
9
+ publishThisResult();
10
+ emitStatus(SmbTaskStatus::Success);
11
+ }
12
+
13
+ } // namespace react_native_smb
@@ -0,0 +1,18 @@
1
+ #pragma once
2
+
3
+ #include <vector>
4
+
5
+ #include "../../ReactNativeSmb.hpp" // SmbShareList
6
+ #include "../Operator.hpp"
7
+
8
+ namespace react_native_smb {
9
+
10
+ class ListSharesOperator : public Operator<std::vector<SmbShareList>> {
11
+ public:
12
+ ListSharesOperator() = default;
13
+
14
+ SmbOperatorKind kind() const override { return SmbOperatorKind::ListShares; }
15
+ void run() override;
16
+ };
17
+
18
+ } // namespace react_native_smb
@@ -0,0 +1,43 @@
1
+ #include "GetPathInfoOperator.hpp"
2
+
3
+ #include <stdexcept>
4
+
5
+ #include "../../connection/SmbConnectionPool.hpp"
6
+ #include "../../io/SmbDirScan.hpp"
7
+ #include "../../io/SmbPathUtil.hpp"
8
+
9
+ namespace react_native_smb {
10
+
11
+ void GetPathInfoOperator::run() {
12
+
13
+ const std::string parentPath = path_util::parentOf(path_);
14
+ const std::string fileName = path_util::extractFileName(path_);
15
+
16
+ auto handle = requestContext(AcquireMode::Interactive);
17
+
18
+ const CancellationToken token = cancelToken();
19
+ bool found = false;
20
+ SmbFileInfo info;
21
+ try {
22
+ std::vector<SmbFileInfo> siblings = handle.submitSync([&](smb2_context* ctx) { return listOnCtx(ctx, parentPath, true, 1, token); });
23
+ for (const auto& item : siblings) {
24
+ if (item.name == fileName) {
25
+ info = item;
26
+ found = true;
27
+ break;
28
+ }
29
+ }
30
+ } catch (...) {
31
+ throw std::runtime_error("Failed to get path info for '" + path_ + "': File not found.");
32
+ }
33
+
34
+ if (!found) {
35
+ throw std::runtime_error("Failed to get path info for '" + path_ + "': File not found.");
36
+ }
37
+
38
+ result_ = info;
39
+ publishThisResult();
40
+ emitStatus(SmbTaskStatus::Success);
41
+ }
42
+
43
+ } // namespace react_native_smb
@@ -0,0 +1,21 @@
1
+ #pragma once
2
+
3
+ #include <string>
4
+
5
+ #include "../../ReactNativeSmb.hpp" // SmbFileInfo
6
+ #include "../Operator.hpp"
7
+
8
+ namespace react_native_smb {
9
+
10
+ class GetPathInfoOperator : public Operator<SmbFileInfo> {
11
+ public:
12
+ explicit GetPathInfoOperator(std::string path) : path_(std::move(path)) {}
13
+
14
+ SmbOperatorKind kind() const override { return SmbOperatorKind::GetPathInfo; }
15
+ void run() override;
16
+
17
+ private:
18
+ std::string path_;
19
+ };
20
+
21
+ } // namespace react_native_smb
@@ -0,0 +1,202 @@
1
+ #include "GetSecurityDescriptorOperator.hpp"
2
+
3
+ #include <poll.h>
4
+ #include <smb2/libsmb2-raw.h>
5
+ #include <smb2/libsmb2.h>
6
+ #include <smb2/smb2.h>
7
+
8
+ #include <cstring>
9
+ #include <stdexcept>
10
+ #include <string>
11
+
12
+ #include "../../connection/SmbConnectionPool.hpp"
13
+ #include "../../io/SmbSecurity.hpp"
14
+
15
+ namespace react_native_smb {
16
+
17
+ namespace {
18
+
19
+ // Mutable state shared with the three compound-PDU callbacks.
20
+ struct AclQueryContext {
21
+ SmbSecurityDescriptor* result;
22
+ std::string error;
23
+ bool finished;
24
+ int createStatus;
25
+ int queryStatus;
26
+ int closeStatus;
27
+ struct smb2_security_descriptor* sd;
28
+ bool createCompleted;
29
+ bool queryCompleted;
30
+ bool closeCompleted;
31
+ };
32
+
33
+ int sendAclQuery(smb2_context* context, const std::string& filePath, AclQueryContext& queryContext) {
34
+ auto createCallback = [](struct smb2_context* smb2, int status, void* /*command_data*/, void* private_data) {
35
+ if (!private_data) return;
36
+ auto* ctx = static_cast<AclQueryContext*>(private_data);
37
+ ctx->createCompleted = true;
38
+ ctx->createStatus = status;
39
+ if (status != 0) {
40
+ ctx->error = "CREATE failed (status=" + std::to_string(status) + "): " + (smb2 ? std::string(smb2_get_error(smb2)) : "");
41
+ }
42
+ };
43
+
44
+ auto queryCallback = [](struct smb2_context* smb2, int status, void* command_data, void* private_data) {
45
+ if (!private_data) return;
46
+ auto* ctx = static_cast<AclQueryContext*>(private_data);
47
+ ctx->queryCompleted = true;
48
+ ctx->queryStatus = status;
49
+ if (status != 0) {
50
+ ctx->error = "QUERY_INFO failed (status=" + std::to_string(status) + "): " + (smb2 ? std::string(smb2_get_error(smb2)) : "");
51
+ return;
52
+ }
53
+ if (!command_data) {
54
+ ctx->error = "QUERY_INFO: No command data received";
55
+ return;
56
+ }
57
+ auto rep = static_cast<struct smb2_query_info_reply*>(command_data);
58
+ if (!rep || !rep->output_buffer) {
59
+ ctx->error = "QUERY_INFO: No security descriptor data received";
60
+ return;
61
+ }
62
+ ctx->sd = static_cast<struct smb2_security_descriptor*>(rep->output_buffer);
63
+ if (!ctx->sd) ctx->error = "QUERY_INFO: Invalid security descriptor format";
64
+ };
65
+
66
+ auto closeCallback = [](struct smb2_context* smb2, int status, void* /*command_data*/, void* private_data) {
67
+ if (!private_data) return;
68
+ auto* ctx = static_cast<AclQueryContext*>(private_data);
69
+ ctx->closeCompleted = true;
70
+ ctx->closeStatus = status;
71
+ ctx->finished = true; // final callback
72
+ if (status != 0) {
73
+ ctx->error = "CLOSE failed (status=" + std::to_string(status) + "): " + (smb2 ? std::string(smb2_get_error(smb2)) : "");
74
+ return;
75
+ }
76
+ if (ctx->createStatus != 0) {
77
+ ctx->error = "CREATE command failed with status: " + std::to_string(ctx->createStatus);
78
+ return;
79
+ }
80
+ if (ctx->queryStatus != 0) {
81
+ ctx->error = "QUERY_INFO command failed with status: " + std::to_string(ctx->queryStatus);
82
+ return;
83
+ }
84
+ if (!ctx->sd) {
85
+ ctx->error = "No security descriptor available for processing";
86
+ return;
87
+ }
88
+ if (!ctx->result) {
89
+ ctx->error = "Result pointer is null";
90
+ return;
91
+ }
92
+ try {
93
+ *ctx->result = SmbSecurity::processSecurityDescriptor(ctx->sd);
94
+ } catch (const std::exception& e) {
95
+ ctx->error = "Error converting security descriptor: " + std::string(e.what());
96
+ } catch (...) {
97
+ ctx->error = "Unknown error converting security descriptor";
98
+ }
99
+ };
100
+
101
+ struct smb2_create_request cr_req;
102
+ struct smb2_query_info_request qi_req;
103
+ struct smb2_close_request cl_req;
104
+ struct smb2_pdu *pdu, *next_pdu;
105
+
106
+ memset(&cr_req, 0, sizeof(cr_req));
107
+ cr_req.requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
108
+ cr_req.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
109
+ cr_req.desired_access = SMB2_READ_CONTROL;
110
+ cr_req.file_attributes = 0;
111
+ cr_req.share_access = SMB2_FILE_SHARE_READ | SMB2_FILE_SHARE_WRITE | SMB2_FILE_SHARE_DELETE;
112
+ cr_req.create_disposition = SMB2_FILE_OPEN;
113
+ cr_req.create_options = 0;
114
+ cr_req.name = filePath.c_str();
115
+
116
+ pdu = smb2_cmd_create_async(context, &cr_req, createCallback, &queryContext);
117
+ if (!pdu) return -1;
118
+
119
+ memset(&qi_req, 0, sizeof(qi_req));
120
+ qi_req.info_type = SMB2_0_INFO_SECURITY;
121
+ qi_req.output_buffer_length = 65535;
122
+ qi_req.additional_information = SMB2_OWNER_SECURITY_INFORMATION | SMB2_GROUP_SECURITY_INFORMATION | SMB2_DACL_SECURITY_INFORMATION;
123
+ memset(qi_req.file_id, 0xFF, SMB2_FD_SIZE);
124
+
125
+ next_pdu = smb2_cmd_query_info_async(context, &qi_req, queryCallback, &queryContext);
126
+ if (!next_pdu) {
127
+ smb2_free_pdu(context, pdu);
128
+ return -1;
129
+ }
130
+ smb2_add_compound_pdu(context, pdu, next_pdu);
131
+
132
+ memset(&cl_req, 0, sizeof(cl_req));
133
+ cl_req.flags = SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB;
134
+ memset(cl_req.file_id, 0xFF, SMB2_FD_SIZE);
135
+
136
+ next_pdu = smb2_cmd_close_async(context, &cl_req, closeCallback, &queryContext);
137
+ if (!next_pdu) {
138
+ smb2_free_pdu(context, pdu);
139
+ return -1;
140
+ }
141
+ smb2_add_compound_pdu(context, pdu, next_pdu);
142
+
143
+ smb2_queue_pdu(context, pdu);
144
+ return 0;
145
+ }
146
+
147
+ void pollUntilComplete(smb2_context* ctx, AclQueryContext& context) {
148
+ if (!ctx) throw std::runtime_error("ACL Error: SMB2 context is invalid during polling.");
149
+
150
+ struct pollfd pfd;
151
+ int timeout_count = 0;
152
+ const int max_timeouts = 10;
153
+
154
+ while (!context.finished) {
155
+ pfd.fd = smb2_get_fd(ctx);
156
+ if (pfd.fd < 0) throw std::runtime_error("ACL Error: Invalid file descriptor from libsmb2. Connection might be broken.");
157
+ pfd.events = smb2_which_events(ctx);
158
+
159
+ if (poll(&pfd, 1, 1000) < 0) throw std::runtime_error("Poll failed during ACL query");
160
+
161
+ if (pfd.revents == 0) {
162
+ if (++timeout_count >= max_timeouts) throw std::runtime_error("ACL query timed out");
163
+ continue;
164
+ }
165
+ timeout_count = 0;
166
+
167
+ if (pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
168
+ throw std::runtime_error("ACL Error: Socket poll failure (revents=" + std::to_string(pfd.revents) + ").");
169
+ }
170
+ if (smb2_service(ctx, pfd.revents) < 0) {
171
+ throw std::runtime_error("ACL Error: smb2_service failed: " + std::string(smb2_get_error(ctx)));
172
+ }
173
+ }
174
+ }
175
+
176
+ } // namespace
177
+
178
+ void GetSecurityDescriptorOperator::run() {
179
+ emitStatus(SmbTaskStatus::Running);
180
+
181
+ auto handle = requestContext(AcquireMode::Interactive);
182
+
183
+ SmbSecurityDescriptor sd{0, {}, "", "", SmbAcl{0, 0, {}}};
184
+
185
+ handle.submitSync([&](smb2_context* ctx) {
186
+ if (!ctx) throw std::runtime_error("ACL Operation Failed: SMB2 context is invalid. Please reconnect.");
187
+
188
+ AclQueryContext queryContext = {&sd, "", false, 0, 0, 0, nullptr, false, false, false};
189
+
190
+ if (sendAclQuery(ctx, path_, queryContext) != 0) {
191
+ throw std::runtime_error("ACL Operation Failed: Could not send ACL query for '" + path_ + "'. Error: " + std::string(smb2_get_error(ctx)));
192
+ }
193
+ pollUntilComplete(ctx, queryContext);
194
+ if (!queryContext.error.empty()) throw std::runtime_error(queryContext.error);
195
+ });
196
+
197
+ result_ = sd;
198
+ publishThisResult();
199
+ emitStatus(SmbTaskStatus::Success);
200
+ }
201
+
202
+ } // namespace react_native_smb
@@ -0,0 +1,22 @@
1
+ #pragma once
2
+
3
+ #include <string>
4
+
5
+ #include "../../ReactNativeSmb.hpp" // SmbSecurityDescriptor
6
+ #include "../Operator.hpp"
7
+
8
+ namespace react_native_smb {
9
+
10
+ // Queries a path security descriptor via CREATE + QUERY_INFO + CLOSE.
11
+ class GetSecurityDescriptorOperator : public Operator<SmbSecurityDescriptor> {
12
+ public:
13
+ explicit GetSecurityDescriptorOperator(std::string path) : path_(std::move(path)) {}
14
+
15
+ SmbOperatorKind kind() const override { return SmbOperatorKind::GetSecurityDescriptor; }
16
+ void run() override;
17
+
18
+ private:
19
+ std::string path_;
20
+ };
21
+
22
+ } // namespace react_native_smb
@@ -0,0 +1,20 @@
1
+ #include "ListDirectoryOperator.hpp"
2
+
3
+ #include "../../connection/SmbConnectionPool.hpp"
4
+ #include "../../io/SmbDirScan.hpp"
5
+
6
+ namespace react_native_smb {
7
+
8
+ void ListDirectoryOperator::run() {
9
+
10
+ const AcquireMode mode = (!recursive_ || maxDepth_ == 0) ? AcquireMode::Interactive : AcquireMode::Metadata;
11
+ auto handle = requestContext(mode);
12
+
13
+ const CancellationToken token = cancelToken();
14
+ result_ = handle.submitSync([&](smb2_context* ctx) { return listOnCtx(ctx, path_, recursive_, maxDepth_, token); });
15
+ publishThisResult();
16
+
17
+ emitStatus(SmbTaskStatus::Success);
18
+ }
19
+
20
+ } // namespace react_native_smb
@@ -0,0 +1,24 @@
1
+ #pragma once
2
+
3
+ #include <string>
4
+ #include <vector>
5
+
6
+ #include "../../ReactNativeSmb.hpp" // SmbFileInfo
7
+ #include "../Operator.hpp"
8
+
9
+ namespace react_native_smb {
10
+
11
+ class ListDirectoryOperator : public Operator<std::vector<SmbFileInfo>> {
12
+ public:
13
+ ListDirectoryOperator(std::string path, bool recursive, int maxDepth) : path_(std::move(path)), recursive_(recursive), maxDepth_(maxDepth) {}
14
+
15
+ SmbOperatorKind kind() const override { return SmbOperatorKind::ListDirectory; }
16
+ void run() override;
17
+
18
+ private:
19
+ std::string path_;
20
+ bool recursive_;
21
+ int maxDepth_;
22
+ };
23
+
24
+ } // namespace react_native_smb
@@ -0,0 +1,19 @@
1
+ #include "CopyItemOperator.hpp"
2
+
3
+ #include "../../io/SmbCopyTree.hpp"
4
+
5
+ namespace react_native_smb {
6
+
7
+ void CopyItemOperator::run() {
8
+ setSourceDestination(fromPath_, toPath_);
9
+ MetadataContextLease lease = makeMetadataLease();
10
+ copyTreeImpl(pool(), kind(), fromPath_, toPath_, recursive_, cancelToken(),
11
+ [this](double done, double total) { emitProgress(done, total); }, [this](int64_t n) { addExpectedBytes(n); }, owningTaskId(), &lease);
12
+ if (isCancelled()) {
13
+ emitStatus(SmbTaskStatus::Cancelled);
14
+ return;
15
+ }
16
+ emitStatus(SmbTaskStatus::Success);
17
+ }
18
+
19
+ } // namespace react_native_smb
@@ -0,0 +1,25 @@
1
+ #pragma once
2
+
3
+ #include <string>
4
+
5
+ #include "../OperatorBase.hpp"
6
+
7
+ namespace react_native_smb {
8
+
9
+ // Copies a file or a directory tree (recursive). Self-contained: mirrors the
10
+ // destination skeleton and copies files via the async pipelined copy. Progress
11
+ // is aggregated into a single cumulative byte count.
12
+ class CopyItemOperator : public OperatorBase {
13
+ public:
14
+ CopyItemOperator(std::string fromPath, std::string toPath, bool recursive = true) : fromPath_(std::move(fromPath)), toPath_(std::move(toPath)), recursive_(recursive) {}
15
+
16
+ SmbOperatorKind kind() const override { return SmbOperatorKind::CopyItem; }
17
+ void run() override;
18
+
19
+ private:
20
+ std::string fromPath_;
21
+ std::string toPath_;
22
+ bool recursive_;
23
+ };
24
+
25
+ } // namespace react_native_smb
@@ -0,0 +1,28 @@
1
+ #include "CreateDirectoryOperator.hpp"
2
+
3
+ #include <smb2/libsmb2.h>
4
+ #include <smb2/smb2.h>
5
+
6
+ #include <stdexcept>
7
+
8
+ #include "../../connection/SmbConnectionPool.hpp"
9
+ #include "../../io/SmbPathUtil.hpp"
10
+
11
+ namespace react_native_smb {
12
+
13
+ void CreateDirectoryOperator::run() {
14
+
15
+ const std::string norm = path_util::normalized(path_);
16
+ auto handle = requestContext(AcquireMode::Interactive);
17
+
18
+ handle.submitSync([&](smb2_context* ctx) {
19
+ const int r = smb2_mkdir(ctx, norm.c_str());
20
+ if (r < 0) {
21
+ throw std::runtime_error("Directory Usage Failed: Could not create directory at '" + path_ + "'. Error: " + smb2_get_error(ctx));
22
+ }
23
+ });
24
+
25
+ emitStatus(SmbTaskStatus::Success);
26
+ }
27
+
28
+ } // namespace react_native_smb
@@ -0,0 +1,20 @@
1
+ #pragma once
2
+
3
+ #include <string>
4
+
5
+ #include "../OperatorBase.hpp"
6
+
7
+ namespace react_native_smb {
8
+
9
+ class CreateDirectoryOperator : public OperatorBase {
10
+ public:
11
+ explicit CreateDirectoryOperator(std::string path) : path_(std::move(path)) {}
12
+
13
+ SmbOperatorKind kind() const override { return SmbOperatorKind::CreateDirectory; }
14
+ void run() override;
15
+
16
+ private:
17
+ std::string path_;
18
+ };
19
+
20
+ } // namespace react_native_smb