summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDirk2014-06-10 14:19:40 +0200
committerDirk2014-06-10 14:19:40 +0200
commit8bb7ed968db64e9b12a6447e2eec3586ef9e935c (patch)
treecd038af0c4b67b2f9a029e4a203fcf102f42aa13
parentMinor cleanup. (diff)
downloadtm-scripts-8bb7ed968db64e9b12a6447e2eec3586ef9e935c.tar.gz
tm-scripts-8bb7ed968db64e9b12a6447e2eec3586ef9e935c.tar.xz
tm-scripts-8bb7ed968db64e9b12a6447e2eec3586ef9e935c.zip
Windows system name changer during bootup.
-rw-r--r--windows/NativeAPI-ComputernameChanging.pdfbin0 -> 592463 bytes
-rw-r--r--windows/bootpgm/BUILD8
-rw-r--r--windows/bootpgm/build-interactive.bat.removethis2
-rw-r--r--windows/bootpgm/build-release.bat.removethis2
-rw-r--r--windows/bootpgm/dirs3
-rw-r--r--windows/bootpgm/doc/exception.txt50
-rw-r--r--windows/bootpgm/native/MAKEFILE7
-rw-r--r--windows/bootpgm/native/SOURCES16
-rw-r--r--windows/bootpgm/native/native.cpp427
-rw-r--r--windows/bootpgm/native/newnative.h322
-rw-r--r--windows/bootpgm/win32/Handle.cpp293
-rw-r--r--windows/bootpgm/win32/Handle.h90
-rw-r--r--windows/bootpgm/win32/IO.cpp136
-rw-r--r--windows/bootpgm/win32/IO.h102
-rw-r--r--windows/bootpgm/win32/MAKEFILE7
-rw-r--r--windows/bootpgm/win32/Main.cpp220
-rw-r--r--windows/bootpgm/win32/Main.h90
-rw-r--r--windows/bootpgm/win32/RegistryBrowser.cpp71
-rw-r--r--windows/bootpgm/win32/RegistryBrowser.h19
-rw-r--r--windows/bootpgm/win32/SOURCES25
-rw-r--r--windows/bootpgm/win32/account.cpp60
-rw-r--r--windows/bootpgm/win32/account.h27
-rw-r--r--windows/bootpgm/win32/computername.cpp435
-rw-r--r--windows/bootpgm/win32/experimental.cpp275
-rw-r--r--windows/bootpgm/win32/stdafx.cpp26
-rw-r--r--windows/bootpgm/win32/stdafx.h50
-rw-r--r--windows/bootpgm/win32/usermode-registry.sln23
-rw-r--r--windows/bootpgm/win32/usermode-registry.vcproj365
-rw-r--r--windows/bootpgm/win32/win32.cpp92
-rw-r--r--windows/winnapi-Vortragsfolien.pdfbin0 -> 399350 bytes
30 files changed, 3243 insertions, 0 deletions
diff --git a/windows/NativeAPI-ComputernameChanging.pdf b/windows/NativeAPI-ComputernameChanging.pdf
new file mode 100644
index 00000000..6108c60b
--- /dev/null
+++ b/windows/NativeAPI-ComputernameChanging.pdf
Binary files differ
diff --git a/windows/bootpgm/BUILD b/windows/bootpgm/BUILD
new file mode 100644
index 00000000..d282ea57
--- /dev/null
+++ b/windows/bootpgm/BUILD
@@ -0,0 +1,8 @@
+= 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.
diff --git a/windows/bootpgm/build-interactive.bat.removethis b/windows/bootpgm/build-interactive.bat.removethis
new file mode 100644
index 00000000..23113901
--- /dev/null
+++ b/windows/bootpgm/build-interactive.bat.removethis
@@ -0,0 +1,2 @@
+set cl=/DINTERACTIVE
+build -cgw \ No newline at end of file
diff --git a/windows/bootpgm/build-release.bat.removethis b/windows/bootpgm/build-release.bat.removethis
new file mode 100644
index 00000000..69605338
--- /dev/null
+++ b/windows/bootpgm/build-release.bat.removethis
@@ -0,0 +1,2 @@
+set cl=
+build -cg \ No newline at end of file
diff --git a/windows/bootpgm/dirs b/windows/bootpgm/dirs
new file mode 100644
index 00000000..2f59ee73
--- /dev/null
+++ b/windows/bootpgm/dirs
@@ -0,0 +1,3 @@
+DIRS= \
+ win32\
+ native \ No newline at end of file
diff --git a/windows/bootpgm/doc/exception.txt b/windows/bootpgm/doc/exception.txt
new file mode 100644
index 00000000..c0d22c36
--- /dev/null
+++ b/windows/bootpgm/doc/exception.txt
@@ -0,0 +1,50 @@
+/* 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
diff --git a/windows/bootpgm/native/MAKEFILE b/windows/bootpgm/native/MAKEFILE
new file mode 100644
index 00000000..9c985f57
--- /dev/null
+++ b/windows/bootpgm/native/MAKEFILE
@@ -0,0 +1,7 @@
+#
+# 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
diff --git a/windows/bootpgm/native/SOURCES b/windows/bootpgm/native/SOURCES
new file mode 100644
index 00000000..f0c287c1
--- /dev/null
+++ b/windows/bootpgm/native/SOURCES
@@ -0,0 +1,16 @@
+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
diff --git a/windows/bootpgm/native/native.cpp b/windows/bootpgm/native/native.cpp
new file mode 100644
index 00000000..e595d7a9
--- /dev/null
+++ b/windows/bootpgm/native/native.cpp
@@ -0,0 +1,427 @@
+/* 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 geöffnet 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
diff --git a/windows/bootpgm/native/newnative.h b/windows/bootpgm/native/newnative.h
new file mode 100644
index 00000000..59f1067d
--- /dev/null
+++ b/windows/bootpgm/native/newnative.h
@@ -0,0 +1,322 @@
+/* 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
diff --git a/windows/bootpgm/win32/Handle.cpp b/windows/bootpgm/win32/Handle.cpp
new file mode 100644
index 00000000..f55f3316
--- /dev/null
+++ b/windows/bootpgm/win32/Handle.cpp
@@ -0,0 +1,293 @@
+#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;
+}
diff --git a/windows/bootpgm/win32/Handle.h b/windows/bootpgm/win32/Handle.h
new file mode 100644
index 00000000..14f65e57
--- /dev/null
+++ b/windows/bootpgm/win32/Handle.h
@@ -0,0 +1,90 @@
+#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";
+ }
+ }
+};
diff --git a/windows/bootpgm/win32/IO.cpp b/windows/bootpgm/win32/IO.cpp
new file mode 100644
index 00000000..9b31832b
--- /dev/null
+++ b/windows/bootpgm/win32/IO.cpp
@@ -0,0 +1,136 @@
+/* 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
diff --git a/windows/bootpgm/win32/IO.h b/windows/bootpgm/win32/IO.h
new file mode 100644
index 00000000..575aef06
--- /dev/null
+++ b/windows/bootpgm/win32/IO.h
@@ -0,0 +1,102 @@
+/* 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
diff --git a/windows/bootpgm/win32/MAKEFILE b/windows/bootpgm/win32/MAKEFILE
new file mode 100644
index 00000000..9c985f57
--- /dev/null
+++ b/windows/bootpgm/win32/MAKEFILE
@@ -0,0 +1,7 @@
+#
+# 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
diff --git a/windows/bootpgm/win32/Main.cpp b/windows/bootpgm/win32/Main.cpp
new file mode 100644
index 00000000..f23a70ec
--- /dev/null
+++ b/windows/bootpgm/win32/Main.cpp
@@ -0,0 +1,220 @@
+/* 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 hinzugefügt 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);
+}
diff --git a/windows/bootpgm/win32/Main.h b/windows/bootpgm/win32/Main.h
new file mode 100644
index 00000000..bd0e1bab
--- /dev/null
+++ b/windows/bootpgm/win32/Main.h
@@ -0,0 +1,90 @@
+/* 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
diff --git a/windows/bootpgm/win32/RegistryBrowser.cpp b/windows/bootpgm/win32/RegistryBrowser.cpp
new file mode 100644
index 00000000..9254f8e8
--- /dev/null
+++ b/windows/bootpgm/win32/RegistryBrowser.cpp
@@ -0,0 +1,71 @@
+#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;
+}
diff --git a/windows/bootpgm/win32/RegistryBrowser.h b/windows/bootpgm/win32/RegistryBrowser.h
new file mode 100644
index 00000000..57424320
--- /dev/null
+++ b/windows/bootpgm/win32/RegistryBrowser.h
@@ -0,0 +1,19 @@
+#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);
+};
diff --git a/windows/bootpgm/win32/SOURCES b/windows/bootpgm/win32/SOURCES
new file mode 100644
index 00000000..8bf55002
--- /dev/null
+++ b/windows/bootpgm/win32/SOURCES
@@ -0,0 +1,25 @@
+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
diff --git a/windows/bootpgm/win32/account.cpp b/windows/bootpgm/win32/account.cpp
new file mode 100644
index 00000000..24a3c32e
--- /dev/null
+++ b/windows/bootpgm/win32/account.cpp
@@ -0,0 +1,60 @@
+#include "stdafx.h"
+
+#include "account.h"
+
+void *get_entry(char *data,unsigned int cEntries,unsigned int index,unsigned int *length)
+{
+ data_entry *entries = reinterpret_cast<data_entry*>(data);
+ if (length != 0)
+ *length = entries[index].length;
+
+ return data + sizeof(data_entry) * cEntries + entries[index].position;
+}
+
+void *get_V_entry(char *data,unsigned int index, unsigned int *length)
+{
+ return get_entry(data,17,index,length);
+}
+
+entry *read_entries(char *data,unsigned int cEntries)
+{
+ data_entry *entries = reinterpret_cast<data_entry*>(data);
+ entry *fixed = new entry[cEntries];
+ for(unsigned int i=0;i<cEntries;i++)
+ {
+ fixed[i].data = data + sizeof(data_entry) * cEntries + entries[i].position;
+ fixed[i].length = entries[i].length;
+ fixed[i].flags = entries[i].flags;
+ }
+ return fixed;
+}
+
+int align(int i)
+{
+ int mod=i%4;
+ if (mod==0)
+ return i;
+ else
+ return i + 4 - mod;
+}
+
+int write_entries(entry *entries,unsigned int cEntries,char *buffer,unsigned int length)
+{
+ data_entry *pents = reinterpret_cast<data_entry*>(buffer);
+
+ int pos = 0;
+
+ for(unsigned int i=0;i<cEntries;i++)
+ {
+ pents[i].position = pos;
+ pents[i].length = entries[i].length;
+ pents[i].flags = entries[i].flags;
+
+ char *dataOffset = buffer + sizeof(data_entry) * cEntries + pos;
+
+ memcpy(dataOffset,entries[i].data,entries[i].length);
+ pos += align(entries[i].length);
+ }
+
+ return sizeof(data_entry) * cEntries + pos;
+} \ No newline at end of file
diff --git a/windows/bootpgm/win32/account.h b/windows/bootpgm/win32/account.h
new file mode 100644
index 00000000..a66f845f
--- /dev/null
+++ b/windows/bootpgm/win32/account.h
@@ -0,0 +1,27 @@
+#pragma once
+
+//#pragma pack(4)
+struct data_entry {
+ unsigned int position;
+ unsigned int length;
+ unsigned int flags;
+};
+
+struct entry {
+ void *data;
+ unsigned int length;
+ unsigned int flags;
+};
+
+#define V_ENTRY_COUNT 17
+
+#define USERNAME_E 1
+#define FULLNAME_E 2
+#define LANMANPW_E 13
+#define NTPW_E 14
+
+void *get_entry(char *data,unsigned int cEntries,unsigned int index,unsigned int *length);
+void *get_V_entry(char *data,unsigned int index, unsigned int *length);
+
+entry *read_entries(char *data,unsigned int cEntries);
+int write_entries(entry *entries,unsigned int cEntries,char *buffer,unsigned int length); \ No newline at end of file
diff --git a/windows/bootpgm/win32/computername.cpp b/windows/bootpgm/win32/computername.cpp
new file mode 100644
index 00000000..19d5bdeb
--- /dev/null
+++ b/windows/bootpgm/win32/computername.cpp
@@ -0,0 +1,435 @@
+/* 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: computername.cpp
+functions to change the computer name in the Windows registry
+*/
+
+#include "stdafx.h"
+#include "io.h"
+#include "main.h"
+
+WCHAR KeyNameBuffer[] = L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ComputerName";
+WCHAR KeyNameBuffer2[] = L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ActiveComputerName";
+WCHAR Tcpip[] = L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters";
+WCHAR ComputerNameBuffer[] = L"ComputerName";
+
+/*
+Function: setRegistryValue
+
+Parameters:
+io: reference to <IO>-Controller
+*/
+void setRegistryValue(IO &io,WCHAR *keyName,WCHAR *valueName,WCHAR *value)
+{
+ Indenter i(io);
+ UNICODE_STRING KeyName, ValueName;
+ HANDLE SoftwareKeyHandle;
+ ULONG Status;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ ULONG Disposition;
+
+ //io.print("Schreibe Registry-Key ");
+
+ //DbgBreakPoint();
+ //
+ // Open the Software key
+ //
+ NT::RtlInitUnicodeString(&KeyName,keyName);
+ InitializeObjectAttributes(
+ &ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ Status = ZwCreateKey(
+ &SoftwareKeyHandle,
+ KEY_ALL_ACCESS,
+ &ObjectAttributes,
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ &Disposition);
+
+ CHECK_STATUS(Status,Öffnen des Schlüssels)
+
+ NT::RtlInitUnicodeString(&ValueName,valueName);
+
+ Status = ZwSetValueKey(
+ SoftwareKeyHandle,
+ &ValueName,
+ 0,
+ REG_SZ,
+ value,
+ (wcslen( value )+1) * sizeof(WCHAR));
+
+ CHECK_STATUSA(Status,Setzen des Schlüssels);
+
+ Status = ZwClose(SoftwareKeyHandle);
+
+ CHECK_STATUS(Status,Schließen des Schlüssels);
+}
+
+/*
+Function: setComputerName
+sets the computer name in the registry to the specified one
+
+Parameters:
+io - reference to the <IO>-Controller
+computerName - the designated computer name as UNICODE string
+*/
+void setComputerName(IO &io,WCHAR *computerName)
+{
+ Indenter i(io);
+ io.println("Setze Computernamen ");
+ setRegistryValue(io,KeyNameBuffer,ComputerNameBuffer,computerName);
+ setRegistryValue(io,KeyNameBuffer2,ComputerNameBuffer,computerName);
+ setRegistryValue(io,Tcpip,L"Hostname",computerName);
+ setRegistryValue(io,Tcpip,L"NV Hostname",computerName);
+}
+/*
+Function: setComputerNameCmd
+command line command for setting the computer name manually
+
+Parameters:
+io - <IO>-Controller
+args - command line argument string
+*/
+void setComputerNameCmd(IO &io,char *args)
+{
+ Indenter i(io);
+ if (strlen(args)<2)
+ {
+ io.println("Syntax: setComputerName <newComputerName>");
+ return;
+ }
+ io.print("Setting Computer Name to: ");
+ io.println(args+1);
+ setComputerName(io,io.char2wchar(args+1));
+}
+
+#define RETURN_NULL_IF_STATUS_UNSUCCESSFULL if (Status!=STATUS_SUCCESS) return 0;
+
+/*
+Constant: whitespaces
+defines whitespace character group, each char of this array
+designates one white space character
+*/
+const char whitespaces[]=" \t\n\x0B\f\r";
+
+/*
+Function: isWhitespace
+Helper function for regexp parser. Tests if c is white space.
+
+Parameters:
+c - character to test
+
+Returns:
+true if character is white space as defined in <whitespaces>
+*/
+bool isWhitespace(char c)
+{
+ for (int i=0;i<sizeof(whitespaces);i++)
+ if (whitespaces[i]==c)
+ return true;
+
+ return false;
+}
+/*
+Function: isCapitalLetter
+Helper function for regexp parser. Tests if c is a capital letter.
+
+Parameters:
+c - character to test
+*/
+bool isCapitalLetter(char c)
+{
+ return c>='A'&&c<='Z';
+}
+bool isDigit(char c)
+{
+ return c>='0'&&c<='9';
+}
+bool isSmallLetter(char c)
+{
+ return c>='a'&&c<='z';
+}
+
+bool isWordCharacter(char c)
+{
+ return isDigit(c)||isCapitalLetter(c)||isSmallLetter(c)||c=='-';
+}
+bool char_matcher(char c,char d)
+{
+ return c==d;
+}
+//const char pattern[]="Computername:\\s+(\\w+)";
+/*
+Constant: pattern
+regular expression pattern which defines the place in a file
+to read the computer name from.
+
+The computer name will be the match for the first bracketed expression.
+
+Example:
+: <computername\\s+param=\"(\\w+)\"
+will match *test* in *<computername param="test" />*
+*/
+const char pattern[]="<computername\\s+param=\"(\\w+)\"";
+
+/*
+Function: parseComputerNameFile
+uses <pattern> to find a match in the buffer
+
+Parameters:
+io - <IO>-Controller
+buffer - source buffer
+length - length of source buffer
+
+Returns:
+a string containing the match or 0 otherwise
+*/
+char *parseComputerNameFile(IO &io,char *buffer,unsigned int length)
+{
+ int patternpos=0;
+ int capture_start=-1;
+ int capture_end=-1;
+ void *matcher=0;
+ char lastData=0;
+ for (unsigned int i=0;i<length;i++)
+ {
+ bool matched=true;
+ switch (pattern[patternpos])
+ {
+ case '\\':
+ patternpos++;
+ switch(pattern[patternpos])
+ {
+ case 's':
+ matcher=isWhitespace;
+ lastData=0;
+ break;
+ case 'w':
+ matcher=isWordCharacter;
+ lastData=0;
+ break;
+ }
+ break;
+ case '(':
+ capture_start=i;
+ patternpos++;
+ matcher=0;
+ continue;
+ case ')':
+ capture_end=i;
+ patternpos++;
+ matcher=0;
+ continue;
+ case '+':
+ matched=true;
+ while (matched)
+ {
+ if (lastData!=0)
+ // use binary matcher
+ matched=((bool(*)(char,char))matcher)(buffer[i],lastData);
+ else
+ // use unary matcher
+ matched=((bool(*)(char))matcher)(buffer[i]);
+
+ if (matched&&i<length)
+ i++;
+ }
+ if (i>0)
+ i--;
+ patternpos++;
+ continue;
+ default:
+ lastData=pattern[patternpos];
+ matcher=char_matcher;
+ break;
+ }
+
+ matched=false;
+ if (lastData!=0)
+ matched=((bool(*)(char,char))matcher)(buffer[i],lastData);
+ else
+ matched=((bool(*)(char))matcher)(buffer[i]);
+
+ if (matched)
+ patternpos++;
+ else
+ patternpos=0;
+ }
+ if (pattern[patternpos]==')')
+ capture_end=length;
+
+ if (capture_start!=-1&&capture_end!=-1)
+ {
+ int matchlength=capture_end-capture_start;
+ char *returnBuffer=(char*)io.malloc(matchlength+1);
+ memcpy(returnBuffer,buffer+capture_start,matchlength);
+ returnBuffer[matchlength]=0;
+ return returnBuffer;
+ }
+ else
+ return 0;
+}
+
+void testMatcher(IO &io,char *args)
+{
+ char string[]="Computername: ";
+ char *return0=parseComputerNameFile(io,string,sizeof(string));
+}
+
+/*
+Function: readComputerNameFromFile
+reads the computer name from the specified file, uses <pattern> to
+find computer name in it
+
+Parameters:
+io - <IO>-Controller
+fileName - reads computer name from this file
+
+Returns:
+UNICODE string containing the new computer name, 0 in case of error or if
+the name couldn't be found
+*/
+wchar_t *readComputerNameFromFile(IO &io,wchar_t *fileName)
+{
+ Indenter i(io);
+ NTSTATUS Status;
+ UNICODE_STRING UnicodeFilespec;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ HANDLE FileHandle;
+ IO_STATUS_BLOCK Iosb;
+ char *buffer;
+ PWCHAR buffer2;
+ ULONG converted;
+
+ RtlInitUnicodeString(&UnicodeFilespec,fileName);
+
+ 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(
+ &FileHandle, // returned file handle
+ (GENERIC_READ | SYNCHRONIZE), // 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
+ FILE_SYNCHRONOUS_IO_NONALERT, // create options
+ NULL, // ptr to extended attributes
+ 0); // length of ea buffer
+
+ CHECK_STATUSA(Status,Öffnen der Computernamensdatei)
+ RETURN_NULL_IF_STATUS_UNSUCCESSFULL
+
+ buffer = (char*)io.malloc(256);//RtlAllocateHeap( Heap, 0, 256 );
+ Status = ZwReadFile(FileHandle,0,NULL,NULL,&Iosb,buffer,256,0,NULL);
+ ((char*)buffer)[Iosb.Information]=0;
+
+ CHECK_STATUSA(Status,Lesen des Computernamens);
+ RETURN_NULL_IF_STATUS_UNSUCCESSFULL
+
+ io.print("Trying to parse file ... ");
+ char *parsed=parseComputerNameFile(io,buffer,Iosb.Information);
+
+ if (parsed!=0)
+ {
+ io.print("successful: ");
+ io.println(parsed);
+ }
+ else
+ {
+ io.println("failed.");
+ io.free(buffer);
+ io.free(parsed);
+ return 0;
+ }
+
+ buffer2 = (PWCHAR)io.malloc(500);
+
+ mbstowcs(buffer2,(char*)parsed,strlen(parsed));
+
+ Status = ZwClose(FileHandle);
+
+ CHECK_STATUS(Status,Schließen der Datei);
+
+ io.free(buffer);
+ io.free(parsed);
+
+ return buffer2;
+}
+
+/*
+Function: setCompnameFromFile
+command line command to set computer name from file.
+
+Uses a list of files to find computer name. List consists of
+command line parameters and hard coded *\\device\\floppy0\\compname.txt*.
+
+Tries to read each file and extract the computer name in the list till a
+valid one is found. This is set as computer name afterwards.
+
+Parameters:
+io - <IO>-Controller
+args - command line
+*/
+void setCompnameFromFile(IO &io,char *args)
+{
+ Indenter i(io);
+ int numFiles=mainSingleton->getArgc();
+ char **valueNames=(char**)io.malloc(4*numFiles);
+ char **cmdargs=mainSingleton->getArgs();
+
+ io.print("Computername file pipe: ");
+
+ for (int i=1;i<numFiles;i++)
+ {
+ io.print(cmdargs[i]);
+ io.print(", ");
+ valueNames[i-1]=cmdargs[i];
+ }
+
+ valueNames[numFiles-1]="\\device\\floppy0\\compname.txt";
+ io.println(valueNames[numFiles-1]);
+
+ io.println("Reading computer-name from ...");
+
+ for (int i=0;i<numFiles;i++)
+ {
+ io.println(valueNames[i]);
+ wchar_t *buffer2=readComputerNameFromFile(io,io.char2wchar(valueNames[i]));
+ if (buffer2!=0)
+ {
+ setComputerName(io,buffer2);
+ io.free(buffer2);
+ io.free(valueNames);
+ return;
+ }
+ }
+ io.free(valueNames);
+} \ No newline at end of file
diff --git a/windows/bootpgm/win32/experimental.cpp b/windows/bootpgm/win32/experimental.cpp
new file mode 100644
index 00000000..23746310
--- /dev/null
+++ b/windows/bootpgm/win32/experimental.cpp
@@ -0,0 +1,275 @@
+#include "stdafx.h"
+#include "handle.h"
+#include "account.h"
+#include "io.h"
+#include "main.h"
+
+void showAutoLogonName(IO &io,char *args)
+{
+ RegKey k(L"Machine\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon");
+ char buffer[40];
+ io.println(k.get_string_value(&UnicodeString(L"DefaultUsername")).chars(buffer,40));
+}
+
+void get_privilege(long id)
+{
+ HANDLE h;
+ ULONG status=NtOpenProcessToken(
+ NtCurrentProcess()
+ ,0x20
+ ,&h);
+ CHECKER(status)
+
+ TOKEN_PRIVILEGES tp;
+ tp.count = 1;
+ tp.Privileges[0].Luid = NT::RtlConvertLongToLuid(id);
+ tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+
+ status = NtAdjustPrivilegesToken(
+ h
+ ,false
+ ,&tp
+ ,0
+ ,0
+ ,0);
+ CHECKER(status)
+
+ ZwClose(h);
+}
+
+void loadSam(IO &io,char *args)
+{
+ get_privilege(SE_RESTORE_PRIVILEGE);
+
+ RegKey machine(L"Machine\\");
+
+ UnicodeString key(L"SAM");
+ UnicodeString path(L"\\??\\C:\\WINDOWS\\system32\\config\\SAM");
+
+ OBJECT_ATTRIBUTES dest;
+ InitializeObjectAttributes(
+ &dest,
+ &key.unicode_string(),
+ OBJ_CASE_INSENSITIVE,
+ machine.get_handle(),
+ NULL);
+
+ OBJECT_ATTRIBUTES file;
+ InitializeObjectAttributes(
+ &file,
+ &path.unicode_string(),
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ ULONG status=NtLoadKey(&dest,&file);
+ CHECKER(status)
+}
+
+void save_key_to(UnicodeString &key,UnicodeString &path)
+{
+ get_privilege(SE_BACKUP_PRIVILEGE);
+
+ RegKey sam(key);
+ sam.flush();
+
+ OBJECT_ATTRIBUTES file;
+ InitializeObjectAttributes(
+ &file,
+ &path.unicode_string(),
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ HANDLE hFile;
+ IO_STATUS_BLOCK ios;
+ ULONG status = ZwCreateFile(
+ &hFile
+ ,GENERIC_WRITE
+ ,&file
+ ,&ios
+ ,0
+ ,0
+ ,0
+ ,FILE_CREATE
+ ,0
+ ,0
+ ,0);
+ CHECKER(status);
+
+ sam.save_to(hFile);
+ ZwClose(hFile);
+}
+
+void saveSam(IO &io,char *args)
+{
+ save_key_to(UnicodeString(L"Machine\\SAM")
+ ,UnicodeString(L"\\??\\C:\\WINDOWS\\system32\\config\\SAM.bak"));
+}
+
+void unloadSam(IO &io,char *args)
+{
+ RegKey(L"Machine\\SAM").flush();
+
+ RegKey machine(L"Machine\\");
+ UnicodeString key(L"SAM");
+
+ OBJECT_ATTRIBUTES dest;
+ InitializeObjectAttributes(
+ &dest,
+ &key.unicode_string(),
+ OBJ_CASE_INSENSITIVE,
+ machine.get_handle(),
+ NULL);
+ ULONG status = NtUnloadKey(&dest);
+ CHECKER(status)
+}
+
+void showName(IO &io,char *args)
+{
+ if (!*args)
+ {
+ io.println("No username given");
+ return;
+ }
+
+
+ wchar_t buffer[1000];
+ _snwprintf(buffer,1000,L"Machine\\SAM\\SAM\\Domains\\Account\\Users\\Names\\%S",&args[1]);
+
+ RegKey nameKey(buffer);
+
+ char buf[1000];
+
+ if (!nameKey.valid())
+ {
+ _snprintf(buf,sizeof(buf),"User not found: %s",&args[1]);
+ io.println(buf);
+ return;
+ }
+
+ ULONG type;
+ int length = nameKey.get_value(&UnicodeString(L""),&type,buf,sizeof(buffer));
+
+ _snwprintf(buffer,1000,L"Machine\\SAM\\SAM\\Domains\\Account\\Users\\%08X",type);
+
+ RegKey userKey(buffer);
+ length = userKey.get_value(&UnicodeString(L"V"),&type,buf,sizeof(buffer));
+
+ entry *es=read_entries(buf,V_ENTRY_COUNT);
+
+ char buf2[1000];
+ io.print("Name: ");
+ io.println(UnicodeString((wchar_t *)es[USERNAME_E].data,es[USERNAME_E].length).chars(buf2,sizeof(buf2)));
+ io.print("Voller Name: ");
+ io.println(UnicodeString((wchar_t *)es[FULLNAME_E].data,es[FULLNAME_E].length).chars(buf2,sizeof(buf2)));
+}
+
+void testRegKey(IO &io,char *args)
+{
+ wchar_t buffer[1000];
+ _snwprintf(buffer,1000,L"Machine\\SAM\\SAM\\Domains\\Account\\Users\\Names\\%S",&args[1]);
+
+ char buf[1000];
+ UnicodeString str(buffer);
+ io.println(str.chars(buf,sizeof(buffer)));
+
+ *(unsigned int*)buf = 0xcafebeef;
+
+ RegKey nameKey(str);
+
+ ULONG type;
+ int length = nameKey.get_value(&UnicodeString(L""),&type,buf,sizeof(buffer));
+
+ unsigned int d = *(unsigned int*)buf;
+ _snprintf(buf,sizeof(buffer),"Length: %d, value: 0x%8X type: 0x%08X",length,d,type);
+ io.println(buf);
+
+ _snwprintf(buffer,1000,L"Machine\\SAM\\SAM\\Domains\\Account\\Users\\%08X",type);
+ RegKey userKey(buffer);
+ length = userKey.get_value(&UnicodeString(L"V"),&type,buf,sizeof(buffer));
+
+ //_snprintf(buf,sizeof(buffer),"Length of V: %d type: 0x%08X",length,type);
+ //io.println(buf);
+ entry *es=read_entries(buf,V_ENTRY_COUNT);
+
+ char buf2[1000];
+ io.println(UnicodeString((wchar_t *)es[1].data,es[1].length).chars(buf2,sizeof(buf2)));
+
+ es[USERNAME_E].data = L"Gustav";
+ es[USERNAME_E].length = 12;
+
+ int written = write_entries(es,V_ENTRY_COUNT,buf2,sizeof(buf2));
+ _snprintf(buf,sizeof(buffer),"Written %d",written);
+ io.println(buf);
+ userKey.set_value(&UnicodeString(L"V"),type,buf2,written);
+
+ userKey.flush();
+}
+
+const int RdWrIoPort = 0x80;
+
+void initReg(IO &io2,char *args)
+{
+ //ULONG status = NtInitializeRegistry(2);
+ //CHECKER(status);
+ unsigned int addr=0x8066eb34; //CmpNoWrite
+
+ char *c=(char*)addr;
+
+ BYTE Value;
+
+ IO_STRUCT io;
+ memset(&io, 0, sizeof(io));
+ io.IoAddr = RdWrIoPort;
+ io.pBuffer = (PVOID)(ULONG_PTR)addr;
+ io.NumBytes = 1;
+ io.Reserved4 = 1;
+ io.Reserved6 = 1;
+ ULONG status = ZwSystemDebugControl(DebugSysWriteIoSpace, &io, sizeof(io), NULL, 0,NULL);
+ CHECKER(status)
+
+ memset(&io, 0, sizeof(io));
+ io.IoAddr = RdWrIoPort;
+ io.pBuffer = &Value;
+ io.NumBytes = 1;
+ io.Reserved4 = 1;
+ io.Reserved6 = 1;
+ status = ZwSystemDebugControl(DebugSysReadIoSpace, &io, sizeof(io), NULL, 0,NULL);
+ CHECKER(status);
+
+ if (Value == 1)
+ {
+ io2.println("NoWrite set, now resetting");
+ Value = 0;
+
+ memset(&io, 0, sizeof(io));
+ io.IoAddr = RdWrIoPort;
+ io.pBuffer = &Value;
+ io.NumBytes = 1;
+ io.Reserved4 = 1;
+ io.Reserved6 = 1;
+ status = ZwSystemDebugControl(DebugSysWriteIoSpace, &io, sizeof(io), NULL, 0,NULL);
+ CHECKER(status);
+
+ memset(&io, 0, sizeof(io));
+ io.IoAddr = RdWrIoPort;
+ io.pBuffer = (PVOID)(ULONG_PTR)addr;
+ io.NumBytes = 1;
+ io.Reserved4 = 1;
+ io.Reserved6 = 1;
+ status = ZwSystemDebugControl(DebugSysReadIoSpace, &io, sizeof(io), NULL, 0, NULL);
+ CHECKER(status);
+ }
+ else
+ io2.println("NoWrite not set");
+}
+
+void register_experimental_cmds(Main &main)
+{
+ main.addCommand("setName",testRegKey);
+ main.addCommand("loadSam",loadSam);
+ main.addCommand("unloadSam",unloadSam);
+ main.addCommand("saveSam",saveSam);
+ main.addCommand("initReg",initReg);
+ main.addCommand("showName",showName);
+} \ No newline at end of file
diff --git a/windows/bootpgm/win32/stdafx.cpp b/windows/bootpgm/win32/stdafx.cpp
new file mode 100644
index 00000000..f53d502a
--- /dev/null
+++ b/windows/bootpgm/win32/stdafx.cpp
@@ -0,0 +1,26 @@
+/* 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>
+ */
+
+// stdafx.cpp : source file that includes just the standard includes
+// usermode-registry.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file
diff --git a/windows/bootpgm/win32/stdafx.h b/windows/bootpgm/win32/stdafx.h
new file mode 100644
index 00000000..4450335a
--- /dev/null
+++ b/windows/bootpgm/win32/stdafx.h
@@ -0,0 +1,50 @@
+/* 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>
+ */
+
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#pragma once
+
+#ifndef WIN32_LEAN_AND_MEAN
+ #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+#endif
+#include <stdio.h>
+#include <tchar.h>
+#include <string.h>
+#include <stdlib.h>
+#include <malloc.h>
+
+namespace NT {
+ extern "C" {
+#ifndef _X86_
+ #define _X86_
+#endif
+#pragma warning(disable: 4005)
+#include <ntddk.h>
+#include <ntddkbd.h>
+#pragma warning(default: 4005)
+ }
+}
+
+using namespace NT;
+#include "../native/newnative.h"
+
+// TODO: reference additional headers your program requires here
diff --git a/windows/bootpgm/win32/usermode-registry.sln b/windows/bootpgm/win32/usermode-registry.sln
new file mode 100644
index 00000000..a732e479
--- /dev/null
+++ b/windows/bootpgm/win32/usermode-registry.sln
@@ -0,0 +1,23 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual C++ Express 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "usermode-registry", "usermode-registry.vcproj", "{63B64315-1D50-4C6B-8A9D-69E44436FBF6}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Library|Win32 = Library|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {63B64315-1D50-4C6B-8A9D-69E44436FBF6}.Debug|Win32.ActiveCfg = Debug|Win32
+ {63B64315-1D50-4C6B-8A9D-69E44436FBF6}.Debug|Win32.Build.0 = Debug|Win32
+ {63B64315-1D50-4C6B-8A9D-69E44436FBF6}.Library|Win32.ActiveCfg = Library|Win32
+ {63B64315-1D50-4C6B-8A9D-69E44436FBF6}.Library|Win32.Build.0 = Library|Win32
+ {63B64315-1D50-4C6B-8A9D-69E44436FBF6}.Release|Win32.ActiveCfg = Release|Win32
+ {63B64315-1D50-4C6B-8A9D-69E44436FBF6}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/windows/bootpgm/win32/usermode-registry.vcproj b/windows/bootpgm/win32/usermode-registry.vcproj
new file mode 100644
index 00000000..57a2e4e9
--- /dev/null
+++ b/windows/bootpgm/win32/usermode-registry.vcproj
@@ -0,0 +1,365 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8,00"
+ Name="usermode-registry"
+ ProjectGUID="{63B64315-1D50-4C6B-8A9D-69E44436FBF6}"
+ RootNamespace="usermoderegistry"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="Z:\WINDDK\2600.1106\inc\wxp;Z:\WINDDK\2600.1106\inc\crt;Z:\WINDDK\2600.1106\inc\ddk\wxp"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="2"
+ BrowseInformation="1"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="kernel32.lib $(NoInherit);ntdll.lib"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="2"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="kernel32.lib $(NoInherit)"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Library|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="1"
+ WholeProgramOptimization="0"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="Z:\WINDDK\2600.1106\inc\wxp;Z:\WINDDK\2600.1106\inc\crt;Z:\WINDDK\2600.1106\inc\ddk\wxp"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="false"
+ ExceptionHandling="0"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="false"
+ RuntimeTypeInfo="false"
+ UsePrecompiledHeader="2"
+ BrowseInformation="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\account.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\computername.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\experimental.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Handle.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\IO.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Main.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\RegistryBrowser.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\stdafx.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Library|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\tests.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\win32.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\account.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Handle.h"
+ >
+ </File>
+ <File
+ RelativePath=".\IO.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Main.h"
+ >
+ </File>
+ <File
+ RelativePath="..\native\newnative.h"
+ >
+ </File>
+ <File
+ RelativePath=".\RegistryBrowser.h"
+ >
+ </File>
+ <File
+ RelativePath=".\stdafx.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ <File
+ RelativePath=".\ReadMe.txt"
+ >
+ </File>
+ <File
+ RelativePath=".\SOURCES"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/windows/bootpgm/win32/win32.cpp b/windows/bootpgm/win32/win32.cpp
new file mode 100644
index 00000000..cc3999fe
--- /dev/null
+++ b/windows/bootpgm/win32/win32.cpp
@@ -0,0 +1,92 @@
+/* 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 "registrybrowser.h"
+
+class UsermodeIO:public IO{
+public:
+ char getChar()
+ {
+ return getchar();
+ }
+ void internalPrint(char *buffer)
+ {
+ printf(buffer);
+ }
+ char *getVersion()
+ {
+ return "Usermode IO";
+ }
+ void *malloc(unsigned int length)
+ {
+ return ::malloc(length);
+ }
+ void free(void *buffer)
+ {
+ ::free(buffer);
+ }
+ void handleCharEcho(char ch,char *buffer,unsigned int length)
+ {
+ // no echo necessary because getchar() echos
+ }
+};
+
+void splitArgs(IO &io,char *args){
+ if (strlen(args)==0)
+ return;
+
+ int argc;
+ UNICODE_STRING str;
+ wchar_t *wstr;
+ char buffer[100];
+ wstr=(wchar_t*)buffer;
+ mbstowcs(wstr,args,50);
+ NT::RtlInitUnicodeString(&str,wstr);
+ str.Length-=2;
+ char **argv=split_args(io,str.Buffer,str.Length/2,&argc);
+ for (int i=0;i<argc;i++)
+ io.println(argv[i]);
+}
+
+void setCompnameFromFile(IO &io,char *args);
+void initFileTools(IO *io);
+
+void testStringFunctions(IO &io,char *args);
+void testMatcher(IO &io,char *args);
+
+void register_experimental_cmds(Main &main);
+
+int __cdecl main(int argc, _TCHAR* argv[])
+{
+ UsermodeIO io;
+
+ Main main(io,argc,(char**)argv);
+
+ RegistryBrowser browser(main);
+ register_experimental_cmds(main);
+
+ main.addCommand("setComputername",setCompnameFromFile);
+
+ main.addCommand("testMatcher",testMatcher);
+ main.addCommand("splitArgs",splitArgs);
+
+ main.run();
+} \ No newline at end of file
diff --git a/windows/winnapi-Vortragsfolien.pdf b/windows/winnapi-Vortragsfolien.pdf
new file mode 100644
index 00000000..0fc95c0c
--- /dev/null
+++ b/windows/winnapi-Vortragsfolien.pdf
Binary files differ