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.

334 lines
8.9 KiB

  1. #pragma warning(disable:4201) /* anonymous unions */
  2. #pragma warning(disable:4115) /* named type definition in parentheses */
  3. #pragma warning(disable:4100) /* unreferenced formal parameter */
  4. #pragma warning(disable:4100) /* unreferenced formal parameter */
  5. #pragma warning(disable:4706) /* assignment within conditional expression */
  6. #include <stdio.h>
  7. #include "windows.h"
  8. #include "winerror.h"
  9. #include "imagehlp.h"
  10. #include "lib.h"
  11. int FindCharInString(PCSTR StringToSearch, int CharToFind)
  12. {
  13. int i = 0;
  14. int UpperCharToFind = 0;
  15. int LowerCharToFind = 0;
  16. UpperCharToFind = TO_UPPER(CharToFind);
  17. LowerCharToFind = TO_LOWER(CharToFind);
  18. for (i = 0 ; StringToSearch[i]; ++i)
  19. if (StringToSearch[i] == LowerCharToFind
  20. || StringToSearch[i] == UpperCharToFind
  21. )
  22. return i;
  23. return -1;
  24. }
  25. int FindCharInStringW(PCWSTR StringToSearch, int CharToFind)
  26. {
  27. int i = 0;
  28. int UpperCharToFind = 0;
  29. int LowerCharToFind = 0;
  30. UpperCharToFind = TO_UPPER(CharToFind);
  31. LowerCharToFind = TO_LOWER(CharToFind);
  32. for (i = 0 ; StringToSearch[i]; ++i)
  33. if (StringToSearch[i] == LowerCharToFind
  34. || StringToSearch[i] == UpperCharToFind
  35. )
  36. return i;
  37. return -1;
  38. }
  39. void RemoveTrailingCharacters(char * s, PCSTR CharsToRemove)
  40. {
  41. char * t;
  42. t = 0;
  43. for (t = s + StringLength(s) ; t != s && FindCharInString(CharsToRemove, *(t - 1)) >= 0 ; --t)
  44. {
  45. *(t - 1) = 0;
  46. }
  47. }
  48. void RemoveTrailingCharactersW(wchar_t * s, PCWSTR CharsToRemove)
  49. {
  50. wchar_t * t;
  51. t = 0;
  52. for (t = s + StringLengthW(s) ; t != s && FindCharInStringW(CharsToRemove, *(t - 1)) >= 0 ; --t)
  53. {
  54. *(t - 1) = 0;
  55. }
  56. }
  57. extern const CHAR Whitespace[] = " \t\r\n";
  58. extern const WCHAR WhitespaceW[] = L" \t\r\n";
  59. void RemoveTrailingWhitespace(char * s)
  60. {
  61. RemoveTrailingCharacters(s, Whitespace);
  62. }
  63. void RemoveTrailingWhitespaceW(wchar_t * s)
  64. {
  65. RemoveTrailingCharactersW(s, WhitespaceW);
  66. }
  67. void RemoveTrailingSlashes(char * s)
  68. {
  69. RemoveTrailingCharacters(s, "\\/");
  70. }
  71. PCSTR GetErrorStringA(int Error)
  72. {
  73. static char Buffer[1U << 15];
  74. Buffer[0] = 0;
  75. FormatMessageA(
  76. FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
  77. NULL,
  78. Error,
  79. 0,
  80. Buffer,
  81. NUMBER_OF(Buffer),
  82. NULL);
  83. RemoveTrailingWhitespace(Buffer);
  84. return Buffer;
  85. }
  86. PCSTR GetLastPathElement(PCSTR s)
  87. {
  88. if (!s || !*s)
  89. return s;
  90. else
  91. {
  92. char * base0;
  93. char * base1;
  94. base0 = strrchr(s, '\\');
  95. base1 = strrchr(s, '/');
  96. if (base0 == NULL && base1 != NULL)
  97. return base1 + 1;
  98. if (base1 == NULL && base0 != NULL)
  99. return base0 + 1;
  100. // return beginning of string if no more slashes
  101. if (base1 == NULL && base0 == NULL)
  102. return s;
  103. return 1 + MAX(base0, base1);
  104. }
  105. }
  106. BOOL MyIsHandleValid(HANDLE Handle)
  107. {
  108. return (Handle != NULL && Handle != INVALID_HANDLE_VALUE);
  109. }
  110. void MyCloseHandle(HANDLE * Handle)
  111. {
  112. HANDLE Local;
  113. Local = *Handle;
  114. *Handle = NULL;
  115. if (MyIsHandleValid(Local))
  116. CloseHandle(Local);
  117. }
  118. void MyUnmapViewOfFile(PVOID * Handle)
  119. {
  120. PVOID Local = 0;
  121. Local = *Handle;
  122. *Handle = NULL;
  123. if (MyIsHandleValid(Local))
  124. UnmapViewOfFile(Local);
  125. }
  126. HRESULT OpenFileForRead(PCSTR Path, HANDLE * FileHandle)
  127. {
  128. HRESULT hr = 0;
  129. *FileHandle = 0;
  130. *FileHandle = CreateFileA(Path, GENERIC_READ, FILE_SHARE_READ, NULL,
  131. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  132. if (*FileHandle == INVALID_HANDLE_VALUE)
  133. {
  134. *FileHandle = 0;
  135. hr = HRESULT_FROM_WIN32(GetLastError());
  136. goto Exit;
  137. }
  138. hr = NOERROR;
  139. Exit:
  140. if (FAILED(hr))
  141. {
  142. MyCloseHandle(FileHandle);
  143. }
  144. return hr;
  145. }
  146. HRESULT GetFileSize64(HANDLE FileHandle, __int64 * Out)
  147. {
  148. DWORD FileSizeLow = 0;
  149. DWORD FileSizeHigh = 0;
  150. LARGE_INTEGER FileSize = {0};
  151. DWORD LastError = 0;
  152. HRESULT hr = 0;
  153. *Out = 0;
  154. FileSizeLow = GetFileSize(FileHandle, &FileSizeHigh);
  155. if (FileSizeLow == (~(DWORD)(0)) && (LastError = GetLastError()) != NO_ERROR)
  156. {
  157. hr = HRESULT_FROM_WIN32(LastError);
  158. goto Exit;
  159. }
  160. FileSize.LowPart = FileSizeLow;
  161. FileSize.HighPart = FileSizeHigh;
  162. *Out = FileSize.QuadPart;
  163. hr = NOERROR;
  164. Exit:
  165. return hr;
  166. }
  167. HRESULT MapEntireFileForRead(HANDLE FileHandle, HANDLE * FileMapping, PBYTE * ViewOfFile)
  168. {
  169. HRESULT hr = 0;
  170. HANDLE LocalFileMapping = 0;
  171. if (FileMapping == NULL)
  172. FileMapping = &LocalFileMapping;
  173. *FileMapping = 0;
  174. *ViewOfFile = 0;
  175. if (!(*FileMapping = CreateFileMappingA(FileHandle, NULL, PAGE_READONLY, 0, 0, 0)))
  176. {
  177. hr = HRESULT_FROM_WIN32(GetLastError());
  178. goto Exit;
  179. }
  180. if (!(*ViewOfFile = (PBYTE)MapViewOfFile(*FileMapping, FILE_MAP_READ, 0, 0, 0)))
  181. {
  182. hr = HRESULT_FROM_WIN32(GetLastError());
  183. goto Exit;
  184. }
  185. hr = NOERROR;
  186. Exit:
  187. if (FAILED(hr))
  188. {
  189. MyCloseHandle(FileMapping);
  190. MyUnmapViewOfFile((PVOID*)ViewOfFile);
  191. }
  192. MyCloseHandle(&LocalFileMapping);
  193. return hr;
  194. }
  195. HRESULT
  196. OpenAndMapEntireFileForRead(
  197. PMEMORY_MAPPED_FILE MemoryMappedFile,
  198. PCSTR FilePath
  199. )
  200. {
  201. HRESULT hr = 0;
  202. if (FAILED(hr = OpenFileForRead(FilePath, &MemoryMappedFile->FileHandle)))
  203. goto Exit;
  204. if (FAILED(hr = GetFileSize64(MemoryMappedFile->FileHandle, &MemoryMappedFile->FileSize)))
  205. goto Exit;
  206. if (FAILED(hr = MapEntireFileForRead(MemoryMappedFile->FileHandle, &MemoryMappedFile->FileMappingHandle, &MemoryMappedFile->MappedViewBase)))
  207. goto Exit;
  208. MemoryMappedFile->FilePathA = FilePath;
  209. hr = NOERROR;
  210. Exit:
  211. if (FAILED(hr))
  212. CloseMemoryMappedFile(MemoryMappedFile);
  213. return hr;
  214. }
  215. void CloseMemoryMappedFile(PMEMORY_MAPPED_FILE MemoryMappedFile)
  216. {
  217. MyCloseHandle(&MemoryMappedFile->FileHandle);
  218. MyCloseHandle(&MemoryMappedFile->FileMappingHandle);
  219. MyUnmapViewOfFile((PVOID*)&MemoryMappedFile->MappedViewBase);
  220. MemoryMappedFile->FileSize = 0;
  221. MemoryMappedFile->FilePathA = NULL;
  222. MemoryMappedFile->FilePathW = NULL;
  223. }
  224. void ClosePdbInfoEx(PPDB_INFO_EX PdbInfo)
  225. {
  226. CloseMemoryMappedFile(&PdbInfo->MemoryMappedFile);
  227. ZeroMemory(PdbInfo, sizeof(*PdbInfo));
  228. }
  229. HRESULT GetPdbInfoEx(PPDB_INFO_EX PdbInfoEx, PCSTR ImageFilePath)
  230. {
  231. HRESULT hr = 0;
  232. PIMAGE_DEBUG_DIRECTORY DebugDirectories = 0;
  233. PIMAGE_DEBUG_DIRECTORY Debug = 0;
  234. ULONG NumberOfDebugDirectories = 0;
  235. PPDB_INFO PdbInfo = 0;
  236. PBYTE MappedViewBase = 0;
  237. BOOL Found = 0;
  238. if (FAILED(hr = OpenAndMapEntireFileForRead(&PdbInfoEx->MemoryMappedFile, ImageFilePath)))
  239. goto Exit;
  240. MappedViewBase = PdbInfoEx->MemoryMappedFile.MappedViewBase;
  241. DebugDirectories = (PIMAGE_DEBUG_DIRECTORY)ImageDirectoryEntryToData(MappedViewBase, FALSE, IMAGE_DIRECTORY_ENTRY_DEBUG, &NumberOfDebugDirectories);
  242. NumberOfDebugDirectories /= sizeof(*DebugDirectories);
  243. if (DebugDirectories == NULL || NumberOfDebugDirectories == 0)
  244. {
  245. fprintf(stderr, "%s(%s): no debug directory\n", __FUNCTION__, ImageFilePath);
  246. hr = E_FAIL;
  247. goto Exit;
  248. }
  249. Found = FALSE;
  250. for ( Debug = DebugDirectories;
  251. !Found && NumberOfDebugDirectories != 0;
  252. (--NumberOfDebugDirectories, ++Debug)
  253. )
  254. {
  255. switch (Debug->Type)
  256. {
  257. default:
  258. break;
  259. case IMAGE_DEBUG_TYPE_CODEVIEW:
  260. PdbInfo = (PPDB_INFO)(MappedViewBase + Debug->PointerToRawData);
  261. if (memcmp(&PdbInfo->TypeSignature, "NB10", 4) == 0)
  262. {
  263. Found = TRUE;
  264. PdbInfoEx->PdbFilePathA = PdbInfo->u.NB10.PdbFilePath;
  265. }
  266. else if (memcmp(&PdbInfo->TypeSignature, "RSDS", 4) == 0)
  267. {
  268. Found = TRUE;
  269. PdbInfoEx->PdbFilePathA = PdbInfo->u.RSDS.PdbFilePath;
  270. }
  271. else
  272. {
  273. fprintf(stderr, "%s(%s): unknown codeview signature %.4s\n", __FUNCTION__, ImageFilePath, PdbInfo->TypeSignature);
  274. // keep looping, maybe there's more
  275. //hr = E_FAIL;
  276. //goto Exit;
  277. }
  278. break;
  279. }
  280. }
  281. if (!Found)
  282. {
  283. fprintf(stderr, "%s(%s): no codeview information found\n", __FUNCTION__, ImageFilePath);
  284. hr = E_FAIL;
  285. goto Exit;
  286. }
  287. PdbInfoEx->PdbInfo = PdbInfo;
  288. PdbInfoEx->ImageFilePathA = ImageFilePath;
  289. hr = NOERROR;
  290. Exit:
  291. if (FAILED(hr))
  292. ClosePdbInfoEx(PdbInfoEx);
  293. return hr;
  294. }