@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
package/docs/API.md ADDED
@@ -0,0 +1,105 @@
1
+ # API reference
2
+
3
+ All async methods return `SmbTask<T>`. Await with `.result()`. See [Task model](./TASK_MODEL.md) for subscribe, cancel, and hook patterns.
4
+
5
+ ## Connection
6
+
7
+ | Method | Returns | `result()` type | Notes |
8
+ | ------ | ------- | --------------- | ----- |
9
+ | `initialize(url, creds)` | `SmbTask<void>` | `void` | Server only, no share |
10
+ | `connect(url, creds)` | `SmbTask<SmbConnectionInfo>` | `SmbConnectionInfo` | Auth + mount share from URL |
11
+ | `connectShare(share)` | `SmbTask<SmbConnectionInfo>` | `SmbConnectionInfo` | Switch share |
12
+ | `disconnect()` | `SmbTask<void>` | `void` | Close session |
13
+ | `listShares()` | `SmbTask<SmbShareList[]>` | `SmbShareList[]` | Enumerate shares |
14
+ | `isConnected()` | `boolean` | — | Sync |
15
+ | `isInitialized()` | `boolean` | — | Sync |
16
+
17
+ URL: `smb://[<domain;][<username>@]<host>[:<port>]/<share>/<path>`
18
+
19
+ ```typescript
20
+ interface SmbCredentials { username: string; password: string; }
21
+
22
+ interface SmbConnectionInfo {
23
+ url: string; server: string; share: string; isConnected: boolean;
24
+ }
25
+
26
+ interface SmbShareList { name: string; comment: string; }
27
+ ```
28
+
29
+ ## File system
30
+
31
+ | Method | Returns | `result()` type | Notes |
32
+ | ------ | ------- | --------------- | ----- |
33
+ | `listDirectory(path, recursive?, maxDepth?)` | `SmbTask<SmbFileInfo[]>` | `SmbFileInfo[]` | `maxDepth: -1` = unlimited |
34
+ | `getPathInfo(path)` | `SmbTask<SmbFileInfo>` | `SmbFileInfo` | |
35
+ | `downloadFile(remote, local)` | `SmbTask<void>` | `void` | `subscribe()` for progress |
36
+ | `uploadFile(local, remote)` | `SmbTask<void>` | `void` | `subscribe()` for progress |
37
+ | `createDirectory(path)` | `SmbTask<void>` | `void` | Creates parents |
38
+ | `deleteItem(path)` | `SmbTask<void>` | `void` | Recursive for dirs |
39
+ | `renameItem(path, newName)` | `SmbTask<void>` | `void` | Basename only |
40
+ | `moveItem(from, to)` | `SmbTask<void>` | `void` | |
41
+ | `copyItem(from, to, recursive?)` | `SmbTask<void>` | `void` | |
42
+ | `duplicateItem(path)` | `SmbTask<string>` | `string` | New path |
43
+ | `getSecurityDescriptor(path)` | `SmbTask<SmbSecurityDescriptor>` | `SmbSecurityDescriptor` | |
44
+
45
+ ```typescript
46
+ interface SmbFileInfo {
47
+ name: string; path: string; size: number; isDirectory: boolean;
48
+ modifiedAt: number; accessedAt: number; createdAt: number; changedAt: number;
49
+ childCount?: number; children?: SmbFileInfo[];
50
+ }
51
+ ```
52
+
53
+ ## Pool
54
+
55
+ | Method | Returns | Notes |
56
+ | ------ | ------- | ----- |
57
+ | `getPoolInfo()` | `PoolInfo` | Slot snapshot |
58
+ | `subscribePoolInfo(cb)` | `string` | Listener ID |
59
+ | `unsubscribePoolInfo(id)` | `void` | |
60
+ | `resetPool()` | `void` | Disconnect all slots |
61
+ | `dispose()` | `void` | Tear down transfer store |
62
+
63
+ See [Connection pool](./ARCHITECTURE.md).
64
+
65
+ ## Types
66
+
67
+ ### `SmbTask<T>`
68
+
69
+ | Member | Description |
70
+ | ------ | ----------- |
71
+ | `id` | Task identifier |
72
+ | `progress`, `status` | Live getters after `subscribe()` |
73
+ | `result()` | `Promise<T>` |
74
+ | `subscribe(listener?)` | Returns unsubscribe |
75
+ | `cancel()` | Abort |
76
+ | `get()` | One-shot snapshot |
77
+ | `SmbTask.settleAll(tasks)` | `Promise.allSettled` over results |
78
+
79
+ ### Errors
80
+
81
+ `SmbTaskError` with `code: SmbError` and optional `taskId`.
82
+
83
+ `SmbError`: `Unknown`, `Cancelled`, `InvalidArgument`, `NotFound`, `AlreadyExists`, `AccessDenied`, `NotDirectory`, `IsDirectory`, `DirectoryNotEmpty`, `NotConnected`, `ConnectionRefused`, `TimedOut`, `Busy`, `NoSpace`, `Io`.
84
+
85
+ ### Hooks
86
+
87
+ | Hook | Purpose |
88
+ | ---- | ------- |
89
+ | `useSubscribe(task)` | React state for progress/status |
90
+ | `useTransfers(smb)` | Active transfer tasks |
91
+ | `useTransferActions(smb)` | `clearCompleted()`, `hide(taskId)` |
92
+
93
+ ## Utilities
94
+
95
+ Path helpers:
96
+
97
+ | Function | Description |
98
+ | -------- | ----------- |
99
+ | `normalizePath` | Forward slashes, trim trailing `/` |
100
+ | `splitPath` | `{ parentDirectory, baseFileName, extension, fullFileName }` |
101
+ | `joinPath`, `getParentPath`, `getFileName` | Path composition |
102
+ | `generateCopyName` | `"file copy 2.pdf"` naming |
103
+ | `formatFileSize`, `formatDate` | Display helpers |
104
+
105
+ Label helpers: `statusLabel`, `operationLabel`, `isTransferKind`, `isDeterminateKind`, `isTerminalStatus`.
@@ -0,0 +1,70 @@
1
+ # Connection pool
2
+
3
+ `HybridSMB` runs up to four SMB operations in parallel through a `SmbConnectionPool(4)`. Each slot is one `SmbConnectionManager` / `smb2_context` — its own TCP socket and session:
4
+
5
+ ```
6
+ TCP → NEGOTIATE → SESSION SETUP → TREE CONNECT
7
+ ```
8
+
9
+ Tasks call `requestContext(mode)`, hold a slot for the operator's lifetime, then release via `PoolContextHandle`. One operator per slot (mutex on the context). Work on different slots runs concurrently.
10
+
11
+ From `SmbConnectionPool.hpp`:
12
+
13
+ ```
14
+ slot[0] — Interactive-only
15
+ slot[1..N-1] — General (any AcquireMode; Interactive may overflow here)
16
+ ```
17
+
18
+ | Slot | Accepts | Typical work |
19
+ | ---- | ------- | ------------ |
20
+ | `slot[0]` | `Interactive` only | `listDirectory`, `getPathInfo`, rename, move |
21
+ | `slot[1..3]` | Any | Download, upload, copy, delete; grows on demand |
22
+
23
+ ```cpp
24
+ bool PoolSlot::accepts(AcquireMode mode) const {
25
+ if (index_ == 0) return mode == AcquireMode::Interactive;
26
+ return true;
27
+ }
28
+ ```
29
+
30
+ Metadata never uses slot 0. Interactive work can overflow to slots 1–3 when slot 0 is busy.
31
+
32
+ ### Acquire modes
33
+
34
+ | Mode | Operators |
35
+ | ---- | --------- |
36
+ | `Interactive` | `getPathInfo`, shallow `listDirectory`, `moveItem`, `renameItem`, `createDirectory`, `getSecurityDescriptor`, `listShares` |
37
+ | `Metadata` | `downloadFile`, `uploadFile`, `copyItem`, `duplicateItem`, `deleteItem`, recursive `listDirectory` |
38
+
39
+ FIFO queue per mode.
40
+
41
+ The server sees each active slot as a separate client connection — multiple full sessions to the same host/share, not channels bound to one session. SMB3 multichannel is the protocol-level alternative: extra TCP links attach to an existing session via `SMB2_SESSION_FLAG_BINDING` and share one `SessionId`. libsmb2 does not implement that; each `smb2_context` maps to one `fd`, so the pool uses independent contexts instead.
42
+
43
+ | | Pool | SMB3 multichannel |
44
+ | --- | --- | --- |
45
+ | Sessions | One per slot | One across channels |
46
+ | Server view | N connections | 1 client, N channels |
47
+ | Slot 0 reserved for UI | Yes | — |
48
+ | Requires server multichannel cap | No | Yes |
49
+
50
+ Slot 0 is application-level scheduling on top of what libsmb2 provides — interactive ops stay off the slots running bulk transfers.
51
+
52
+ ## Chunk pipeline
53
+
54
+ Cross-task parallelism is the pool. Within a single transfer, `SmbFileIO` pipelines up to eight SMB2 READ/WRITE on the same `smb2_context` (`kMaxInFlight` in `SmbFileIO.cpp`). Same connection, same session — credit-based pipelining, separate from slot assignment.
55
+
56
+ ## Diagnostics
57
+
58
+ ```typescript
59
+ const info = smb.getPoolInfo();
60
+ const id = smb.subscribePoolInfo((snap) => console.log(snap));
61
+ smb.unsubscribePoolInfo(id);
62
+ ```
63
+
64
+ `PoolSlotInfo`: `index`, `interactiveOnly`, `state` (`Idle` | `Assigned` | `Activating`), `isConnected`, `shareName`, `taskId`, `kind`.
65
+
66
+ - Same `index` turning over quickly → tasks queuing on one slot.
67
+ - Slots 1–3 all `Assigned`, metadata still pending → pool full.
68
+ - Interactive `kind` on slot 1–3 → slot 0 was busy.
69
+
70
+ `example/components/PoolDebugPanel.js`
@@ -0,0 +1,149 @@
1
+ # Task model
2
+
3
+ Every SMB operation returns a `SmbTask<T>`. Creating the task starts native work immediately. Nothing is subscribed until you ask for it.
4
+
5
+ You can mix three actions on any task:
6
+
7
+ | Action | When | API |
8
+ | ------ | ---- | --- |
9
+ | Get result | You need the return value | `await task.result()` |
10
+ | Watch progress | UI needs updates | `task.subscribe()` or `useSubscribe` |
11
+ | Cancel | User aborts | `task.cancel()` |
12
+
13
+ ## Get the result
14
+
15
+ ```typescript
16
+ import { SMB, type SmbCredentials } from '@cetapod/react-native-smb';
17
+
18
+ const smb = SMB();
19
+ const creds: SmbCredentials = { username: 'user', password: 'pass' };
20
+
21
+ await smb.connect('smb://192.168.1.100/Share', creds).result();
22
+
23
+ const files = await smb.listDirectory('/', false, -1).result();
24
+ await smb.downloadFile('/doc.pdf', '/local/doc.pdf').result();
25
+ ```
26
+
27
+ Hold the handle and await later:
28
+
29
+ ```typescript
30
+ const task = smb.copyItem('/src', '/dst', true);
31
+ await task.result();
32
+ ```
33
+
34
+ Run several tasks and collect outcomes (like `Promise.allSettled`):
35
+
36
+ ```typescript
37
+ import { SmbTask } from '@cetapod/react-native-smb';
38
+
39
+ const tasks = files.map((f) => smb.deleteItem(f.path));
40
+ const results = await SmbTask.settleAll(tasks);
41
+ ```
42
+
43
+ ## Watch progress
44
+
45
+ Imperative:
46
+
47
+ ```typescript
48
+ const task = smb.downloadFile(remote, local);
49
+
50
+ const unsub = task.subscribe(); // live task.progress / task.status
51
+ // or:
52
+ const unsub2 = task.subscribe((snap) => {
53
+ console.log(snap.progress, snap.bytesPerSecond, snap.status);
54
+ });
55
+
56
+ task.cancel();
57
+ unsub();
58
+ ```
59
+
60
+ React — `useSubscribe` subscribes automatically on mount and unsubscribes on unmount / task change:
61
+
62
+ ```tsx
63
+ import { useSubscribe, statusLabel } from '@cetapod/react-native-smb';
64
+
65
+ function DownloadBar({ task }) {
66
+ const { progress, status, cancel } = useSubscribe(task);
67
+
68
+ return (
69
+ <>
70
+ <Text>{Math.round(progress * 100)}%</Text>
71
+ <Text>{statusLabel(status)}</Text>
72
+ <Button onPress={cancel} title="Cancel" />
73
+ </>
74
+ );
75
+ }
76
+ ```
77
+
78
+ `progress` and `status` on the task object are live getters. Don't destructure them at creation time — read them after subscribing (`task.subscribe()`), or use `useSubscribe`, which subscribes for you.
79
+
80
+ ### Snapshot fields
81
+
82
+ `subscribe` and `get()` return `SmbTaskState`:
83
+
84
+ | Field | Description |
85
+ | ----- | ----------- |
86
+ | `progress` | `0–1` (determinate for transfers) |
87
+ | `status` | `TaskStatus` enum |
88
+ | `bytesDone` / `totalBytes` | Raw byte counts |
89
+ | `bytesPerSecond` / `etaSeconds` | Throughput estimate |
90
+ | `determinate` | `true` for download/upload/copy |
91
+ | `sourcePath` / `destinationPath` | Paths for transfer ops |
92
+ | `errorCode` / `errorMessage` | Set on failure |
93
+
94
+ ## Fire-and-forget
95
+
96
+ Start work without awaiting — useful for bulk ops with a transfer tray:
97
+
98
+ ```typescript
99
+ files.forEach((f) => smb.downloadFile(f.remote, f.local));
100
+ ```
101
+
102
+ Refresh when everything settles:
103
+
104
+ ```typescript
105
+ const tasks = files.map((f) => smb.deleteItem(f.path));
106
+ void SmbTask.settleAll(tasks).then(() => reload());
107
+ ```
108
+
109
+ ### Transfer tray hooks
110
+
111
+ ```typescript
112
+ import { useTransfers, useTransferActions } from '@cetapod/react-native-smb';
113
+
114
+ function TransferTray({ smb }) {
115
+ const tasks = useTransfers(smb);
116
+ const { clearCompleted, hide } = useTransferActions(smb);
117
+
118
+ // tasks is SmbTaskState[] — all active transfers in the client store
119
+ }
120
+ ```
121
+
122
+ The example app's `TransferTrayPanel` shows this pattern end-to-end.
123
+
124
+ ## Error handling
125
+
126
+ ```typescript
127
+ import { SMB, SmbError, SmbTaskError } from '@cetapod/react-native-smb';
128
+
129
+ try {
130
+ await smb.getPathInfo('/nonexistent').result();
131
+ } catch (error) {
132
+ if (error instanceof SmbTaskError) {
133
+ if (error.code === SmbError.NotFound) { /* ... */ }
134
+ if (error.code === SmbError.AccessDenied) { /* ... */ }
135
+ }
136
+ }
137
+ ```
138
+
139
+ `SmbTaskError` carries `code` (`SmbError` enum) and optional `taskId`.
140
+
141
+ ## Lifecycle
142
+
143
+ When you're done with a client instance (e.g. user logs out), call `dispose()` to stop the transfer store listener:
144
+
145
+ ```typescript
146
+ smb.dispose();
147
+ ```
148
+
149
+ Sync state checks (`isConnected`, `isInitialized`) are available anytime without a task.
@@ -0,0 +1,172 @@
1
+ /* -*- mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil; -*- */
2
+ /*
3
+ Copyright (C) 2020 by Ronnie Sahlberg <ronniesahlberg@gmail.com>
4
+
5
+ This program is free software; you can redistribute it and/or modify
6
+ it under the terms of the GNU Lesser General Public License as published by
7
+ the Free Software Foundation; either version 2.1 of the License, or
8
+ (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU Lesser General Public License for more details.
14
+
15
+ You should have received a copy of the GNU Lesser General Public License
16
+ along with this program; if not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ #ifndef _LIBSMB2_DCERPC_LSA_H_
20
+ #define _LIBSMB2_DCERPC_LSA_H_
21
+
22
+ #ifdef __cplusplus
23
+ extern "C" {
24
+ #endif
25
+
26
+ #define LSA_CLOSE 0x00
27
+ #define LSA_OPENPOLICY2 0x2c
28
+ #define LSA_LOOKUPSIDS2 0x39
29
+
30
+ /* Access Mask. LSA specific flags. */
31
+ #define POLICY_VIEW_LOCAL_INFORMATION 0x00000001
32
+ #define POLICY_VIEW_AUDIT_INFORMATION 0x00000002
33
+ #define POLICY_GET_PRIVATE_INFORMATION 0x00000004
34
+ #define POLICY_TRUST_ADMIN 0x00000008
35
+ #define POLICY_CREATE_ACCOUNT 0x00000010
36
+ #define POLICY_CREATE_SECRET 0x00000020
37
+ #define POLICY_CREATE_PRIVILEGE 0x00000040
38
+ #define POLICY_SET_DEFAULT_QUOTA_LIMITS 0x00000080
39
+ #define POLICY_SET_AUDIT_REQUIREMENTS 0x00000100
40
+ #define POLICY_AUDIT_LOG_ADMIN 0x00000200
41
+ #define POLICY_SERVER_ADMIN 0x00000400
42
+ #define POLICY_LOOKUP_NAMES 0x00000800
43
+ #define POLICY_NOTIFICATION 0x00001000
44
+
45
+ extern unsigned char NT_SID_AUTHORITY[6];
46
+
47
+ typedef struct RPC_SID {
48
+ uint8_t Revision;
49
+ uint8_t SubAuthorityCount;
50
+ uint8_t IdentifierAuthority[6];
51
+ uint32_t *SubAuthority;
52
+ } RPC_SID, *PRPC_SID;
53
+
54
+ typedef struct _LSAPR_TRANSLATED_NAME_EX {
55
+ uint32_t Use;
56
+ char *Name;
57
+ uint32_t DomainIndex;
58
+ uint32_t Flags;
59
+ } LSAPR_TRANSLATED_NAME_EX, *PLSAPR_TRANSLATED_NAME_EX;
60
+
61
+ typedef struct _LSAPR_TRANSLATED_NAMES_EX {
62
+ uint32_t Entries;
63
+ LSAPR_TRANSLATED_NAME_EX *Names;
64
+ } LSAPR_TRANSLATED_NAMES_EX, *PLSAPR_TRANSLATED_NAMES_EX;
65
+
66
+ typedef struct _SID_ENUM_BUFFER {
67
+ uint32_t Entries;
68
+ PRPC_SID *SidInfo;
69
+ } LSAPR_SID_ENUM_BUFFER, *PLSAPR_SID_ENUM_BUFFER;
70
+
71
+ typedef enum _LSAP_LOOKUP_LEVEL {
72
+ LsapLookupWksta = 1,
73
+ LsapLookupPDC,
74
+ LsapLookupTDL,
75
+ LsapLookupGC,
76
+ LsapLookupXForestReferral,
77
+ LsapLookupXForestResolve,
78
+ LsapLookupRODCReferralToFullDC
79
+ } LSAP_LOOKUP_LEVEL, *PLSAP_LOOKUP_LEVEL;
80
+
81
+ typedef struct _LSAPR_TRUST_INFORMATION {
82
+ char *Name;
83
+ RPC_SID Sid;
84
+ } LSAPR_TRUST_INFORMATION, *PLSAPR_TRUST_INFORMATION;
85
+
86
+ typedef struct _LSAPR_REFERENCED_DOMAIN_LIST {
87
+ uint32_t Entries;
88
+ LSAPR_TRUST_INFORMATION *Domains;
89
+ uint32_t MaxEntries; /* must be ignored */
90
+ } LSAPR_REFERENCED_DOMAIN_LIST, *PLSAPR_REFERENCED_DOMAIN_LIST;
91
+
92
+ /* For OPENPOLICY2: RootDirectory MUST be zero. Everything else is ignored. */
93
+ typedef struct _LSAPR_OBJECT_ATTRIBUTES {
94
+ uint32_t Length;
95
+ unsigned char *RootDirectory;
96
+ void *ObjectName;
97
+ uint32_t Attributes;
98
+ void *SecurityDescriptor;
99
+ void *SecurityQualityOfService;
100
+ } LSAPR_OBJECT_ATTRIBUTES, *PLSAPR_OBJECT_ATTRIBUTES;
101
+
102
+ struct lsa_close_req {
103
+ struct ndr_context_handle PolicyHandle;
104
+ };
105
+
106
+ struct lsa_close_rep {
107
+ uint32_t status;
108
+
109
+ struct ndr_context_handle PolicyHandle;
110
+ };
111
+
112
+ struct lsa_openpolicy2_req {
113
+ char *SystemName;
114
+ LSAPR_OBJECT_ATTRIBUTES ObjectAttributes;
115
+ uint32_t DesiredAccess;
116
+ };
117
+
118
+ struct lsa_openpolicy2_rep {
119
+ uint32_t status;
120
+
121
+ struct ndr_context_handle PolicyHandle;
122
+ };
123
+
124
+ struct lsa_lookupsids2_req {
125
+ struct ndr_context_handle PolicyHandle;
126
+ LSAPR_SID_ENUM_BUFFER SidEnumBuffer;
127
+ LSAPR_TRANSLATED_NAMES_EX TranslatedNames;
128
+ LSAP_LOOKUP_LEVEL LookupLevel;
129
+ };
130
+
131
+ struct lsa_lookupsids2_rep {
132
+ uint32_t status;
133
+
134
+ LSAPR_REFERENCED_DOMAIN_LIST ReferencedDomains;
135
+ LSAPR_TRANSLATED_NAMES_EX TranslatedNames;
136
+ uint32_t MappedCount;
137
+ };
138
+
139
+ int lsa_Close_rep_coder(struct dcerpc_context *dce,
140
+ struct dcerpc_pdu *pdu,
141
+ struct smb2_iovec *iov, int *offset,
142
+ void *ptr);
143
+ int lsa_Close_req_coder(struct dcerpc_context *dce,
144
+ struct dcerpc_pdu *pdu,
145
+ struct smb2_iovec *iov, int *offset,
146
+ void *ptr);
147
+ int lsa_LookupSids2_rep_coder(struct dcerpc_context *dce,
148
+ struct dcerpc_pdu *pdu,
149
+ struct smb2_iovec *iov, int *offset,
150
+ void *ptr);
151
+ int lsa_LookupSids2_req_coder(struct dcerpc_context *dce,
152
+ struct dcerpc_pdu *pdu,
153
+ struct smb2_iovec *iov, int *offset,
154
+ void *ptr);
155
+ int lsa_OpenPolicy2_rep_coder(struct dcerpc_context *dce,
156
+ struct dcerpc_pdu *pdu,
157
+ struct smb2_iovec *iov, int *offset,
158
+ void *ptr);
159
+ int lsa_OpenPolicy2_req_coder(struct dcerpc_context *dce,
160
+ struct dcerpc_pdu *pdu,
161
+ struct smb2_iovec *iov, int *offset,
162
+ void *ptr);
163
+ int lsa_RPC_SID_coder(struct dcerpc_context *dce,
164
+ struct dcerpc_pdu *pdu,
165
+ struct smb2_iovec *iov, int *offset,
166
+ void *ptr);
167
+
168
+ #ifdef __cplusplus
169
+ }
170
+ #endif
171
+
172
+ #endif /* !_LIBSMB2_DCERPC_LSA_H_ */
@@ -0,0 +1,180 @@
1
+ /* -*- mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil; -*- */
2
+ /*
3
+ Copyright (C) 2018 by Ronnie Sahlberg <ronniesahlberg@gmail.com>
4
+
5
+ This program is free software; you can redistribute it and/or modify
6
+ it under the terms of the GNU Lesser General Public License as published by
7
+ the Free Software Foundation; either version 2.1 of the License, or
8
+ (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU Lesser General Public License for more details.
14
+
15
+ You should have received a copy of the GNU Lesser General Public License
16
+ along with this program; if not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ #ifndef _LIBSMB2_DCERPC_SRVSVC_H_
20
+ #define _LIBSMB2_DCERPC_SRVSVC_H_
21
+
22
+ #ifdef __cplusplus
23
+ extern "C" {
24
+ #endif
25
+
26
+ #include <smb2/libsmb2-dcerpc.h>
27
+
28
+ #define SRVSVC_NETRSHAREENUM 0x0f
29
+ #define SRVSVC_NETRSHAREGETINFO 0x10
30
+
31
+ struct dcerpc_context;
32
+ struct dcerpc_pdu;
33
+
34
+
35
+ /* Low 2 bits desctibe the type */
36
+ #define SHARE_TYPE_DISKTREE 0
37
+ #define SHARE_TYPE_PRINTQ 1
38
+ #define SHARE_TYPE_DEVICE 2
39
+ #define SHARE_TYPE_IPC 3
40
+
41
+ #define SHARE_TYPE_TEMPORARY 0x40000000
42
+ #define SHARE_TYPE_HIDDEN 0x80000000
43
+
44
+ enum SHARE_INFO_enum {
45
+ SHARE_INFO_0 = 0,
46
+ SHARE_INFO_1 = 1,
47
+ };
48
+
49
+ struct srvsvc_SHARE_INFO_0 {
50
+ struct dcerpc_utf16 netname;
51
+ };
52
+ int srvsvc_SHARE_INFO_0_coder(struct dcerpc_context *ctx,
53
+ struct dcerpc_pdu *pdu,
54
+ struct smb2_iovec *iov, int *offset,
55
+ void *ptr);
56
+
57
+ struct srvsvc_SHARE_INFO_0_carray {
58
+ uint32_t max_count;
59
+ struct srvsvc_SHARE_INFO_0 *share_info_0;
60
+ };
61
+
62
+ struct srvsvc_SHARE_INFO_0_CONTAINER {
63
+ uint32_t EntriesRead;
64
+ struct srvsvc_SHARE_INFO_0_carray *Buffer;
65
+ };
66
+
67
+ struct srvsvc_SHARE_INFO_1 {
68
+ struct dcerpc_utf16 netname;
69
+ uint32_t type;
70
+ struct dcerpc_utf16 remark;
71
+ };
72
+ int srvsvc_SHARE_INFO_1_coder(struct dcerpc_context *ctx,
73
+ struct dcerpc_pdu *pdu,
74
+ struct smb2_iovec *iov, int *offset,
75
+ void *ptr);
76
+
77
+ struct srvsvc_SHARE_INFO_1_carray {
78
+ uint32_t max_count;
79
+ struct srvsvc_SHARE_INFO_1 *share_info_1;
80
+ };
81
+
82
+ struct srvsvc_SHARE_INFO_1_CONTAINER {
83
+ uint32_t EntriesRead;
84
+ struct srvsvc_SHARE_INFO_1_carray *Buffer;
85
+ };
86
+
87
+ int srvsvc_SHARE_INFO_1_CONTAINER_coder(struct dcerpc_context *dce,
88
+ struct dcerpc_pdu *pdu,
89
+ struct smb2_iovec *iov, int *offset,
90
+ void *ptr);
91
+
92
+ struct srvsvc_SHARE_ENUM_UNION {
93
+ uint32_t Level;
94
+ union {
95
+ struct srvsvc_SHARE_INFO_0_CONTAINER Level0;
96
+ struct srvsvc_SHARE_INFO_1_CONTAINER Level1;
97
+ };
98
+ };
99
+
100
+ struct srvsvc_SHARE_ENUM_STRUCT {
101
+ uint32_t Level;
102
+ struct srvsvc_SHARE_ENUM_UNION ShareInfo;
103
+ };
104
+
105
+ struct srvsvc_NetrShareEnum_req {
106
+ struct dcerpc_utf16 ServerName;
107
+ struct srvsvc_SHARE_ENUM_STRUCT ses;
108
+ uint32_t PreferedMaximumLength;
109
+ uint32_t ResumeHandle;
110
+ };
111
+
112
+ struct srvsvc_NetrShareEnum_rep {
113
+ uint32_t status;
114
+
115
+ struct srvsvc_SHARE_ENUM_STRUCT ses;
116
+ uint32_t total_entries;
117
+ uint32_t resume_handle;
118
+ };
119
+
120
+ struct srvsvc_SHARE_INFO {
121
+ uint32_t level;
122
+ union {
123
+ struct srvsvc_SHARE_INFO_1 ShareInfo1;
124
+ };
125
+ };
126
+
127
+ struct srvsvc_NetrShareGetInfo_req {
128
+ struct dcerpc_utf16 ServerName;
129
+ struct dcerpc_utf16 NetName;
130
+ uint32_t Level;
131
+ };
132
+
133
+ struct srvsvc_NetrShareGetInfo_rep {
134
+ uint32_t status;
135
+
136
+ struct srvsvc_SHARE_INFO InfoStruct;
137
+ };
138
+
139
+ struct srvsvc_rep {
140
+ uint32_t status;
141
+ };
142
+
143
+ /*
144
+ * Async share_enum()
145
+ * This function only works when connected to the IPC$ share.
146
+ *
147
+ * Returns
148
+ * 0 : The operation was initiated. Result of the operation will be
149
+ * reported through the callback function.
150
+ * -errno : There was an error. The callback function will not be invoked.
151
+ *
152
+ * When the callback is invoked, status indicates the result:
153
+ * 0 : Success. Command_data is struct srvsvc_NetrShareEnum_rep *
154
+ * This pointer must be freed using smb2_free_data().
155
+ * -errno : An error occurred.
156
+ */
157
+ int smb2_share_enum_async(struct smb2_context *smb2, enum SHARE_INFO_enum level,
158
+ smb2_command_cb cb, void *cb_data);
159
+
160
+ int srvsvc_NetrShareEnum_rep_coder(struct dcerpc_context *dce,
161
+ struct dcerpc_pdu *pdu,
162
+ struct smb2_iovec *iov, int *offset,
163
+ void *ptr);
164
+ int srvsvc_NetrShareEnum_req_coder(struct dcerpc_context *ctx,
165
+ struct dcerpc_pdu *pdu,
166
+ struct smb2_iovec *iov, int *offset,
167
+ void *ptr);
168
+ int srvsvc_NetrShareGetInfo_rep_coder(struct dcerpc_context *dce,
169
+ struct dcerpc_pdu *pdu,
170
+ struct smb2_iovec *iov, int *offset,
171
+ void *ptr);
172
+ int srvsvc_NetrShareGetInfo_req_coder(struct dcerpc_context *ctx,
173
+ struct dcerpc_pdu *pdu,
174
+ struct smb2_iovec *iov, int *offset,
175
+ void *ptr);
176
+ #ifdef __cplusplus
177
+ }
178
+ #endif
179
+
180
+ #endif /* !_LIBSMB2_DCERPC_SRVSVC_H_ */