Skip to content
Snippets Groups Projects
Commit 8bb7ed96 authored by Dirk's avatar Dirk
Browse files

Windows system name changer during bootup.

parent 4ad1ebe0
Branches
No related tags found
No related merge requests found
Showing
with 1890 additions and 0 deletions
File added
= How to build =
== Boot Program ==
To build the boot program you need Windows 2000 DDK (others not tested). Start DDK Build command prompt and cd to this dir. Type build-interactive to build an boot program with interactive console.
== Win32 Test Program ==
Use the provided Visual C++ Express workspace (win32/usermode-registry.sln) to build.
set cl=/DINTERACTIVE
build -cgw
\ No newline at end of file
set cl=
build -cg
\ No newline at end of file
DIRS= \
win32\
native
\ No newline at end of file
/* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
* The Initial Developer of the Original Code is Johannes Rudolph.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Johannes Rudolph <johannes_rudolph@gmx.de>
*/
= C++ exceptions in native programs =
This native api program/library uses C++-features like classes in many
places. This seems to work without problems so far.
It would be appropriate to use C++ exceptions as well. This won't
work. At least not with much effort. C++ exceptions are working
through the subtle mechanisms of Windows, the C++ compiler *and* the
runtime library working together.
To use exception handling one has to enable the specific options in
the compiler. You can use this lines in your SOURCES to enable it:
{{{
USE_NATIVE_EH=1
USE_RTTI=1
}}}
If we don't link a runtime library linking will error with unresolved
externals like __CxxFrameHandler and others.
Since we can't use Win32 dlls in a native program we can't link
against the standard rt (msvcrt). So the right choice seems to be the
use of the staticly linkable runtime library libc. This does not work
either. Even libc contains uncountable references to functions defined
in kernel32 and user32. We cannot link to them, of course.
So your choices are:
* reimplement C++ exception handling on top of the native (API) features
provided by Windows and the compiler
* use structured exception handling as documented by Microsoft, this
will not work in functions relying on automatic object deconstruction
* don't use exceptions at all (that was my choice)
\ No newline at end of file
#
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the driver components of the Windows NT DDK
#
!INCLUDE $(NTMAKEENV)\makefile.def
TARGETNAME=bootpgm
TARGETPATH=..\obj
TARGETTYPE=PROGRAM
TARGETLIBS=\
..\obj\i386\common.lib\
$(DDK_LIB_PATH)\ntdll.lib\
$(DDK_LIB_PATH)\nt.lib
# $(DDK_LIB_PATH)\libcmt.lib
# $(DDK_LIB_PATH)\ntoskrnl.lib
INCLUDES=$(SDK_INC_PATH);$(DDK_INC_PATH);..\win32
SOURCES= native.cpp
#UMTYPE=nt
\ No newline at end of file
/* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
* The Initial Developer of the Original Code is Johannes Rudolph.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Johannes Rudolph <johannes_rudolph@gmx.de>
*/
#include "stdafx.h"
#include "io.h"
#include "main.h"
#include "newnative.h"
#include "registrybrowser.h"
#include <stdlib.h>
#include <stdio.h>
char keys[]={0,0,'1','2','3','4','5','6','7','8','9','0','','',8/*Backspace*/ //0-14
,0/*tab*/,'q','w','e','r','t','z','u','i','o','p','','+','\n'/*return*/ //15-28
,0/*strg*/,'a','s','d','f','g','h','j','k','l','','','^',0/*left shift*/,'#' //29-43
,'y','x','c','v','b','n','m',',','.','-',0/*right shift*/ //44-54
,'*'/*num*/,0/*left alt*/,' ',0/*caps lock*/}; //55-58
char shiftkeys[]={0,0,'!','\"','','$','%','&','/','(',')','=','?','`',0/*Backspace*/ //0-14
,0/*tab*/,'Q','W','E','R','T','Z','U','I','O','P','','*','\n'/*return*/ //15-28
,0/*strg*/,'A','S','D','F','G','H','J','K','L','','','',0/*left shift*/,'\'' //29-43
,'Y','X','C','V','B','N','M',';',':','_',0/*right shift*/ //44-54
,'*'/*num*/,0/*left alt*/,' ',0/*caps lock*/};
IO *myIO=0;
void fatal(char *msg)
{
if (myIO!=0)
myIO->println(msg);
NtTerminateProcess( NtCurrentProcess(), 0 );
}
struct KeyboardState
{
bool shiftDown;
bool altDown;
bool altGrDown;
KeyboardState():shiftDown(false),altDown(false),altGrDown(false)
{}
};
class NativeBootIO:public IO{
HANDLE Heap;
HANDLE Keyboard;
HANDLE KeyboardEvent;
KeyboardState keyboardState;
private:
void createHeap()
{
RTL_HEAP_DEFINITION heapParams;
memset( &heapParams, 0, sizeof( RTL_HEAP_DEFINITION ));
heapParams.Length = sizeof( RTL_HEAP_DEFINITION );
Heap = RtlCreateHeap( 2, 0, 0x100000, 0x1000, 0, &heapParams );
}
void openKeyboard()
{
UNICODE_STRING UnicodeFilespec;
OBJECT_ATTRIBUTES ObjectAttributes;
NTSTATUS Status;
IO_STATUS_BLOCK Iosb;
RtlInitUnicodeString(&UnicodeFilespec, L"\\device\\KeyboardClass0");
InitializeObjectAttributes(&ObjectAttributes, // ptr to structure
&UnicodeFilespec, // ptr to file spec
OBJ_CASE_INSENSITIVE, // attributes
NULL, // root directory handle
NULL ); // ptr to security descriptor
Status = ZwCreateFile(&Keyboard, // returned file handle
(GENERIC_READ|SYNCHRONIZE|FILE_READ_ATTRIBUTES), // desired access
&ObjectAttributes, // ptr to object attributes
&Iosb, // ptr to I/O status block
0, // allocation size
FILE_ATTRIBUTE_NORMAL, // file attributes
0, // share access
FILE_OPEN, // create disposition
1, // create options
NULL, // ptr to extended attributes
0); // length of ea buffer
if (Status!=STATUS_SUCCESS)
fatal("Fehler: Keyboardhandle konnte nicht geffnet werden");
InitializeObjectAttributes(&ObjectAttributes, // ptr to structure
NULL, // ptr to file spec
0, // attributes
NULL, // root directory handle
NULL ); // ptr to security descriptor
Status=NtCreateEvent(&KeyboardEvent,EVENT_ALL_ACCESS,&ObjectAttributes,SynchronizationEvent,FALSE);
if (Status!=STATUS_SUCCESS)
fatal("Fehler: Keyboardevent konnte nicht erstellt werden");
}
void updateKeyboardStatus(KEYBOARD_INPUT_DATA &kid)
{
if (((kid.MakeCode==42)||(kid.MakeCode==54))&&(kid.Flags&KEY_E0)==0&&(kid.Flags&KEY_E1)==0)
keyboardState.shiftDown=!(kid.Flags&KEY_BREAK);
}
void printkid(KEYBOARD_INPUT_DATA &kid)
{
static char *buffer=(char*)malloc(100);
int keyMake=kid.Flags&KEY_MAKE;
int keyBreak=kid.Flags&KEY_BREAK;
int e0=kid.Flags&KEY_E0;
int e1=kid.Flags&KEY_E1;
_snprintf(buffer,99,"Key: Code: %d\tMake: %d\tBreak: %d\te0: %d\te1: %d",kid.MakeCode,keyMake,keyBreak,e0,e1);
println(buffer);
}
public:
NativeBootIO()
{
createHeap();
openKeyboard();
}
~NativeBootIO()
{
//RtlDestroyHeap()
}
void handleCharEcho(char ch,char *buffer,unsigned int length)
{
char b[2];
b[0]=ch;
b[1]=0;
if (ch==8)
{
println("");
buffer[length]=0;
print("> ");
print(buffer);
}
else
print(b);
}
char getChar()
{
debugout("getChar startet");
KEYBOARD_INPUT_DATA kid;
int chr=0;
do
{
NTSTATUS Status=waitForKeyboardInput(0,&kid);
if (Status!=STATUS_SUCCESS)
{
//_snprintf(buffer,99,"Fehler beim Tastaturlesen: 0x%x",Status);
println("Fehler beim Tastaturlesen");
debugout("Fehler beim Tastatur lesen");
}
else
{
debugout("Taste empfangen");
updateKeyboardStatus(kid);
if (((kid.Flags&KEY_BREAK)==0)&&kid.MakeCode<58&&kid.MakeCode>0)
if (keyboardState.shiftDown)
chr=shiftkeys[kid.MakeCode];
else
chr=keys[kid.MakeCode];
else
chr=0;
}
}
while(chr==0);
debugout("getChar Ende");
return (char)chr;
}
void *malloc(unsigned int size)
{
return RtlAllocateHeap( Heap, 0, size);
}
void free(void *buffer)
{
RtlFreeHeap(Heap,0,buffer);
}
void internalPrint(char *buffer)
{
UNICODE_STRING UnicodeFilespec=getUnicodeString(buffer);
NtDisplayString(&UnicodeFilespec);
}
char *getVersion()
{
return "Native Boot IO Revision: $Rev$";
}
NTSTATUS waitForKeyboardInput(__int64 time,KEYBOARD_INPUT_DATA *kid)
{
LARGE_INTEGER bo;
LARGE_INTEGER litime;
NTSTATUS Status;
IO_STATUS_BLOCK Iosb;
bo.HighPart=0;
bo.LowPart=0;
debugout("wFKI: vor ZwReadFile");
Status=ZwReadFile(Keyboard,
KeyboardEvent,0,0,&Iosb,kid,sizeof(KEYBOARD_INPUT_DATA),&bo,NULL);
debugout("wFKI: nach ZwReadFile");
PLARGE_INTEGER pli=NULL;
if (time!=0)
pli=(PLARGE_INTEGER)&time;
if (Status==STATUS_PENDING)
{
debugout("wFKI: vor WaitFor...");
Status=NtWaitForMultipleObjects(1,&KeyboardEvent,1,1,pli);
debugout("wFKI: nach WaitFor...");
if (Status!=STATUS_SUCCESS)
{
NtCancelIoFile(Keyboard,&Iosb);
return Status;
}
}
return STATUS_SUCCESS;
}
void printKeyboardData(KEYBOARD_INPUT_DATA kid)
{
char buffer[100];
int keyMake=kid.Flags&KEY_MAKE;
int keyBreak=kid.Flags&KEY_BREAK;
int e0=kid.Flags&KEY_E0;
int e1=kid.Flags&KEY_E1;
_snprintf(buffer,99,"Key: Code: %d\tMake: %d\tBreak: %d\te0: %d\te1: %d\n",kid.MakeCode,keyMake,keyBreak,e0,e1);
debugout(buffer);
}
void testKeyboard()
{
KEYBOARD_INPUT_DATA kid;
kid.MakeCode=0;
char buffer[100];
while(kid.MakeCode!=1)
{
NTSTATUS Status=waitForKeyboardInput(0,&kid);
if (Status!=STATUS_SUCCESS)
{
_snprintf(buffer,99,"Fehler beim Tastaturlesen: 0x%x",Status);
println(buffer);
}
else
{
printKeyboardData(kid);
}
}
println("Keyboardtest beendet");
}
void resetKeyboard()
{
debugout("Clearing Event");
NtClearEvent(KeyboardEvent);
}
};
extern "C"
int __cdecl _purecall()
{
DbgBreakPoint();
return 0;
}
void debugBreak(IO &io,char *args)
{
DbgBreakPoint();
}
void setCompnameFromFile(IO &io,char *args);
void setComputerNameCmd(IO &io,char *args);
void myitoa(int i,char *buffer)
{
int length=0;
if (i==0)
{
buffer[0]='0';
length=1;
}
else
{
char buffer2[20];
while (i>0)
{
buffer2[length]='0'+i%10;
i/=10;
length++;
}
for (i=0;i<length;i++)
{
buffer[length-i-1]=buffer2[i];
}
}
buffer[length]=0;
}
bool keyPressedInTime(NativeBootIO &io,__int64 time,char key)
{
KEYBOARD_INPUT_DATA kid;
io.debugout("kPIT startet");
NTSTATUS status=io.waitForKeyboardInput(time,&kid);
io.debugout("kPIT wFKI fertig");
//CHECK_STATUS(status,wFKI-from-kPIT)
if (status!=STATUS_SUCCESS)
return false;
if (((kid.Flags&KEY_BREAK)==0)&&kid.MakeCode<58&&kid.MakeCode>0)
if (keys[kid.MakeCode]==key)
{
io.debugout("Key pressed !!!");
return true;
}
else
io.debugout("Wrong key pressed");
else
io.printKeyboardData(kid);
return false;
}
bool startupWithKeyInner(NativeBootIO &io,int maxtime,char key) //maxtime in seconds
{
io.print("System starting up: ");
for (int i=maxtime;i>=0;i--)
{
char buffer[2];
myitoa(i,buffer);
io.print(buffer);
io.print(" ");
if (keyPressedInTime(io,-3333000,key))
return true;
else
io.print(".");
if (keyPressedInTime(io,-3333000,key))
return true;
else
io.print(".");
if (keyPressedInTime(io,-3333000,key))
return true;
else
io.print(" ");
}
return false;
}
void clearKeyboardPipe(NativeBootIO &io)
{
io.debugout("Starting clearKeyboardPipe");
io.resetKeyboard();
KEYBOARD_INPUT_DATA kid;
while (io.waitForKeyboardInput(-1,&kid)==STATUS_SUCCESS);
io.resetKeyboard();
io.debugout("Ending clearKeyboardPipe");
}
bool startupWithKey(NativeBootIO &io,int maxtime,char key) //maxtime in seconds
{
bool res=startupWithKeyInner(io,maxtime,key);
io.println(" ");
clearKeyboardPipe(io);
return res;
}
void register_experimental_cmds(Main &main);
extern "C" void NtProcessStartup(::PPEB peb )
{
NativeBootIO io;
myIO=&io;
UNICODE_STRING &cmdLine = peb->ProcessParameters->CommandLine;
char **arguments;
int argc;
arguments=split_args(io,cmdLine.Buffer,cmdLine.Length/2,&argc);
Main main(io,argc,arguments);
RegistryBrowser reg(main);
main.addCommand("break",debugBreak);
main.addCommand("setComputerNameFromFile",setCompnameFromFile);
main.addCommand("setComputerName",setComputerNameCmd);
register_experimental_cmds(main);
main.showSplashScreen();
#ifdef INTERACTIVE
if (startupWithKey(io,2,'v'))
main.rpl();
else
#endif
setCompnameFromFile(io,0);
NtTerminateProcess( NtCurrentProcess(), 0 );
}
\ No newline at end of file
/* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
* The Initial Developer of the Original Code is Johannes Rudolph.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Johannes Rudolph <johannes_rudolph@gmx.de>
* Tomasz Nowak <tommy@ntinternals.net>
*
* Most of this content comes from http://undocumented.ntinternals.net/
* This page and the information used is written by
* Tomasz Nowak <tommy@ntinternals.net>
* There is an .chm version in ../doc/ntundoc.chm
* The license presented on the page sounds:
*
*
* LICENSE CONDITIONS
* This software and / or documentation is provided at no cost
* and can be redistributed freely, in its entirety or in parts,
* as long as the Copyright notice and author's name are included.
* You are hereby permited to use, view, read, copy, print, publish,
* redistribute and modify this software and / or documentation,
* under conditions described herein.
* This software / documentation is provided to you "as is" without
* warranty of any kind. By using this material you accept all of the
* related risks and all direct and indirect consequences, including
* potential data loss and hardware damage.
* If you do not agree to these license conditions, please do not use
* our software and / or documentation.
*
*/
#pragma once
extern "C"{
#define PPVOID void**
#define BYTE char
/* I mostly copied this structures from the source above.
* I removed parts which would introduce spurious dependencies.
*
*/
typedef struct _RTL_DRIVE_LETTER_CURDIR {
USHORT Flags;
USHORT Length;
ULONG TimeStamp;
UNICODE_STRING DosPath;
} RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR;
typedef struct _RTL_USER_PROCESS_PARAMETERS {
ULONG MaximumLength;
ULONG Length;
ULONG Flags;
ULONG DebugFlags;
PVOID ConsoleHandle;
ULONG ConsoleFlags;
HANDLE StdInputHandle;
HANDLE StdOutputHandle;
HANDLE StdErrorHandle;
UNICODE_STRING CurrentDirectoryPath;
HANDLE CurrentDirectoryHandle;
UNICODE_STRING DllPath;
UNICODE_STRING ImagePathName;
UNICODE_STRING CommandLine;
PVOID Environment;
ULONG StartingPositionLeft;
ULONG StartingPositionTop;
ULONG Width;
ULONG Height;
ULONG CharWidth;
ULONG CharHeight;
ULONG ConsoleTextAttributes;
ULONG WindowFlags;
ULONG ShowWindowFlags;
UNICODE_STRING WindowTitle;
UNICODE_STRING DesktopName;
UNICODE_STRING ShellInfo;
UNICODE_STRING RuntimeData;
RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20];
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
typedef struct _PEB {
BOOLEAN InheritedAddressSpace;
BOOLEAN ReadImageFileExecOptions;
BOOLEAN BeingDebugged;
BOOLEAN Spare;
HANDLE Mutant;
PVOID ImageBaseAddress;
PVOID/*PPEB_LDR_DATA*/ LoaderData;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
PVOID SubSystemData;
PVOID ProcessHeap;
PVOID FastPebLock;
PVOID/*PPEBLOCKROUTINE*/FastPebLockRoutine;
PVOID/*PPEBLOCKROUTINE*/FastPebUnlockRoutine;
ULONG EnvironmentUpdateCount;
PPVOID KernelCallbackTable;
PVOID EventLogSection;
PVOID EventLog;
PVOID/*PPEB_FREE_BLOCK*/FreeList;
ULONG TlsExpansionCounter;
PVOID TlsBitmap;
ULONG TlsBitmapBits[0x2];
PVOID ReadOnlySharedMemoryBase;
PVOID ReadOnlySharedMemoryHeap;
PPVOID ReadOnlyStaticServerData;
PVOID AnsiCodePageData;
PVOID OemCodePageData;
PVOID UnicodeCaseTableData;
ULONG NumberOfProcessors;
ULONG NtGlobalFlag;
BYTE Spare2[0x4];
LARGE_INTEGER CriticalSectionTimeout;
ULONG HeapSegmentReserve;
ULONG HeapSegmentCommit;
ULONG HeapDeCommitTotalFreeThreshold;
ULONG HeapDeCommitFreeBlockThreshold;
ULONG NumberOfHeaps;
ULONG MaximumNumberOfHeaps;
PPVOID *ProcessHeaps;
PVOID GdiSharedHandleTable;
PVOID ProcessStarterHelper;
PVOID GdiDCAttributeList;
PVOID LoaderLock;
ULONG OSMajorVersion;
ULONG OSMinorVersion;
ULONG OSBuildNumber;
ULONG OSPlatformId;
ULONG ImageSubSystem;
ULONG ImageSubSystemMajorVersion;
ULONG ImageSubSystemMinorVersion;
ULONG GdiHandleBuffer[0x22];
ULONG PostProcessInitRoutine;
ULONG TlsExpansionBitmap;
BYTE TlsExpansionBitmapBits[0x80];
ULONG SessionId;
} PEB, *PPEB;
typedef struct _RTL_HEAP_DEFINITION {
ULONG Length;
ULONG Unknown[12];
} RTL_HEAP_DEFINITION, *PRTL_HEAP_DEFINITION;
NTSYSAPI
NTSTATUS
NTAPI
NtTerminateProcess(
/*IN*/ HANDLE ProcessHandle /*OPTIONAL*/,
/*IN*/ NTSTATUS ExitStatus );
NTSYSAPI
NTSTATUS
NTAPI
NtDisplayString(
/*IN*/ PUNICODE_STRING String );
NTSYSAPI
PVOID
NTAPI
RtlCreateHeap(
/*IN*/ ULONG Flags,
/*IN*/ PVOID Base /*OPTIONAL*/,
/*IN*/ ULONG Reserve /*OPTIONAL*/,
/*IN*/ ULONG Commit,
/*IN*/ BOOLEAN Lock /*OPTIONAL*/,
/*IN*/ PRTL_HEAP_DEFINITION RtlHeapParams /*OPTIONAL*/ );
NTSYSAPI
PVOID
NTAPI
RtlAllocateHeap(
/*IN*/ PVOID HeapHandle,
/*IN*/ ULONG Flags,
/*IN*/ ULONG Size );
NTSYSAPI
BOOLEAN
NTAPI
RtlFreeHeap(
/*IN*/ PVOID HeapHandle,
/*IN*/ ULONG Flags /*OPTIONAL*/,
/*IN*/ PVOID MemoryPointer );
NTSYSAPI NTSTATUS NTAPI NtCreateEvent(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,EVENT_TYPE,BOOLEAN);
NTSYSAPI NTSTATUS NTAPI NtWaitForMultipleObjects(ULONG handlecount,PHANDLE handles,int wait_type,BOOLEAN alertable,PLARGE_INTEGER timeout);
NTSYSAPI NTSTATUS NTAPI NtClearEvent(HANDLE Eventhandle);
NTSYSAPI NTSTATUS NTAPI NtCancelIoFile(HANDLE Filehandle, PIO_STATUS_BLOCK IoStatusBlock);
typedef enum _OBJECT_INFORMATION_CLASS
{
ObjectBasicInformation, // Result is OBJECT_BASIC_INFORMATION structure
ObjectNameInformation, // Result is OBJECT_NAME_INFORMATION structure
ObjectTypeInformation, // Result is OBJECT_TYPE_INFORMATION structure
ObjectAllInformation, // Result is OBJECT_ALL_INFORMATION structure
ObjectDataInformation // Result is OBJECT_DATA_INFORMATION structure
} OBJECT_INFORMATION_CLASS, *POBJECT_INFORMATION_CLASS;
NTSYSAPI
NTSTATUS
NTAPI
NtQueryObject(
HANDLE ObjectHandle,
OBJECT_INFORMATION_CLASS ObjectInformationClass,
PVOID ObjectInformation,
ULONG Length,
PULONG ResultLength );
typedef struct _OBJECT_BASIC_INFORMATION {
ULONG Attributes;
ACCESS_MASK GrantedAccess;
ULONG HandleCount;
ULONG ReferenceCount;
ULONG PagedPoolQuota;
ULONG NonPagedPoolQuota;
ULONG Unknown[3];
ULONG NameInformationLength;
ULONG TypeInformationLength;
ULONG SecurityDescriptorLength;
LARGE_INTEGER CreateTime;
} OBJECT_BASIC_INFORMATION, *POBJECT_BASIC_INFORMATION;
NTSYSAPI
NTSTATUS
NTAPI
NtLoadKey(
POBJECT_ATTRIBUTES DestinationKeyName,
POBJECT_ATTRIBUTES HiveFileName );
NTSYSAPI
NTSTATUS
NTAPI
NtOpenProcessToken(
HANDLE ProcessHandle,
ACCESS_MASK DesiredAccess,
PHANDLE TokenHandle );
typedef struct _TOKEN_PRIVILEGES
{
ULONG count;
LUID_AND_ATTRIBUTES Privileges[1];
} TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES;
NTSYSAPI
NTSTATUS
NTAPI
NtAdjustPrivilegesToken(
HANDLE TokenHandle,
BOOLEAN DisableAllPrivileges,
PTOKEN_PRIVILEGES TokenPrivileges,
ULONG PreviousPrivilegesLength,
PTOKEN_PRIVILEGES PreviousPrivileges,
PULONG RequiredLength);
NTSYSAPI
NTSTATUS
NTAPI
NtUnloadKey(
POBJECT_ATTRIBUTES DestinationKeyName );
NTSYSAPI
NTSTATUS
NTAPI
NtFlushKey(
HANDLE KeyHandle );
NTSYSAPI
NTSTATUS
NTAPI
NtSaveKey(
HANDLE KeyHandle,
HANDLE FileHandle );
NTSYSAPI
NTSTATUS
NTAPI
NtInitializeRegistry(
int flag);
typedef enum _DEBUG_CONTROL_CODE {
DebugSysReadIoSpace = 14,
DebugSysWriteIoSpace = 15,
DebugSysReadMsr = 16,
DebugSysWriteMsr = 17,
DebugSysReadBusData = 18,
DebugSysWriteBusData = 19,
} DEBUG_CONTROL_CODE;
NTSYSAPI
NTSTATUS
NTAPI
ZwSystemDebugControl(
DEBUG_CONTROL_CODE ControlCode,
PVOID InputBuffer,
ULONG InputBufferLength,
PVOID OutputBuffer,
ULONG OutputBufferLength,
PULONG ReturnLength
);
typedef struct _IO_STRUCT {
int IoAddr; // IN: Aligned to NumBytes,I/O address
int Reserved1; // Never accessed by the kernel
PVOID pBuffer; // IN (write) or OUT (read): Ptr to buffer
int NumBytes; // IN: # bytes to read/write. Only use 1, 2, or 4.
int Reserved4; // Must be 1
int Reserved5; // Must be 0
int Reserved6; // Must be 1
int Reserved7; // Never accessed by the kernel
} IO_STRUCT;
}
\ No newline at end of file
#include "StdAfx.h"
#include "Handle.h"
#include "main.h"
void debug(char *msg)
{
mainSingleton->get_io().debugout(msg);
}
void handle(ULONG status,char *file,char *line)
{
if (status!=STATUS_SUCCESS)
{
char *buffer = new char[5000];
sprintf(buffer,"Fehler in %s Zeile %s: 0x%X",file,line,status);
mainSingleton->get_io().println(buffer);
mainSingleton->get_io().readln(buffer,sizeof(buffer));
}
}
WinObject::~WinObject()
{
if (valid())
{
char buffer[500];
debug((L"Closing Handle to '" + get_name() + L"'" ).chars(buffer,500));
ULONG status = ZwClose(handle);
CHECKER(status)
}
}
UnicodeString WinObject::get_name()
{
OBJECT_BASIC_INFORMATION info;
ULONG status = NtQueryObject(
handle
,ObjectBasicInformation
,&info
,sizeof(info)
,0);
CHECKER(status);
int len=info.NameInformationLength;
len = len==0? 500 : len;
if (len>0)
{
OBJECT_NAME_INFORMATION *poni=reinterpret_cast<OBJECT_NAME_INFORMATION*>(_alloca(len));
status = NtQueryObject(
handle
,ObjectNameInformation
,poni
,len
,0);
CHECKER(status);
return UnicodeString::from_unicode(poni->Name);
}
else
return UnicodeString(L"");
}
UnicodeString::UnicodeString(const wchar_t *chars)
{
unsigned short len = (unsigned short)wcslen(chars);
wchar_t *buffer=new wchar_t[len];
string.Length= len * sizeof(wchar_t);
string.Buffer=buffer;
string.MaximumLength=string.Length;
memcpy(buffer,chars,len*2);
/*debug("UnicodeString created:");
char buffer2[500];
debug(this->chars(buffer2,500));*/
}
UnicodeString::UnicodeString(const wchar_t *chars,unsigned int length)
{
string.Length = (USHORT)length;
string.MaximumLength = (USHORT)length;
string.Buffer = new wchar_t[length/2];
memcpy(string.Buffer,chars,length);
}
UnicodeString::UnicodeString(const char *chars)
{
unsigned short l=(unsigned short)strlen(chars);
wchar_t *wcs=new wchar_t[l];
mbstowcs(wcs,chars,l);
string.Length = l*2;
string.MaximumLength = l*2;
string.Buffer = wcs;
}
/*UnicodeString &UnicodeString::operator=(wchar_t *chars)
{
char buffer[1000];
_snprintf(buffer,1000,"UnicodeString = called old = %S, new = %S",string.Buffer,chars);
debug(buffer);
unsigned short len= (unsigned short)wcslen(chars) * 2;
if (len > string.MaximumLength)
{
delete string.Buffer;
string.Buffer = new wchar_t[len/2];
string.MaximumLength = len;
}
memcpy(string.Buffer,chars,len);
string.Length = len;
return *this;
}*/
UnicodeString::~UnicodeString()
{
debug("UnicodeString deleted:");
char buffer[500];
debug(this->chars(buffer,500));
delete string.Buffer;
}
UnicodeString UnicodeString::operator+(UnicodeString&str2)
{
UNICODE_STRING str;
str.Length = 0;
str.MaximumLength = string.Length + str2.string.Length;
str.Buffer = new wchar_t[str.MaximumLength/2];
NT::RtlAppendUnicodeStringToString(&str,&string);
NT::RtlAppendUnicodeStringToString(&str,&str2.string);
return UnicodeString(str);
}
int RegKey::get_value(UnicodeString *path,PULONG type,void *buffer,int length)
{
int len=length + sizeof(KEY_VALUE_PARTIAL_INFORMATION);
void *temp=_alloca(len);
ULONG read;
KEY_VALUE_PARTIAL_INFORMATION *pinfo = reinterpret_cast<KEY_VALUE_PARTIAL_INFORMATION*>(temp);
ULONG status=ZwQueryValueKey(
handle
,&path->unicode_string()
,KeyValuePartialInformation
,pinfo
,len
,&read);
CHECKER(status)
if (status!=STATUS_SUCCESS)
return 0;
memcpy(buffer,pinfo->Data,pinfo->DataLength);
*type = pinfo->Type;
return pinfo->DataLength;
}
void RegKey::set_value(UnicodeString *path,ULONG type,void *data,ULONG size)
{
ULONG status = ZwSetValueKey(
handle
,&path->unicode_string()
,0
,type
,data
,size);
CHECKER(status)
}
UnicodeString RegKey::get_string_value(UnicodeString *name)
{
char buffer[500];
ULONG type;
ULONG len=get_value(name,&type,buffer,sizeof(buffer));
if (type!=REG_SZ){
debug("Only REG_SZ allowed in get_string_value");
return (wchar_t*)0;
}
wchar_t *value= reinterpret_cast<wchar_t*>(buffer);
value[min(sizeof(buffer)-1,len)] = 0;
return value;
}
HANDLE RegKey::open_key(HANDLE parent,UnicodeString &path)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UnicodeString fullPath = UnicodeString(L"\\Registry\\") + path;
UnicodeString *pp = parent ? &path : &fullPath;
InitializeObjectAttributes(
&ObjectAttributes,
const_cast<UNICODE_STRING*>(&pp->unicode_string()),
OBJ_CASE_INSENSITIVE,
parent,
NULL);
HANDLE h;
ULONG Disposition;
ULONG status = ZwOpenKey(
&h,
KEY_ALL_ACCESS,
&ObjectAttributes);
if (status == 0xC000034){
IO &io=mainSingleton->get_io();
io.print("Not found: ");
char buffer[1000];
io.println(path.chars(buffer,sizeof(buffer)));
}
return status == STATUS_SUCCESS? h : 0;
}
void RegKey::flush()
{
ULONG status=NtFlushKey(handle);
CHECKER(status);
}
void RegKey::save_to(HANDLE fileHandle)
{
ULONG status = NtSaveKey(handle,fileHandle);
CHECKER(status);
}
void RegKey::print_subkeys(IO &io)
{
ULONG status = STATUS_SUCCESS;
int i=0;
char buffer[1000];
do
{
ULONG res;
KEY_BASIC_INFORMATION *info = reinterpret_cast<KEY_BASIC_INFORMATION*>(buffer);
status = ZwEnumerateKey(
handle
,i
,KeyBasicInformation
,buffer
,sizeof(buffer)
,&res);
if (status == STATUS_SUCCESS)
{
UnicodeString name(info->Name,info->NameLength);
io.println(name.chars(buffer,sizeof(buffer)));
}
i++;
} while (status == STATUS_SUCCESS);
}
void RegKey::print_values(IO &io)
{
ULONG status = STATUS_SUCCESS;
int i=0;
char buffer[1000];
do
{
ULONG len;
status = ZwEnumerateValueKey(
handle
,i
,KeyValueBasicInformation
,buffer
,sizeof(buffer)-2
,&len);
if (status==STATUS_SUCCESS)
{
KEY_VALUE_BASIC_INFORMATION *info = reinterpret_cast<KEY_VALUE_BASIC_INFORMATION*>(buffer);
info->Name[info->NameLength/2] = 0;
char buf[100];
_snprintf(buf,sizeof(buf),"%-30S | %-15s",info->Name,type_to_name(info->Type));
io.println(buf);
}
i++;
} while(status == STATUS_SUCCESS);
}
RegKey *RegKey::subkey(UnicodeString&name)
{
HANDLE h = open_key(handle,name);
if (h)
return new RegKey(h);
else
return 0;
}
#pragma once
class IO;
class UnicodeString
{
NT::UNICODE_STRING string;
UnicodeString(UNICODE_STRING str):string(str){}
public:
UnicodeString(const wchar_t *chars);
UnicodeString(const wchar_t *chars,unsigned int length);
UnicodeString(const char *chars);
UNICODE_STRING& unicode_string(){return string;}
virtual ~UnicodeString();
static UnicodeString& from_unicode(UNICODE_STRING str)
{
UNICODE_STRING str2 = str;
str2.Buffer = new wchar_t[str.Length/2];
memcpy(str2.Buffer,str.Buffer,str.Length);
return *new UnicodeString(str2);
}
//UnicodeString& operator=(wchar_t *new_data);
//UnicodeString& operator=(UnicodeString &other);
char *chars(char *buffer,size_t len)
{
wcstombs(buffer,string.Buffer,min(len,(unsigned int)string.Length/2));
buffer[min(len-1,(unsigned int)string.Length/2)]=0;
return buffer;
}
UnicodeString operator+(UnicodeString&str2);
UnicodeString operator+(wchar_t *ch)
{
return *this + UnicodeString(ch);
}
friend UnicodeString operator+(wchar_t* ch,UnicodeString str)
{
return UnicodeString(ch) + str;
}
};
class WinObject
{
protected:
const HANDLE handle;
public:
WinObject(HANDLE h):handle(h){}
public:
~WinObject();
UnicodeString get_name();
HANDLE get_handle(){return handle;}
bool valid(){return handle != 0;}
};
class RegKey:public WinObject
{
private:
static HANDLE open_key(HANDLE parent,UnicodeString &path);
RegKey(HANDLE h):WinObject(h){}
public:
RegKey(UnicodeString &path):WinObject(open_key(0,path)){}
RegKey(const wchar_t *path):WinObject(open_key(0,UnicodeString(path))){}
int get_value(UnicodeString *path,PULONG type,void *buffer,int length);
UnicodeString get_string_value(UnicodeString *name);
void set_value(UnicodeString *path,ULONG type,void *data,ULONG size);
void flush();
void save_to(HANDLE fileHandle);
RegKey *subkey(UnicodeString&name);
void print_subkeys(IO &io);
void print_values(IO &io);
static const char *type_to_name(ULONG type)
{
switch(type)
{
case REG_SZ:
return "String";
case REG_EXPAND_SZ:
return "Expandable String";
case REG_MULTI_SZ:
return "Multiline String";
case REG_DWORD:
return "DWORD";
default:
return "Unknown";
}
}
};
/* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
* The Initial Developer of the Original Code is Johannes Rudolph.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Johannes Rudolph <johannes_rudolph@gmx.de>
*/
#include "StdAfx.h"
#include "IO.h"
IO::IO(void):indent(0),current(0)
{
}
IO::~IO(void)
{
}
void IO::print(char *buffer)
{
if (current==0)
{
for (int i=0;i<indent;i++)
internalPrint(" ");
current+=indent;
}
current+=strlen(buffer);
internalPrint(buffer);
}
void IO::println(char *buffer)
{
print(buffer);
print("\n");
current=0;
}
void IO::readln(char *buffer,unsigned int length)
{
debugout("readln gestartet");
//NT::DbgPrint("readln startet\n");
unsigned int curlength=0;
char curChar[2];
curChar[0]=0;
curChar[1]=0;
while (curlength<length&&curChar[0]!='\n')
{
curChar[0]=getChar();
if (curChar[0]!=8) //BACKSPACE
{
buffer[curlength]=curChar[0];
handleCharEcho(curChar[0],buffer,curlength);
curlength++;
}
else
{
if (curlength>0)
{
curlength--;
handleCharEcho(curChar[0],buffer,curlength);
}
}
}
buffer[curlength-1]=0;
debugout("readln beendet");
//NT::DbgPrint("readln beendet\n");
}
wchar_t *IO::char2wchar(char *buffer)
{
unsigned int size=strlen(buffer)+1;
wchar_t *buffer2=(wchar_t*)malloc(sizeof(wchar_t)*size);
mbstowcs(buffer2,(char*)buffer,size);
buffer2[size-1]=0;
return buffer2;
}
NT::UNICODE_STRING IO::getUnicodeString(char *buffer)
{
wchar_t *buffer2=char2wchar(buffer);
NT::UNICODE_STRING UnicodeFilespec;
RtlInitUnicodeString(&UnicodeFilespec, buffer2);
return UnicodeFilespec;
}
void IO::handleStatus(NT::NTSTATUS status,char *place,char *file,char *line,bool onlyWhenDebugging){
#ifndef DEBUGGING
if (!onlyWhenDebugging)
#endif
if (status!=STATUS_SUCCESS)
{
print("[error]");
print(file);
print("(");
print(line);
println("):");
print("[error] Fehler: ");
println(place);
NT::DbgPrint("Fehler (Datei: %s \tZeile: %s): %s, %d\n",file,line,place,status);
}
else
{
print("[success] Erfolg: ");
println(place);
NT::DbgPrint("Erfolg: %s\n",place);
}
}
inline void IO::debugout(char *string)
{
//#ifdef DEBUGGING
//print("[debug] ");
//println(string);
NT::DbgPrint("[bootpgm] %s\n",string);
//#endif
}
void IO::setIndent(unsigned char indent)
{
this->indent=indent;
}
unsigned char IO::getIndent()
{
return indent;
}
\ No newline at end of file
/* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
* The Initial Developer of the Original Code is Johannes Rudolph.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Johannes Rudolph <johannes_rudolph@gmx.de>
*/
/*
File: IO.h
Declaration of IO and Indenter classes
*/
#pragma once
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define CHECK_STATUS(status,name) io.handleStatus(status, #name,__FILE__ ,TOSTRING(__LINE__),true);
#define CHECK_STATUSA(status,name) io.handleStatus(status, #name,__FILE__ ,TOSTRING(__LINE__),false);
#define CHECKER(status) ::handle(status, __FILE__ ,TOSTRING(__LINE__));
void handle(ULONG status,char *file,char *line);
/*
Class: IO
Interface for the main input/output functions, contains some helper functions
*/
class IO
{
unsigned char indent;
unsigned char current;
public:
/*
Method: getChar
has to be implemented by concrete controllers
Returns:
one char per call from input device (keyboard)
*/
virtual char getChar()=0;
/*
Method: internalPrint
prints buffer to screen, must be implemented by concrete controllers
Parameters:
buffer - null-terminated string to be printed to screen
*/
virtual void internalPrint(char *buffer)=0;
/*
Method: malloc
allocates memory of specified size, must be implemented by concrete controllers
Parameters:
length - length of buffer to allocate
Returns:
pointer to allocated memory
*/
virtual void*malloc(unsigned int length)=0;
virtual void free(void *buffer)=0;
virtual char *getVersion()=0;
virtual void handleCharEcho(char ch,char *buffer,unsigned int length)=0;
IO(void);
~IO(void);
void print(char *buffer);
void println(char *buffer);
void readln(char *buffer,unsigned int length);
wchar_t *char2wchar(char *buffer);
NT::UNICODE_STRING getUnicodeString(char *buffer);
void handleStatus(NTSTATUS status, char *function, char *file, char *line,bool onlyWhenDebugging);
void debugout(char *string);
void setIndent(unsigned char indent);
unsigned char getIndent();
};
class Indenter
{
unsigned char original;
IO &io;
public:
Indenter(IO &pio):io(pio)
{
original=io.getIndent();
io.setIndent(original+2);
}
~Indenter()
{
io.setIndent(original);
}
};
\ No newline at end of file
#
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the driver components of the Windows NT DDK
#
!INCLUDE $(NTMAKEENV)\makefile.def
/* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
* The Initial Developer of the Original Code is Johannes Rudolph.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Johannes Rudolph <johannes_rudolph@gmx.de>
*/
#include "StdAfx.h"
#include "Main.h"
Main *mainSingleton=NULL;
char **split_args(IO &io,wchar_t* cmdLine,int length,int *pargc)
{
int argCount=0;
for (int i=0;i<length;i++)
if (*(cmdLine+i)==L' ')
argCount++;
argCount++;
char **argv=(char**)io.malloc(4*argCount);
int last=0;
int argNo=0;
for (int i=0;i<=length;i++)
{
wchar_t ch= i<length ? *(cmdLine+i) : 0;
if (ch==L' '||ch==0)
{
int argLength=i-last;
char *arg=(char*)io.malloc(argLength+1);
wcstombs(arg,cmdLine+last,argLength);
arg[argLength]=0;
argv[argNo]=arg;
argNo++;
last=i+1;
}
}
*pargc=argCount;
return argv;
}
void command::invoke(IO &io,char *args)
{
if (pObject)
{
// ugly hack to make member pointer working as needed...
Main *p=(Main*)pObject;
void(Main::*f)(IO&,char*)=*reinterpret_cast<void(Main::**)(IO&,char*)>(&func);
(p->*f)(io,args);
}
else
func(io,args);
}
void Main::showCmds(IO &io,char *args)
{
io.println("Available commands:");
Indenter i(io);
for (int i=0;i<funcc;i++)
{
command &c=commands[i];
char buffer[100];
_snprintf(buffer,100,"%-20s | %-40s",c.name,c.description ? c.description : "");
io.println(buffer);
}
}
void Main::showArgs(IO &io,char *args)
{
io.println("Commandline arguments:");
Indenter i(io);
for (int i=0;i<argc;i++)
{
char buffer[100];
_snprintf(buffer,100,"[%d] %-70s",i,(char*)argv[i]);
io.println(buffer);
}
}
void Main::help(IO &io,char *args)
{
if (!*args)
{
help(io," help");
return;
}
command *cmd = findCommand(&args[1]);
if (!cmd)
{
io.println("Command not found");
return;
}
io.println(cmd->help ? cmd->help : "No help entry available");
}
command *Main::findCommand(char *name)
{
for(int i=0;i<funcc;i++)
if (strstr(name,commands[i].name)==name)
return &commands[i];
return 0;
}
Main::Main(IO &io,int argc,char** argv):io(io),funcc(0),argv(argv),argc(argc)
{
addCommand("cmds",make_dg(this,&Main::showCmds)
,"Show all available commands"
,"Usage: cmds\nShow all available commands");
addCommand("showArgs",make_dg(this,&Main::showArgs)
,"Show the arguments of the program"
,"Usage: showArgs\nShow the arguments of the program");
addCommand("help",make_dg(this,&Main::help)
,"Show the help entry for a command"
,"Usage: help <command>\nShow help entries for command if available");
if (mainSingleton!=NULL)
{
io.println("Error: Main may be instantiated only once");
return;
}
else
{
mainSingleton=this;
}
}
Main::~Main(void)
{
mainSingleton=NULL;
}
void Main::run()
{
showSplashScreen();
rpl();
}
void Main::rpl()
{
io.println("Starting RPL (Read-Print-Loop) Type \"exit\" to stop.");
char buffer[100];
buffer[0]=0;
while (strcmp(buffer,"exit")!=0)
{
io.print("rpl> ");
io.readln(buffer,100);
command *cmd=findCommand(buffer);
if (cmd)
cmd->invoke(io,buffer + strlen(cmd->name));
else
io.println("Command not found");
}
io.println("Exiting RPL");
}
void Main::showSplashScreen()
{
io.println("Boot-time Computername Changer by Johannes Rudolph");
io.println("v0.1");
io.print("IO: ");
io.println(io.getVersion());
}
void Main::addCommand(char *name,invokeFunc func,char *desc,char *help,void*pObject)
{
if (funcc>=maxFuncs)
{
io.println("Es kann kein neues Kommando hinzugefgt werden");
return;
}
command c;
c.func=func;
c.name=name;
c.description=desc;
c.help=help;
c.pObject=pObject;
commands[funcc]=c;
funcc++;
}
void Main::addCommand(char *name,deleg dg,char *desc,char *help)
{
addCommand(name,(invokeFunc)dg.func,desc,help,dg.object);
}
void* __cdecl operator new(size_t sz) {
IO& io=mainSingleton->get_io();
void* m = io.malloc((unsigned int)sz);
if(!m)
io.println("out of memory");
return m;
}
void __cdecl operator delete(void* m) {
mainSingleton->get_io().free(m);
}
/* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
* The Initial Developer of the Original Code is Johannes Rudolph.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Johannes Rudolph <johannes_rudolph@gmx.de>
*/
#pragma once
#include "io.h"
typedef void (*invokeFunc)(IO &io,char *args);
struct command{
invokeFunc func;
void *pObject;
char *name;
char *description;
char *help;
void invoke(IO &io,char *args);
};
struct deleg
{
void *func;
void *object;
};
// template to create a command delegate
template<class T> deleg make_dg(T *t,void(T::*func)(IO&,char*))
{
deleg dg;
dg.func = *(void**)&func;
dg.object = t;
return dg;
}
class Main
{
IO &io;
int funcc;
static const int maxFuncs=50;
command commands[maxFuncs];
char** argv;
int argc;
void help(IO &io,char *args);
void showCmds(IO &io,char *args);
void showArgs(IO &io,char *args);
command *findCommand(char *name);
public:
Main(IO &io,int argc,char** argv);
void run();
~Main(void);
void rpl();
void addCommand(char *name,invokeFunc func,char *desc=0,char *help=0,void *pObject=0);
void addCommand(char *name,deleg d,char *desc=0,char *help=0);
void showSplashScreen();
IO &get_io(){return io;}
private:
friend void showCmds(IO &io,char *args);
friend void showArgs(IO &io,char *args);
public:
int getArgc()
{
return argc;
}
char **getArgs()
{
return argv;
}
};
extern Main *mainSingleton;
char **split_args(IO &io,wchar_t* cmdLine,int length,int *pargc);
\ No newline at end of file
#include "StdAfx.h"
#include "RegistryBrowser.h"
#include "io.h"
#include "main.h"
#include "handle.h"
RegKey *RegistryBrowser::get_current_key()
{
if (!current)
current = new RegKey(L"");
return current;
}
void RegistryBrowser::lk(IO &io,char *args)
{
get_current_key()->print_subkeys(io);
}
void RegistryBrowser::lv(IO &io,char *args)
{
get_current_key()->print_values(io);
}
void RegistryBrowser::tk(IO &io,char *args)
{
char buffer[1000];
io.println(get_current_key()->get_name().chars(buffer,sizeof(buffer)));
}
void RegistryBrowser::ck(IO &io,char *args)
{
if (*args==0)
{
if (current) delete current;
current = 0;
return;
}
UnicodeString name(&args[1]);
RegKey *key=get_current_key()->subkey(name);
if (key)
{
if (current) delete current;
current = key;
}
else
io.println("Key not found");
}
RegistryBrowser::RegistryBrowser(Main &main) : current(0)
{
main.addCommand("lk",make_dg(this,&RegistryBrowser::lk)
,"List subkeys"
,"Usage: lk\nList all subkeys of the current key");
main.addCommand("lv",make_dg(this,&RegistryBrowser::lv)
,"List values"
,"Usage: lv\nList the names of all values of the current key with their types");
main.addCommand("ck",make_dg(this,&RegistryBrowser::ck)
,"Change current registry key"
,"Usage: ck [<subkey>]\nGo into the subkey if specified or else to the root of the registry");
main.addCommand("tk",make_dg(this,&RegistryBrowser::tk)
,"Show information about current key"
,"Usage: tk\nShow information about the current key (*t*his *k*ey)");
}
RegistryBrowser::~RegistryBrowser(void)
{
if (current)
delete current;
current = 0;
}
#pragma once
class RegKey;
class IO;
class Main;
class RegistryBrowser
{
RegKey *current;
RegKey *get_current_key();
public:
RegistryBrowser(Main &m);
~RegistryBrowser(void);
void lk(IO &io,char *args);
void lv(IO &io,char *args);
void ck(IO &io,char *args);
void tk(IO &io,char *args);
};
TARGETNAME=common
TARGETPATH=../obj
TARGETTYPE=LIBRARY
#USE_NATIVE_EH=
#USE_RTTI=
#TARGETTYPE=PROGRAM
TARGETLIBS=$(DDK_LIB_PATH)\ntdll.lib
# $(DDK_LIB_PATH)\libc.lib
# $(DDK_LIB_PATH)\msvcrt.lib
INCLUDES=$(SDK_INC_PATH);$(DDK_INC_PATH);
SOURCES=io.cpp \
main.cpp \
stdafx.cpp \
computername.cpp \
tests.cpp \
registrybrowser.cpp \
experimental.cpp \
account.cpp \
handle.cpp
#UMTYPE=console
#UMBASE=0x400000
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment