github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbfs/dokan/bridge.c (about) 1 // Copyright 2016-2018 Keybase Inc. All rights reserved. 2 // Use of this source code is governed by a BSD 3 // license that can be found in the LICENSE file. 4 5 #if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__) 6 7 #include "bridge.h" 8 9 uintptr_t kbfsLibdokanPtr_RemoveMountPoint; 10 uintptr_t kbfsLibdokanPtr_OpenRequestorToken; 11 uintptr_t kbfsLibdokanPtr_Main; 12 13 extern NTSTATUS kbfsLibdokanCreateFile(LPCWSTR FileName, 14 PDOKAN_IO_SECURITY_CONTEXT psec, 15 ACCESS_MASK DesiredAccess, 16 ULONG FileAttributes, 17 ULONG ShareAccess, 18 ULONG CreateDisposition, 19 ULONG CreateOptions, 20 PDOKAN_FILE_INFO pfi); 21 22 extern DOKAN_CALLBACK NTSTATUS kbfsLibdokanC_CreateFile(LPCWSTR FileName, 23 PDOKAN_IO_SECURITY_CONTEXT psec, 24 ACCESS_MASK DesiredAccess, 25 ULONG FileAttributes, 26 ULONG ShareAccess, 27 ULONG CreateDisposition, 28 ULONG CreateOptions, 29 PDOKAN_FILE_INFO pfi) { 30 return kbfsLibdokanCreateFile(FileName,psec,DesiredAccess,FileAttributes,ShareAccess,CreateDisposition,CreateOptions,pfi); 31 } 32 33 extern void kbfsLibdokanCleanup(LPCWSTR FileName, PDOKAN_FILE_INFO FileInfo); 34 35 static DOKAN_CALLBACK void kbfsLibdokanC_Cleanup(LPCWSTR FileName, PDOKAN_FILE_INFO FileInfo) { 36 kbfsLibdokanCleanup(FileName,FileInfo); 37 } 38 39 extern void kbfsLibdokanCloseFile(LPCWSTR FileName, PDOKAN_FILE_INFO FileInfo); 40 41 static DOKAN_CALLBACK void kbfsLibdokanC_CloseFile(LPCWSTR FileName, PDOKAN_FILE_INFO FileInfo) { 42 kbfsLibdokanCloseFile(FileName,FileInfo); 43 } 44 45 extern NTSTATUS kbfsLibdokanReadFile(LPCWSTR FileName, 46 LPVOID Buffer, 47 DWORD NumberOfBytesToRead, 48 LPDWORD NumberOfBytesRead, 49 LONGLONG Offset, 50 PDOKAN_FILE_INFO FileInfo); 51 52 static DOKAN_CALLBACK NTSTATUS kbfsLibdokanC_ReadFile(LPCWSTR FileName, 53 LPVOID Buffer, 54 DWORD NumberOfBytesToRead, 55 LPDWORD NumberOfBytesRead, 56 LONGLONG Offset, 57 PDOKAN_FILE_INFO FileInfo) { 58 return kbfsLibdokanReadFile(FileName, Buffer, NumberOfBytesToRead, NumberOfBytesRead, Offset, FileInfo); 59 } 60 61 extern NTSTATUS kbfsLibdokanWriteFile(LPCWSTR FileName, 62 LPCVOID Buffer, 63 DWORD NumberOfBytesToWrite, 64 LPDWORD NumberOfBytesWritten, 65 LONGLONG Offset, 66 PDOKAN_FILE_INFO FileInfo); 67 68 static DOKAN_CALLBACK NTSTATUS kbfsLibdokanC_WriteFile(LPCWSTR FileName, 69 LPCVOID Buffer, 70 DWORD NumberOfBytesToWrite, 71 LPDWORD NumberOfBytesWritten, 72 LONGLONG Offset, 73 PDOKAN_FILE_INFO FileInfo) { 74 return kbfsLibdokanWriteFile(FileName, Buffer, NumberOfBytesToWrite, NumberOfBytesWritten, Offset, FileInfo); 75 } 76 77 extern NTSTATUS kbfsLibdokanFlushFileBuffers(LPCWSTR FileName, PDOKAN_FILE_INFO FileInfo); 78 79 static DOKAN_CALLBACK NTSTATUS kbfsLibdokanC_FlushFileBuffers(LPCWSTR FileName, PDOKAN_FILE_INFO FileInfo) { 80 return kbfsLibdokanFlushFileBuffers(FileName, FileInfo); 81 } 82 83 extern NTSTATUS kbfsLibdokanGetFileInformation(LPCWSTR FileName, 84 LPBY_HANDLE_FILE_INFORMATION Buffer, 85 PDOKAN_FILE_INFO FileInfo); 86 87 static DOKAN_CALLBACK NTSTATUS kbfsLibdokanC_GetFileInformation(LPCWSTR FileName, 88 LPBY_HANDLE_FILE_INFORMATION Buffer, 89 PDOKAN_FILE_INFO FileInfo) { 90 return kbfsLibdokanGetFileInformation(FileName, Buffer, FileInfo); 91 } 92 93 extern NTSTATUS kbfsLibdokanFindFiles(LPCWSTR PathName, 94 PFillFindData FindData, // call this function with PWIN32_FIND_DATAW 95 PDOKAN_FILE_INFO FileInfo); 96 97 static DOKAN_CALLBACK NTSTATUS kbfsLibdokanC_FindFiles(LPCWSTR PathName, 98 PFillFindData FindData, // call this function with PWIN32_FIND_DATAW 99 PDOKAN_FILE_INFO FileInfo) { 100 return kbfsLibdokanFindFiles(PathName, FindData, FileInfo); 101 } 102 103 extern NTSTATUS kbfsLibdokanFindFilesWithPattern(LPCWSTR PathName, 104 LPCWSTR SearchPattern, 105 PFillFindData FindData, // call this function with PWIN32_FIND_DATAW 106 PDOKAN_FILE_INFO FileInfo); 107 static DOKAN_CALLBACK NTSTATUS kbfsLibdokanC_FindFilesWithPattern(LPCWSTR PathName, 108 LPCWSTR SearchPattern, 109 PFillFindData FindData, // call this function with PWIN32_FIND_DATAW 110 PDOKAN_FILE_INFO FileInfo) { 111 return kbfsLibdokanFindFilesWithPattern(PathName, SearchPattern, FindData, FileInfo); 112 } 113 114 extern NTSTATUS kbfsLibdokanSetFileAttributes(LPCWSTR FileName, 115 DWORD FileAttributes, 116 PDOKAN_FILE_INFO FileInfo); 117 static DOKAN_CALLBACK NTSTATUS kbfsLibdokanC_SetFileAttributes(LPCWSTR FileName, 118 DWORD FileAttributes, 119 PDOKAN_FILE_INFO FileInfo) { 120 return kbfsLibdokanSetFileAttributes(FileName, FileAttributes, FileInfo); 121 } 122 123 extern NTSTATUS kbfsLibdokanSetFileTime(LPCWSTR FileName, 124 CONST FILETIME* CreationTime, 125 CONST FILETIME* LastAccessTime, 126 CONST FILETIME* LastWriteTime, 127 PDOKAN_FILE_INFO FileInfo); 128 static DOKAN_CALLBACK NTSTATUS kbfsLibdokanC_SetFileTime(LPCWSTR FileName, 129 CONST FILETIME* CreationTime, 130 CONST FILETIME* LastAccessTime, 131 CONST FILETIME* LastWriteTime, 132 PDOKAN_FILE_INFO FileInfo) { 133 return kbfsLibdokanSetFileTime(FileName, CreationTime, LastAccessTime, LastWriteTime, FileInfo); 134 } 135 136 extern NTSTATUS kbfsLibdokanDeleteFile(LPCWSTR FileName, PDOKAN_FILE_INFO FileInfo); 137 138 static DOKAN_CALLBACK NTSTATUS kbfsLibdokanC_DeleteFile(LPCWSTR FileName, PDOKAN_FILE_INFO FileInfo) { 139 return kbfsLibdokanDeleteFile(FileName, FileInfo); 140 } 141 142 extern NTSTATUS kbfsLibdokanDeleteDirectory(LPCWSTR FileName, PDOKAN_FILE_INFO FileInfo); 143 144 static DOKAN_CALLBACK NTSTATUS kbfsLibdokanC_DeleteDirectory(LPCWSTR FileName, PDOKAN_FILE_INFO FileInfo) { 145 return kbfsLibdokanDeleteDirectory(FileName, FileInfo); 146 } 147 148 extern NTSTATUS kbfsLibdokanMoveFile(LPCWSTR ExistingFileName, 149 LPCWSTR NewFileName, 150 BOOL ReplaceExisiting, 151 PDOKAN_FILE_INFO FileInfo); 152 static DOKAN_CALLBACK NTSTATUS kbfsLibdokanC_MoveFile(LPCWSTR ExistingFileName, 153 LPCWSTR NewFileName, 154 BOOL ReplaceExisiting, 155 PDOKAN_FILE_INFO FileInfo) { 156 return kbfsLibdokanMoveFile(ExistingFileName, NewFileName, ReplaceExisiting, FileInfo); 157 } 158 159 extern NTSTATUS kbfsLibdokanSetEndOfFile(LPCWSTR FileName, 160 LONGLONG Length, 161 PDOKAN_FILE_INFO FileInfo); 162 static DOKAN_CALLBACK NTSTATUS kbfsLibdokanC_SetEndOfFile(LPCWSTR FileName, 163 LONGLONG Length, 164 PDOKAN_FILE_INFO FileInfo) { 165 return kbfsLibdokanSetEndOfFile(FileName, Length, FileInfo); 166 } 167 168 extern NTSTATUS kbfsLibdokanSetAllocationSize(LPCWSTR FileName, 169 LONGLONG Length, 170 PDOKAN_FILE_INFO FileInfo); 171 static DOKAN_CALLBACK NTSTATUS kbfsLibdokanC_SetAllocationSize(LPCWSTR FileName, 172 LONGLONG Length, 173 PDOKAN_FILE_INFO FileInfo) { 174 return kbfsLibdokanSetAllocationSize(FileName, Length, FileInfo); 175 } 176 177 extern NTSTATUS kbfsLibdokanLockFile(LPCWSTR FileName, 178 LONGLONG ByteOffset, 179 LONGLONG Length, 180 PDOKAN_FILE_INFO FileInfo); 181 182 static DOKAN_CALLBACK NTSTATUS kbfsLibdokanC_LockFile(LPCWSTR FileName, 183 LONGLONG ByteOffset, 184 LONGLONG Length, 185 PDOKAN_FILE_INFO FileInfo) { 186 return kbfsLibdokanLockFile(FileName, ByteOffset, Length, FileInfo); 187 } 188 189 extern NTSTATUS kbfsLibdokanUnlockFile(LPCWSTR FileName, 190 LONGLONG ByteOffset, 191 LONGLONG Length, 192 PDOKAN_FILE_INFO FileInfo); 193 static DOKAN_CALLBACK NTSTATUS kbfsLibdokanC_UnlockFile(LPCWSTR FileName, 194 LONGLONG ByteOffset, 195 LONGLONG Length, 196 PDOKAN_FILE_INFO FileInfo) { 197 return kbfsLibdokanUnlockFile(FileName, ByteOffset, Length, FileInfo); 198 } 199 200 201 // see Win32 API GetDiskFreeSpaceEx 202 extern NTSTATUS kbfsLibdokanGetDiskFreeSpace(ULONGLONG* FreeBytesAvailable, 203 ULONGLONG* TotalNumberOfBytes, 204 ULONGLONG* TotalNumberOfFreeBytes, 205 PDOKAN_FILE_INFO FileInfo); 206 static DOKAN_CALLBACK NTSTATUS kbfsLibdokanC_GetDiskFreeSpace(PULONGLONG FreeBytesAvailable, 207 PULONGLONG TotalNumberOfBytes, 208 PULONGLONG TotalNumberOfFreeBytes, 209 PDOKAN_FILE_INFO FileInfo) { 210 return kbfsLibdokanGetDiskFreeSpace((ULONGLONG*)FreeBytesAvailable, (ULONGLONG*)TotalNumberOfBytes, (ULONGLONG*)TotalNumberOfFreeBytes, FileInfo); 211 } 212 213 // see Win32 API GetVolumeInformation 214 extern NTSTATUS kbfsLibdokanGetVolumeInformation(LPWSTR VolumeNameBuffer, 215 DWORD VolumeNameSize, // in num of chars 216 LPDWORD VolumeSerialNumber, 217 LPDWORD MaximumComponentLength, // in num of chars 218 LPDWORD FileSystemFlags, 219 LPWSTR FileSystemNameBuffer, 220 DWORD FileSystemNameSize, // in num of chars 221 PDOKAN_FILE_INFO FileInfo); 222 static DOKAN_CALLBACK NTSTATUS kbfsLibdokanC_GetVolumeInformation(LPWSTR VolumeNameBuffer, 223 DWORD VolumeNameSize, // in num of chars 224 LPDWORD VolumeSerialNumber, 225 LPDWORD MaximumComponentLength, // in num of chars 226 LPDWORD FileSystemFlags, 227 LPWSTR FileSystemNameBuffer, 228 DWORD FileSystemNameSize, // in num of chars 229 PDOKAN_FILE_INFO FileInfo) { 230 return kbfsLibdokanGetVolumeInformation(VolumeNameBuffer, VolumeNameSize, VolumeSerialNumber, MaximumComponentLength, FileSystemFlags, FileSystemNameBuffer, FileSystemNameSize, FileInfo); 231 } 232 233 extern NTSTATUS kbfsLibdokanMounted(PDOKAN_FILE_INFO FileInfo); 234 static DOKAN_CALLBACK NTSTATUS kbfsLibdokanC_Mounted(PDOKAN_FILE_INFO FileInfo) { 235 return kbfsLibdokanMounted(FileInfo); 236 } 237 238 extern NTSTATUS kbfsLibdokanGetFileSecurity(LPCWSTR FileName, 239 //A pointer to SECURITY_INFORMATION value being requested 240 PSECURITY_INFORMATION input, 241 // A pointer to SECURITY_DESCRIPTOR buffer to be filled 242 PSECURITY_DESCRIPTOR output, 243 ULONG outlen,// length of Security descriptor buffer 244 PULONG LengthNeeded, 245 PDOKAN_FILE_INFO FileInfo); 246 static DOKAN_CALLBACK NTSTATUS kbfsLibdokanC_GetFileSecurity(LPCWSTR FileName, 247 //A pointer to SECURITY_INFORMATION value being requested 248 PSECURITY_INFORMATION input, 249 // A pointer to SECURITY_DESCRIPTOR buffer to be filled 250 PSECURITY_DESCRIPTOR output, 251 ULONG outlen,// length of Security descriptor buffer 252 PULONG LengthNeeded, 253 PDOKAN_FILE_INFO FileInfo) { 254 return kbfsLibdokanGetFileSecurity(FileName, input, output, outlen, LengthNeeded, FileInfo); 255 } 256 257 extern NTSTATUS kbfsLibdokanSetFileSecurity(LPCWSTR FileName, 258 PSECURITY_INFORMATION SecurityInformation, 259 PSECURITY_DESCRIPTOR SecurityDescriptor, 260 ULONG SecurityDescriptorLength, 261 PDOKAN_FILE_INFO FileInfo); 262 static DOKAN_CALLBACK NTSTATUS kbfsLibdokanC_SetFileSecurity(LPCWSTR FileName, 263 PSECURITY_INFORMATION SecurityInformation, 264 PSECURITY_DESCRIPTOR SecurityDescriptor, 265 ULONG SecurityDescriptorLength, 266 PDOKAN_FILE_INFO FileInfo) { 267 return kbfsLibdokanSetFileSecurity(FileName, SecurityInformation, SecurityDescriptor, SecurityDescriptorLength, FileInfo); 268 } 269 270 /* 271 extern NTSTATUS kbfsLibdokanFindStreams(LPCWSTR FileName, 272 // call this function with PWIN32_FIND_STREAM_DATA 273 PFillFindStreamData FindStreamData, 274 PDOKAN_FILE_INFO FileInfo); 275 */ 276 277 278 279 struct kbfsLibdokanCtx* kbfsLibdokanAllocCtx(ULONG64 slot) { 280 struct kbfsLibdokanCtx *ctx = malloc(sizeof(struct kbfsLibdokanCtx)); 281 if(!ctx) 282 return ctx; 283 memset(ctx, 0, sizeof(struct kbfsLibdokanCtx)); 284 ctx->dokan_options.Version = DOKAN_VERSION; 285 // Dokan timeout 10 minutes... Disables - was related to dokan crashes! 286 // ctx->dokan_options.Timeout = 600 * 1000; 287 ctx->dokan_options.GlobalContext = slot; 288 289 ctx->dokan_operations.ZwCreateFile = kbfsLibdokanC_CreateFile; 290 ctx->dokan_operations.Cleanup = kbfsLibdokanC_Cleanup; 291 ctx->dokan_operations.CloseFile = kbfsLibdokanC_CloseFile; 292 ctx->dokan_operations.ReadFile = kbfsLibdokanC_ReadFile; 293 ctx->dokan_operations.WriteFile = kbfsLibdokanC_WriteFile; 294 ctx->dokan_operations.FlushFileBuffers = kbfsLibdokanC_FlushFileBuffers; 295 ctx->dokan_operations.GetFileInformation = kbfsLibdokanC_GetFileInformation; 296 ctx->dokan_operations.FindFiles = kbfsLibdokanC_FindFiles; 297 ctx->dokan_operations.SetFileAttributes = kbfsLibdokanC_SetFileAttributes; 298 ctx->dokan_operations.SetFileTime = kbfsLibdokanC_SetFileTime; 299 ctx->dokan_operations.DeleteFile = kbfsLibdokanC_DeleteFile; 300 ctx->dokan_operations.DeleteDirectory = kbfsLibdokanC_DeleteDirectory; 301 ctx->dokan_operations.MoveFile = kbfsLibdokanC_MoveFile; 302 ctx->dokan_operations.SetEndOfFile = kbfsLibdokanC_SetEndOfFile; 303 ctx->dokan_operations.SetAllocationSize = kbfsLibdokanC_SetAllocationSize; 304 ctx->dokan_operations.LockFile = kbfsLibdokanC_LockFile; 305 ctx->dokan_operations.UnlockFile = kbfsLibdokanC_UnlockFile; 306 ctx->dokan_operations.GetDiskFreeSpace = kbfsLibdokanC_GetDiskFreeSpace; 307 ctx->dokan_operations.GetVolumeInformation = kbfsLibdokanC_GetVolumeInformation; 308 ctx->dokan_operations.Mounted = kbfsLibdokanC_Mounted; 309 ctx->dokan_operations.GetFileSecurity = kbfsLibdokanC_GetFileSecurity; 310 ctx->dokan_operations.SetFileSecurity = kbfsLibdokanC_SetFileSecurity; 311 // FIXME: Multiple streams per file for e.g. resource forks 312 // ctx->dokan_operations.FindStreams = kbfsLibdokanC_FindStreams; 313 return ctx; 314 } 315 316 void kbfsLibdokanSet_path(struct kbfsLibdokanCtx* ctx, void* ptr) { 317 if(ctx->dokan_options.MountPoint) 318 free((void*)ctx->dokan_options.MountPoint); 319 ctx->dokan_options.MountPoint = wcsdup(ptr); 320 } 321 322 error_t kbfsLibdokanFree(struct kbfsLibdokanCtx* ctx) { 323 if(ctx) { 324 if(ctx->dokan_options.MountPoint) 325 free((void*)ctx->dokan_options.MountPoint); 326 free(ctx); 327 } 328 return 0; 329 } 330 331 error_t kbfsLibdokanRun(struct kbfsLibdokanCtx* ctx) { 332 int __stdcall (*dokanMain)(PDOKAN_OPTIONS DokanOptions, PDOKAN_OPERATIONS DokanOperations) = (void*)kbfsLibdokanPtr_Main; 333 if(!dokanMain) 334 return kbfsLibDokan_DLL_LOAD_ERROR; 335 if((ctx->dokan_options.Options & kbfsLibdokanUseFindFilesWithPattern) != 0) { 336 ctx->dokan_options.Options &= ~kbfsLibdokanUseFindFilesWithPattern; 337 ctx->dokan_operations.FindFilesWithPattern = kbfsLibdokanC_FindFilesWithPattern; 338 } 339 int status = (*dokanMain)(&ctx->dokan_options, &ctx->dokan_operations); 340 return status; 341 } 342 343 int kbfsLibdokanFill_find(PFillFindData fptr, PWIN32_FIND_DATAW a1, PDOKAN_FILE_INFO a2) { 344 return fptr(a1, a2); 345 } 346 347 BOOL kbfsLibdokan_RemoveMountPoint(LPCWSTR MountPoint) { 348 BOOL __stdcall (*removeMountPoint)(LPCWSTR MountPoint) = (void*)kbfsLibdokanPtr_RemoveMountPoint; 349 if(!removeMountPoint) 350 return 0; 351 return (*removeMountPoint)(MountPoint); 352 } 353 354 355 void* kbfsLibdokan_OpenRequestorToken(PDOKAN_FILE_INFO DokanFileInfo) { 356 HANDLE __stdcall (*openRequestorToken)(PDOKAN_FILE_INFO DokanFileInfo) = (void*)kbfsLibdokanPtr_OpenRequestorToken; 357 if(!openRequestorToken) 358 return (void*)INVALID_HANDLE_VALUE; 359 return (void*)((*openRequestorToken)(DokanFileInfo)); 360 } 361 362 ULONG kbfsLibDokan_GetVersion(uintptr_t proc) { 363 if(!proc) 364 return 0; 365 ULONG __stdcall (*fun)() = (void*)proc; 366 return fun(); 367 } 368 369 370 #endif /* windows check */