Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

195 lines
4.5 KiB

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <nt.h>
  4. #include <ntrtl.h>
  5. #include <nturtl.h>
  6. #include <ntioapi.h>
  7. #include <windows.h>
  8. #include <fcntl.h>
  9. #include <string.h>
  10. #include <assert.h>
  11. #include "..\..\filter\sis.h"
  12. void usage(void)
  13. {
  14. fprintf(stderr,"usage: refcount CommonStoreFileName\n");
  15. fprintf(stderr," prints out the backpointer stream info for the given CS file.\n");
  16. exit(1);
  17. }
  18. void
  19. printFileNameById(
  20. PLARGE_INTEGER fileId,
  21. HANDLE hFile) // hFile is for any file on the same volume as fileId
  22. {
  23. UNICODE_STRING fileIdString[1];
  24. NTSTATUS status;
  25. OBJECT_ATTRIBUTES Obja[1];
  26. HANDLE fileByIdHandle = NULL;
  27. IO_STATUS_BLOCK Iosb[1];
  28. struct {
  29. FILE_NAME_INFORMATION nameFileInfo[1];
  30. WCHAR nameBuffer[255];
  31. } nameFile;
  32. memset(&nameFile, 0, sizeof(nameFile));
  33. fileIdString->Length = fileIdString->MaximumLength = sizeof(LARGE_INTEGER);
  34. fileIdString->Buffer = (PWCHAR)fileId;
  35. InitializeObjectAttributes(
  36. Obja,
  37. fileIdString,
  38. OBJ_CASE_INSENSITIVE,
  39. hFile,
  40. NULL); // security descriptor
  41. status = NtCreateFile(
  42. &fileByIdHandle,
  43. FILE_READ_ATTRIBUTES | SYNCHRONIZE,
  44. Obja,
  45. Iosb,
  46. NULL, // allocation size
  47. FILE_ATTRIBUTE_NORMAL,
  48. FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
  49. FILE_OPEN,
  50. FILE_NON_DIRECTORY_FILE | FILE_OPEN_BY_FILE_ID,
  51. NULL, // EA buffer
  52. 0); // EA length
  53. if (!NT_SUCCESS(status)) {
  54. printf("open failed 0x%x",status);
  55. return;
  56. }
  57. status = NtQueryInformationFile(
  58. fileByIdHandle,
  59. Iosb,
  60. nameFile.nameFileInfo,
  61. sizeof(nameFile),
  62. FileNameInformation);
  63. if (!NT_SUCCESS(status)) {
  64. printf("couldn't query name 0x%x",status);
  65. NtClose(fileByIdHandle);
  66. return;
  67. }
  68. printf("%ws",nameFile.nameFileInfo->FileName);
  69. NtClose(fileByIdHandle);
  70. return;
  71. }
  72. void __cdecl main(int argc, char **argv)
  73. {
  74. if (argc != 2) usage();
  75. char *streamName = (char *)malloc(strlen(argv[1]) + 100);
  76. unsigned validReferences = 0;
  77. unsigned consecutiveMaxIndicesSeen = 0;
  78. strcpy(streamName,argv[1]);
  79. strcat(streamName,":sisBackpointers$");
  80. HANDLE hFile =
  81. CreateFile(
  82. streamName,
  83. GENERIC_READ,
  84. FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
  85. NULL,
  86. OPEN_EXISTING,
  87. FILE_ATTRIBUTE_NORMAL,
  88. NULL);
  89. if (hFile == INVALID_HANDLE_VALUE) {
  90. fprintf(stderr,"Unable to open backpointer stream for file %s, %d\n",streamName,GetLastError());
  91. exit(1);
  92. }
  93. const int backpointerEntriesPerSector = 512 / sizeof(SIS_BACKPOINTER);
  94. PSIS_BACKPOINTER sector = (PSIS_BACKPOINTER) malloc(512);
  95. int firstEntry = TRUE;
  96. assert(sector);
  97. ULONGLONG previousLinkIndex = 0;
  98. for (;;) {
  99. unsigned long bytesRead;
  100. if (!ReadFile(hFile,sector,512,&bytesRead,NULL)) {
  101. fprintf(stderr,"readFile of sector failed %d\n",GetLastError());
  102. exit(1);
  103. }
  104. if (0 == bytesRead) {
  105. break;
  106. }
  107. if (bytesRead < 512) {
  108. fprintf(stderr,"*** read %d of 512 bytes\n",bytesRead);
  109. }
  110. for (unsigned i = 0 ; i < backpointerEntriesPerSector; i++) {
  111. if (firstEntry) {
  112. firstEntry = FALSE;
  113. PSIS_BACKPOINTER_STREAM_HEADER header = (PSIS_BACKPOINTER_STREAM_HEADER)sector;
  114. printf("format version %d, magic 0x%x, checksum 0x%x.0x%x\n\n",
  115. header->FormatVersion,header->Magic,(DWORD)(header->FileContentChecksum >> 32),
  116. (DWORD)header->FileContentChecksum);
  117. } else {
  118. if (MAXLONGLONG != sector[i].LinkFileNtfsId.QuadPart) {
  119. if (0 != consecutiveMaxIndicesSeen) {
  120. printf("%d consecutive MaxIndices (ie., null entries)\n",consecutiveMaxIndicesSeen);
  121. consecutiveMaxIndicesSeen = 0;
  122. }
  123. printf("0x%08x.0x%08x -> 0x%08x.0x%08x\t%c ",sector[i].LinkFileIndex.HighPart,sector[i].LinkFileIndex.LowPart,
  124. sector[i].LinkFileNtfsId.HighPart,sector[i].LinkFileNtfsId.LowPart,
  125. sector[i].LinkFileIndex.QuadPart >= previousLinkIndex ? ' ' : '*');
  126. }
  127. previousLinkIndex = sector[i].LinkFileIndex.QuadPart;
  128. if (MAXLONGLONG == sector[i].LinkFileNtfsId.QuadPart) {
  129. if (0 == consecutiveMaxIndicesSeen) printf("\n");
  130. consecutiveMaxIndicesSeen++;
  131. } else {
  132. if (sector[i].LinkFileNtfsId.LowPart != 0xffffffff || sector[i].LinkFileNtfsId.HighPart != 0x7fffffff) {
  133. validReferences++;
  134. printFileNameById(&sector[i].LinkFileNtfsId,hFile);
  135. }
  136. printf("\n");
  137. }
  138. }
  139. }
  140. }
  141. if (0 != consecutiveMaxIndicesSeen) {
  142. printf("File ends with %d consecutive MaxIndices (ie., null entries)\n", consecutiveMaxIndicesSeen);
  143. }
  144. printf("%d Total valid references\n",validReferences);
  145. }