antfs_directory.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /*
  2. This software is subject to the license described in the License.txt file
  3. included with this software distribution. You may not use this file except
  4. in compliance with this license.
  5. Copyright (c) Dynastream Innovations Inc. 2016
  6. All rights reserved.
  7. */
  8. #include "types.h"
  9. #include "dsi_convert.h"
  10. #include "antfs_directory.h"
  11. typedef struct
  12. {
  13. UCHAR usFileIndexByte0;
  14. UCHAR usFileIndexByte1;
  15. UCHAR ucFileDataType;
  16. UCHAR ucFileSubType;
  17. UCHAR usFileNumberByte0;
  18. UCHAR usFileNumberByte1;
  19. UCHAR ucSpecificFlags;
  20. UCHAR ucGeneralFlags;
  21. UCHAR ulFileSizeByte0;
  22. UCHAR ulFileSizeByte1;
  23. UCHAR ulFileSizeByte2;
  24. UCHAR ulFileSizeByte3;
  25. UCHAR ulTimeStampByte0;
  26. UCHAR ulTimeStampByte1;
  27. UCHAR ulTimeStampByte2;
  28. UCHAR ulTimeStampByte3;
  29. } ANTFSP_DIRECTORY_LOOKUP;
  30. ///////////////////////////////////////////////////////////////////////
  31. ULONG ANTFSDir_GetNumberOfFileEntries(void *pvDirectory_, ULONG ulDirectoryFileLength_)
  32. {
  33. ANTFS_DIRECTORY_HEADER *psDirHeader;
  34. if (pvDirectory_ == NULL)
  35. return 0;
  36. psDirHeader = (ANTFS_DIRECTORY_HEADER*)pvDirectory_;
  37. if (psDirHeader->ucVersion != 1)
  38. return 0;
  39. if (psDirHeader->ucElementLength != 16)
  40. return 0;
  41. if ((sizeof(ANTFS_DIRECTORY_HEADER) + psDirHeader->ucElementLength) > ulDirectoryFileLength_) //return 0 if the directory size is smaller than the header + 1 entry
  42. return 0;
  43. return ((ulDirectoryFileLength_ - sizeof(ANTFS_DIRECTORY_HEADER)) / psDirHeader->ucElementLength);
  44. }
  45. ///////////////////////////////////////////////////////////////////////
  46. BOOL ANTFSDir_LookupFileEntry(void *pvDirectory_, ULONG ulDirectoryFileLength_, ULONG ulFileEntry_, ANTFSP_DIRECTORY *pusDirectoryStruct_)
  47. {
  48. ANTFS_DIRECTORY_HEADER *psDirHeader;
  49. ANTFSP_DIRECTORY_LOOKUP *psCurrentDirElement;
  50. if (pvDirectory_ == NULL)
  51. return FALSE;
  52. psDirHeader = (ANTFS_DIRECTORY_HEADER*)pvDirectory_;
  53. if (psDirHeader->ucVersion != 1)
  54. return FALSE;
  55. if (psDirHeader->ucElementLength != 16)
  56. return FALSE;
  57. if (pusDirectoryStruct_ == (ANTFSP_DIRECTORY*)NULL)
  58. return FALSE;
  59. if ((sizeof(ANTFS_DIRECTORY_HEADER) + ((ulFileEntry_ + 1) * psDirHeader->ucElementLength)) <= ulDirectoryFileLength_)
  60. {
  61. psCurrentDirElement = (ANTFSP_DIRECTORY_LOOKUP *)((UCHAR*)pvDirectory_ + sizeof(ANTFS_DIRECTORY_HEADER) + (psDirHeader->ucElementLength * ulFileEntry_));
  62. pusDirectoryStruct_->usFileIndex = Convert_Bytes_To_USHORT(psCurrentDirElement->usFileIndexByte1,psCurrentDirElement->usFileIndexByte0);
  63. pusDirectoryStruct_->ucFileDataType = psCurrentDirElement->ucFileDataType;
  64. pusDirectoryStruct_->ucFileSubType = psCurrentDirElement->ucFileSubType;
  65. pusDirectoryStruct_->usFileNumber = Convert_Bytes_To_USHORT(psCurrentDirElement->usFileNumberByte1,psCurrentDirElement->usFileNumberByte0);
  66. pusDirectoryStruct_->ucSpecificFlags = psCurrentDirElement->ucSpecificFlags;
  67. pusDirectoryStruct_->ucGeneralFlags = psCurrentDirElement->ucGeneralFlags;
  68. pusDirectoryStruct_->ulFileSize = Convert_Bytes_To_ULONG(psCurrentDirElement->ulFileSizeByte3,psCurrentDirElement->ulFileSizeByte2,psCurrentDirElement->ulFileSizeByte1,psCurrentDirElement->ulFileSizeByte0);
  69. pusDirectoryStruct_->ulTimeStamp = Convert_Bytes_To_ULONG(psCurrentDirElement->ulTimeStampByte3,psCurrentDirElement->ulTimeStampByte2,psCurrentDirElement->ulTimeStampByte1,psCurrentDirElement->ulTimeStampByte0);
  70. return TRUE;
  71. }
  72. return FALSE;
  73. }
  74. ///////////////////////////////////////////////////////////////////////
  75. BOOL ANTFSDir_GetNewFileList(void *pvDirectory_, ULONG ulDirectoryFileLength_, USHORT *pusFileIndexList_, USHORT * pusListLength_)
  76. {
  77. ANTFS_DIRECTORY_HEADER *psDirHeader;
  78. ANTFSP_DIRECTORY_LOOKUP *psCurrentDirElement;
  79. ULONG ulElementNum = 0;
  80. USHORT usNumberOfMatches = 0;
  81. if (pvDirectory_ == NULL)
  82. return FALSE;
  83. psDirHeader = (ANTFS_DIRECTORY_HEADER*)pvDirectory_;
  84. if (psDirHeader->ucVersion != 1)
  85. return FALSE;
  86. if (psDirHeader->ucElementLength != 16)
  87. return FALSE;
  88. while ((sizeof(ANTFS_DIRECTORY_HEADER) + ((ulElementNum + 1) * psDirHeader->ucElementLength)) <= ulDirectoryFileLength_)
  89. {
  90. psCurrentDirElement = (ANTFSP_DIRECTORY_LOOKUP *)((UCHAR*)pvDirectory_ + sizeof(ANTFS_DIRECTORY_HEADER) + (psDirHeader->ucElementLength * ulElementNum));
  91. if (psCurrentDirElement->ucFileDataType == 0x80) //ANTFS+ data type
  92. {
  93. if (psCurrentDirElement->ucFileSubType == 4) //ANTFS+ session sub type
  94. {
  95. if ((!(psCurrentDirElement->ucGeneralFlags & ANTFS_GENERAL_FLAG_ARCHIVE)) &&
  96. (psCurrentDirElement->ucGeneralFlags & ANTFS_GENERAL_FLAG_READ)) //This has never been downloaded and can be read
  97. {
  98. usNumberOfMatches++;
  99. if (pusFileIndexList_ != NULL)
  100. {
  101. *pusFileIndexList_ = Convert_Bytes_To_USHORT(psCurrentDirElement->usFileIndexByte1,psCurrentDirElement->usFileIndexByte0);
  102. pusFileIndexList_ ++;
  103. }
  104. }
  105. }
  106. }
  107. ulElementNum++;
  108. }
  109. if (pusListLength_ != NULL)
  110. *pusListLength_ = usNumberOfMatches;
  111. return TRUE;
  112. }
  113. ///////////////////////////////////////////////////////////////////////
  114. BOOL ANTFSDir_LookupFileIndex(void *pvDirectory_, ULONG ulDirectoryFileLength_, USHORT usFileIndex_, ANTFSP_DIRECTORY *pusDirectoryStruct_)
  115. {
  116. ANTFS_DIRECTORY_HEADER *psDirHeader;
  117. ANTFSP_DIRECTORY_LOOKUP *psCurrentDirElement;
  118. ULONG ulElementNum = 0;
  119. if (pvDirectory_ == NULL)
  120. return FALSE;
  121. psDirHeader = (ANTFS_DIRECTORY_HEADER*)pvDirectory_;
  122. if (psDirHeader->ucVersion != 1)
  123. return FALSE;
  124. if (psDirHeader->ucElementLength != 16)
  125. return FALSE;
  126. if (pusDirectoryStruct_ == (ANTFSP_DIRECTORY*)NULL)
  127. return FALSE;
  128. while ((sizeof(ANTFS_DIRECTORY_HEADER) + ((ulElementNum + 1) * psDirHeader->ucElementLength)) <= ulDirectoryFileLength_)
  129. {
  130. USHORT usCurrentFileIndex;
  131. psCurrentDirElement = (ANTFSP_DIRECTORY_LOOKUP *)((UCHAR*)pvDirectory_ + sizeof(ANTFS_DIRECTORY_HEADER) + (psDirHeader->ucElementLength * ulElementNum));
  132. usCurrentFileIndex = Convert_Bytes_To_USHORT(psCurrentDirElement->usFileIndexByte1,psCurrentDirElement->usFileIndexByte0);
  133. if (usCurrentFileIndex == usFileIndex_) //If this is the index we want.
  134. {
  135. pusDirectoryStruct_->usFileIndex = usCurrentFileIndex;
  136. pusDirectoryStruct_->ucFileDataType = psCurrentDirElement->ucFileDataType;
  137. pusDirectoryStruct_->ucFileSubType = psCurrentDirElement->ucFileSubType;
  138. pusDirectoryStruct_->usFileNumber = Convert_Bytes_To_USHORT(psCurrentDirElement->usFileNumberByte1,psCurrentDirElement->usFileNumberByte0);
  139. pusDirectoryStruct_->ucSpecificFlags = psCurrentDirElement->ucSpecificFlags;
  140. pusDirectoryStruct_->ucGeneralFlags = psCurrentDirElement->ucGeneralFlags;
  141. pusDirectoryStruct_->ulFileSize = Convert_Bytes_To_ULONG(psCurrentDirElement->ulFileSizeByte3,psCurrentDirElement->ulFileSizeByte2,psCurrentDirElement->ulFileSizeByte1,psCurrentDirElement->ulFileSizeByte0);
  142. pusDirectoryStruct_->ulTimeStamp = Convert_Bytes_To_ULONG(psCurrentDirElement->ulTimeStampByte3,psCurrentDirElement->ulTimeStampByte2,psCurrentDirElement->ulTimeStampByte1,psCurrentDirElement->ulTimeStampByte0);
  143. return TRUE;
  144. }
  145. ulElementNum++;
  146. }
  147. return FALSE;
  148. }