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 */