|
|
/*****************************************************************/ /** Microsoft LAN Manager **/ /** Copyright(c) Microsoft Corp., 1988-1991 **/ /*****************************************************************/
/**** he - HexEdit a file
* * Wrapper to HexEdit function to allow file (or drive) editting * * Written: Ken Reneris * */
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <ntdddisk.h>
#include <stdio.h>
#include <stdlib.h>
#include <process.h>
#include <windows.h>
#include "hexedit.h"
NTSTATUS fncRead(), fncWrite(), fncWriteDASD();
void EditFile (char *name); void ReadIni ();
WORD vAttrList, vAttrTitle, vAttrHigh;
VOID __cdecl main (argc, argv) USHORT argc; char *argv[]; { char *argument = argv[1];
if (argc < 2) { printf ("he fname\n"); exit (1); }
ReadIni ();
if ((strncmp(argv[1], "\\\\.\\", 4)) == 0) { char *cp; int index;
// Insure there is a backslash on the DosName being opened.
for (cp = argv[1], index = 0; *cp; *cp++, index++) { // action in for loop
} cp--; if (*cp != '\\') {
// Need to add backslash to name.
argument = GlobalAlloc (0,index + 4); if (!argument) { printf("Out of memory\n"); exit (1); } for (cp = argv[1], index = 0; argument[index] = *cp; *cp++, index++) { // action in for loop
} argument[index] = '\\'; argument[index + 1] = '\0'; } } EditFile (argument); }
void EditFile ( char *name ) { FILE_ALIGNMENT_INFORMATION AlignmentInfo; PDISK_GEOMETRY_EX DiskGeo; ULONGLONG li; struct HexEditParm ei; USHORT rc, rc1, i, l; PWSTR WideName; OBJECT_ATTRIBUTES oa; NTSTATUS status; UNICODE_STRING NtDriveName; ANSI_STRING NtDriveNameAnsi; IO_STATUS_BLOCK status_block; UCHAR GeoBuf[ 8*1024]; UCHAR Root[12];
//
// Try to open & edit as regular filename
//
memset ((PUCHAR) &ei, 0, sizeof (ei)); ei.ename = name; ei.flag = FHE_VERIFYONCE | FHE_SAVESCRN | FHE_JUMP; ei.read = fncRead; ei.write = fncWrite; ei.ioalign = 1; ei.Console = INVALID_HANDLE_VALUE; ei.AttrNorm = vAttrList; ei.AttrHigh = vAttrTitle; ei.AttrReverse = vAttrHigh;
ei.handle = CreateFile ( name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL );
if (ei.handle == INVALID_HANDLE_VALUE) { // Try for just read access
ei.handle = CreateFile ( name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL ); }
if (ei.handle != INVALID_HANDLE_VALUE) {
ULONG High = 0;
ei.totlen = 0; ei.totlen = SetFilePointer (ei.handle, 0, &High, FILE_END); ei.totlen |= ((ULONGLONG)High) << 32;
HexEdit (&ei); return; }
rc = (USHORT)GetLastError ();
//
// Try expanding the name from dosname to ntname.
// Since regular name failed, assume a sector edit
//
l = strlen(name)+1; WideName = GlobalAlloc (0,l * sizeof(WCHAR)); if (!WideName) { printf("Out of memory\n"); exit(1); }
ZeroMemory(WideName, l*sizeof(WCHAR));
for(i=0; i < l; i++) WideName[i] = name[i];
// OK, now get the corresponding NT name
rc1 = RtlDosPathNameToNtPathName_U ( WideName, &NtDriveName, NULL, NULL );
if (!rc1) { printf ("Open error %d\n", rc); exit (rc); }
// If the NT drive name has a trailing backslash, remove it.
l = NtDriveName.Length/sizeof(WCHAR); if( NtDriveName.Buffer[l-1] == '\\' ) {
NtDriveName.Buffer[l-1] = 0; NtDriveName.Length -= sizeof(WCHAR); }
InitializeObjectAttributes( &oa, &NtDriveName, OBJ_CASE_INSENSITIVE, 0, 0 );
status = NtOpenFile( &ei.handle, SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA, &oa, &status_block, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_ALERT );
if (!NT_SUCCESS(status)) { // try for just read access
status = NtOpenFile( &ei.handle, SYNCHRONIZE | FILE_READ_DATA, &oa, &status_block, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_ALERT ); }
if (!NT_SUCCESS(status)) { NtDriveName.Length = strlen(name) * sizeof(WCHAR); NtDriveName.Buffer = WideName;
InitializeObjectAttributes( &oa, &NtDriveName, OBJ_CASE_INSENSITIVE, 0, 0 );
status = NtOpenFile( &ei.handle, SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA, &oa, &status_block, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_ALERT );
if (!NT_SUCCESS(status)) { // try for just read access
status = NtOpenFile( &ei.handle, SYNCHRONIZE | FILE_READ_DATA, &oa, &status_block, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_ALERT ); } }
RtlUnicodeStringToAnsiString (&NtDriveNameAnsi, &NtDriveName, TRUE); ei.ename = NtDriveNameAnsi.Buffer;
if (!NT_SUCCESS(status)) { printf ("%s open error %lx\n", ei.ename, status); exit (status); } /*
NtQueryInformationFile( ei.handle, &status_block, &AlignmentInfo, sizeof( AlignmentInfo ), FileAlignmentInformation ); ei.ioalign = AlignmentInfo.AlignmentRequirement; */ ei.ioalign = 0; ei.totlen = 0; if (NtDriveNameAnsi.Buffer[ NtDriveNameAnsi.Length - 1] == ':') {
sprintf( Root, "%c:\\", NtDriveNameAnsi.Buffer[ NtDriveNameAnsi.Length - 2]);
//
// For non-cdrom drive letter opens, we need to use
// get partition info, not get disk info, for the partition size.
//
if (DRIVE_CDROM != GetDriveType( Root)) {
PPARTITION_INFORMATION Part = (PVOID)GeoBuf; status = NtDeviceIoControlFile( ei.handle, 0, NULL, NULL, &status_block, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0, GeoBuf, sizeof( GeoBuf) );
if (NT_SUCCESS(status)) {
ei.totlen = Part->PartitionLength.QuadPart; } } }
//
// Get sectorsize and, if we haven't got it already, disk/partition size
//
status = NtDeviceIoControlFile( ei.handle, 0, NULL, NULL, &status_block, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, GeoBuf, sizeof( GeoBuf) );
if (NT_SUCCESS(status)) {
DiskGeo = (PVOID)GeoBuf;
if (ei.ioalign < DiskGeo->Geometry.BytesPerSector) {
ei.ioalign = DiskGeo->Geometry.BytesPerSector; } if (0 == ei.totlen) { ei.totlen = DiskGeo->DiskSize.QuadPart; } } else {
//
// The EX call failed, try the old one. GPT discs seem
// to fail the EX call.
//
PDISK_GEOMETRY OldGeo; status = NtDeviceIoControlFile( ei.handle, 0, NULL, NULL, &status_block, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, GeoBuf, sizeof( GeoBuf) );
if (NT_SUCCESS(status)) {
OldGeo = (PVOID)GeoBuf;
if (ei.ioalign < OldGeo->BytesPerSector) { ei.ioalign = OldGeo->BytesPerSector; } if (0 == ei.totlen) { ei.totlen = OldGeo->Cylinders.QuadPart * OldGeo->BytesPerSector * OldGeo->SectorsPerTrack * OldGeo->TracksPerCylinder; } } }
//
// Last resort for partition/disk size.
//
if (0 == ei.totlen) {
ULONG High = 0;
if (ei.ioalign < 0x200) { ei.ioalign = 0x200; }
ei.totlen = 0; ei.totlen = SetFilePointer (ei.handle, 0, &High, FILE_END); ei.totlen |= ((ULONGLONG)High) << 32; }
//
// If a filesystem is mounted, we need to enable extended
// DASD io in order to read the whole volume. Ignore result,
// not all FSs support it.
//
status = NtDeviceIoControlFile( ei.handle, 0, NULL, NULL, &status_block, FSCTL_ALLOW_EXTENDED_DASD_IO, NULL, 0, NULL, 0);
ei.flag = FHE_VERIFYALL | FHE_PROMPTSEC | FHE_SAVESCRN | FHE_JUMP; HexEdit (&ei); }
NTSTATUS fncRead (h, loc, data, len) HANDLE h; DWORD len; ULONGLONG loc; char *data; { DWORD l, br; ULONG High = (ULONG)(loc >> 32);
l = SetFilePointer (h, (ULONG)loc, &High, FILE_BEGIN); if (l == -1) return GetLastError();
if (!ReadFile (h, data, len, &br, NULL)) return GetLastError();
return (br != len ? ERROR_READ_FAULT : 0); }
NTSTATUS fncWrite (h, loc, data, len) HANDLE h; DWORD len; ULONGLONG loc; char *data; { DWORD l, bw; ULONG High = (ULONG)(loc >> 32);
l = SetFilePointer (h, (ULONG)loc, &High, FILE_BEGIN); if (l == -1) return GetLastError();
if (!WriteFile (h, data, len, &bw, NULL)) return GetLastError();
return (bw != len ? ERROR_WRITE_FAULT : 0); }
/*** xtoi - Hex to int
* * Entry: * pt - pointer to hex number * * Return: * value of hex number * */ unsigned xtoi (pt) char *pt; { unsigned u; char c;
u = 0; while (c = *(pt++)) { if (c >= 'a' && c <= 'f') c -= 'a' - 'A'; if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')) u = u << 4 | c - (c >= 'A' ? 'A'-10 : '0'); } return (u); }
void ReadIni () { static char Delim[] = " :=;\t\r\n"; FILE *fp; char *env, *verb, *value; char s [200]; long l;
env = getenv ("INIT"); if (env == NULL) return;
if ((strlen(env) + sizeof ("\\TOOLS.INI") + 1) > sizeof(s)) return;
strcpy (s, env); strcat (s, "\\TOOLS.INI"); // just use list ini section
fp = fopen (s, "r"); if (fp == NULL) return;
while (fgets (s, 200, fp) != NULL) { if (s[0] != '[') continue; _strupr (s); if (strstr (s, "LIST") == NULL) continue; /*
* ini file found w/ "list" keyword. Now read it. */ while (fgets (s, 200, fp) != NULL) { if (s[0] == '[') break; verb = strtok (s, Delim); value = strtok (NULL, Delim); if (verb == NULL) continue; if (value == NULL) value = "";
_strupr (verb); if (strcmp (verb, "LCOLOR") == 0) vAttrList = (WORD)xtoi(value); else if (strcmp (verb, "TCOLOR") == 0) vAttrTitle= (WORD)xtoi(value); else if (strcmp (verb, "HCOLOR") == 0) vAttrHigh = (WORD)xtoi(value); } break; } fclose (fp); }
|