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.

515 lines
13 KiB

  1. /*****************************************************************/
  2. /** Microsoft LAN Manager **/
  3. /** Copyright(c) Microsoft Corp., 1988-1991 **/
  4. /*****************************************************************/
  5. /**** he - HexEdit a file
  6. *
  7. * Wrapper to HexEdit function to allow file (or drive) editting
  8. *
  9. * Written: Ken Reneris
  10. *
  11. */
  12. #include <nt.h>
  13. #include <ntrtl.h>
  14. #include <nturtl.h>
  15. #include <ntdddisk.h>
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <process.h>
  19. #include <windows.h>
  20. #include "hexedit.h"
  21. NTSTATUS fncRead(HANDLE, ULONGLONG, PUCHAR, DWORD);
  22. NTSTATUS fncWrite(HANDLE, ULONGLONG, PUCHAR, DWORD);
  23. void EditFile (char *name);
  24. void ReadIni ();
  25. WORD vAttrList, vAttrTitle, vAttrHigh;
  26. VOID __cdecl
  27. main (argc, argv)
  28. USHORT argc;
  29. char *argv[];
  30. {
  31. char *argument = argv[1];
  32. if (argc < 2) {
  33. printf ("he fname\n");
  34. exit (1);
  35. }
  36. ReadIni ();
  37. if ((strncmp(argv[1], "\\\\.\\", 4)) == 0) {
  38. char *cp;
  39. int index;
  40. // Insure there is a backslash on the DosName being opened.
  41. for (cp = argv[1], index = 0; *cp; *cp++, index++) {
  42. // action in for loop
  43. }
  44. cp--;
  45. if (*cp != '\\') {
  46. // Need to add backslash to name.
  47. argument = GlobalAlloc (0,index + 4);
  48. if (!argument) {
  49. printf("Out of memory\n");
  50. exit (1);
  51. }
  52. for (cp = argv[1], index = 0; argument[index] = *cp; *cp++, index++) {
  53. // action in for loop
  54. }
  55. argument[index] = '\\';
  56. argument[index + 1] = '\0';
  57. }
  58. }
  59. EditFile (argument);
  60. }
  61. void
  62. EditFile (
  63. char *name
  64. )
  65. {
  66. FILE_ALIGNMENT_INFORMATION AlignmentInfo;
  67. PDISK_GEOMETRY_EX DiskGeo;
  68. ULONGLONG li;
  69. struct HexEditParm ei;
  70. USHORT rc, rc1, i, l;
  71. PWSTR WideName;
  72. OBJECT_ATTRIBUTES oa;
  73. NTSTATUS status;
  74. UNICODE_STRING NtDriveName;
  75. ANSI_STRING NtDriveNameAnsi;
  76. IO_STATUS_BLOCK status_block;
  77. UCHAR GeoBuf[ 8*1024];
  78. UCHAR Root[12];
  79. //
  80. // Try to open & edit as regular filename
  81. //
  82. memset ((PUCHAR) &ei, 0, sizeof (ei));
  83. ei.ename = name;
  84. ei.flag = FHE_VERIFYONCE | FHE_SAVESCRN | FHE_JUMP;
  85. ei.read = fncRead;
  86. ei.write = fncWrite;
  87. ei.ioalign = 1;
  88. ei.Console = INVALID_HANDLE_VALUE;
  89. ei.AttrNorm = vAttrList;
  90. ei.AttrHigh = vAttrTitle;
  91. ei.AttrReverse = vAttrHigh;
  92. ei.handle = CreateFile (
  93. name,
  94. GENERIC_READ | GENERIC_WRITE,
  95. FILE_SHARE_READ | FILE_SHARE_WRITE,
  96. NULL,
  97. OPEN_EXISTING,
  98. 0,
  99. NULL );
  100. if (ei.handle == INVALID_HANDLE_VALUE) {
  101. // Try for just read access
  102. ei.handle = CreateFile (
  103. name,
  104. GENERIC_READ,
  105. FILE_SHARE_READ | FILE_SHARE_WRITE,
  106. NULL,
  107. OPEN_EXISTING,
  108. 0,
  109. NULL );
  110. }
  111. if (ei.handle != INVALID_HANDLE_VALUE) {
  112. ULONG High = 0;
  113. ei.totlen = 0;
  114. ei.totlen = SetFilePointer (ei.handle, 0, &High, FILE_END);
  115. ei.totlen |= ((ULONGLONG)High) << 32;
  116. HexEdit (&ei);
  117. return;
  118. }
  119. rc = (USHORT)GetLastError ();
  120. //
  121. // Try expanding the name from dosname to ntname.
  122. // Since regular name failed, assume a sector edit
  123. //
  124. l = strlen(name)+1;
  125. WideName = GlobalAlloc (0,l * sizeof(WCHAR));
  126. if (!WideName) {
  127. printf("Out of memory\n");
  128. exit(1);
  129. }
  130. ZeroMemory(WideName, l*sizeof(WCHAR));
  131. for(i=0; i < l; i++)
  132. WideName[i] = name[i];
  133. // OK, now get the corresponding NT name
  134. rc1 = RtlDosPathNameToNtPathName_U (
  135. WideName,
  136. &NtDriveName,
  137. NULL,
  138. NULL );
  139. if (!rc1) {
  140. printf ("Open error %d\n", rc);
  141. exit (rc);
  142. }
  143. // If the NT drive name has a trailing backslash, remove it.
  144. l = NtDriveName.Length/sizeof(WCHAR);
  145. if( NtDriveName.Buffer[l-1] == '\\' ) {
  146. NtDriveName.Buffer[l-1] = 0;
  147. NtDriveName.Length -= sizeof(WCHAR);
  148. }
  149. InitializeObjectAttributes(
  150. &oa,
  151. &NtDriveName,
  152. OBJ_CASE_INSENSITIVE,
  153. 0,
  154. 0 );
  155. status = NtOpenFile(
  156. &ei.handle,
  157. SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
  158. &oa,
  159. &status_block,
  160. FILE_SHARE_READ | FILE_SHARE_WRITE,
  161. FILE_SYNCHRONOUS_IO_ALERT );
  162. if (!NT_SUCCESS(status)) {
  163. // try for just read access
  164. status = NtOpenFile(
  165. &ei.handle,
  166. SYNCHRONIZE | FILE_READ_DATA,
  167. &oa,
  168. &status_block,
  169. FILE_SHARE_READ | FILE_SHARE_WRITE,
  170. FILE_SYNCHRONOUS_IO_ALERT );
  171. }
  172. if (!NT_SUCCESS(status)) {
  173. NtDriveName.Length = strlen(name) * sizeof(WCHAR);
  174. NtDriveName.Buffer = WideName;
  175. InitializeObjectAttributes(
  176. &oa,
  177. &NtDriveName,
  178. OBJ_CASE_INSENSITIVE,
  179. 0,
  180. 0 );
  181. status = NtOpenFile(
  182. &ei.handle,
  183. SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
  184. &oa,
  185. &status_block,
  186. FILE_SHARE_READ | FILE_SHARE_WRITE,
  187. FILE_SYNCHRONOUS_IO_ALERT );
  188. if (!NT_SUCCESS(status)) {
  189. // try for just read access
  190. status = NtOpenFile(
  191. &ei.handle,
  192. SYNCHRONIZE | FILE_READ_DATA,
  193. &oa,
  194. &status_block,
  195. FILE_SHARE_READ | FILE_SHARE_WRITE,
  196. FILE_SYNCHRONOUS_IO_ALERT );
  197. }
  198. }
  199. RtlUnicodeStringToAnsiString (&NtDriveNameAnsi, &NtDriveName, TRUE);
  200. ei.ename = NtDriveNameAnsi.Buffer;
  201. if (!NT_SUCCESS(status)) {
  202. printf ("%s open error %lx\n", ei.ename, status);
  203. exit (status);
  204. }
  205. /*
  206. NtQueryInformationFile(
  207. ei.handle,
  208. &status_block,
  209. &AlignmentInfo,
  210. sizeof( AlignmentInfo ),
  211. FileAlignmentInformation );
  212. ei.ioalign = AlignmentInfo.AlignmentRequirement;
  213. */
  214. ei.ioalign = 0;
  215. ei.totlen = 0;
  216. if (NtDriveNameAnsi.Buffer[ NtDriveNameAnsi.Length - 1] == ':') {
  217. sprintf( Root, "%c:\\", NtDriveNameAnsi.Buffer[ NtDriveNameAnsi.Length - 2]);
  218. //
  219. // For non-cdrom drive letter opens, we need to use
  220. // get partition info, not get disk info, for the partition size.
  221. //
  222. if (DRIVE_CDROM != GetDriveType( Root)) {
  223. PPARTITION_INFORMATION Part = (PVOID)GeoBuf;
  224. status = NtDeviceIoControlFile(
  225. ei.handle,
  226. 0,
  227. NULL,
  228. NULL,
  229. &status_block,
  230. IOCTL_DISK_GET_PARTITION_INFO,
  231. NULL,
  232. 0,
  233. GeoBuf,
  234. sizeof( GeoBuf) );
  235. if (NT_SUCCESS(status)) {
  236. ei.totlen = Part->PartitionLength.QuadPart;
  237. }
  238. }
  239. }
  240. //
  241. // Get sectorsize and, if we haven't got it already, disk/partition size
  242. //
  243. status = NtDeviceIoControlFile( ei.handle,
  244. 0,
  245. NULL,
  246. NULL,
  247. &status_block,
  248. IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
  249. NULL,
  250. 0,
  251. GeoBuf,
  252. sizeof( GeoBuf) );
  253. if (NT_SUCCESS(status)) {
  254. DiskGeo = (PVOID)GeoBuf;
  255. if (ei.ioalign < DiskGeo->Geometry.BytesPerSector) {
  256. ei.ioalign = DiskGeo->Geometry.BytesPerSector;
  257. }
  258. if (0 == ei.totlen) {
  259. ei.totlen = DiskGeo->DiskSize.QuadPart;
  260. }
  261. }
  262. else {
  263. //
  264. // The EX call failed, try the old one. GPT discs seem
  265. // to fail the EX call.
  266. //
  267. PDISK_GEOMETRY OldGeo;
  268. status = NtDeviceIoControlFile( ei.handle,
  269. 0,
  270. NULL,
  271. NULL,
  272. &status_block,
  273. IOCTL_DISK_GET_DRIVE_GEOMETRY,
  274. NULL,
  275. 0,
  276. GeoBuf,
  277. sizeof( GeoBuf) );
  278. if (NT_SUCCESS(status)) {
  279. OldGeo = (PVOID)GeoBuf;
  280. if (ei.ioalign < OldGeo->BytesPerSector) {
  281. ei.ioalign = OldGeo->BytesPerSector;
  282. }
  283. if (0 == ei.totlen) {
  284. ei.totlen = OldGeo->Cylinders.QuadPart * OldGeo->BytesPerSector *
  285. OldGeo->SectorsPerTrack * OldGeo->TracksPerCylinder;
  286. }
  287. }
  288. }
  289. //
  290. // Last resort for partition/disk size.
  291. //
  292. if (0 == ei.totlen) {
  293. ULONG High = 0;
  294. if (ei.ioalign < 0x200) {
  295. ei.ioalign = 0x200;
  296. }
  297. ei.totlen = 0;
  298. ei.totlen = SetFilePointer (ei.handle, 0, &High, FILE_END);
  299. ei.totlen |= ((ULONGLONG)High) << 32;
  300. }
  301. //
  302. // If a filesystem is mounted, we need to enable extended
  303. // DASD io in order to read the whole volume. Ignore result,
  304. // not all FSs support it.
  305. //
  306. status = NtDeviceIoControlFile(
  307. ei.handle,
  308. 0,
  309. NULL,
  310. NULL,
  311. &status_block,
  312. FSCTL_ALLOW_EXTENDED_DASD_IO,
  313. NULL,
  314. 0,
  315. NULL,
  316. 0);
  317. ei.flag = FHE_VERIFYALL | FHE_PROMPTSEC | FHE_SAVESCRN | FHE_JUMP;
  318. HexEdit (&ei);
  319. }
  320. NTSTATUS fncRead (HANDLE h, ULONGLONG loc, PUCHAR data, DWORD len)
  321. {
  322. DWORD l, br;
  323. ULONG High = (ULONG)(loc >> 32);
  324. l = SetFilePointer (h, (ULONG)loc, &High, FILE_BEGIN);
  325. if (l == -1)
  326. return GetLastError();
  327. if (!ReadFile (h, data, len, &br, NULL))
  328. return GetLastError();
  329. return (br != len ? ERROR_READ_FAULT : 0);
  330. }
  331. NTSTATUS fncWrite (HANDLE h, ULONGLONG loc, PUCHAR data, DWORD len)
  332. {
  333. DWORD l, bw;
  334. ULONG High = (ULONG)(loc >> 32);
  335. l = SetFilePointer (h, (ULONG)loc, &High, FILE_BEGIN);
  336. if (l == -1)
  337. return GetLastError();
  338. if (!WriteFile (h, data, len, &bw, NULL))
  339. return GetLastError();
  340. return (bw != len ? ERROR_WRITE_FAULT : 0);
  341. }
  342. /*** xtoi - Hex to int
  343. *
  344. * Entry:
  345. * pt - pointer to hex number
  346. *
  347. * Return:
  348. * value of hex number
  349. *
  350. */
  351. unsigned xtoi (pt)
  352. char *pt;
  353. {
  354. unsigned u;
  355. char c;
  356. u = 0;
  357. while (c = *(pt++)) {
  358. if (c >= 'a' && c <= 'f')
  359. c -= 'a' - 'A';
  360. if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F'))
  361. u = u << 4 | c - (c >= 'A' ? 'A'-10 : '0');
  362. }
  363. return (u);
  364. }
  365. void
  366. ReadIni ()
  367. {
  368. static char Delim[] = " :=;\t\r\n";
  369. FILE *fp;
  370. char *env, *verb, *value;
  371. char s [200];
  372. long l;
  373. env = getenv ("INIT");
  374. if (env == NULL)
  375. return;
  376. if ((strlen(env) + sizeof ("\\TOOLS.INI") + 1) > sizeof(s))
  377. return;
  378. strcpy (s, env);
  379. strcat (s, "\\TOOLS.INI"); // just use list ini section
  380. fp = fopen (s, "r");
  381. if (fp == NULL)
  382. return;
  383. while (fgets (s, 200, fp) != NULL) {
  384. if (s[0] != '[')
  385. continue;
  386. _strupr (s);
  387. if (strstr (s, "LIST") == NULL)
  388. continue;
  389. /*
  390. * ini file found w/ "list" keyword. Now read it.
  391. */
  392. while (fgets (s, 200, fp) != NULL) {
  393. if (s[0] == '[')
  394. break;
  395. verb = strtok (s, Delim);
  396. value = strtok (NULL, Delim);
  397. if (verb == NULL)
  398. continue;
  399. if (value == NULL)
  400. value = "";
  401. _strupr (verb);
  402. if (strcmp (verb, "LCOLOR") == 0) vAttrList = (WORD)xtoi(value);
  403. else if (strcmp (verb, "TCOLOR") == 0) vAttrTitle= (WORD)xtoi(value);
  404. else if (strcmp (verb, "HCOLOR") == 0) vAttrHigh = (WORD)xtoi(value);
  405. }
  406. break;
  407. }
  408. fclose (fp);
  409. }