read_write.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. #include <stdlib.h>
  2. #include "debug.h"
  3. #include "file.h"
  4. #include "read_write.h"
  5. #include "inode.h"
  6. int MxfsReadBlocks(MINIX_FS *FileSys, void *Buffer, unsigned FirstBlock, unsigned BlocksCount)
  7. {
  8. while(BlocksCount > 0)
  9. {
  10. int Result = MxfsCacheRead(FileSys, Buffer, FirstBlock, 0, MINIX_BLOCK_SIZE);
  11. if(Result < 0)
  12. return Result;
  13. Buffer = ((PBYTE)Buffer) + MINIX_BLOCK_SIZE;
  14. ++FirstBlock;
  15. --BlocksCount;
  16. }
  17. return 0;
  18. }
  19. int DOKAN_CALLBACK MxfsReadFile(
  20. LPCWSTR FileName,
  21. LPVOID Buffer,
  22. DWORD NumberOfBytesToRead,
  23. LPDWORD NumberOfBytesRead,
  24. LONGLONG Offset,
  25. PDOKAN_FILE_INFO FileInfo)
  26. {
  27. TRACE("%ls %lu %I64u", FileName, NumberOfBytesToRead, Offset);
  28. MINIX_FS *FileSys = (MINIX_FS*)(LONG_PTR)FileInfo->DokanOptions->GlobalContext;
  29. FILE_CTX *FileCtx = (FILE_CTX*)(LONG_PTR)FileInfo->Context;
  30. if(!FileCtx || Offset < 0)
  31. {
  32. ERR("Invalid params %p %I64d\n", FileCtx, Offset);
  33. return -ERROR_INVALID_PARAMETER;
  34. }
  35. ASSERT(FileCtx && Offset >= 0);
  36. minix_inode Info;
  37. int Result = MxfsReadInode(FileSys, FileCtx->Index, &Info);
  38. if(Result < 0)
  39. return Result;
  40. *NumberOfBytesRead = 0;
  41. if(Offset > FileCtx->Length)
  42. Offset = FileCtx->Length;
  43. if(Offset + NumberOfBytesToRead > FileCtx->Length)
  44. NumberOfBytesToRead = FileCtx->Length - Offset;
  45. while(NumberOfBytesToRead > 0)
  46. {
  47. int Block = MxfsGetBlockFromFileOffset(FileSys, FileCtx->Index, &Info, Offset, FALSE);
  48. if(Block < 0)
  49. return Block;
  50. unsigned ChunkOffset = Offset % MINIX_BLOCK_SIZE;
  51. unsigned ChunkLength = min(NumberOfBytesToRead, MINIX_BLOCK_SIZE - ChunkOffset);
  52. int Result = MxfsCacheRead(FileSys, Buffer, Block, ChunkOffset, ChunkLength);
  53. if(Result < 0)
  54. return Result;
  55. Buffer = ((PBYTE)Buffer) + ChunkLength;
  56. Offset += ChunkLength;
  57. NumberOfBytesToRead -= ChunkLength;
  58. *NumberOfBytesRead += ChunkLength;
  59. }
  60. return 0;
  61. }
  62. int DOKAN_CALLBACK MxfsWriteFile(
  63. LPCWSTR FileName,
  64. LPCVOID Buffer,
  65. DWORD NumberOfBytesToWrite,
  66. LPDWORD NumberOfBytesWritten,
  67. LONGLONG Offset,
  68. PDOKAN_FILE_INFO FileInfo)
  69. {
  70. TRACE("%ls %lu %I64d\n", FileName, NumberOfBytesToWrite, Offset);
  71. MINIX_FS *FileSys = (MINIX_FS*)(LONG_PTR)FileInfo->DokanOptions->GlobalContext;
  72. FILE_CTX *FileCtx = (FILE_CTX*)(LONG_PTR)FileInfo->Context;
  73. ASSERT(FileCtx && Offset >= 0);
  74. minix_inode Info;
  75. int Result = MxfsReadInode(FileSys, FileCtx->Index, &Info);
  76. if(Result < 0)
  77. return Result;
  78. *NumberOfBytesWritten = 0;
  79. if(Offset > FileCtx->Length)
  80. Offset = FileCtx->Length;
  81. while(NumberOfBytesToWrite > 0)
  82. {
  83. int Block = MxfsGetBlockFromFileOffset(FileSys, FileCtx->Index, &Info, Offset, TRUE);
  84. if(Block < 0)
  85. {
  86. ERR("MxfsGetBlockFromFileOffset failed %I64d\n", Offset);
  87. Result = Block;
  88. break;
  89. }
  90. unsigned ChunkOffset = Offset % MINIX_BLOCK_SIZE;
  91. unsigned ChunkLength = min(NumberOfBytesToWrite, MINIX_BLOCK_SIZE - ChunkOffset);
  92. Result = MxfsCacheWrite(FileSys, Buffer, Block, ChunkOffset, ChunkLength);
  93. if(Result < 0)
  94. break;
  95. Buffer = ((PBYTE)Buffer) + ChunkLength;
  96. Offset += ChunkLength;
  97. NumberOfBytesToWrite -= ChunkLength;
  98. *NumberOfBytesWritten += ChunkLength;
  99. }
  100. if(*NumberOfBytesWritten > 0)
  101. {
  102. if(Offset > FileCtx->Length)
  103. FileCtx->Length = Offset;
  104. FileCtx->Changed = TRUE;
  105. }
  106. return Result;
  107. }