Leaked source code of windows server 2003
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.

201 lines
4.8 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;
  76. unsigned validReferences = 0;
  77. unsigned consecutiveMaxIndicesSeen = 0;
  78. streamName = (char *)malloc(strlen(argv[1]) + 100);
  79. if (streamName == NULL) {
  80. fprintf(stderr,"Unable to allocate memory\n");
  81. exit(1);
  82. }
  83. strcpy(streamName,argv[1]);
  84. strcat(streamName,":sisBackpointers$");
  85. HANDLE hFile =
  86. CreateFile(
  87. streamName,
  88. GENERIC_READ,
  89. FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
  90. NULL,
  91. OPEN_EXISTING,
  92. FILE_ATTRIBUTE_NORMAL,
  93. NULL);
  94. if (hFile == INVALID_HANDLE_VALUE) {
  95. fprintf(stderr,"Unable to open backpointer stream for file %s, %d\n",streamName,GetLastError());
  96. exit(1);
  97. }
  98. const int backpointerEntriesPerSector = 512 / sizeof(SIS_BACKPOINTER);
  99. PSIS_BACKPOINTER sector = (PSIS_BACKPOINTER) malloc(512);
  100. int firstEntry = TRUE;
  101. assert(sector);
  102. ULONGLONG previousLinkIndex = 0;
  103. for (;;) {
  104. unsigned long bytesRead;
  105. if (!ReadFile(hFile,sector,512,&bytesRead,NULL)) {
  106. fprintf(stderr,"readFile of sector failed %d\n",GetLastError());
  107. exit(1);
  108. }
  109. if (0 == bytesRead) {
  110. break;
  111. }
  112. if (bytesRead < 512) {
  113. fprintf(stderr,"*** read %d of 512 bytes\n",bytesRead);
  114. }
  115. for (unsigned i = 0 ; i < backpointerEntriesPerSector; i++) {
  116. if (firstEntry) {
  117. firstEntry = FALSE;
  118. PSIS_BACKPOINTER_STREAM_HEADER header = (PSIS_BACKPOINTER_STREAM_HEADER)sector;
  119. printf("format version %d, magic 0x%x, checksum 0x%x.0x%x\n\n",
  120. header->FormatVersion,header->Magic,(DWORD)(header->FileContentChecksum >> 32),
  121. (DWORD)header->FileContentChecksum);
  122. } else {
  123. if (MAXLONGLONG != sector[i].LinkFileNtfsId.QuadPart) {
  124. if (0 != consecutiveMaxIndicesSeen) {
  125. printf("%d consecutive MaxIndices (ie., null entries)\n",consecutiveMaxIndicesSeen);
  126. consecutiveMaxIndicesSeen = 0;
  127. }
  128. printf("0x%08x.0x%08x -> 0x%08x.0x%08x\t%c ",sector[i].LinkFileIndex.HighPart,sector[i].LinkFileIndex.LowPart,
  129. sector[i].LinkFileNtfsId.HighPart,sector[i].LinkFileNtfsId.LowPart,
  130. sector[i].LinkFileIndex.QuadPart >= previousLinkIndex ? ' ' : '*');
  131. }
  132. previousLinkIndex = sector[i].LinkFileIndex.QuadPart;
  133. if (MAXLONGLONG == sector[i].LinkFileNtfsId.QuadPart) {
  134. if (0 == consecutiveMaxIndicesSeen) printf("\n");
  135. consecutiveMaxIndicesSeen++;
  136. } else {
  137. if (sector[i].LinkFileNtfsId.LowPart != 0xffffffff || sector[i].LinkFileNtfsId.HighPart != 0x7fffffff) {
  138. validReferences++;
  139. printFileNameById(&sector[i].LinkFileNtfsId,hFile);
  140. }
  141. printf("\n");
  142. }
  143. }
  144. }
  145. }
  146. if (0 != consecutiveMaxIndicesSeen) {
  147. printf("File ends with %d consecutive MaxIndices (ie., null entries)\n", consecutiveMaxIndicesSeen);
  148. }
  149. printf("%d Total valid references\n",validReferences);
  150. }