mirror of
https://github.com/reactos/reactos.git
synced 2025-04-22 13:10:39 +00:00
[TOOLS]: Slap some sense in the indentation of some files. Next time: PLEASE CHECK YOUR F*CKING EDITOR's TABS AND SET THEM TO 4 SPACES BEFORE DOING ANYTHING ELSE!!!! (and not to 8 spaces and then use 4 space indentation and complete with tabs).
svn path=/trunk/; revision=65998
This commit is contained in:
parent
30f966769f
commit
cef76b7a93
40 changed files with 3082 additions and 3111 deletions
|
@ -1676,7 +1676,7 @@ ULONG CCabinet::WriteFileToScratchStorage(PCFFILE_NODE FileNode)
|
|||
CurrentFolderNode->UncompOffset += TotalBytesLeft;
|
||||
FileNode->File.FileControlID = (USHORT)(NextFolderNumber - 1);
|
||||
CurrentFolderNode->Commit = true;
|
||||
PrevCabinetNumber = CurrentDiskNumber;
|
||||
PrevCabinetNumber = CurrentDiskNumber;
|
||||
|
||||
Size = sizeof(CFFILE) + (ULONG)strlen(GetFileName(FileNode->FileName)) + 1;
|
||||
CABHeader.FileTableOffset += Size;
|
||||
|
|
|
@ -255,7 +255,8 @@ typedef struct _CAB_SEARCH
|
|||
|
||||
/* Codecs */
|
||||
|
||||
class CCABCodec {
|
||||
class CCABCodec
|
||||
{
|
||||
public:
|
||||
/* Default constructor */
|
||||
CCABCodec() {};
|
||||
|
@ -291,7 +292,8 @@ public:
|
|||
|
||||
#ifndef CAB_READ_ONLY
|
||||
|
||||
class CCFDATAStorage {
|
||||
class CCFDATAStorage
|
||||
{
|
||||
public:
|
||||
/* Default constructor */
|
||||
CCFDATAStorage();
|
||||
|
@ -312,7 +314,8 @@ private:
|
|||
|
||||
#endif /* CAB_READ_ONLY */
|
||||
|
||||
class CCabinet {
|
||||
class CCabinet
|
||||
{
|
||||
public:
|
||||
/* Default constructor */
|
||||
CCabinet();
|
||||
|
|
|
@ -18,7 +18,8 @@
|
|||
|
||||
/* Classes */
|
||||
|
||||
class CCABManager : public CDFParser {
|
||||
class CCABManager : public CDFParser
|
||||
{
|
||||
public:
|
||||
CCABManager();
|
||||
virtual ~CCABManager();
|
||||
|
|
|
@ -21,7 +21,7 @@ Syntax Description
|
|||
Standard variable Description
|
||||
-------------------------------------------------------------------------------
|
||||
Cabinet=ON|OFF Turns cabinet mode on or off (* -- currently always on)
|
||||
CabinetFileCountThreshold=count Threshold count of files per cabinet (*)
|
||||
CabinetFileCountThreshold=count Threshold count of files per cabinet (*)
|
||||
CabinetNamen=filename Cabinet file name for cabinet number n
|
||||
CabinetNameTemplate=template Cabinet file name template
|
||||
* is replaced by cabinet number
|
||||
|
|
|
@ -9,19 +9,22 @@
|
|||
|
||||
#include "cabinet.h"
|
||||
|
||||
typedef struct _CABINET_NAME {
|
||||
typedef struct _CABINET_NAME
|
||||
{
|
||||
struct _CABINET_NAME *Next;
|
||||
ULONG DiskNumber;
|
||||
char Name[128];
|
||||
} CABINET_NAME, *PCABINET_NAME;
|
||||
|
||||
typedef struct _DISK_NUMBER {
|
||||
typedef struct _DISK_NUMBER
|
||||
{
|
||||
struct _DISK_NUMBER *Next;
|
||||
ULONG DiskNumber;
|
||||
ULONG Number;
|
||||
} DISK_NUMBER, *PDISK_NUMBER;
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
TokenUnknown,
|
||||
TokenInteger,
|
||||
TokenIdentifier,
|
||||
|
@ -35,7 +38,8 @@ typedef enum {
|
|||
} DFP_TOKEN;
|
||||
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
stCabinetName,
|
||||
stCabinetNameTemplate,
|
||||
stDiskLabel,
|
||||
|
@ -45,7 +49,8 @@ typedef enum {
|
|||
} SETTYPE;
|
||||
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
ntDisk,
|
||||
ntCabinet,
|
||||
ntFolder,
|
||||
|
@ -54,7 +59,8 @@ typedef enum {
|
|||
|
||||
/* Classes */
|
||||
|
||||
class CDFParser : public CCabinet {
|
||||
class CDFParser : public CCabinet
|
||||
{
|
||||
public:
|
||||
CDFParser();
|
||||
virtual ~CDFParser();
|
||||
|
|
|
@ -346,7 +346,7 @@ bool CCABManager::ParseCmdline(int argc, char* argv[])
|
|||
SetFileRelativePath(&argv[i][2]);
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case 'V':
|
||||
Verbose = true;
|
||||
break;
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
PATH_TO_TOP = ../..
|
||||
|
||||
TARGET_TYPE = program
|
||||
|
||||
TARGET_APPTYPE = console
|
||||
|
||||
TARGET_NAME = cabman
|
||||
#TARGET_NAME = test
|
||||
|
||||
TARGET_CPPAPP = yes
|
||||
|
||||
TARGET_OBJECTS = cabinet.o mszip.o raw.o main.o dfp.o
|
||||
|
||||
TARGET_SDKLIBS = zlib.a
|
||||
|
||||
TARGET_CFLAGS = -I$(PATH_TO_TOP)/lib/zlib -Werror -Wall
|
||||
|
||||
TARGET_CPPFLAGS = $(TARGET_CFLAGS)
|
||||
|
||||
TARGET_GCCLIBS = stdc++
|
||||
|
||||
TARGET_NORC = yes
|
||||
|
||||
include $(PATH_TO_TOP)/rules.mak
|
||||
|
||||
include $(TOOLS_PATH)/helper.mk
|
||||
|
|
@ -15,7 +15,8 @@
|
|||
|
||||
/* Classes */
|
||||
|
||||
class CMSZipCodec : public CCABCodec {
|
||||
class CMSZipCodec : public CCABCodec
|
||||
{
|
||||
public:
|
||||
/* Default constructor */
|
||||
CMSZipCodec();
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
|
||||
/* Classes */
|
||||
|
||||
class CRawCodec : public CCABCodec {
|
||||
class CRawCodec : public CCABCodec
|
||||
{
|
||||
public:
|
||||
/* Default constructor */
|
||||
CRawCodec();
|
||||
|
|
|
@ -66,13 +66,13 @@ typedef int BOOL;
|
|||
|
||||
// file system parameters
|
||||
|
||||
#define MAX_LEVEL 8
|
||||
#define MAX_NAME_LENGTH 64
|
||||
#define MAX_CDNAME_LENGTH 8
|
||||
#define MAX_EXTENSION_LENGTH 10
|
||||
#define MAX_CDEXTENSION_LENGTH 3
|
||||
#define SECTOR_SIZE 2048
|
||||
#define BUFFER_SIZE (8 * SECTOR_SIZE)
|
||||
#define MAX_LEVEL 8
|
||||
#define MAX_NAME_LENGTH 64
|
||||
#define MAX_CDNAME_LENGTH 8
|
||||
#define MAX_EXTENSION_LENGTH 10
|
||||
#define MAX_CDEXTENSION_LENGTH 3
|
||||
#define SECTOR_SIZE 2048
|
||||
#define BUFFER_SIZE (8 * SECTOR_SIZE)
|
||||
|
||||
const BYTE HIDDEN_FLAG = 1;
|
||||
const BYTE DIRECTORY_FLAG = 2;
|
||||
|
@ -395,8 +395,8 @@ This function writes a directory record to the CD_ROM image.
|
|||
|
||||
static void
|
||||
write_directory_record(PDIR_RECORD d,
|
||||
DIR_RECORD_TYPE DirType,
|
||||
BOOL joliet)
|
||||
DIR_RECORD_TYPE DirType,
|
||||
BOOL joliet)
|
||||
{
|
||||
unsigned identifier_size;
|
||||
unsigned record_size;
|
||||
|
@ -1253,7 +1253,7 @@ static void get_time_string(char *str)
|
|||
struct tm *current;
|
||||
time_t timestamp = time(NULL);
|
||||
current = gmtime(×tamp);
|
||||
sprintf(str, "%04d%02d%02d%02d%02d%02d00",
|
||||
sprintf(str, "%04d%02d%02d%02d%02d%02d00",
|
||||
current->tm_year + 1900,
|
||||
current->tm_mon,
|
||||
current->tm_mday,
|
||||
|
|
|
@ -35,4 +35,4 @@ dir_hash_create_dir(struct target_dir_hash *dh, const char *casename, const char
|
|||
struct target_dir_entry *dir_hash_next_dir(struct target_dir_hash *dh, struct target_dir_traversal *t);
|
||||
void dir_hash_destroy(struct target_dir_hash *dh);
|
||||
|
||||
#endif//_REACTOS_TOOLS_CDMAKE_DIRHASH_H_
|
||||
#endif //_REACTOS_TOOLS_CDMAKE_DIRHASH_H_
|
||||
|
|
|
@ -12,10 +12,10 @@ site into the unicode.org subdirectory and create_nls will build the .nls
|
|||
files.
|
||||
|
||||
Makefile targets:
|
||||
'make': builds create_nls tool.
|
||||
'make clean': deletes all executable and object files
|
||||
'make nls': generates binary .nls files.
|
||||
'make clean_nls': deletes binary .nls files.
|
||||
'make': builds create_nls tool.
|
||||
'make clean': deletes all executable and object files
|
||||
'make nls': generates binary .nls files.
|
||||
'make clean_nls': deletes binary .nls files.
|
||||
|
||||
Since the binary .nls files are part of the ReactOS source tree it is not
|
||||
necessary to build these files yourself. Therefore create_nls is not
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -10,8 +10,8 @@ list(APPEND SOURCE
|
|||
options.c
|
||||
revision.c
|
||||
stat.c
|
||||
util.c)
|
||||
util.c)
|
||||
|
||||
include_directories(${REACTOS_SOURCE_DIR}/tools/rsym)
|
||||
add_executable(log2lines ${SOURCE})
|
||||
target_link_libraries(log2lines rsym_common)
|
||||
target_link_libraries(log2lines rsym_common)
|
||||
|
|
|
@ -69,9 +69,9 @@ unpack_iso(char *dir, char *iso)
|
|||
int
|
||||
cleanable(char *path)
|
||||
{
|
||||
if (strcmp(basename(path),DEF_OPT_DIR) == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
if (strcmp(basename(path),DEF_OPT_DIR) == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -144,10 +144,10 @@ check_directory(int force)
|
|||
cache_name = malloc(PATH_MAX);
|
||||
tmp_name = malloc(PATH_MAX);
|
||||
strcpy(cache_name, opt_dir);
|
||||
if (cleanable(opt_dir))
|
||||
strcat(cache_name, ALT_PATH_STR CACHEFILE);
|
||||
else
|
||||
strcat(cache_name, PATH_STR CACHEFILE);
|
||||
if (cleanable(opt_dir))
|
||||
strcat(cache_name, ALT_PATH_STR CACHEFILE);
|
||||
else
|
||||
strcat(cache_name, PATH_STR CACHEFILE);
|
||||
strcpy(tmp_name, cache_name);
|
||||
strcat(tmp_name, "~");
|
||||
return 0;
|
||||
|
|
|
@ -160,7 +160,7 @@ handle_address_cmd(FILE *outFile, char *arg)
|
|||
if (( plm = entry_lookup(&cache, Image) ))
|
||||
{
|
||||
if (plm->RelBase != INVALID_BASE)
|
||||
esclog(outFile, "Address: 0x%lx\n", plm->RelBase + Offset)
|
||||
esclog(outFile, "Address: 0x%lx\n", plm->RelBase + Offset)
|
||||
else
|
||||
esclog(outFile, "Relocated base missing for '%s' ('mod' will update)\n", Image);
|
||||
}
|
||||
|
@ -168,7 +168,7 @@ handle_address_cmd(FILE *outFile, char *arg)
|
|||
esclog(outFile, "Image '%s' not found\n", Image);
|
||||
}
|
||||
else
|
||||
esclog(outFile, "usage: `a <Image>:<offset>\n");
|
||||
esclog(outFile, "usage: `a <Image>:<offset>\n");
|
||||
}
|
||||
else
|
||||
esclog(outFile, "':' expected\n");
|
||||
|
@ -259,10 +259,10 @@ handle_escape_cmd(FILE *outFile, char *Line, char *path, char *LineOut)
|
|||
break;
|
||||
case 'R':
|
||||
changed = handle_switch_pstr(outFile, &opt_Revision, arg, NULL);
|
||||
opt_Revision_check = 0;
|
||||
opt_Revision_check = 0;
|
||||
if (opt_Revision)
|
||||
{
|
||||
opt_Revision_check = 1;
|
||||
opt_Revision_check = 1;
|
||||
if (strstr(opt_Revision, "check") == opt_Revision)
|
||||
{
|
||||
esclog(outFile, "-R is \"%s\" (%s)\n", opt_Revision, changed ? "changed":"unchanged");
|
||||
|
@ -302,7 +302,7 @@ handle_escape_cmd(FILE *outFile, char *Line, char *path, char *LineOut)
|
|||
{
|
||||
handle_switch(outFile, &opt_undo, "1", "-u Undo");
|
||||
handle_switch(outFile, &opt_redo, "1", "-U Undo and reprocess");
|
||||
opt_Revision_check = 1;
|
||||
opt_Revision_check = 1;
|
||||
}
|
||||
esclog(outFile, "-S Sources option is %d+%d,\"%s\"\n", opt_Source, opt_SrcPlus, opt_SourcesPath);
|
||||
esclog(outFile, "(Setting source tree not implemented)\n");
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
PATH_STR "reactos" PATH_STR "reactos > " DEV_NULL
|
||||
|
||||
/* When we can't use a normal path, because it gets cleaned,
|
||||
* fallback to name mangling:
|
||||
*/
|
||||
* fallback to name mangling:
|
||||
*/
|
||||
#define ALT_PATH_STR "#"
|
||||
|
||||
#define LINESIZE 1024
|
||||
|
|
|
@ -43,7 +43,7 @@ entry_lookup(PLIST list, char *name)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
PLIST_MEMBER
|
||||
PLIST_MEMBER
|
||||
entry_delete(PLIST_MEMBER pentry)
|
||||
{
|
||||
if (!pentry)
|
||||
|
@ -54,7 +54,7 @@ entry_delete(PLIST_MEMBER pentry)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
PLIST_MEMBER
|
||||
PLIST_MEMBER
|
||||
entry_insert(PLIST list, PLIST_MEMBER pentry)
|
||||
{
|
||||
if (!pentry)
|
||||
|
@ -115,7 +115,7 @@ entry_remove(LIST *list, LIST_MEMBER *pentry)
|
|||
}
|
||||
#endif
|
||||
|
||||
PLIST_MEMBER
|
||||
PLIST_MEMBER
|
||||
cache_entry_create(char *Line)
|
||||
{
|
||||
PLIST_MEMBER pentry;
|
||||
|
@ -169,7 +169,7 @@ cache_entry_create(char *Line)
|
|||
}
|
||||
|
||||
|
||||
PLIST_MEMBER
|
||||
PLIST_MEMBER
|
||||
sources_entry_create(PLIST list, char *path, char *prefix)
|
||||
{
|
||||
PLIST_MEMBER pentry;
|
||||
|
|
|
@ -70,7 +70,7 @@ int optionInit(int argc, const char **argv)
|
|||
|
||||
//The user introduced "log2lines.exe" or "log2lines.exe /?"
|
||||
//Let's help the user
|
||||
if ((argc == 1) ||
|
||||
if ((argc == 1) ||
|
||||
((argc == 2) && (argv[1][0] == '/') && (argv[1][1] == '?')))
|
||||
{
|
||||
opt_help++;
|
||||
|
@ -169,8 +169,8 @@ int optionParse(int argc, const char **argv)
|
|||
free(opt_Revision);
|
||||
opt_Revision = malloc(LINESIZE);
|
||||
sscanf(optarg, "%s", opt_Revision);
|
||||
if (strcmp(opt_Revision, "check") == 0)
|
||||
opt_Revision_check ++;
|
||||
if (strcmp(opt_Revision, "check") == 0)
|
||||
opt_Revision_check ++;
|
||||
break;
|
||||
case 's':
|
||||
opt_stats++;
|
||||
|
@ -186,7 +186,7 @@ int optionParse(int argc, const char **argv)
|
|||
/* need to retranslate for source info: */
|
||||
opt_undo++;
|
||||
opt_redo++;
|
||||
opt_Revision_check ++;
|
||||
opt_Revision_check ++;
|
||||
}
|
||||
break;
|
||||
case 't':
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
typedef struct revinfo_struct
|
||||
{
|
||||
int rev;
|
||||
int rev;
|
||||
int buildrev;
|
||||
int range;
|
||||
int opt_verbose;
|
||||
|
|
|
@ -37,7 +37,7 @@ stat_print(FILE *outFile, PSUMM psumm)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
stat_clear(PSUMM psumm)
|
||||
{
|
||||
memset(psumm, 0, sizeof(SUMM));
|
||||
|
|
|
@ -31,28 +31,28 @@
|
|||
|
||||
BOOL
|
||||
ExportBinaryHive(
|
||||
IN PCSTR FileName,
|
||||
IN PCMHIVE Hive)
|
||||
IN PCSTR FileName,
|
||||
IN PCMHIVE Hive)
|
||||
{
|
||||
FILE *File;
|
||||
BOOL ret;
|
||||
FILE *File;
|
||||
BOOL ret;
|
||||
|
||||
printf (" Creating binary hive: %s\n", FileName);
|
||||
printf (" Creating binary hive: %s\n", FileName);
|
||||
|
||||
/* Create new hive file */
|
||||
File = fopen (FileName, "w+b");
|
||||
if (File == NULL)
|
||||
{
|
||||
printf(" Error creating/opening file\n");
|
||||
return FALSE;
|
||||
}
|
||||
/* Create new hive file */
|
||||
File = fopen (FileName, "w+b");
|
||||
if (File == NULL)
|
||||
{
|
||||
printf(" Error creating/opening file\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fseek (File, 0, SEEK_SET);
|
||||
fseek (File, 0, SEEK_SET);
|
||||
|
||||
Hive->FileHandles[HFILE_TYPE_PRIMARY] = (HANDLE)File;
|
||||
ret = HvWriteHive(&Hive->Hive);
|
||||
fclose (File);
|
||||
return ret;
|
||||
Hive->FileHandles[HFILE_TYPE_PRIMARY] = (HANDLE)File;
|
||||
ret = HvWriteHive(&Hive->Hive);
|
||||
fclose (File);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
BOOL
|
||||
ExportBinaryHive(
|
||||
IN PCSTR FileName,
|
||||
IN PCMHIVE Hive);
|
||||
IN PCSTR FileName,
|
||||
IN PCMHIVE Hive);
|
||||
|
||||
/* EOF */
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -28,38 +28,38 @@
|
|||
|
||||
NTSTATUS
|
||||
CmiInitializeTempHive(
|
||||
IN OUT PCMHIVE Hive);
|
||||
IN OUT PCMHIVE Hive);
|
||||
|
||||
NTSTATUS
|
||||
CmiAddSubKey(
|
||||
IN PCMHIVE RegistryHive,
|
||||
IN HCELL_INDEX ParentKeyCellOffset,
|
||||
IN PCUNICODE_STRING SubKeyName,
|
||||
IN ULONG CreateOptions,
|
||||
OUT PCM_KEY_NODE *pSubKeyCell,
|
||||
OUT HCELL_INDEX *pBlockOffset);
|
||||
IN PCMHIVE RegistryHive,
|
||||
IN HCELL_INDEX ParentKeyCellOffset,
|
||||
IN PCUNICODE_STRING SubKeyName,
|
||||
IN ULONG CreateOptions,
|
||||
OUT PCM_KEY_NODE *pSubKeyCell,
|
||||
OUT HCELL_INDEX *pBlockOffset);
|
||||
|
||||
NTSTATUS
|
||||
CmiScanForSubKey(
|
||||
IN PCMHIVE RegistryHive,
|
||||
IN HCELL_INDEX ParentKeyCellOffset,
|
||||
IN PCUNICODE_STRING SubKeyName,
|
||||
IN ULONG Attributes,
|
||||
OUT PCM_KEY_NODE *pSubKeyCell,
|
||||
OUT HCELL_INDEX *pBlockOffset);
|
||||
IN PCMHIVE RegistryHive,
|
||||
IN HCELL_INDEX ParentKeyCellOffset,
|
||||
IN PCUNICODE_STRING SubKeyName,
|
||||
IN ULONG Attributes,
|
||||
OUT PCM_KEY_NODE *pSubKeyCell,
|
||||
OUT HCELL_INDEX *pBlockOffset);
|
||||
|
||||
NTSTATUS
|
||||
CmiAddValueKey(
|
||||
IN PCMHIVE RegistryHive,
|
||||
IN HCELL_INDEX KeyCellOffset,
|
||||
IN PCUNICODE_STRING ValueName,
|
||||
OUT PCM_KEY_VALUE *pValueCell,
|
||||
OUT HCELL_INDEX *pValueCellOffset);
|
||||
IN PCMHIVE RegistryHive,
|
||||
IN HCELL_INDEX KeyCellOffset,
|
||||
IN PCUNICODE_STRING ValueName,
|
||||
OUT PCM_KEY_VALUE *pValueCell,
|
||||
OUT HCELL_INDEX *pValueCellOffset);
|
||||
|
||||
NTSTATUS
|
||||
CmiScanForValueKey(
|
||||
IN PCMHIVE RegistryHive,
|
||||
IN HCELL_INDEX KeyCellOffset,
|
||||
IN PCUNICODE_STRING ValueName,
|
||||
OUT PCM_KEY_VALUE *pValueCell,
|
||||
OUT HCELL_INDEX *pValueCellOffset);
|
||||
IN PCMHIVE RegistryHive,
|
||||
IN HCELL_INDEX KeyCellOffset,
|
||||
IN PCUNICODE_STRING ValueName,
|
||||
OUT PCM_KEY_VALUE *pValueCell,
|
||||
OUT HCELL_INDEX *pValueCellOffset);
|
||||
|
|
|
@ -49,105 +49,105 @@
|
|||
|
||||
void usage (void)
|
||||
{
|
||||
printf ("Usage: mkhive <dstdir> <inffiles>\n\n");
|
||||
printf (" dstdir - binary hive files are created in this directory\n");
|
||||
printf (" inffiles - inf files with full path\n");
|
||||
printf ("Usage: mkhive <dstdir> <inffiles>\n\n");
|
||||
printf (" dstdir - binary hive files are created in this directory\n");
|
||||
printf (" inffiles - inf files with full path\n");
|
||||
}
|
||||
|
||||
void convert_path(char *dst, char *src)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (src[i] != 0)
|
||||
{
|
||||
i = 0;
|
||||
while (src[i] != 0)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (src[i] == '/')
|
||||
{
|
||||
dst[i] = '\\';
|
||||
}
|
||||
if (src[i] == '/')
|
||||
{
|
||||
dst[i] = '\\';
|
||||
}
|
||||
#else
|
||||
if (src[i] == '\\')
|
||||
{
|
||||
dst[i] = '/';
|
||||
}
|
||||
if (src[i] == '\\')
|
||||
{
|
||||
dst[i] = '/';
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
dst[i] = src[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[i] = src[i];
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
dst[i] = 0;
|
||||
i++;
|
||||
}
|
||||
dst[i] = 0;
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
char FileName[PATH_MAX];
|
||||
int i;
|
||||
char FileName[PATH_MAX];
|
||||
int i;
|
||||
|
||||
if (argc < 3)
|
||||
{
|
||||
usage ();
|
||||
return 1;
|
||||
}
|
||||
if (argc < 3)
|
||||
{
|
||||
usage ();
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf ("Binary hive maker\n");
|
||||
printf ("Binary hive maker\n");
|
||||
|
||||
RegInitializeRegistry ();
|
||||
RegInitializeRegistry ();
|
||||
|
||||
for (i = 2; i < argc; i++)
|
||||
{
|
||||
convert_path (FileName, argv[i]);
|
||||
ImportRegistryFile (FileName);
|
||||
}
|
||||
for (i = 2; i < argc; i++)
|
||||
{
|
||||
convert_path (FileName, argv[i]);
|
||||
ImportRegistryFile (FileName);
|
||||
}
|
||||
|
||||
convert_path (FileName, argv[1]);
|
||||
strcat (FileName, DIR_SEPARATOR_STRING);
|
||||
strcat (FileName, "default");
|
||||
if (!ExportBinaryHive (FileName, &DefaultHive))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
convert_path (FileName, argv[1]);
|
||||
strcat (FileName, DIR_SEPARATOR_STRING);
|
||||
strcat (FileName, "default");
|
||||
if (!ExportBinaryHive (FileName, &DefaultHive))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
convert_path (FileName, argv[1]);
|
||||
strcat (FileName, DIR_SEPARATOR_STRING);
|
||||
strcat (FileName, "sam");
|
||||
if (!ExportBinaryHive (FileName, &SamHive))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
convert_path (FileName, argv[1]);
|
||||
strcat (FileName, DIR_SEPARATOR_STRING);
|
||||
strcat (FileName, "sam");
|
||||
if (!ExportBinaryHive (FileName, &SamHive))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
convert_path (FileName, argv[1]);
|
||||
strcat (FileName, DIR_SEPARATOR_STRING);
|
||||
strcat (FileName, "security");
|
||||
if (!ExportBinaryHive (FileName, &SecurityHive))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
convert_path (FileName, argv[1]);
|
||||
strcat (FileName, DIR_SEPARATOR_STRING);
|
||||
strcat (FileName, "security");
|
||||
if (!ExportBinaryHive (FileName, &SecurityHive))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
convert_path (FileName, argv[1]);
|
||||
strcat (FileName, DIR_SEPARATOR_STRING);
|
||||
strcat (FileName, "software");
|
||||
if (!ExportBinaryHive (FileName, &SoftwareHive))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
convert_path (FileName, argv[1]);
|
||||
strcat (FileName, DIR_SEPARATOR_STRING);
|
||||
strcat (FileName, "software");
|
||||
if (!ExportBinaryHive (FileName, &SoftwareHive))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
convert_path (FileName, argv[1]);
|
||||
strcat (FileName, DIR_SEPARATOR_STRING);
|
||||
strcat (FileName, "system");
|
||||
if (!ExportBinaryHive (FileName, &SystemHive))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
convert_path (FileName, argv[1]);
|
||||
strcat (FileName, DIR_SEPARATOR_STRING);
|
||||
strcat (FileName, "system");
|
||||
if (!ExportBinaryHive (FileName, &SystemHive))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
RegShutdownRegistry ();
|
||||
RegShutdownRegistry ();
|
||||
|
||||
printf (" Done.\n");
|
||||
printf (" Done.\n");
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -67,33 +67,33 @@ static const WCHAR DelReg[] = {'D','e','l','R','e','g',0};
|
|||
static BOOL
|
||||
GetRootKey (PWCHAR Name)
|
||||
{
|
||||
if (!strcmpiW (Name, HKCR))
|
||||
{
|
||||
strcpyW (Name, HKCRPath);
|
||||
return TRUE;
|
||||
}
|
||||
if (!strcmpiW (Name, HKCR))
|
||||
{
|
||||
strcpyW (Name, HKCRPath);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!strcmpiW (Name, HKCU))
|
||||
{
|
||||
strcpyW (Name, HKCUPath);
|
||||
return TRUE;
|
||||
}
|
||||
if (!strcmpiW (Name, HKCU))
|
||||
{
|
||||
strcpyW (Name, HKCUPath);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!strcmpiW (Name, HKLM))
|
||||
{
|
||||
strcpyW (Name, HKLMPath);
|
||||
return TRUE;
|
||||
}
|
||||
if (!strcmpiW (Name, HKLM))
|
||||
{
|
||||
strcpyW (Name, HKLMPath);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!strcmpiW (Name, HKU))
|
||||
{
|
||||
strcpyW (Name, HKUPath);
|
||||
return TRUE;
|
||||
}
|
||||
if (!strcmpiW (Name, HKU))
|
||||
{
|
||||
strcpyW (Name, HKUPath);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (!strcmpiW (Name, HKR))
|
||||
return FALSE;
|
||||
if (!strcmpiW (Name, HKR))
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
return FALSE;
|
||||
|
@ -107,77 +107,77 @@ GetRootKey (PWCHAR Name)
|
|||
*/
|
||||
static VOID
|
||||
AppendMultiSzValue (
|
||||
IN HKEY KeyHandle,
|
||||
IN PWCHAR ValueName,
|
||||
IN PWCHAR Strings,
|
||||
IN SIZE_T StringSize)
|
||||
IN HKEY KeyHandle,
|
||||
IN PWCHAR ValueName,
|
||||
IN PWCHAR Strings,
|
||||
IN SIZE_T StringSize)
|
||||
{
|
||||
SIZE_T Size;
|
||||
ULONG Type;
|
||||
size_t Total;
|
||||
PWCHAR Buffer;
|
||||
PWCHAR p;
|
||||
size_t len;
|
||||
LONG Error;
|
||||
SIZE_T Size;
|
||||
ULONG Type;
|
||||
size_t Total;
|
||||
PWCHAR Buffer;
|
||||
PWCHAR p;
|
||||
size_t len;
|
||||
LONG Error;
|
||||
|
||||
Error = RegQueryValueExW (
|
||||
KeyHandle,
|
||||
ValueName,
|
||||
NULL,
|
||||
&Type,
|
||||
NULL,
|
||||
&Size);
|
||||
if ((Error != ERROR_SUCCESS) ||
|
||||
(Type != REG_MULTI_SZ))
|
||||
return;
|
||||
Error = RegQueryValueExW (
|
||||
KeyHandle,
|
||||
ValueName,
|
||||
NULL,
|
||||
&Type,
|
||||
NULL,
|
||||
&Size);
|
||||
if ((Error != ERROR_SUCCESS) ||
|
||||
(Type != REG_MULTI_SZ))
|
||||
return;
|
||||
|
||||
Buffer = malloc ((Size + StringSize) * sizeof(WCHAR));
|
||||
if (Buffer == NULL)
|
||||
return;
|
||||
Buffer = malloc ((Size + StringSize) * sizeof(WCHAR));
|
||||
if (Buffer == NULL)
|
||||
return;
|
||||
|
||||
Error = RegQueryValueExW (
|
||||
KeyHandle,
|
||||
ValueName,
|
||||
NULL,
|
||||
NULL,
|
||||
(PUCHAR)Buffer,
|
||||
&Size);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
goto done;
|
||||
Error = RegQueryValueExW (
|
||||
KeyHandle,
|
||||
ValueName,
|
||||
NULL,
|
||||
NULL,
|
||||
(PUCHAR)Buffer,
|
||||
&Size);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
goto done;
|
||||
|
||||
/* compare each string against all the existing ones */
|
||||
Total = Size;
|
||||
while (*Strings != 0)
|
||||
{
|
||||
len = strlenW(Strings) + 1;
|
||||
/* compare each string against all the existing ones */
|
||||
Total = Size;
|
||||
while (*Strings != 0)
|
||||
{
|
||||
len = strlenW(Strings) + 1;
|
||||
|
||||
for (p = Buffer; *p != 0; p += strlenW(p) + 1)
|
||||
if (!strcmpiW(p, Strings))
|
||||
break;
|
||||
for (p = Buffer; *p != 0; p += strlenW(p) + 1)
|
||||
if (!strcmpiW(p, Strings))
|
||||
break;
|
||||
|
||||
if (*p == 0) /* not found, need to append it */
|
||||
{
|
||||
memcpy (p, Strings, len);
|
||||
p[len] = 0;
|
||||
Total += len;
|
||||
}
|
||||
Strings += len;
|
||||
}
|
||||
if (*p == 0) /* not found, need to append it */
|
||||
{
|
||||
memcpy (p, Strings, len);
|
||||
p[len] = 0;
|
||||
Total += len;
|
||||
}
|
||||
Strings += len;
|
||||
}
|
||||
|
||||
if (Total != Size)
|
||||
{
|
||||
DPRINT ("setting value %S to %S\n", ValueName, Buffer);
|
||||
RegSetValueExW (
|
||||
KeyHandle,
|
||||
ValueName,
|
||||
0,
|
||||
REG_MULTI_SZ,
|
||||
(PUCHAR)Buffer,
|
||||
(ULONG)Total * sizeof(WCHAR));
|
||||
}
|
||||
if (Total != Size)
|
||||
{
|
||||
DPRINT ("setting value %S to %S\n", ValueName, Buffer);
|
||||
RegSetValueExW (
|
||||
KeyHandle,
|
||||
ValueName,
|
||||
0,
|
||||
REG_MULTI_SZ,
|
||||
(PUCHAR)Buffer,
|
||||
(ULONG)Total * sizeof(WCHAR));
|
||||
}
|
||||
|
||||
done:
|
||||
free (Buffer);
|
||||
free (Buffer);
|
||||
}
|
||||
|
||||
|
||||
|
@ -188,202 +188,202 @@ done:
|
|||
*/
|
||||
static BOOL
|
||||
do_reg_operation(
|
||||
IN HKEY KeyHandle,
|
||||
IN PWCHAR ValueName,
|
||||
IN PINFCONTEXT Context,
|
||||
IN ULONG Flags)
|
||||
IN HKEY KeyHandle,
|
||||
IN PWCHAR ValueName,
|
||||
IN PINFCONTEXT Context,
|
||||
IN ULONG Flags)
|
||||
{
|
||||
WCHAR EmptyStr = (CHAR)0;
|
||||
ULONG Type;
|
||||
ULONG Size;
|
||||
LONG Error;
|
||||
WCHAR EmptyStr = (CHAR)0;
|
||||
ULONG Type;
|
||||
ULONG Size;
|
||||
LONG Error;
|
||||
|
||||
if (Flags & FLG_ADDREG_DELVAL) /* deletion */
|
||||
{
|
||||
if (ValueName)
|
||||
{
|
||||
RegDeleteValueW (KeyHandle, ValueName);
|
||||
}
|
||||
else
|
||||
{
|
||||
RegDeleteKeyW (KeyHandle, NULL);
|
||||
}
|
||||
if (Flags & FLG_ADDREG_DELVAL) /* deletion */
|
||||
{
|
||||
if (ValueName)
|
||||
{
|
||||
RegDeleteValueW (KeyHandle, ValueName);
|
||||
}
|
||||
else
|
||||
{
|
||||
RegDeleteKeyW (KeyHandle, NULL);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (Flags & FLG_ADDREG_KEYONLY)
|
||||
return TRUE;
|
||||
if (Flags & FLG_ADDREG_KEYONLY)
|
||||
return TRUE;
|
||||
|
||||
if (Flags & (FLG_ADDREG_NOCLOBBER | FLG_ADDREG_OVERWRITEONLY))
|
||||
{
|
||||
Error = RegQueryValueExW (
|
||||
KeyHandle,
|
||||
ValueName,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
if ((Error == ERROR_SUCCESS) &&
|
||||
(Flags & FLG_ADDREG_NOCLOBBER))
|
||||
return TRUE;
|
||||
if (Flags & (FLG_ADDREG_NOCLOBBER | FLG_ADDREG_OVERWRITEONLY))
|
||||
{
|
||||
Error = RegQueryValueExW (
|
||||
KeyHandle,
|
||||
ValueName,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
if ((Error == ERROR_SUCCESS) &&
|
||||
(Flags & FLG_ADDREG_NOCLOBBER))
|
||||
return TRUE;
|
||||
|
||||
if ((Error != ERROR_SUCCESS) &&
|
||||
(Flags & FLG_ADDREG_OVERWRITEONLY))
|
||||
return TRUE;
|
||||
}
|
||||
if ((Error != ERROR_SUCCESS) &&
|
||||
(Flags & FLG_ADDREG_OVERWRITEONLY))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
switch (Flags & FLG_ADDREG_TYPE_MASK)
|
||||
{
|
||||
case FLG_ADDREG_TYPE_SZ:
|
||||
Type = REG_SZ;
|
||||
break;
|
||||
switch (Flags & FLG_ADDREG_TYPE_MASK)
|
||||
{
|
||||
case FLG_ADDREG_TYPE_SZ:
|
||||
Type = REG_SZ;
|
||||
break;
|
||||
|
||||
case FLG_ADDREG_TYPE_MULTI_SZ:
|
||||
Type = REG_MULTI_SZ;
|
||||
break;
|
||||
case FLG_ADDREG_TYPE_MULTI_SZ:
|
||||
Type = REG_MULTI_SZ;
|
||||
break;
|
||||
|
||||
case FLG_ADDREG_TYPE_EXPAND_SZ:
|
||||
Type = REG_EXPAND_SZ;
|
||||
break;
|
||||
case FLG_ADDREG_TYPE_EXPAND_SZ:
|
||||
Type = REG_EXPAND_SZ;
|
||||
break;
|
||||
|
||||
case FLG_ADDREG_TYPE_BINARY:
|
||||
Type = REG_BINARY;
|
||||
break;
|
||||
case FLG_ADDREG_TYPE_BINARY:
|
||||
Type = REG_BINARY;
|
||||
break;
|
||||
|
||||
case FLG_ADDREG_TYPE_DWORD:
|
||||
Type = REG_DWORD;
|
||||
break;
|
||||
case FLG_ADDREG_TYPE_DWORD:
|
||||
Type = REG_DWORD;
|
||||
break;
|
||||
|
||||
case FLG_ADDREG_TYPE_NONE:
|
||||
Type = REG_NONE;
|
||||
break;
|
||||
case FLG_ADDREG_TYPE_NONE:
|
||||
Type = REG_NONE;
|
||||
break;
|
||||
|
||||
default:
|
||||
Type = Flags >> 16;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
Type = Flags >> 16;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(Flags & FLG_ADDREG_BINVALUETYPE) ||
|
||||
(Type == REG_DWORD && InfHostGetFieldCount (Context) == 5))
|
||||
{
|
||||
PWCHAR Str = NULL;
|
||||
if (!(Flags & FLG_ADDREG_BINVALUETYPE) ||
|
||||
(Type == REG_DWORD && InfHostGetFieldCount (Context) == 5))
|
||||
{
|
||||
PWCHAR Str = NULL;
|
||||
|
||||
if (Type == REG_MULTI_SZ)
|
||||
{
|
||||
if (InfHostGetMultiSzField (Context, 5, NULL, 0, &Size) != 0)
|
||||
Size = 0;
|
||||
if (Type == REG_MULTI_SZ)
|
||||
{
|
||||
if (InfHostGetMultiSzField (Context, 5, NULL, 0, &Size) != 0)
|
||||
Size = 0;
|
||||
|
||||
if (Size)
|
||||
{
|
||||
Str = malloc (Size * sizeof(WCHAR));
|
||||
if (Str == NULL)
|
||||
return FALSE;
|
||||
if (Size)
|
||||
{
|
||||
Str = malloc (Size * sizeof(WCHAR));
|
||||
if (Str == NULL)
|
||||
return FALSE;
|
||||
|
||||
InfHostGetMultiSzField (Context, 5, Str, (ULONG)Size, NULL);
|
||||
}
|
||||
InfHostGetMultiSzField (Context, 5, Str, (ULONG)Size, NULL);
|
||||
}
|
||||
|
||||
if (Flags & FLG_ADDREG_APPEND)
|
||||
{
|
||||
if (Str == NULL)
|
||||
return TRUE;
|
||||
if (Flags & FLG_ADDREG_APPEND)
|
||||
{
|
||||
if (Str == NULL)
|
||||
return TRUE;
|
||||
|
||||
AppendMultiSzValue (
|
||||
KeyHandle,
|
||||
ValueName,
|
||||
Str,
|
||||
Size);
|
||||
AppendMultiSzValue (
|
||||
KeyHandle,
|
||||
ValueName,
|
||||
Str,
|
||||
Size);
|
||||
|
||||
free (Str);
|
||||
return TRUE;
|
||||
}
|
||||
/* else fall through to normal string handling */
|
||||
}
|
||||
else
|
||||
{
|
||||
if (InfHostGetStringField (Context, 5, NULL, 0, &Size) != 0)
|
||||
Size = 0;
|
||||
free (Str);
|
||||
return TRUE;
|
||||
}
|
||||
/* else fall through to normal string handling */
|
||||
}
|
||||
else
|
||||
{
|
||||
if (InfHostGetStringField (Context, 5, NULL, 0, &Size) != 0)
|
||||
Size = 0;
|
||||
|
||||
if (Size)
|
||||
{
|
||||
Str = malloc (Size * sizeof(WCHAR));
|
||||
if (Str == NULL)
|
||||
return FALSE;
|
||||
if (Size)
|
||||
{
|
||||
Str = malloc (Size * sizeof(WCHAR));
|
||||
if (Str == NULL)
|
||||
return FALSE;
|
||||
|
||||
InfHostGetStringField (Context, 5, Str, (ULONG)Size, NULL);
|
||||
}
|
||||
}
|
||||
InfHostGetStringField (Context, 5, Str, (ULONG)Size, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (Type == REG_DWORD)
|
||||
{
|
||||
ULONG dw = Str ? strtoulW (Str, NULL, 0) : 0;
|
||||
if (Type == REG_DWORD)
|
||||
{
|
||||
ULONG dw = Str ? strtoulW (Str, NULL, 0) : 0;
|
||||
|
||||
DPRINT("setting dword %S to %x\n", ValueName, dw);
|
||||
DPRINT("setting dword %S to %x\n", ValueName, dw);
|
||||
|
||||
RegSetValueExW (
|
||||
KeyHandle,
|
||||
ValueName,
|
||||
0,
|
||||
Type,
|
||||
(const PUCHAR)&dw,
|
||||
sizeof(ULONG));
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("setting value %S to %S\n", ValueName, Str);
|
||||
RegSetValueExW (
|
||||
KeyHandle,
|
||||
ValueName,
|
||||
0,
|
||||
Type,
|
||||
(const PUCHAR)&dw,
|
||||
sizeof(ULONG));
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("setting value %S to %S\n", ValueName, Str);
|
||||
|
||||
if (Str)
|
||||
{
|
||||
RegSetValueExW (
|
||||
KeyHandle,
|
||||
ValueName,
|
||||
0,
|
||||
Type,
|
||||
(PVOID)Str,
|
||||
(ULONG)Size * sizeof(WCHAR));
|
||||
}
|
||||
else
|
||||
{
|
||||
RegSetValueExW (
|
||||
KeyHandle,
|
||||
ValueName,
|
||||
0,
|
||||
Type,
|
||||
(PVOID)&EmptyStr,
|
||||
(ULONG)sizeof(WCHAR));
|
||||
}
|
||||
}
|
||||
free (Str);
|
||||
}
|
||||
else /* get the binary data */
|
||||
{
|
||||
PUCHAR Data = NULL;
|
||||
if (Str)
|
||||
{
|
||||
RegSetValueExW (
|
||||
KeyHandle,
|
||||
ValueName,
|
||||
0,
|
||||
Type,
|
||||
(PVOID)Str,
|
||||
(ULONG)Size * sizeof(WCHAR));
|
||||
}
|
||||
else
|
||||
{
|
||||
RegSetValueExW (
|
||||
KeyHandle,
|
||||
ValueName,
|
||||
0,
|
||||
Type,
|
||||
(PVOID)&EmptyStr,
|
||||
(ULONG)sizeof(WCHAR));
|
||||
}
|
||||
}
|
||||
free (Str);
|
||||
}
|
||||
else /* get the binary data */
|
||||
{
|
||||
PUCHAR Data = NULL;
|
||||
|
||||
if (InfHostGetBinaryField (Context, 5, NULL, 0, &Size) != 0)
|
||||
Size = 0;
|
||||
if (InfHostGetBinaryField (Context, 5, NULL, 0, &Size) != 0)
|
||||
Size = 0;
|
||||
|
||||
if (Size)
|
||||
{
|
||||
Data = malloc (Size);
|
||||
if (Data == NULL)
|
||||
return FALSE;
|
||||
if (Size)
|
||||
{
|
||||
Data = malloc (Size);
|
||||
if (Data == NULL)
|
||||
return FALSE;
|
||||
|
||||
DPRINT("setting binary data %S len %d\n", ValueName, Size);
|
||||
InfHostGetBinaryField (Context, 5, Data, Size, NULL);
|
||||
}
|
||||
DPRINT("setting binary data %S len %d\n", ValueName, Size);
|
||||
InfHostGetBinaryField (Context, 5, Data, Size, NULL);
|
||||
}
|
||||
|
||||
RegSetValueExW (
|
||||
KeyHandle,
|
||||
ValueName,
|
||||
0,
|
||||
Type,
|
||||
(PVOID)Data,
|
||||
(ULONG)Size);
|
||||
RegSetValueExW (
|
||||
KeyHandle,
|
||||
ValueName,
|
||||
0,
|
||||
Type,
|
||||
(PVOID)Data,
|
||||
(ULONG)Size);
|
||||
|
||||
free (Data);
|
||||
}
|
||||
free (Data);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -394,114 +394,114 @@ do_reg_operation(
|
|||
static BOOL
|
||||
registry_callback (HINF hInf, PWCHAR Section, BOOL Delete)
|
||||
{
|
||||
WCHAR Buffer[MAX_INF_STRING_LENGTH];
|
||||
PWCHAR ValuePtr;
|
||||
ULONG Flags;
|
||||
size_t Length;
|
||||
WCHAR Buffer[MAX_INF_STRING_LENGTH];
|
||||
PWCHAR ValuePtr;
|
||||
ULONG Flags;
|
||||
size_t Length;
|
||||
|
||||
PINFCONTEXT Context = NULL;
|
||||
HKEY KeyHandle;
|
||||
BOOL Ok;
|
||||
PINFCONTEXT Context = NULL;
|
||||
HKEY KeyHandle;
|
||||
BOOL Ok;
|
||||
|
||||
|
||||
Ok = InfHostFindFirstLine (hInf, Section, NULL, &Context) == 0;
|
||||
if (!Ok)
|
||||
return TRUE; /* Don't fail if the section isn't present */
|
||||
Ok = InfHostFindFirstLine (hInf, Section, NULL, &Context) == 0;
|
||||
if (!Ok)
|
||||
return TRUE; /* Don't fail if the section isn't present */
|
||||
|
||||
for (;Ok; Ok = (InfHostFindNextLine (Context, Context) == 0))
|
||||
{
|
||||
/* get root */
|
||||
if (InfHostGetStringField (Context, 1, Buffer, MAX_INF_STRING_LENGTH, NULL) != 0)
|
||||
continue;
|
||||
if (!GetRootKey (Buffer))
|
||||
continue;
|
||||
for (;Ok; Ok = (InfHostFindNextLine (Context, Context) == 0))
|
||||
{
|
||||
/* get root */
|
||||
if (InfHostGetStringField (Context, 1, Buffer, MAX_INF_STRING_LENGTH, NULL) != 0)
|
||||
continue;
|
||||
if (!GetRootKey (Buffer))
|
||||
continue;
|
||||
|
||||
/* get key */
|
||||
Length = strlenW (Buffer);
|
||||
if (InfHostGetStringField (Context, 2, Buffer + Length, MAX_INF_STRING_LENGTH - (ULONG)Length, NULL) != 0)
|
||||
*Buffer = 0;
|
||||
/* get key */
|
||||
Length = strlenW (Buffer);
|
||||
if (InfHostGetStringField (Context, 2, Buffer + Length, MAX_INF_STRING_LENGTH - (ULONG)Length, NULL) != 0)
|
||||
*Buffer = 0;
|
||||
|
||||
DPRINT("KeyName: <%S>\n", Buffer);
|
||||
DPRINT("KeyName: <%S>\n", Buffer);
|
||||
|
||||
if (Delete)
|
||||
{
|
||||
Flags = FLG_ADDREG_DELVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* get flags */
|
||||
if (InfHostGetIntField (Context, 4, (INT *)&Flags) != 0)
|
||||
Flags = 0;
|
||||
}
|
||||
if (Delete)
|
||||
{
|
||||
Flags = FLG_ADDREG_DELVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* get flags */
|
||||
if (InfHostGetIntField (Context, 4, (INT *)&Flags) != 0)
|
||||
Flags = 0;
|
||||
}
|
||||
|
||||
DPRINT("Flags: 0x%x\n", Flags);
|
||||
DPRINT("Flags: 0x%x\n", Flags);
|
||||
|
||||
if (Delete || (Flags & FLG_ADDREG_OVERWRITEONLY))
|
||||
{
|
||||
if (RegOpenKeyW (NULL, Buffer, &KeyHandle) != ERROR_SUCCESS)
|
||||
{
|
||||
DPRINT("RegOpenKey(%S) failed\n", Buffer);
|
||||
continue; /* ignore if it doesn't exist */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (RegCreateKeyW (NULL, Buffer, &KeyHandle) != ERROR_SUCCESS)
|
||||
{
|
||||
DPRINT("RegCreateKey(%S) failed\n", Buffer);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (Delete || (Flags & FLG_ADDREG_OVERWRITEONLY))
|
||||
{
|
||||
if (RegOpenKeyW (NULL, Buffer, &KeyHandle) != ERROR_SUCCESS)
|
||||
{
|
||||
DPRINT("RegOpenKey(%S) failed\n", Buffer);
|
||||
continue; /* ignore if it doesn't exist */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (RegCreateKeyW (NULL, Buffer, &KeyHandle) != ERROR_SUCCESS)
|
||||
{
|
||||
DPRINT("RegCreateKey(%S) failed\n", Buffer);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* get value name */
|
||||
if (InfHostGetStringField (Context, 3, Buffer, MAX_INF_STRING_LENGTH, NULL) == 0)
|
||||
{
|
||||
ValuePtr = Buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
ValuePtr = NULL;
|
||||
}
|
||||
/* get value name */
|
||||
if (InfHostGetStringField (Context, 3, Buffer, MAX_INF_STRING_LENGTH, NULL) == 0)
|
||||
{
|
||||
ValuePtr = Buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
ValuePtr = NULL;
|
||||
}
|
||||
|
||||
/* and now do it */
|
||||
if (!do_reg_operation (KeyHandle, ValuePtr, Context, Flags))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
/* and now do it */
|
||||
if (!do_reg_operation (KeyHandle, ValuePtr, Context, Flags))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
InfHostFreeContext(Context);
|
||||
InfHostFreeContext(Context);
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL
|
||||
ImportRegistryFile(PCHAR FileName)
|
||||
{
|
||||
HINF hInf;
|
||||
ULONG ErrorLine;
|
||||
HINF hInf;
|
||||
ULONG ErrorLine;
|
||||
|
||||
/* Load inf file from install media. */
|
||||
if (InfHostOpenFile(&hInf, FileName, 0, &ErrorLine) != 0)
|
||||
{
|
||||
DPRINT1 ("InfHostOpenFile(%s) failed\n", FileName);
|
||||
return FALSE;
|
||||
}
|
||||
/* Load inf file from install media. */
|
||||
if (InfHostOpenFile(&hInf, FileName, 0, &ErrorLine) != 0)
|
||||
{
|
||||
DPRINT1 ("InfHostOpenFile(%s) failed\n", FileName);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!registry_callback (hInf, (PWCHAR)DelReg, TRUE))
|
||||
{
|
||||
DPRINT1 ("registry_callback() for DelReg failed\n");
|
||||
}
|
||||
if (!registry_callback (hInf, (PWCHAR)DelReg, TRUE))
|
||||
{
|
||||
DPRINT1 ("registry_callback() for DelReg failed\n");
|
||||
}
|
||||
|
||||
if (!registry_callback (hInf, (PWCHAR)AddReg, FALSE))
|
||||
{
|
||||
DPRINT1 ("registry_callback() for AddReg failed\n");
|
||||
}
|
||||
if (!registry_callback (hInf, (PWCHAR)AddReg, FALSE))
|
||||
{
|
||||
DPRINT1 ("registry_callback() for AddReg failed\n");
|
||||
}
|
||||
|
||||
InfHostCloseFile (hInf);
|
||||
InfHostCloseFile (hInf);
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -25,9 +25,9 @@
|
|||
|
||||
/*
|
||||
* TODO:
|
||||
* - Implement RegDeleteKeyW()
|
||||
* - Implement RegEnumValue()
|
||||
* - Implement RegQueryValueExW()
|
||||
* - Implement RegDeleteKeyW()
|
||||
* - Implement RegEnumValue()
|
||||
* - Implement RegQueryValueExW()
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@ -50,200 +50,198 @@ CMHIVE SystemHive; /* \Registry\Machine\SYSTEM */
|
|||
|
||||
static PMEMKEY
|
||||
CreateInMemoryStructure(
|
||||
IN PCMHIVE RegistryHive,
|
||||
IN HCELL_INDEX KeyCellOffset)
|
||||
IN PCMHIVE RegistryHive,
|
||||
IN HCELL_INDEX KeyCellOffset)
|
||||
{
|
||||
PMEMKEY Key;
|
||||
PMEMKEY Key;
|
||||
|
||||
Key = (PMEMKEY) malloc (sizeof(MEMKEY));
|
||||
if (!Key)
|
||||
return NULL;
|
||||
Key = (PMEMKEY) malloc (sizeof(MEMKEY));
|
||||
if (!Key)
|
||||
return NULL;
|
||||
|
||||
Key->RegistryHive = RegistryHive;
|
||||
Key->KeyCellOffset = KeyCellOffset;
|
||||
return Key;
|
||||
Key->RegistryHive = RegistryHive;
|
||||
Key->KeyCellOffset = KeyCellOffset;
|
||||
return Key;
|
||||
}
|
||||
|
||||
LIST_ENTRY CmiReparsePointsHead;
|
||||
|
||||
static LONG
|
||||
RegpOpenOrCreateKey(
|
||||
IN HKEY hParentKey,
|
||||
IN PCWSTR KeyName,
|
||||
IN BOOL AllowCreation,
|
||||
IN BOOL Volatile,
|
||||
OUT PHKEY Key)
|
||||
IN HKEY hParentKey,
|
||||
IN PCWSTR KeyName,
|
||||
IN BOOL AllowCreation,
|
||||
IN BOOL Volatile,
|
||||
OUT PHKEY Key)
|
||||
{
|
||||
PWSTR LocalKeyName;
|
||||
PWSTR End;
|
||||
UNICODE_STRING KeyString;
|
||||
NTSTATUS Status;
|
||||
PREPARSE_POINT CurrentReparsePoint;
|
||||
PMEMKEY CurrentKey;
|
||||
PCMHIVE ParentRegistryHive;
|
||||
HCELL_INDEX ParentCellOffset;
|
||||
PLIST_ENTRY Ptr;
|
||||
PCM_KEY_NODE SubKeyCell;
|
||||
HCELL_INDEX BlockOffset;
|
||||
PWSTR LocalKeyName;
|
||||
PWSTR End;
|
||||
UNICODE_STRING KeyString;
|
||||
NTSTATUS Status;
|
||||
PREPARSE_POINT CurrentReparsePoint;
|
||||
PMEMKEY CurrentKey;
|
||||
PCMHIVE ParentRegistryHive;
|
||||
HCELL_INDEX ParentCellOffset;
|
||||
PLIST_ENTRY Ptr;
|
||||
PCM_KEY_NODE SubKeyCell;
|
||||
HCELL_INDEX BlockOffset;
|
||||
|
||||
DPRINT("RegpCreateOpenKey('%S')\n", KeyName);
|
||||
DPRINT("RegpCreateOpenKey('%S')\n", KeyName);
|
||||
|
||||
if (*KeyName == L'\\')
|
||||
{
|
||||
KeyName++;
|
||||
ParentRegistryHive = RootKey->RegistryHive;
|
||||
ParentCellOffset = RootKey->KeyCellOffset;
|
||||
}
|
||||
else if (hParentKey == NULL)
|
||||
{
|
||||
ParentRegistryHive = RootKey->RegistryHive;
|
||||
ParentCellOffset = RootKey->KeyCellOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
ParentRegistryHive = HKEY_TO_MEMKEY(RootKey)->RegistryHive;
|
||||
ParentCellOffset = HKEY_TO_MEMKEY(RootKey)->KeyCellOffset;
|
||||
}
|
||||
if (*KeyName == L'\\')
|
||||
{
|
||||
KeyName++;
|
||||
ParentRegistryHive = RootKey->RegistryHive;
|
||||
ParentCellOffset = RootKey->KeyCellOffset;
|
||||
}
|
||||
else if (hParentKey == NULL)
|
||||
{
|
||||
ParentRegistryHive = RootKey->RegistryHive;
|
||||
ParentCellOffset = RootKey->KeyCellOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
ParentRegistryHive = HKEY_TO_MEMKEY(RootKey)->RegistryHive;
|
||||
ParentCellOffset = HKEY_TO_MEMKEY(RootKey)->KeyCellOffset;
|
||||
}
|
||||
|
||||
LocalKeyName = (PWSTR)KeyName;
|
||||
for (;;)
|
||||
{
|
||||
End = (PWSTR)strchrW(LocalKeyName, '\\');
|
||||
if (End)
|
||||
{
|
||||
KeyString.Buffer = LocalKeyName;
|
||||
KeyString.Length = KeyString.MaximumLength =
|
||||
(USHORT)((ULONG_PTR)End - (ULONG_PTR)LocalKeyName);
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlInitUnicodeString(&KeyString, LocalKeyName);
|
||||
if (KeyString.Length == 0)
|
||||
{
|
||||
/* Trailing backslash char; we're done */
|
||||
break;
|
||||
}
|
||||
}
|
||||
LocalKeyName = (PWSTR)KeyName;
|
||||
for (;;)
|
||||
{
|
||||
End = (PWSTR)strchrW(LocalKeyName, '\\');
|
||||
if (End)
|
||||
{
|
||||
KeyString.Buffer = LocalKeyName;
|
||||
KeyString.Length = KeyString.MaximumLength =
|
||||
(USHORT)((ULONG_PTR)End - (ULONG_PTR)LocalKeyName);
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlInitUnicodeString(&KeyString, LocalKeyName);
|
||||
if (KeyString.Length == 0)
|
||||
{
|
||||
/* Trailing backslash char; we're done */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Status = CmiScanForSubKey(
|
||||
ParentRegistryHive,
|
||||
ParentCellOffset,
|
||||
&KeyString,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
&SubKeyCell,
|
||||
&BlockOffset);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Search for a possible reparse point */
|
||||
Ptr = CmiReparsePointsHead.Flink;
|
||||
while (Ptr != &CmiReparsePointsHead)
|
||||
{
|
||||
CurrentReparsePoint = CONTAINING_RECORD(Ptr, REPARSE_POINT, ListEntry);
|
||||
if (CurrentReparsePoint->SourceHive == ParentRegistryHive &&
|
||||
CurrentReparsePoint->SourceKeyCellOffset == BlockOffset)
|
||||
{
|
||||
ParentRegistryHive = CurrentReparsePoint->DestinationHive;
|
||||
BlockOffset = CurrentReparsePoint->DestinationKeyCellOffset;
|
||||
break;
|
||||
}
|
||||
Ptr = Ptr->Flink;
|
||||
}
|
||||
}
|
||||
else if (Status == STATUS_OBJECT_NAME_NOT_FOUND && AllowCreation)
|
||||
{
|
||||
Status = CmiAddSubKey(
|
||||
ParentRegistryHive,
|
||||
ParentCellOffset,
|
||||
&KeyString,
|
||||
Volatile ? REG_OPTION_VOLATILE : 0,
|
||||
&SubKeyCell,
|
||||
&BlockOffset);
|
||||
}
|
||||
if (!NT_SUCCESS(Status))
|
||||
return ERROR_UNSUCCESSFUL;
|
||||
Status = CmiScanForSubKey(ParentRegistryHive,
|
||||
ParentCellOffset,
|
||||
&KeyString,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
&SubKeyCell,
|
||||
&BlockOffset);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Search for a possible reparse point */
|
||||
Ptr = CmiReparsePointsHead.Flink;
|
||||
while (Ptr != &CmiReparsePointsHead)
|
||||
{
|
||||
CurrentReparsePoint = CONTAINING_RECORD(Ptr, REPARSE_POINT, ListEntry);
|
||||
if (CurrentReparsePoint->SourceHive == ParentRegistryHive &&
|
||||
CurrentReparsePoint->SourceKeyCellOffset == BlockOffset)
|
||||
{
|
||||
ParentRegistryHive = CurrentReparsePoint->DestinationHive;
|
||||
BlockOffset = CurrentReparsePoint->DestinationKeyCellOffset;
|
||||
break;
|
||||
}
|
||||
Ptr = Ptr->Flink;
|
||||
}
|
||||
}
|
||||
else if (Status == STATUS_OBJECT_NAME_NOT_FOUND && AllowCreation)
|
||||
{
|
||||
Status = CmiAddSubKey(ParentRegistryHive,
|
||||
ParentCellOffset,
|
||||
&KeyString,
|
||||
Volatile ? REG_OPTION_VOLATILE : 0,
|
||||
&SubKeyCell,
|
||||
&BlockOffset);
|
||||
}
|
||||
if (!NT_SUCCESS(Status))
|
||||
return ERROR_UNSUCCESSFUL;
|
||||
|
||||
nextsubkey:
|
||||
ParentCellOffset = BlockOffset;
|
||||
if (End)
|
||||
LocalKeyName = End + 1;
|
||||
else
|
||||
break;
|
||||
}
|
||||
ParentCellOffset = BlockOffset;
|
||||
if (End)
|
||||
LocalKeyName = End + 1;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
CurrentKey = CreateInMemoryStructure(ParentRegistryHive, ParentCellOffset);
|
||||
if (!CurrentKey)
|
||||
return ERROR_OUTOFMEMORY;
|
||||
*Key = MEMKEY_TO_HKEY(CurrentKey);
|
||||
CurrentKey = CreateInMemoryStructure(ParentRegistryHive, ParentCellOffset);
|
||||
if (!CurrentKey)
|
||||
return ERROR_OUTOFMEMORY;
|
||||
*Key = MEMKEY_TO_HKEY(CurrentKey);
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
LONG WINAPI
|
||||
RegCreateKeyW(
|
||||
IN HKEY hKey,
|
||||
IN LPCWSTR lpSubKey,
|
||||
OUT PHKEY phkResult)
|
||||
IN HKEY hKey,
|
||||
IN LPCWSTR lpSubKey,
|
||||
OUT PHKEY phkResult)
|
||||
{
|
||||
return RegpOpenOrCreateKey(hKey, lpSubKey, TRUE, FALSE, phkResult);
|
||||
return RegpOpenOrCreateKey(hKey, lpSubKey, TRUE, FALSE, phkResult);
|
||||
}
|
||||
|
||||
static PWSTR
|
||||
MultiByteToWideChar(
|
||||
IN PCSTR MultiByteString)
|
||||
IN PCSTR MultiByteString)
|
||||
{
|
||||
ANSI_STRING Source;
|
||||
UNICODE_STRING Destination;
|
||||
NTSTATUS Status;
|
||||
ANSI_STRING Source;
|
||||
UNICODE_STRING Destination;
|
||||
NTSTATUS Status;
|
||||
|
||||
RtlInitAnsiString(&Source, MultiByteString);
|
||||
Status = RtlAnsiStringToUnicodeString(&Destination, &Source, TRUE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return NULL;
|
||||
return Destination.Buffer;
|
||||
RtlInitAnsiString(&Source, MultiByteString);
|
||||
Status = RtlAnsiStringToUnicodeString(&Destination, &Source, TRUE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return NULL;
|
||||
return Destination.Buffer;
|
||||
}
|
||||
|
||||
LONG WINAPI
|
||||
RegDeleteKeyW(
|
||||
IN HKEY hKey,
|
||||
IN LPCWSTR lpSubKey)
|
||||
IN HKEY hKey,
|
||||
IN LPCWSTR lpSubKey)
|
||||
{
|
||||
DPRINT1("FIXME: implement RegDeleteKeyW!\n");
|
||||
return ERROR_SUCCESS;
|
||||
DPRINT1("FIXME: implement RegDeleteKeyW!\n");
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
LONG WINAPI
|
||||
RegDeleteKeyA(
|
||||
IN HKEY hKey,
|
||||
IN LPCSTR lpSubKey)
|
||||
IN HKEY hKey,
|
||||
IN LPCSTR lpSubKey)
|
||||
{
|
||||
PWSTR lpSubKeyW = NULL;
|
||||
LONG rc;
|
||||
PWSTR lpSubKeyW = NULL;
|
||||
LONG rc;
|
||||
|
||||
if (lpSubKey != NULL && strchr(lpSubKey, '\\') != NULL)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
if (lpSubKey != NULL && strchr(lpSubKey, '\\') != NULL)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
if (lpSubKey)
|
||||
{
|
||||
lpSubKeyW = MultiByteToWideChar(lpSubKey);
|
||||
if (!lpSubKeyW)
|
||||
return ERROR_OUTOFMEMORY;
|
||||
}
|
||||
if (lpSubKey)
|
||||
{
|
||||
lpSubKeyW = MultiByteToWideChar(lpSubKey);
|
||||
if (!lpSubKeyW)
|
||||
return ERROR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
rc = RegDeleteKeyW(hKey, lpSubKeyW);
|
||||
rc = RegDeleteKeyW(hKey, lpSubKeyW);
|
||||
|
||||
if (lpSubKey)
|
||||
free(lpSubKeyW);
|
||||
if (lpSubKey)
|
||||
free(lpSubKeyW);
|
||||
|
||||
return rc;
|
||||
return rc;
|
||||
}
|
||||
|
||||
LONG WINAPI
|
||||
RegOpenKeyW(
|
||||
IN HKEY hKey,
|
||||
IN LPCWSTR lpSubKey,
|
||||
OUT PHKEY phkResult)
|
||||
IN HKEY hKey,
|
||||
IN LPCWSTR lpSubKey,
|
||||
OUT PHKEY phkResult)
|
||||
{
|
||||
return RegpOpenOrCreateKey(hKey, lpSubKey, FALSE, FALSE, phkResult);
|
||||
return RegpOpenOrCreateKey(hKey, lpSubKey, FALSE, FALSE, phkResult);
|
||||
}
|
||||
|
||||
LONG WINAPI
|
||||
|
@ -267,250 +265,248 @@ RegCreateKeyExW(
|
|||
|
||||
LONG WINAPI
|
||||
RegOpenKeyA(
|
||||
IN HKEY hKey,
|
||||
IN LPCSTR lpSubKey,
|
||||
OUT PHKEY phkResult)
|
||||
IN HKEY hKey,
|
||||
IN LPCSTR lpSubKey,
|
||||
OUT PHKEY phkResult)
|
||||
{
|
||||
PWSTR lpSubKeyW;
|
||||
LONG rc;
|
||||
PWSTR lpSubKeyW;
|
||||
LONG rc;
|
||||
|
||||
lpSubKeyW = MultiByteToWideChar(lpSubKey);
|
||||
if (!lpSubKeyW)
|
||||
return ERROR_OUTOFMEMORY;
|
||||
lpSubKeyW = MultiByteToWideChar(lpSubKey);
|
||||
if (!lpSubKeyW)
|
||||
return ERROR_OUTOFMEMORY;
|
||||
|
||||
rc = RegOpenKeyW(hKey, lpSubKeyW, phkResult);
|
||||
free(lpSubKeyW);
|
||||
return rc;
|
||||
rc = RegOpenKeyW(hKey, lpSubKeyW, phkResult);
|
||||
free(lpSubKeyW);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static LONG
|
||||
RegpOpenOrCreateValue(
|
||||
IN HKEY hKey,
|
||||
IN LPCWSTR ValueName,
|
||||
IN BOOL AllowCreation,
|
||||
OUT PCM_KEY_VALUE *ValueCell,
|
||||
OUT PHCELL_INDEX ValueCellOffset)
|
||||
IN HKEY hKey,
|
||||
IN LPCWSTR ValueName,
|
||||
IN BOOL AllowCreation,
|
||||
OUT PCM_KEY_VALUE *ValueCell,
|
||||
OUT PHCELL_INDEX ValueCellOffset)
|
||||
{
|
||||
PMEMKEY ParentKey;
|
||||
UNICODE_STRING ValueString;
|
||||
NTSTATUS Status;
|
||||
PMEMKEY ParentKey;
|
||||
UNICODE_STRING ValueString;
|
||||
NTSTATUS Status;
|
||||
|
||||
ParentKey = HKEY_TO_MEMKEY(hKey);
|
||||
RtlInitUnicodeString(&ValueString, ValueName);
|
||||
ParentKey = HKEY_TO_MEMKEY(hKey);
|
||||
RtlInitUnicodeString(&ValueString, ValueName);
|
||||
|
||||
Status = CmiScanForValueKey(
|
||||
ParentKey->RegistryHive,
|
||||
ParentKey->KeyCellOffset,
|
||||
&ValueString,
|
||||
ValueCell,
|
||||
ValueCellOffset);
|
||||
if (AllowCreation && Status == STATUS_OBJECT_NAME_NOT_FOUND)
|
||||
{
|
||||
Status = CmiAddValueKey(
|
||||
ParentKey->RegistryHive,
|
||||
ParentKey->KeyCellOffset,
|
||||
&ValueString,
|
||||
ValueCell,
|
||||
ValueCellOffset);
|
||||
}
|
||||
if (!NT_SUCCESS(Status))
|
||||
return ERROR_UNSUCCESSFUL;
|
||||
return ERROR_SUCCESS;
|
||||
Status = CmiScanForValueKey(ParentKey->RegistryHive,
|
||||
ParentKey->KeyCellOffset,
|
||||
&ValueString,
|
||||
ValueCell,
|
||||
ValueCellOffset);
|
||||
if (AllowCreation && Status == STATUS_OBJECT_NAME_NOT_FOUND)
|
||||
{
|
||||
Status = CmiAddValueKey(ParentKey->RegistryHive,
|
||||
ParentKey->KeyCellOffset,
|
||||
&ValueString,
|
||||
ValueCell,
|
||||
ValueCellOffset);
|
||||
}
|
||||
if (!NT_SUCCESS(Status))
|
||||
return ERROR_UNSUCCESSFUL;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
LONG WINAPI
|
||||
RegSetValueExW(
|
||||
IN HKEY hKey,
|
||||
IN LPCWSTR lpValueName OPTIONAL,
|
||||
IN ULONG Reserved,
|
||||
IN ULONG dwType,
|
||||
IN const UCHAR* lpData,
|
||||
IN USHORT cbData)
|
||||
IN HKEY hKey,
|
||||
IN LPCWSTR lpValueName OPTIONAL,
|
||||
IN ULONG Reserved,
|
||||
IN ULONG dwType,
|
||||
IN const UCHAR* lpData,
|
||||
IN USHORT cbData)
|
||||
{
|
||||
PMEMKEY Key, DestKey;
|
||||
PHKEY phKey;
|
||||
PCM_KEY_VALUE ValueCell;
|
||||
HCELL_INDEX ValueCellOffset;
|
||||
PVOID DataCell;
|
||||
LONG DataCellSize;
|
||||
NTSTATUS Status;
|
||||
PMEMKEY Key, DestKey;
|
||||
PHKEY phKey;
|
||||
PCM_KEY_VALUE ValueCell;
|
||||
HCELL_INDEX ValueCellOffset;
|
||||
PVOID DataCell;
|
||||
LONG DataCellSize;
|
||||
NTSTATUS Status;
|
||||
|
||||
if (dwType == REG_LINK)
|
||||
{
|
||||
/* Special handling of registry links */
|
||||
if (cbData != sizeof(PVOID))
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
phKey = (PHKEY)lpData;
|
||||
Key = HKEY_TO_MEMKEY(hKey);
|
||||
DestKey = HKEY_TO_MEMKEY(*phKey);
|
||||
if (dwType == REG_LINK)
|
||||
{
|
||||
/* Special handling of registry links */
|
||||
if (cbData != sizeof(PVOID))
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
/* Create the link in registry hive (if applicable) */
|
||||
if (Key->RegistryHive != DestKey->RegistryHive)
|
||||
return STATUS_SUCCESS;
|
||||
DPRINT1("Save link to registry\n");
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
phKey = (PHKEY)lpData;
|
||||
Key = HKEY_TO_MEMKEY(hKey);
|
||||
DestKey = HKEY_TO_MEMKEY(*phKey);
|
||||
|
||||
if ((cbData & REG_DATA_SIZE_MASK) != cbData)
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
/* Create the link in registry hive (if applicable) */
|
||||
if (Key->RegistryHive != DestKey->RegistryHive)
|
||||
return STATUS_SUCCESS;
|
||||
DPRINT1("Save link to registry\n");
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
Key = HKEY_TO_MEMKEY(hKey);
|
||||
if ((cbData & REG_DATA_SIZE_MASK) != cbData)
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
|
||||
Status = RegpOpenOrCreateValue(hKey, lpValueName, TRUE, &ValueCell, &ValueCellOffset);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return ERROR_UNSUCCESSFUL;
|
||||
Key = HKEY_TO_MEMKEY(hKey);
|
||||
|
||||
/* Get size of the allocated cellule (if any) */
|
||||
if (!(ValueCell->DataLength & REG_DATA_IN_OFFSET) &&
|
||||
(ValueCell->DataLength & REG_DATA_SIZE_MASK) != 0)
|
||||
{
|
||||
DataCell = HvGetCell(&Key->RegistryHive->Hive, ValueCell->Data);
|
||||
if (!DataCell)
|
||||
return ERROR_UNSUCCESSFUL;
|
||||
DataCellSize = -HvGetCellSize(&Key->RegistryHive->Hive, DataCell);
|
||||
}
|
||||
else
|
||||
{
|
||||
DataCell = NULL;
|
||||
DataCellSize = 0;
|
||||
}
|
||||
Status = RegpOpenOrCreateValue(hKey, lpValueName, TRUE, &ValueCell, &ValueCellOffset);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return ERROR_UNSUCCESSFUL;
|
||||
|
||||
if (cbData <= sizeof(HCELL_INDEX))
|
||||
{
|
||||
/* If data size <= sizeof(HCELL_INDEX) then store data in the data offset */
|
||||
DPRINT("ValueCell->DataLength %u\n", ValueCell->DataLength);
|
||||
if (DataCell)
|
||||
HvFreeCell(&Key->RegistryHive->Hive, ValueCell->Data);
|
||||
/* Get size of the allocated cellule (if any) */
|
||||
if (!(ValueCell->DataLength & REG_DATA_IN_OFFSET) &&
|
||||
(ValueCell->DataLength & REG_DATA_SIZE_MASK) != 0)
|
||||
{
|
||||
DataCell = HvGetCell(&Key->RegistryHive->Hive, ValueCell->Data);
|
||||
if (!DataCell)
|
||||
return ERROR_UNSUCCESSFUL;
|
||||
|
||||
RtlCopyMemory(&ValueCell->Data, lpData, cbData);
|
||||
ValueCell->DataLength = (ULONG)(cbData | REG_DATA_IN_OFFSET);
|
||||
ValueCell->Type = dwType;
|
||||
HvMarkCellDirty(&Key->RegistryHive->Hive, ValueCellOffset, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cbData > (SIZE_T)DataCellSize)
|
||||
{
|
||||
/* New data size is larger than the current, destroy current
|
||||
* data block and allocate a new one. */
|
||||
HCELL_INDEX NewOffset;
|
||||
DataCellSize = -HvGetCellSize(&Key->RegistryHive->Hive, DataCell);
|
||||
}
|
||||
else
|
||||
{
|
||||
DataCell = NULL;
|
||||
DataCellSize = 0;
|
||||
}
|
||||
|
||||
DPRINT("ValueCell->DataLength %u\n", ValueCell->DataLength);
|
||||
if (cbData <= sizeof(HCELL_INDEX))
|
||||
{
|
||||
/* If data size <= sizeof(HCELL_INDEX) then store data in the data offset */
|
||||
DPRINT("ValueCell->DataLength %u\n", ValueCell->DataLength);
|
||||
if (DataCell)
|
||||
HvFreeCell(&Key->RegistryHive->Hive, ValueCell->Data);
|
||||
|
||||
NewOffset = HvAllocateCell(&Key->RegistryHive->Hive, cbData, Stable, HCELL_NIL);
|
||||
if (NewOffset == HCELL_NIL)
|
||||
{
|
||||
DPRINT("HvAllocateCell() failed with status 0x%08x\n", Status);
|
||||
return ERROR_UNSUCCESSFUL;
|
||||
}
|
||||
RtlCopyMemory(&ValueCell->Data, lpData, cbData);
|
||||
ValueCell->DataLength = (ULONG)(cbData | REG_DATA_IN_OFFSET);
|
||||
ValueCell->Type = dwType;
|
||||
HvMarkCellDirty(&Key->RegistryHive->Hive, ValueCellOffset, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cbData > (SIZE_T)DataCellSize)
|
||||
{
|
||||
/* New data size is larger than the current, destroy current
|
||||
* data block and allocate a new one. */
|
||||
HCELL_INDEX NewOffset;
|
||||
|
||||
if (DataCell)
|
||||
HvFreeCell(&Key->RegistryHive->Hive, ValueCell->Data);
|
||||
DPRINT("ValueCell->DataLength %u\n", ValueCell->DataLength);
|
||||
|
||||
ValueCell->Data = NewOffset;
|
||||
DataCell = (PVOID)HvGetCell(&Key->RegistryHive->Hive, NewOffset);
|
||||
}
|
||||
NewOffset = HvAllocateCell(&Key->RegistryHive->Hive, cbData, Stable, HCELL_NIL);
|
||||
if (NewOffset == HCELL_NIL)
|
||||
{
|
||||
DPRINT("HvAllocateCell() failed with status 0x%08x\n", Status);
|
||||
return ERROR_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
/* Copy new contents to cellule */
|
||||
RtlCopyMemory(DataCell, lpData, cbData);
|
||||
ValueCell->DataLength = (ULONG)(cbData & REG_DATA_SIZE_MASK);
|
||||
ValueCell->Type = dwType;
|
||||
HvMarkCellDirty(&Key->RegistryHive->Hive, ValueCell->Data, FALSE);
|
||||
HvMarkCellDirty(&Key->RegistryHive->Hive, ValueCellOffset, FALSE);
|
||||
}
|
||||
if (DataCell)
|
||||
HvFreeCell(&Key->RegistryHive->Hive, ValueCell->Data);
|
||||
|
||||
HvMarkCellDirty(&Key->RegistryHive->Hive, Key->KeyCellOffset, FALSE);
|
||||
ValueCell->Data = NewOffset;
|
||||
DataCell = (PVOID)HvGetCell(&Key->RegistryHive->Hive, NewOffset);
|
||||
}
|
||||
|
||||
DPRINT("Return status 0x%08x\n", Status);
|
||||
return Status;
|
||||
/* Copy new contents to cellule */
|
||||
RtlCopyMemory(DataCell, lpData, cbData);
|
||||
ValueCell->DataLength = (ULONG)(cbData & REG_DATA_SIZE_MASK);
|
||||
ValueCell->Type = dwType;
|
||||
HvMarkCellDirty(&Key->RegistryHive->Hive, ValueCell->Data, FALSE);
|
||||
HvMarkCellDirty(&Key->RegistryHive->Hive, ValueCellOffset, FALSE);
|
||||
}
|
||||
|
||||
HvMarkCellDirty(&Key->RegistryHive->Hive, Key->KeyCellOffset, FALSE);
|
||||
|
||||
DPRINT("Return status 0x%08x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
LONG WINAPI
|
||||
RegQueryValueExW(
|
||||
IN HKEY hKey,
|
||||
IN LPCWSTR lpValueName,
|
||||
IN PULONG lpReserved,
|
||||
OUT PULONG lpType,
|
||||
OUT PUCHAR lpData,
|
||||
OUT PSIZE_T lpcbData)
|
||||
IN HKEY hKey,
|
||||
IN LPCWSTR lpValueName,
|
||||
IN PULONG lpReserved,
|
||||
OUT PULONG lpType,
|
||||
OUT PUCHAR lpData,
|
||||
OUT PSIZE_T lpcbData)
|
||||
{
|
||||
//ParentKey = HKEY_TO_MEMKEY(RootKey);
|
||||
PCM_KEY_VALUE ValueCell;
|
||||
HCELL_INDEX ValueCellOffset;
|
||||
LONG rc;
|
||||
//ParentKey = HKEY_TO_MEMKEY(RootKey);
|
||||
PCM_KEY_VALUE ValueCell;
|
||||
HCELL_INDEX ValueCellOffset;
|
||||
LONG rc;
|
||||
|
||||
rc = RegpOpenOrCreateValue(
|
||||
hKey,
|
||||
lpValueName,
|
||||
FALSE,
|
||||
&ValueCell,
|
||||
&ValueCellOffset);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
return rc;
|
||||
rc = RegpOpenOrCreateValue(hKey,
|
||||
lpValueName,
|
||||
FALSE,
|
||||
&ValueCell,
|
||||
&ValueCellOffset);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
return rc;
|
||||
|
||||
DPRINT1("RegQueryValueExW(%S) not implemented\n", lpValueName);
|
||||
/* ValueCell and ValueCellOffset are valid */
|
||||
DPRINT1("RegQueryValueExW(%S) not implemented\n", lpValueName);
|
||||
/* ValueCell and ValueCellOffset are valid */
|
||||
|
||||
return ERROR_UNSUCCESSFUL;
|
||||
return ERROR_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
LONG WINAPI
|
||||
RegDeleteValueW(
|
||||
IN HKEY hKey,
|
||||
IN LPCWSTR lpValueName OPTIONAL)
|
||||
IN HKEY hKey,
|
||||
IN LPCWSTR lpValueName OPTIONAL)
|
||||
{
|
||||
DPRINT1("RegDeleteValueW() unimplemented\n");
|
||||
return ERROR_UNSUCCESSFUL;
|
||||
DPRINT1("RegDeleteValueW() unimplemented\n");
|
||||
return ERROR_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
static BOOL
|
||||
ConnectRegistry(
|
||||
IN HKEY RootKey,
|
||||
IN PCMHIVE HiveToConnect,
|
||||
IN LPCWSTR Path)
|
||||
IN HKEY RootKey,
|
||||
IN PCMHIVE HiveToConnect,
|
||||
IN LPCWSTR Path)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PREPARSE_POINT ReparsePoint;
|
||||
PMEMKEY NewKey;
|
||||
LONG rc;
|
||||
NTSTATUS Status;
|
||||
PREPARSE_POINT ReparsePoint;
|
||||
PMEMKEY NewKey;
|
||||
LONG rc;
|
||||
|
||||
ReparsePoint = (PREPARSE_POINT)malloc(sizeof(REPARSE_POINT));
|
||||
if (!ReparsePoint)
|
||||
return FALSE;
|
||||
ReparsePoint = (PREPARSE_POINT)malloc(sizeof(REPARSE_POINT));
|
||||
if (!ReparsePoint)
|
||||
return FALSE;
|
||||
|
||||
Status = CmiInitializeTempHive(HiveToConnect);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("CmiInitializeTempHive() failed with status 0x%08x\n", Status);
|
||||
free(ReparsePoint);
|
||||
return FALSE;
|
||||
}
|
||||
Status = CmiInitializeTempHive(HiveToConnect);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("CmiInitializeTempHive() failed with status 0x%08x\n", Status);
|
||||
free(ReparsePoint);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Create key */
|
||||
rc = RegCreateKeyExW(
|
||||
RootKey,
|
||||
Path,
|
||||
0,
|
||||
NULL,
|
||||
REG_OPTION_VOLATILE,
|
||||
0,
|
||||
NULL,
|
||||
(PHKEY)&NewKey,
|
||||
NULL);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
free(ReparsePoint);
|
||||
return FALSE;
|
||||
}
|
||||
/* Create key */
|
||||
rc = RegCreateKeyExW(RootKey,
|
||||
Path,
|
||||
0,
|
||||
NULL,
|
||||
REG_OPTION_VOLATILE,
|
||||
0,
|
||||
NULL,
|
||||
(PHKEY)&NewKey,
|
||||
NULL);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
free(ReparsePoint);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ReparsePoint->SourceHive = NewKey->RegistryHive;
|
||||
ReparsePoint->SourceKeyCellOffset = NewKey->KeyCellOffset;
|
||||
NewKey->RegistryHive = HiveToConnect;
|
||||
NewKey->KeyCellOffset = HiveToConnect->Hive.BaseBlock->RootCell;
|
||||
ReparsePoint->DestinationHive = NewKey->RegistryHive;
|
||||
ReparsePoint->DestinationKeyCellOffset = NewKey->KeyCellOffset;
|
||||
InsertTailList(&CmiReparsePointsHead, &ReparsePoint->ListEntry);
|
||||
return TRUE;
|
||||
ReparsePoint->SourceHive = NewKey->RegistryHive;
|
||||
ReparsePoint->SourceKeyCellOffset = NewKey->KeyCellOffset;
|
||||
NewKey->RegistryHive = HiveToConnect;
|
||||
NewKey->KeyCellOffset = HiveToConnect->Hive.BaseBlock->RootCell;
|
||||
ReparsePoint->DestinationHive = NewKey->RegistryHive;
|
||||
ReparsePoint->DestinationKeyCellOffset = NewKey->KeyCellOffset;
|
||||
InsertTailList(&CmiReparsePointsHead, &ReparsePoint->ListEntry);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
LIST_ENTRY CmiHiveListHead;
|
||||
|
@ -518,88 +514,80 @@ LIST_ENTRY CmiHiveListHead;
|
|||
VOID
|
||||
RegInitializeRegistry(VOID)
|
||||
{
|
||||
UNICODE_STRING RootKeyName = RTL_CONSTANT_STRING(L"\\");
|
||||
NTSTATUS Status;
|
||||
PMEMKEY ControlSetKey, CurrentControlSetKey;
|
||||
PREPARSE_POINT ReparsePoint;
|
||||
UNICODE_STRING RootKeyName = RTL_CONSTANT_STRING(L"\\");
|
||||
NTSTATUS Status;
|
||||
PMEMKEY ControlSetKey, CurrentControlSetKey;
|
||||
PREPARSE_POINT ReparsePoint;
|
||||
|
||||
InitializeListHead(&CmiHiveListHead);
|
||||
InitializeListHead(&CmiReparsePointsHead);
|
||||
InitializeListHead(&CmiHiveListHead);
|
||||
InitializeListHead(&CmiReparsePointsHead);
|
||||
|
||||
Status = CmiInitializeTempHive(&RootHive);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("CmiInitializeTempHive() failed with status 0x%08x\n", Status);
|
||||
return;
|
||||
}
|
||||
Status = CmiInitializeTempHive(&RootHive);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("CmiInitializeTempHive() failed with status 0x%08x\n", Status);
|
||||
return;
|
||||
}
|
||||
|
||||
RootKey = CreateInMemoryStructure(
|
||||
&RootHive,
|
||||
RootHive.Hive.BaseBlock->RootCell);
|
||||
RootKey = CreateInMemoryStructure(&RootHive,
|
||||
RootHive.Hive.BaseBlock->RootCell);
|
||||
|
||||
/* Create DEFAULT key */
|
||||
ConnectRegistry(
|
||||
NULL,
|
||||
&DefaultHive,
|
||||
L"Registry\\User\\.DEFAULT");
|
||||
/* Create DEFAULT key */
|
||||
ConnectRegistry(NULL,
|
||||
&DefaultHive,
|
||||
L"Registry\\User\\.DEFAULT");
|
||||
|
||||
/* Create SAM key */
|
||||
ConnectRegistry(
|
||||
NULL,
|
||||
&SamHive,
|
||||
L"Registry\\Machine\\SAM");
|
||||
/* Create SAM key */
|
||||
ConnectRegistry(NULL,
|
||||
&SamHive,
|
||||
L"Registry\\Machine\\SAM");
|
||||
|
||||
/* Create SECURITY key */
|
||||
ConnectRegistry(
|
||||
NULL,
|
||||
&SecurityHive,
|
||||
L"Registry\\Machine\\SECURITY");
|
||||
/* Create SECURITY key */
|
||||
ConnectRegistry(NULL,
|
||||
&SecurityHive,
|
||||
L"Registry\\Machine\\SECURITY");
|
||||
|
||||
/* Create SOFTWARE key */
|
||||
ConnectRegistry(
|
||||
NULL,
|
||||
&SoftwareHive,
|
||||
L"Registry\\Machine\\SOFTWARE");
|
||||
/* Create SOFTWARE key */
|
||||
ConnectRegistry(NULL,
|
||||
&SoftwareHive,
|
||||
L"Registry\\Machine\\SOFTWARE");
|
||||
|
||||
/* Create SYSTEM key */
|
||||
ConnectRegistry(
|
||||
NULL,
|
||||
&SystemHive,
|
||||
L"Registry\\Machine\\SYSTEM");
|
||||
/* Create SYSTEM key */
|
||||
ConnectRegistry(NULL,
|
||||
&SystemHive,
|
||||
L"Registry\\Machine\\SYSTEM");
|
||||
|
||||
/* Create 'ControlSet001' key */
|
||||
RegCreateKeyW(
|
||||
NULL,
|
||||
L"Registry\\Machine\\SYSTEM\\ControlSet001",
|
||||
(HKEY*)&ControlSetKey);
|
||||
/* Create 'ControlSet001' key */
|
||||
RegCreateKeyW(NULL,
|
||||
L"Registry\\Machine\\SYSTEM\\ControlSet001",
|
||||
(HKEY*)&ControlSetKey);
|
||||
|
||||
/* Create 'CurrentControlSet' key */
|
||||
RegCreateKeyExW(
|
||||
NULL,
|
||||
L"Registry\\Machine\\SYSTEM\\CurrentControlSet",
|
||||
0,
|
||||
NULL,
|
||||
REG_OPTION_VOLATILE,
|
||||
0,
|
||||
NULL,
|
||||
(HKEY*)&CurrentControlSetKey,
|
||||
NULL);
|
||||
/* Create 'CurrentControlSet' key */
|
||||
RegCreateKeyExW(NULL,
|
||||
L"Registry\\Machine\\SYSTEM\\CurrentControlSet",
|
||||
0,
|
||||
NULL,
|
||||
REG_OPTION_VOLATILE,
|
||||
0,
|
||||
NULL,
|
||||
(HKEY*)&CurrentControlSetKey,
|
||||
NULL);
|
||||
|
||||
/* Connect 'CurrentControlSet' to 'ControlSet001' */
|
||||
ReparsePoint = (PREPARSE_POINT)malloc(sizeof(REPARSE_POINT));
|
||||
ReparsePoint->SourceHive = CurrentControlSetKey->RegistryHive;
|
||||
ReparsePoint->SourceKeyCellOffset = CurrentControlSetKey->KeyCellOffset;
|
||||
ReparsePoint->DestinationHive = ControlSetKey->RegistryHive;
|
||||
ReparsePoint->DestinationKeyCellOffset = ControlSetKey->KeyCellOffset;
|
||||
InsertTailList(&CmiReparsePointsHead, &ReparsePoint->ListEntry);
|
||||
/* Connect 'CurrentControlSet' to 'ControlSet001' */
|
||||
ReparsePoint = (PREPARSE_POINT)malloc(sizeof(REPARSE_POINT));
|
||||
ReparsePoint->SourceHive = CurrentControlSetKey->RegistryHive;
|
||||
ReparsePoint->SourceKeyCellOffset = CurrentControlSetKey->KeyCellOffset;
|
||||
ReparsePoint->DestinationHive = ControlSetKey->RegistryHive;
|
||||
ReparsePoint->DestinationKeyCellOffset = ControlSetKey->KeyCellOffset;
|
||||
InsertTailList(&CmiReparsePointsHead, &ReparsePoint->ListEntry);
|
||||
}
|
||||
|
||||
VOID
|
||||
RegShutdownRegistry(VOID)
|
||||
{
|
||||
/* FIXME: clean up the complete hive */
|
||||
/* FIXME: clean up the complete hive */
|
||||
|
||||
free(RootKey);
|
||||
free(RootKey);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -17,9 +17,9 @@ typedef struct _REPARSE_POINT
|
|||
|
||||
typedef struct _MEMKEY
|
||||
{
|
||||
/* Information on hard disk structure */
|
||||
HCELL_INDEX KeyCellOffset;
|
||||
PCMHIVE RegistryHive;
|
||||
/* Information on hard disk structure */
|
||||
HCELL_INDEX KeyCellOffset;
|
||||
PCMHIVE RegistryHive;
|
||||
} MEMKEY, *PMEMKEY;
|
||||
|
||||
#define HKEY_TO_MEMKEY(hKey) ((PMEMKEY)(hKey))
|
||||
|
|
|
@ -24,24 +24,24 @@
|
|||
*/
|
||||
VOID NTAPI
|
||||
RtlInitAnsiString(
|
||||
IN OUT PANSI_STRING DestinationString,
|
||||
IN PCSTR SourceString)
|
||||
IN OUT PANSI_STRING DestinationString,
|
||||
IN PCSTR SourceString)
|
||||
{
|
||||
SIZE_T DestSize;
|
||||
SIZE_T DestSize;
|
||||
|
||||
if(SourceString)
|
||||
{
|
||||
DestSize = strlen(SourceString);
|
||||
DestinationString->Length = (USHORT)DestSize;
|
||||
DestinationString->MaximumLength = (USHORT)DestSize + sizeof(CHAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
DestinationString->Length = 0;
|
||||
DestinationString->MaximumLength = 0;
|
||||
}
|
||||
if(SourceString)
|
||||
{
|
||||
DestSize = strlen(SourceString);
|
||||
DestinationString->Length = (USHORT)DestSize;
|
||||
DestinationString->MaximumLength = (USHORT)DestSize + sizeof(CHAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
DestinationString->Length = 0;
|
||||
DestinationString->MaximumLength = 0;
|
||||
}
|
||||
|
||||
DestinationString->Buffer = (PCHAR)SourceString;
|
||||
DestinationString->Buffer = (PCHAR)SourceString;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -52,129 +52,129 @@ RtlInitAnsiString(
|
|||
*/
|
||||
VOID NTAPI
|
||||
RtlInitUnicodeString(
|
||||
IN OUT PUNICODE_STRING DestinationString,
|
||||
IN PCWSTR SourceString)
|
||||
IN OUT PUNICODE_STRING DestinationString,
|
||||
IN PCWSTR SourceString)
|
||||
{
|
||||
SIZE_T DestSize;
|
||||
SIZE_T DestSize;
|
||||
|
||||
if(SourceString)
|
||||
{
|
||||
DestSize = strlenW(SourceString) * sizeof(WCHAR);
|
||||
DestinationString->Length = (USHORT)DestSize;
|
||||
DestinationString->MaximumLength = (USHORT)DestSize + sizeof(WCHAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
DestinationString->Length = 0;
|
||||
DestinationString->MaximumLength = 0;
|
||||
}
|
||||
if(SourceString)
|
||||
{
|
||||
DestSize = strlenW(SourceString) * sizeof(WCHAR);
|
||||
DestinationString->Length = (USHORT)DestSize;
|
||||
DestinationString->MaximumLength = (USHORT)DestSize + sizeof(WCHAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
DestinationString->Length = 0;
|
||||
DestinationString->MaximumLength = 0;
|
||||
}
|
||||
|
||||
DestinationString->Buffer = (PWCHAR)SourceString;
|
||||
DestinationString->Buffer = (PWCHAR)SourceString;
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI
|
||||
RtlAnsiStringToUnicodeString(
|
||||
IN OUT PUNICODE_STRING UniDest,
|
||||
IN PANSI_STRING AnsiSource,
|
||||
IN BOOLEAN AllocateDestinationString)
|
||||
IN OUT PUNICODE_STRING UniDest,
|
||||
IN PANSI_STRING AnsiSource,
|
||||
IN BOOLEAN AllocateDestinationString)
|
||||
{
|
||||
ULONG Length;
|
||||
PUCHAR WideString;
|
||||
USHORT i;
|
||||
ULONG Length;
|
||||
PUCHAR WideString;
|
||||
USHORT i;
|
||||
|
||||
Length = AnsiSource->Length * sizeof(WCHAR);
|
||||
if (Length > MAXUSHORT) return STATUS_INVALID_PARAMETER_2;
|
||||
UniDest->Length = (USHORT)Length;
|
||||
Length = AnsiSource->Length * sizeof(WCHAR);
|
||||
if (Length > MAXUSHORT) return STATUS_INVALID_PARAMETER_2;
|
||||
UniDest->Length = (USHORT)Length;
|
||||
|
||||
if (AllocateDestinationString)
|
||||
{
|
||||
UniDest->MaximumLength = (USHORT)Length + sizeof(WCHAR);
|
||||
UniDest->Buffer = (PWSTR) malloc(UniDest->MaximumLength);
|
||||
if (!UniDest->Buffer)
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
else if (UniDest->Length >= UniDest->MaximumLength)
|
||||
{
|
||||
return STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
if (AllocateDestinationString)
|
||||
{
|
||||
UniDest->MaximumLength = (USHORT)Length + sizeof(WCHAR);
|
||||
UniDest->Buffer = (PWSTR) malloc(UniDest->MaximumLength);
|
||||
if (!UniDest->Buffer)
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
else if (UniDest->Length >= UniDest->MaximumLength)
|
||||
{
|
||||
return STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
WideString = (PUCHAR)UniDest->Buffer;
|
||||
for (i = 0; i <= AnsiSource->Length; i++)
|
||||
{
|
||||
WideString[2 * i + 0] = AnsiSource->Buffer[i];
|
||||
WideString[2 * i + 1] = 0;
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
WideString = (PUCHAR)UniDest->Buffer;
|
||||
for (i = 0; i <= AnsiSource->Length; i++)
|
||||
{
|
||||
WideString[2 * i + 0] = AnsiSource->Buffer[i];
|
||||
WideString[2 * i + 1] = 0;
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
LONG NTAPI
|
||||
RtlCompareUnicodeString(
|
||||
IN PCUNICODE_STRING String1,
|
||||
IN PCUNICODE_STRING String2,
|
||||
IN BOOLEAN CaseInSensitive)
|
||||
IN PCUNICODE_STRING String1,
|
||||
IN PCUNICODE_STRING String2,
|
||||
IN BOOLEAN CaseInSensitive)
|
||||
{
|
||||
USHORT i;
|
||||
WCHAR c1, c2;
|
||||
USHORT i;
|
||||
WCHAR c1, c2;
|
||||
|
||||
for (i = 0; i <= String1->Length / sizeof(WCHAR) && i <= String2->Length / sizeof(WCHAR); i++)
|
||||
{
|
||||
if (CaseInSensitive)
|
||||
{
|
||||
c1 = RtlUpcaseUnicodeChar(String1->Buffer[i]);
|
||||
c2 = RtlUpcaseUnicodeChar(String2->Buffer[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
c1 = String1->Buffer[i];
|
||||
c2 = String2->Buffer[i];
|
||||
}
|
||||
for (i = 0; i <= String1->Length / sizeof(WCHAR) && i <= String2->Length / sizeof(WCHAR); i++)
|
||||
{
|
||||
if (CaseInSensitive)
|
||||
{
|
||||
c1 = RtlUpcaseUnicodeChar(String1->Buffer[i]);
|
||||
c2 = RtlUpcaseUnicodeChar(String2->Buffer[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
c1 = String1->Buffer[i];
|
||||
c2 = String2->Buffer[i];
|
||||
}
|
||||
|
||||
if (c1 < c2)
|
||||
return -1;
|
||||
else if (c1 > c2)
|
||||
return 1;
|
||||
}
|
||||
if (c1 < c2)
|
||||
return -1;
|
||||
else if (c1 > c2)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
WCHAR NTAPI
|
||||
RtlUpcaseUnicodeChar(
|
||||
IN WCHAR Source)
|
||||
IN WCHAR Source)
|
||||
{
|
||||
USHORT Offset;
|
||||
USHORT Offset;
|
||||
|
||||
if (Source < 'a')
|
||||
return Source;
|
||||
if (Source < 'a')
|
||||
return Source;
|
||||
|
||||
if (Source <= 'z')
|
||||
return (Source - ('a' - 'A'));
|
||||
if (Source <= 'z')
|
||||
return (Source - ('a' - 'A'));
|
||||
|
||||
Offset = 0;
|
||||
Offset = 0;
|
||||
|
||||
return Source + (SHORT)Offset;
|
||||
return Source + (SHORT)Offset;
|
||||
}
|
||||
|
||||
VOID NTAPI
|
||||
KeQuerySystemTime(
|
||||
OUT PLARGE_INTEGER CurrentTime)
|
||||
OUT PLARGE_INTEGER CurrentTime)
|
||||
{
|
||||
CurrentTime->QuadPart = 0;
|
||||
CurrentTime->QuadPart = 0;
|
||||
}
|
||||
|
||||
PVOID NTAPI
|
||||
ExAllocatePool(
|
||||
IN POOL_TYPE PoolType,
|
||||
IN SIZE_T NumberOfBytes)
|
||||
IN POOL_TYPE PoolType,
|
||||
IN SIZE_T NumberOfBytes)
|
||||
{
|
||||
return (PVOID) malloc(NumberOfBytes);
|
||||
return (PVOID) malloc(NumberOfBytes);
|
||||
}
|
||||
|
||||
VOID NTAPI
|
||||
ExFreePool(
|
||||
IN PVOID p)
|
||||
IN PVOID p)
|
||||
{
|
||||
free(p);
|
||||
free(p);
|
||||
}
|
||||
|
||||
ULONG
|
||||
|
|
|
@ -92,10 +92,10 @@ typedef struct _LNK_LOCAL_VOLUME_INFO
|
|||
char VolumeLabel[0];
|
||||
} LNK_LOCAL_VOLUME_INFO;
|
||||
|
||||
#define PT_GUID 0x1F
|
||||
#define PT_DRIVE1 0x2F
|
||||
#define PT_FOLDER 0x31
|
||||
#define PT_VALUE 0x32
|
||||
#define PT_GUID 0x1F
|
||||
#define PT_DRIVE1 0x2F
|
||||
#define PT_FOLDER 0x31
|
||||
#define PT_VALUE 0x32
|
||||
|
||||
typedef struct _ID_LIST_FILE
|
||||
{
|
||||
|
|
|
@ -57,14 +57,14 @@ char *c_operators[] = {
|
|||
|
||||
int isident( int c ) {
|
||||
return (c != '{') && (c != '}') && (c != '(') && (c != ')') &&
|
||||
(c != '\'') && (c != '\"') && !isspace(c);
|
||||
(c != '\'') && (c != '\"') && !isspace(c);
|
||||
}
|
||||
|
||||
bool areinclass( string str, int (*isclass)(int) ) {
|
||||
int i;
|
||||
|
||||
for( i = 0; i < (int)str.size(); i++ )
|
||||
if( !isclass( str[i] ) ) return false;
|
||||
for( i = 0; i < (int)str.size(); i++ )
|
||||
if( !isclass( str[i] ) ) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -74,13 +74,13 @@ bool areident( string s ) { return areinclass( s, isident ); }
|
|||
bool isop( string tok ) {
|
||||
int i;
|
||||
for( i = 0; c_operators[i] && tok != c_operators[i]; i++ );
|
||||
if( c_operators[i] ) return true; else return false;
|
||||
if( c_operators[i] ) return true; else return false;
|
||||
}
|
||||
|
||||
enum fstate { EMPTY, INT, FRAC, EXP };
|
||||
|
||||
string generic_match( string tok, string la,
|
||||
bool (*mf)( string ) ) {
|
||||
bool (*mf)( string ) ) {
|
||||
if( tok.size() < 1 ) return "";
|
||||
if( mf(tok) && !mf(la) ) return tok; else return "";
|
||||
}
|
||||
|
@ -95,16 +95,16 @@ string match_ident( string tok, string la ) {
|
|||
|
||||
string match_quoted_const( string tok, string la, char q ) {
|
||||
if( ((tok.size() && tok[0] == q) ||
|
||||
((tok.size() > 2) && tok[0] == 'L' && tok[1] == q)) &&
|
||||
(tok.rfind(q) == (tok.size() - 1)) ) {
|
||||
if( (tok.rfind("\\") != (tok.size() - 2)) ||
|
||||
(tok.size() > 3 && tok.rfind("\\\\") == (tok.size() - 3)) )
|
||||
return tok;
|
||||
else return "";
|
||||
((tok.size() > 2) && tok[0] == 'L' && tok[1] == q)) &&
|
||||
(tok.rfind(q) == (tok.size() - 1)) ) {
|
||||
if( (tok.rfind("\\") != (tok.size() - 2)) ||
|
||||
(tok.size() > 3 && tok.rfind("\\\\") == (tok.size() - 3)) )
|
||||
return tok;
|
||||
else return "";
|
||||
}
|
||||
else return "";
|
||||
}
|
||||
|
||||
|
||||
sl_t snarf_tokens( string line ) {
|
||||
int i;
|
||||
sl_t out;
|
||||
|
@ -113,57 +113,57 @@ sl_t snarf_tokens( string line ) {
|
|||
line += " ";
|
||||
|
||||
for( i = 0; i < (int)line.size() - 1; i++ ) {
|
||||
/*cout << "Char [" << line[i] << "] and [" << line[i+1] << "]"
|
||||
<< endl; */
|
||||
/*cout << "Char [" << line[i] << "] and [" << line[i+1] << "]"
|
||||
<< endl; */
|
||||
|
||||
if( (!curtok.size() ||
|
||||
(curtok[0] != '\'' && curtok[0] != '\"')) &&
|
||||
(curtok.size() <= 2 ||
|
||||
curtok[0] != 'L' ||
|
||||
(curtok[1] != '\'' && curtok[1] != '\"')) &&
|
||||
isspace(line[i]) ) {
|
||||
if( curtok.size() ) out.push_back( curtok );
|
||||
curtok = "";
|
||||
continue;
|
||||
}
|
||||
if( (!curtok.size() ||
|
||||
(curtok[0] != '\'' && curtok[0] != '\"')) &&
|
||||
(curtok.size() <= 2 ||
|
||||
curtok[0] != 'L' ||
|
||||
(curtok[1] != '\'' && curtok[1] != '\"')) &&
|
||||
isspace(line[i]) ) {
|
||||
if( curtok.size() ) out.push_back( curtok );
|
||||
curtok = "";
|
||||
continue;
|
||||
}
|
||||
|
||||
curtok.push_back( line[i] );
|
||||
curtok.push_back( line[i] );
|
||||
|
||||
la = curtok + line[i+1];
|
||||
la = curtok + line[i+1];
|
||||
|
||||
op = match_operator( curtok, la );
|
||||
|
||||
if( op != "" ) {
|
||||
out.push_back( op MAYBE(+ "O") );
|
||||
curtok = "";
|
||||
continue;
|
||||
}
|
||||
op = match_operator( curtok, la );
|
||||
|
||||
if( la != "L\"" && la != "L\'" ) {
|
||||
ident = match_ident( curtok, la );
|
||||
|
||||
if( ident != "" ) {
|
||||
out.push_back( ident MAYBE(+ "I") );
|
||||
curtok = "";
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if( op != "" ) {
|
||||
out.push_back( op MAYBE(+ "O") );
|
||||
curtok = "";
|
||||
continue;
|
||||
}
|
||||
|
||||
qconst = match_quoted_const( curtok, la, '\'' );
|
||||
|
||||
if( qconst != "" ) {
|
||||
out.push_back( qconst MAYBE(+ "q") );
|
||||
curtok = "";
|
||||
continue;
|
||||
}
|
||||
if( la != "L\"" && la != "L\'" ) {
|
||||
ident = match_ident( curtok, la );
|
||||
|
||||
qconst = match_quoted_const( curtok, la, '\"' );
|
||||
|
||||
if( qconst != "" ) {
|
||||
out.push_back( qconst MAYBE(+ "Q") );
|
||||
curtok = "";
|
||||
continue;
|
||||
}
|
||||
if( ident != "" ) {
|
||||
out.push_back( ident MAYBE(+ "I") );
|
||||
curtok = "";
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
qconst = match_quoted_const( curtok, la, '\'' );
|
||||
|
||||
if( qconst != "" ) {
|
||||
out.push_back( qconst MAYBE(+ "q") );
|
||||
curtok = "";
|
||||
continue;
|
||||
}
|
||||
|
||||
qconst = match_quoted_const( curtok, la, '\"' );
|
||||
|
||||
if( qconst != "" ) {
|
||||
out.push_back( qconst MAYBE(+ "Q") );
|
||||
curtok = "";
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
|
@ -175,29 +175,29 @@ istream &getline_no_comments( istream &is, string &line ) {
|
|||
int seen_slash = false;
|
||||
|
||||
while( (ch = is.get()) != -1 ) {
|
||||
if( seen_slash ) {
|
||||
if( ch == '/' ) {
|
||||
do {
|
||||
ch = is.get();
|
||||
} while( ch != -1 && ch != '\n' && ch != '\r' );
|
||||
break;
|
||||
} else if( ch == '*' ) {
|
||||
ch = is.get(); /* Skip one char */
|
||||
do {
|
||||
while( ch != '*' )
|
||||
ch = is.get();
|
||||
ch = is.get();
|
||||
} while( ch != '/' );
|
||||
buf += ' ';
|
||||
} else {
|
||||
buf += '/'; buf += (char)ch;
|
||||
}
|
||||
seen_slash = false;
|
||||
} else {
|
||||
if( ch == '/' ) seen_slash = true;
|
||||
else if( ch == '\r' || ch == '\n' ) break;
|
||||
else buf += (char)ch;
|
||||
}
|
||||
if( seen_slash ) {
|
||||
if( ch == '/' ) {
|
||||
do {
|
||||
ch = is.get();
|
||||
} while( ch != -1 && ch != '\n' && ch != '\r' );
|
||||
break;
|
||||
} else if( ch == '*' ) {
|
||||
ch = is.get(); /* Skip one char */
|
||||
do {
|
||||
while( ch != '*' )
|
||||
ch = is.get();
|
||||
ch = is.get();
|
||||
} while( ch != '/' );
|
||||
buf += ' ';
|
||||
} else {
|
||||
buf += '/'; buf += (char)ch;
|
||||
}
|
||||
seen_slash = false;
|
||||
} else {
|
||||
if( ch == '/' ) seen_slash = true;
|
||||
else if( ch == '\r' || ch == '\n' ) break;
|
||||
else buf += (char)ch;
|
||||
}
|
||||
}
|
||||
|
||||
line = buf;
|
||||
|
@ -212,33 +212,34 @@ bool expand_input( sl_t &tok ) {
|
|||
|
||||
out = getline_no_comments( cin, line );
|
||||
while( line.size() && isspace( line[0] ) )
|
||||
line = line.substr( 1 );
|
||||
line = line.substr( 1 );
|
||||
if( line[0] == '#' ) {
|
||||
tok.push_back( line );
|
||||
while( line[line.size()-1] == '\\' ) {
|
||||
getline_no_comments( cin, line );
|
||||
tok.push_back( line );
|
||||
tok.push_back( "\n" );
|
||||
}
|
||||
tok.push_back( "\n" );
|
||||
} else {
|
||||
new_tokens = snarf_tokens( line );
|
||||
tok.splice( tok.end(), new_tokens );
|
||||
tok.push_back( "\n" );
|
||||
tok.push_back( line );
|
||||
while( line[line.size()-1] == '\\' ) {
|
||||
getline_no_comments( cin, line );
|
||||
tok.push_back( line );
|
||||
tok.push_back( "\n" );
|
||||
}
|
||||
|
||||
tok.push_back( "\n" );
|
||||
} else {
|
||||
new_tokens = snarf_tokens( line );
|
||||
tok.splice( tok.end(), new_tokens );
|
||||
tok.push_back( "\n" );
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
sl_it
|
||||
complete_block( sl_it i,
|
||||
sl_it end,
|
||||
string start_ch, string end_ch) {
|
||||
sl_it end,
|
||||
string start_ch,
|
||||
string end_ch) {
|
||||
int bc = 1;
|
||||
|
||||
|
||||
for( i++; i != end && bc; i++ ) {
|
||||
if( *i == start_ch ) bc++;
|
||||
if( *i == end_ch ) bc--;
|
||||
if( *i == start_ch ) bc++;
|
||||
if( *i == end_ch ) bc--;
|
||||
}
|
||||
|
||||
return i;
|
||||
|
@ -255,21 +256,21 @@ string makename( string intro ) {
|
|||
|
||||
void append_block( sl_t &t, sl_it b, sl_it e ) {
|
||||
while( b != e ) {
|
||||
t.push_back( *b );
|
||||
b++;
|
||||
t.push_back( *b );
|
||||
b++;
|
||||
}
|
||||
}
|
||||
|
||||
void error( sl_t &container, sl_it it, string l ) {
|
||||
int line = 0;
|
||||
for( sl_it i = container.begin(); i != it; i++ )
|
||||
if( (*i)[0] == '#' ) {
|
||||
sscanf( i->substr(1).c_str(), "%d", &line );
|
||||
cerr << "*standard-input*:" << line << ": " << l;
|
||||
}
|
||||
int line = 0;
|
||||
for( sl_it i = container.begin(); i != it; i++ )
|
||||
if( (*i)[0] == '#' ) {
|
||||
sscanf( i->substr(1).c_str(), "%d", &line );
|
||||
cerr << "*standard-input*:" << line << ": " << l;
|
||||
}
|
||||
}
|
||||
|
||||
/* Goal: match and transform one __try { a } __except [ (foo) ] { b }
|
||||
/* Goal: match and transform one __try { a } __except [ (foo) ] { b }
|
||||
* [ __finally { c } ]
|
||||
*
|
||||
* into
|
||||
|
@ -288,51 +289,51 @@ void handle_try( sl_t &container, sl_it try_kw, sl_it end ) {
|
|||
sl_t pseh_clause, temp_tok;
|
||||
string finally_name, filter_name;
|
||||
sl_it try_block, try_block_end, except_kw, paren, end_paren,
|
||||
except_block, except_block_end, todelete,
|
||||
finally_kw, finally_block, finally_block_end, clause_end;
|
||||
except_block, except_block_end, todelete,
|
||||
finally_kw, finally_block, finally_block_end, clause_end;
|
||||
|
||||
try_block = try_kw;
|
||||
try_block++;
|
||||
try_block_end = complete_block( try_block, end, "{", "}" );
|
||||
|
||||
if( try_block_end == end )
|
||||
error( container, try_block, "unclosed try block");
|
||||
|
||||
if( try_block_end == end )
|
||||
error( container, try_block, "unclosed try block");
|
||||
|
||||
except_kw = try_block_end;
|
||||
|
||||
if( *except_kw == FINALLY_TOKEN ) {
|
||||
finally_kw = except_kw;
|
||||
except_kw = end;
|
||||
paren = end;
|
||||
end_paren = end;
|
||||
except_block = end;
|
||||
except_block_end = end;
|
||||
finally_kw = except_kw;
|
||||
except_kw = end;
|
||||
paren = end;
|
||||
end_paren = end;
|
||||
except_block = end;
|
||||
except_block_end = end;
|
||||
} else if( *except_kw == EXCEPT_TOKEN ) {
|
||||
paren = except_kw;
|
||||
paren++;
|
||||
if( *paren == "(" ) {
|
||||
end_paren = complete_block( paren, end, "(", ")" );
|
||||
except_block = end_paren;
|
||||
} else {
|
||||
except_block = paren;
|
||||
paren = end;
|
||||
end_paren = end;
|
||||
}
|
||||
except_block_end = complete_block( except_block, end, "{", "}" );
|
||||
finally_kw = except_block_end;
|
||||
paren = except_kw;
|
||||
paren++;
|
||||
if( *paren == "(" ) {
|
||||
end_paren = complete_block( paren, end, "(", ")" );
|
||||
except_block = end_paren;
|
||||
} else {
|
||||
except_kw = paren = end_paren = except_block = except_block_end =
|
||||
finally_kw = finally_block = finally_block_end = end;
|
||||
except_block = paren;
|
||||
paren = end;
|
||||
end_paren = end;
|
||||
}
|
||||
except_block_end = complete_block( except_block, end, "{", "}" );
|
||||
finally_kw = except_block_end;
|
||||
} else {
|
||||
except_kw = paren = end_paren = except_block = except_block_end =
|
||||
finally_kw = finally_block = finally_block_end = end;
|
||||
}
|
||||
|
||||
if( finally_kw != end && *finally_kw != FINALLY_TOKEN ) {
|
||||
finally_kw = end;
|
||||
finally_block = end;
|
||||
finally_block_end = end;
|
||||
finally_kw = end;
|
||||
finally_block = end;
|
||||
finally_block_end = end;
|
||||
} else {
|
||||
finally_block = finally_kw;
|
||||
finally_block++;
|
||||
finally_block_end = complete_block( finally_block, end, "{", "}" );
|
||||
finally_block = finally_kw;
|
||||
finally_block++;
|
||||
finally_block_end = complete_block( finally_block, end, "{", "}" );
|
||||
}
|
||||
|
||||
if( finally_block_end != end ) clause_end = finally_block_end;
|
||||
|
@ -351,11 +352,11 @@ void handle_try( sl_t &container, sl_it try_kw, sl_it end ) {
|
|||
pseh_clause.push_back( "(" );
|
||||
pseh_clause.push_back( finally_name );
|
||||
pseh_clause.push_back( ")" );
|
||||
if( finally_kw != end )
|
||||
append_block( pseh_clause, finally_block, finally_block_end );
|
||||
if( finally_kw != end )
|
||||
append_block( pseh_clause, finally_block, finally_block_end );
|
||||
else {
|
||||
pseh_clause.push_back( "{" );
|
||||
pseh_clause.push_back( "}" );
|
||||
pseh_clause.push_back( "{" );
|
||||
pseh_clause.push_back( "}" );
|
||||
}
|
||||
|
||||
pseh_clause.push_back( "_SEH_FILTER" );
|
||||
|
@ -365,9 +366,9 @@ void handle_try( sl_t &container, sl_it try_kw, sl_it end ) {
|
|||
pseh_clause.push_back( "{" );
|
||||
pseh_clause.push_back( "return" );
|
||||
if( paren != end )
|
||||
append_block( pseh_clause, paren, end_paren );
|
||||
append_block( pseh_clause, paren, end_paren );
|
||||
else
|
||||
pseh_clause.push_back( "EXCEPTION_EXECUTE_HANDLER" );
|
||||
pseh_clause.push_back( "EXCEPTION_EXECUTE_HANDLER" );
|
||||
pseh_clause.push_back( ";" );
|
||||
pseh_clause.push_back( "}" );
|
||||
|
||||
|
@ -381,23 +382,23 @@ void handle_try( sl_t &container, sl_it try_kw, sl_it end ) {
|
|||
pseh_clause.push_back( "_SEH_HANDLE" );
|
||||
pseh_clause.push_back( "{" );
|
||||
if( except_block != end )
|
||||
append_block( pseh_clause, except_block, except_block_end );
|
||||
append_block( pseh_clause, except_block, except_block_end );
|
||||
pseh_clause.push_back( "}" );
|
||||
pseh_clause.push_back( "_SEH_END" );
|
||||
pseh_clause.push_back( ";" );
|
||||
|
||||
container.splice( try_kw, pseh_clause );
|
||||
while( try_kw != clause_end ) {
|
||||
todelete = try_kw;
|
||||
try_kw++;
|
||||
container.erase( todelete );
|
||||
todelete = try_kw;
|
||||
try_kw++;
|
||||
container.erase( todelete );
|
||||
}
|
||||
}
|
||||
|
||||
void print_tokens( sl_it begin, sl_it end ) {
|
||||
for( sl_it i = begin; i != end; i++ )
|
||||
if( *i == "\n" ) cout << *i;
|
||||
else cout << /*"[" <<*/ *i << /*"]" <<*/ " ";
|
||||
for( sl_it i = begin; i != end; i++ )
|
||||
if( *i == "\n" ) cout << *i;
|
||||
else cout << /*"[" <<*/ *i << /*"]" <<*/ " ";
|
||||
}
|
||||
|
||||
int main( int argc, char **argv ) {
|
||||
|
@ -406,24 +407,24 @@ int main( int argc, char **argv ) {
|
|||
int i;
|
||||
|
||||
for( i = 1; i < argc; i++ ) {
|
||||
if( string(argv[i]) == "-try" && i < argc - 1 ) {
|
||||
i++;
|
||||
TRY_TOKEN = argv[i];
|
||||
} else if( string(argv[i]) == "-except" && i < argc - 1 ) {
|
||||
i++;
|
||||
EXCEPT_TOKEN = argv[i];
|
||||
} else if( string(argv[i]) == "-finally" && i < argc - 1 ) {
|
||||
i++;
|
||||
FINALLY_TOKEN = argv[i];
|
||||
}
|
||||
if( string(argv[i]) == "-try" && i < argc - 1 ) {
|
||||
i++;
|
||||
TRY_TOKEN = argv[i];
|
||||
} else if( string(argv[i]) == "-except" && i < argc - 1 ) {
|
||||
i++;
|
||||
EXCEPT_TOKEN = argv[i];
|
||||
} else if( string(argv[i]) == "-finally" && i < argc - 1 ) {
|
||||
i++;
|
||||
FINALLY_TOKEN = argv[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX Uses much memory for large files */
|
||||
while( expand_input(tok) );
|
||||
|
||||
while( (try_found = find( tok.begin(), tok.end(), TRY_TOKEN )) !=
|
||||
tok.end() ) {
|
||||
handle_try( tok, try_found, tok.end() );
|
||||
tok.end() ) {
|
||||
handle_try( tok, try_found, tok.end() );
|
||||
}
|
||||
|
||||
tok.push_front("#include <pseh/framebased.h>\n");
|
||||
|
|
|
@ -69,7 +69,7 @@ WriteToFlash(IN INT NandImageFile,
|
|||
/* Offset to NAND Page convert */
|
||||
StartPage = ImageStart / NAND_PAGE_SIZE;
|
||||
EndPage = ImageEnd / NAND_PAGE_SIZE;
|
||||
|
||||
|
||||
/* Jump to NAND offset */
|
||||
if (NeedsOob) OobSize = NAND_OOB_SIZE;
|
||||
lseek(NandImageFile, StartPage * (NAND_PAGE_SIZE + OobSize), SEEK_SET);
|
||||
|
@ -153,7 +153,7 @@ main(ULONG argc,
|
|||
char **argv)
|
||||
{
|
||||
INT NandImageFile, RamDiskFile;
|
||||
|
||||
|
||||
/* Flat NAND, no OOB */
|
||||
if (argc == 2) NeedsOob = FALSE;
|
||||
|
||||
|
@ -177,7 +177,7 @@ main(ULONG argc,
|
|||
|
||||
/* Write it */
|
||||
WriteRamDisk(RamDiskFile);
|
||||
|
||||
|
||||
/* Close */
|
||||
close(RamDiskFile);
|
||||
}
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
# Function Args Returns Types
|
||||
# Function Args Returns Types
|
||||
# Real OFW functions to proxy
|
||||
finddevice 1 1 char* int
|
||||
open 1 1 char* int
|
||||
getprop 4 1 int char* char*:arg3 int int
|
||||
nextprop 3 1 int char* char* int
|
||||
getproplen 2 1 int char* int
|
||||
write 3 1 int char*:arg2 int int
|
||||
read 3 1 int char*:arg2 int int
|
||||
exit 0 0
|
||||
child 1 1 int int
|
||||
peer 1 1 int int
|
||||
parent 1 1 int int
|
||||
seek 3 1 int int int int
|
||||
package-to-path 3 1 int char*:arg2 int int
|
||||
claim 3 1 int int int int
|
||||
finddevice 1 1 char* int
|
||||
open 1 1 char* int
|
||||
getprop 4 1 int char* char*:arg3 int int
|
||||
nextprop 3 1 int char* char* int
|
||||
getproplen 2 1 int char* int
|
||||
write 3 1 int char*:arg2 int int
|
||||
read 3 1 int char*:arg2 int int
|
||||
exit 0 0
|
||||
child 1 1 int int
|
||||
peer 1 1 int int
|
||||
parent 1 1 int int
|
||||
seek 3 1 int int int int
|
||||
package-to-path 3 1 int char*:arg2 int int
|
||||
claim 3 1 int int int int
|
||||
|
|
|
@ -18,35 +18,35 @@ public:
|
|||
class vartype {
|
||||
public:
|
||||
vartype( const std::string &typestr ) {
|
||||
size_t amp = typestr.find('&');
|
||||
size_t col = typestr.find(':');
|
||||
if( amp != std::string::npos ) {
|
||||
if( col > amp && col != std::string::npos )
|
||||
lit_value = typestr.substr(amp+1,col-amp+1);
|
||||
else lit_value = typestr.substr(amp+1);
|
||||
}
|
||||
if( col != std::string::npos ) {
|
||||
if( amp > col && amp != std::string::npos )
|
||||
len = typestr.substr(col+1,amp-col+1);
|
||||
else len = typestr.substr(col+1);
|
||||
}
|
||||
size_t amp = typestr.find('&');
|
||||
size_t col = typestr.find(':');
|
||||
if( amp != std::string::npos ) {
|
||||
if( col > amp && col != std::string::npos )
|
||||
lit_value = typestr.substr(amp+1,col-amp+1);
|
||||
else lit_value = typestr.substr(amp+1);
|
||||
}
|
||||
if( col != std::string::npos ) {
|
||||
if( amp > col && amp != std::string::npos )
|
||||
len = typestr.substr(col+1,amp-col+1);
|
||||
else len = typestr.substr(col+1);
|
||||
}
|
||||
|
||||
if( amp != std::string::npos && amp < col ) col = amp;
|
||||
if( col == std::string::npos ) col = typestr.size();
|
||||
c_type = typestr.substr(0,col);
|
||||
if( amp != std::string::npos && amp < col ) col = amp;
|
||||
if( col == std::string::npos ) col = typestr.size();
|
||||
c_type = typestr.substr(0,col);
|
||||
}
|
||||
|
||||
vartype( const vartype &other )
|
||||
: c_type(other.c_type),
|
||||
len(other.len),
|
||||
lit_value(other.lit_value) {
|
||||
: c_type(other.c_type),
|
||||
len(other.len),
|
||||
lit_value(other.lit_value) {
|
||||
}
|
||||
|
||||
vartype &operator = ( const vartype &other ) {
|
||||
c_type = other.c_type;
|
||||
len = other.len;
|
||||
lit_value = other.lit_value;
|
||||
return *this;
|
||||
c_type = other.c_type;
|
||||
len = other.len;
|
||||
lit_value = other.lit_value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string c_type;
|
||||
|
@ -57,7 +57,7 @@ public:
|
|||
std::string uppercase( const std::string &toucase ) {
|
||||
std::vector<char> ucase_work(toucase.size());
|
||||
for( size_t i = 0; i < toucase.size(); i++ ) {
|
||||
ucase_work[i] = toupper(toucase[i]);
|
||||
ucase_work[i] = toupper(toucase[i]);
|
||||
}
|
||||
return std::string(&ucase_work[0], toucase.size());
|
||||
}
|
||||
|
@ -65,9 +65,9 @@ std::string uppercase( const std::string &toucase ) {
|
|||
std::string clip_eol( std::string in, const std::string &eol_marks ) {
|
||||
size_t found;
|
||||
for( size_t i = 0; i < eol_marks.size(); i++ ) {
|
||||
found = in.find( eol_marks[i] );
|
||||
if( found != std::string::npos )
|
||||
in = in.substr( 0, found );
|
||||
found = in.find( eol_marks[i] );
|
||||
if( found != std::string::npos )
|
||||
in = in.substr( 0, found );
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
@ -90,39 +90,39 @@ void populate_definition( ofw_wrappers &wrapper, const std::string &line ) {
|
|||
if( !name.size() ) return;
|
||||
|
||||
if( (f = name.find('!')) != std::string::npos ) {
|
||||
nametext = name.substr(f+1);
|
||||
name = name.substr(0,f);
|
||||
nametext = name.substr(f+1);
|
||||
name = name.substr(0,f);
|
||||
}
|
||||
if( name[0] == '-' ) {
|
||||
name = name.substr(1);
|
||||
make_function = false;
|
||||
name = name.substr(1);
|
||||
make_function = false;
|
||||
}
|
||||
if( name[0] == '+' ) {
|
||||
name = name.substr(1);
|
||||
make_stub = false;
|
||||
name = name.substr(1);
|
||||
make_stub = false;
|
||||
}
|
||||
if( name[0] == '@' ) {
|
||||
name = name.substr(1);
|
||||
method_call = true;
|
||||
make_function = false;
|
||||
name = name.substr(1);
|
||||
method_call = true;
|
||||
make_function = false;
|
||||
}
|
||||
|
||||
if( !nametext.size() ) nametext = name;
|
||||
|
||||
for( i = 1; i < (int)name.size(); i++ )
|
||||
if( name[i] == '-' ) name[i] = '_';
|
||||
if( name[i] == '-' ) name[i] = '_';
|
||||
|
||||
if( nametext == "call-method" )
|
||||
wrapper.method_ctindex = wrapper.ctindex;
|
||||
wrapper.method_ctindex = wrapper.ctindex;
|
||||
|
||||
for( i = 0; i < args; i++ ) {
|
||||
iss >> argtype;
|
||||
argtypes.push_back(vartype(argtype));
|
||||
argtypes.push_back(vartype(argtype));
|
||||
}
|
||||
|
||||
if( method_call ) {
|
||||
userarg_start = 1;
|
||||
args += 2;
|
||||
userarg_start = 1;
|
||||
args += 2;
|
||||
}
|
||||
|
||||
iss >> rettype;
|
||||
|
@ -132,76 +132,76 @@ void populate_definition( ofw_wrappers &wrapper, const std::string &line ) {
|
|||
total_stack = round_up(12 + local_offset, 16);
|
||||
|
||||
function << "asm_ofw_" << name << ":\n"
|
||||
<< "\t/* Reserve stack space */\n"
|
||||
<< "\tsubi %r1,%r1," << total_stack << "\n"
|
||||
<< "\t/* Store r8, r9, lr */\n"
|
||||
<< "\tstw %r8," << (local_offset + 0) << "(%r1)\n"
|
||||
<< "\tstw %r9," << (local_offset + 4) << "(%r1)\n"
|
||||
<< "\tmflr %r8\n"
|
||||
<< "\tstw %r8," << (local_offset + 8) << "(%r1)\n"
|
||||
<< "\t/* Get read name */\n"
|
||||
<< "\tlis %r8," << name << "_ofw_name@ha\n"
|
||||
<< "\taddi %r9,%r8," << name << "_ofw_name@l\n"
|
||||
<< "\tstw %r9,0(%r1)\n"
|
||||
<< "\t/* " << args << " arguments and " << rets << " return */\n"
|
||||
<< "\tli %r9," << args << "\n"
|
||||
<< "\tstw %r9,4(%r1)\n"
|
||||
<< "\tli %r9," << rets << "\n"
|
||||
<< "\tstw %r9,8(%r1)\n";
|
||||
<< "\t/* Reserve stack space */\n"
|
||||
<< "\tsubi %r1,%r1," << total_stack << "\n"
|
||||
<< "\t/* Store r8, r9, lr */\n"
|
||||
<< "\tstw %r8," << (local_offset + 0) << "(%r1)\n"
|
||||
<< "\tstw %r9," << (local_offset + 4) << "(%r1)\n"
|
||||
<< "\tmflr %r8\n"
|
||||
<< "\tstw %r8," << (local_offset + 8) << "(%r1)\n"
|
||||
<< "\t/* Get read name */\n"
|
||||
<< "\tlis %r8," << name << "_ofw_name@ha\n"
|
||||
<< "\taddi %r9,%r8," << name << "_ofw_name@l\n"
|
||||
<< "\tstw %r9,0(%r1)\n"
|
||||
<< "\t/* " << args << " arguments and " << rets << " return */\n"
|
||||
<< "\tli %r9," << args << "\n"
|
||||
<< "\tstw %r9,4(%r1)\n"
|
||||
<< "\tli %r9," << rets << "\n"
|
||||
<< "\tstw %r9,8(%r1)\n";
|
||||
|
||||
for( int i = 0; i < args; i++ )
|
||||
function << "\tstw %r" << (i+3) << "," << (4 * (i + 3)) << "(%r1)\n";
|
||||
function << "\tstw %r" << (i+3) << "," << (4 * (i + 3)) << "(%r1)\n";
|
||||
|
||||
function << "\t/* Load up the call address */\n"
|
||||
<< "\tlis %r10,ofw_call_addr@ha\n"
|
||||
<< "\tlwz %r9,ofw_call_addr@l(%r10)\n"
|
||||
<< "\tmtlr %r9\n"
|
||||
<< "\t/* Set argument */\n"
|
||||
<< "\tmr %r3,%r1\n"
|
||||
<< "\t/* Fire */\n"
|
||||
<< "\tblrl\n"
|
||||
<< "\tlwz %r3," << (local_offset - 4) << "(%r1)\n"
|
||||
<< "\t/* Restore registers */\n"
|
||||
<< "\tlwz %r8," << (local_offset + 8) << "(%r1)\n"
|
||||
<< "\tmtlr %r8\n"
|
||||
<< "\tlwz %r9," << (local_offset + 4) << "(%r1)\n"
|
||||
<< "\tlwz %r8," << (local_offset + 0) << "(%r1)\n"
|
||||
<< "\t/* Return */\n"
|
||||
<< "\taddi %r1,%r1," << total_stack << "\n"
|
||||
<< "\tblr\n";
|
||||
<< "\tlwz %r9,ofw_call_addr@l(%r10)\n"
|
||||
<< "\tmtlr %r9\n"
|
||||
<< "\t/* Set argument */\n"
|
||||
<< "\tmr %r3,%r1\n"
|
||||
<< "\t/* Fire */\n"
|
||||
<< "\tblrl\n"
|
||||
<< "\tlwz %r3," << (local_offset - 4) << "(%r1)\n"
|
||||
<< "\t/* Restore registers */\n"
|
||||
<< "\tlwz %r8," << (local_offset + 8) << "(%r1)\n"
|
||||
<< "\tmtlr %r8\n"
|
||||
<< "\tlwz %r9," << (local_offset + 4) << "(%r1)\n"
|
||||
<< "\tlwz %r8," << (local_offset + 0) << "(%r1)\n"
|
||||
<< "\t/* Return */\n"
|
||||
<< "\taddi %r1,%r1," << total_stack << "\n"
|
||||
<< "\tblr\n";
|
||||
|
||||
if( method_call ) {
|
||||
argtypes.insert(argtypes.begin(),vartype("int"));
|
||||
argtypes.insert(argtypes.begin(),vartype("char*"));
|
||||
argtypes.insert(argtypes.begin(),vartype("int"));
|
||||
argtypes.insert(argtypes.begin(),vartype("char*"));
|
||||
}
|
||||
|
||||
le_stub << rettype << " ofw_" << name << "(";
|
||||
|
||||
comma = false;
|
||||
for( i = userarg_start; i < args; i++ ) {
|
||||
if( !argtypes[i].lit_value.size() ) {
|
||||
if( !comma ) comma = true; else le_stub << ",";
|
||||
le_stub << argtypes[i].c_type << " arg" << i;
|
||||
}
|
||||
if( !argtypes[i].lit_value.size() ) {
|
||||
if( !comma ) comma = true; else le_stub << ",";
|
||||
le_stub << argtypes[i].c_type << " arg" << i;
|
||||
}
|
||||
}
|
||||
le_stub << ")";
|
||||
of_call << le_stub.str() << ";\n";
|
||||
|
||||
le_stub << " {\n";
|
||||
if( rettype != "void" )
|
||||
le_stub << "\t" << rettype << " ret;\n";
|
||||
le_stub << "\t" << rettype << " ret;\n";
|
||||
|
||||
if( method_call ) {
|
||||
le_stub << "\tchar arg0["
|
||||
<< round_up(nametext.size()+1,8)
|
||||
<< "] = \"" << nametext << "\";\n";
|
||||
le_stub << "\tchar arg0["
|
||||
<< round_up(nametext.size()+1,8)
|
||||
<< "] = \"" << nametext << "\";\n";
|
||||
}
|
||||
|
||||
for( i = 0; i < args; i++ ) {
|
||||
if( argtypes[i].lit_value.size() ) {
|
||||
le_stub << "\t" << argtypes[i].c_type << " arg" << i << " = "
|
||||
<< argtypes[i].lit_value << ";\n";
|
||||
}
|
||||
if( argtypes[i].lit_value.size() ) {
|
||||
le_stub << "\t" << argtypes[i].c_type << " arg" << i << " = "
|
||||
<< argtypes[i].lit_value << ";\n";
|
||||
}
|
||||
}
|
||||
|
||||
le_stub << "\t";
|
||||
|
@ -211,26 +211,26 @@ void populate_definition( ofw_wrappers &wrapper, const std::string &line ) {
|
|||
(method_call ? (wrapper.method_ctindex * 4) : (wrapper.ctindex * 4));
|
||||
|
||||
for( i = 0; i < 6; i++ ) {
|
||||
if( i < args ) le_stub << ",(void *)arg" << i;
|
||||
else le_stub << ",NULL";
|
||||
if( i < args ) le_stub << ",(void *)arg" << i;
|
||||
else le_stub << ",NULL";
|
||||
}
|
||||
|
||||
le_stub << ");\n";
|
||||
|
||||
if( rettype != "void" )
|
||||
le_stub << "\treturn ret;\n";
|
||||
le_stub << "\treturn ret;\n";
|
||||
|
||||
le_stub << "}\n";
|
||||
|
||||
if( make_function ) wrapper.functions += function.str();
|
||||
if( make_stub ) {
|
||||
wrapper.le_stubs += le_stub.str();
|
||||
wrapper.of_call += of_call.str();
|
||||
wrapper.le_stubs += le_stub.str();
|
||||
wrapper.of_call += of_call.str();
|
||||
}
|
||||
if( !method_call ) {
|
||||
wrapper.names += name + "_ofw_name:\n\t.asciz \"" + nametext + "\"\n";
|
||||
wrapper.calltable += std::string("\t.long asm_ofw_") + name + "\n";
|
||||
wrapper.ctindex++;
|
||||
wrapper.names += name + "_ofw_name:\n\t.asciz \"" + nametext + "\"\n";
|
||||
wrapper.calltable += std::string("\t.long asm_ofw_") + name + "\n";
|
||||
wrapper.ctindex++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -246,70 +246,70 @@ int main( int argc, char **argv ) {
|
|||
wrappers.ctindex = 0;
|
||||
|
||||
if( argc < 5 ) {
|
||||
fprintf( stderr, "%s [interface.ofw] [ofw.s] [le_stub.c] [le_stub.h]\n", argv[0] );
|
||||
return 1;
|
||||
fprintf( stderr, "%s [interface.ofw] [ofw.s] [le_stub.c] [le_stub.h]\n", argv[0] );
|
||||
return 1;
|
||||
}
|
||||
|
||||
in.open( argv[1] );
|
||||
if( !in ) {
|
||||
fprintf( stderr, "can't open %s\n", argv[1] );
|
||||
status = 1;
|
||||
goto error;
|
||||
fprintf( stderr, "can't open %s\n", argv[1] );
|
||||
status = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
out.open( argv[2] );
|
||||
if( !out ) {
|
||||
fprintf( stderr, "can't open %s\n", argv[2] );
|
||||
status = 1;
|
||||
goto error;
|
||||
fprintf( stderr, "can't open %s\n", argv[2] );
|
||||
status = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
outcsource.open( argv[3] );
|
||||
if( !outcsource ) {
|
||||
fprintf( stderr, "can't open %s\n", argv[3] );
|
||||
status = 1;
|
||||
goto error;
|
||||
fprintf( stderr, "can't open %s\n", argv[3] );
|
||||
status = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
outcheader.open( argv[4] );
|
||||
if( !outcheader ) {
|
||||
fprintf( stderr, "can't open %s\n", argv[4] );
|
||||
status = 1;
|
||||
goto error;
|
||||
fprintf( stderr, "can't open %s\n", argv[4] );
|
||||
status = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
while( std::getline( in, line ) ) {
|
||||
line = clip_eol( line, eol_marks );
|
||||
if( line.size() ) populate_definition( wrappers, line );
|
||||
line = clip_eol( line, eol_marks );
|
||||
if( line.size() ) populate_definition( wrappers, line );
|
||||
}
|
||||
|
||||
out << "/* AUTOMATICALLY GENERATED BY ofw_interface */\n"
|
||||
<< "\t.section .text\n"
|
||||
<< "\t.align 4\n"
|
||||
<< "\t.globl _start\n"
|
||||
<< "\t.globl ofw_functions\n"
|
||||
<< "\t.globl ofw_call_addr\n"
|
||||
<< "ofw_call_addr:\n"
|
||||
<< "\t.long 0\n"
|
||||
<< "\n/* Function Wrappers */\n\n"
|
||||
<< wrappers.functions
|
||||
<< "\n/* Function Names */\n\n"
|
||||
<< wrappers.names
|
||||
<< "\n/* Function Call Table for Freeldr */\n\n"
|
||||
<< "\t.section .text\n"
|
||||
<< "\t.align 4\n"
|
||||
<< "ofw_functions:\n"
|
||||
<< wrappers.calltable
|
||||
<< "\n/* End */\n";
|
||||
<< "\t.globl _start\n"
|
||||
<< "\t.globl ofw_functions\n"
|
||||
<< "\t.globl ofw_call_addr\n"
|
||||
<< "ofw_call_addr:\n"
|
||||
<< "\t.long 0\n"
|
||||
<< "\n/* Function Wrappers */\n\n"
|
||||
<< wrappers.functions
|
||||
<< "\n/* Function Names */\n\n"
|
||||
<< wrappers.names
|
||||
<< "\n/* Function Call Table for Freeldr */\n\n"
|
||||
<< "\t.align 4\n"
|
||||
<< "ofw_functions:\n"
|
||||
<< wrappers.calltable
|
||||
<< "\n/* End */\n";
|
||||
|
||||
outcsource << "/* AUTOMATICALLY GENERATED BY ofw_interface */\n"
|
||||
<< "#include \"of.h\"\n"
|
||||
<< wrappers.le_stubs;
|
||||
<< "#include \"of.h\"\n"
|
||||
<< wrappers.le_stubs;
|
||||
|
||||
outcheader << "/* AUTOMATICALLY GENERATE BY ofw_interface */\n"
|
||||
<< "#ifndef _OFW_CALLS_H\n"
|
||||
<< "#define _OFW_CALLS_H\n"
|
||||
<< wrappers.of_call
|
||||
<< "#endif/*_OFW_CALLS_H*/\n";
|
||||
<< "#ifndef _OFW_CALLS_H\n"
|
||||
<< "#define _OFW_CALLS_H\n"
|
||||
<< wrappers.of_call
|
||||
<< "#endif/*_OFW_CALLS_H*/\n";
|
||||
|
||||
error:
|
||||
return status;
|
||||
|
|
|
@ -2,235 +2,233 @@
|
|||
// piperead.cpp
|
||||
//
|
||||
// Martin Fuchs, 30.11.2003
|
||||
//
|
||||
//
|
||||
// Jan Roeloffzen, 26.1.2010
|
||||
// Pipe client, based on msdn example
|
||||
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <errno.h>
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define PIPEREAD_VERSION "0.3"
|
||||
#define PIPEREAD_NOPIPE (-101)
|
||||
#define PIPEREAD_VERSION "0.3"
|
||||
#define PIPEREAD_NOPIPE (-101)
|
||||
|
||||
// This definition currently missing in MinGW.
|
||||
#ifndef FILE_FLAG_FIRST_PIPE_INSTANCE
|
||||
#define FILE_FLAG_FIRST_PIPE_INSTANCE 0x00080000
|
||||
#ifndef FILE_FLAG_FIRST_PIPE_INSTANCE
|
||||
#define FILE_FLAG_FIRST_PIPE_INSTANCE 0x00080000
|
||||
#endif
|
||||
|
||||
|
||||
#define BUFSIZE 1024
|
||||
#define BUFSIZE 1024
|
||||
|
||||
static void print_error(DWORD win32_error)
|
||||
{
|
||||
fprintf(stderr, "WIN32 error %lu\n", win32_error);
|
||||
fprintf(stderr, "WIN32 error %lu\n", win32_error);
|
||||
}
|
||||
|
||||
static int pipeServer(char *path)
|
||||
{
|
||||
HANDLE hPipe = CreateNamedPipe(path, PIPE_ACCESS_DUPLEX|FILE_FLAG_FIRST_PIPE_INSTANCE, PIPE_WAIT|PIPE_TYPE_BYTE, 1, 4096, 4096, 30000, NULL);
|
||||
HANDLE hPipe = CreateNamedPipe(path, PIPE_ACCESS_DUPLEX|FILE_FLAG_FIRST_PIPE_INSTANCE, PIPE_WAIT|PIPE_TYPE_BYTE, 1, 4096, 4096, 30000, NULL);
|
||||
|
||||
if (hPipe == INVALID_HANDLE_VALUE) {
|
||||
print_error(GetLastError());
|
||||
return 1;
|
||||
}
|
||||
if (hPipe == INVALID_HANDLE_VALUE) {
|
||||
print_error(GetLastError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
DWORD read;
|
||||
BYTE buffer[BUFSIZE];
|
||||
for(;;) {
|
||||
DWORD read;
|
||||
BYTE buffer[BUFSIZE];
|
||||
|
||||
if (!ReadFile(hPipe, buffer, sizeof(buffer), &read, NULL)) {
|
||||
DWORD error = GetLastError();
|
||||
if (!ReadFile(hPipe, buffer, sizeof(buffer), &read, NULL)) {
|
||||
DWORD error = GetLastError();
|
||||
|
||||
if (error == ERROR_PIPE_LISTENING) {
|
||||
Sleep(1000);
|
||||
} else if (error == ERROR_BROKEN_PIPE) {
|
||||
CloseHandle(hPipe);
|
||||
if (error == ERROR_PIPE_LISTENING) {
|
||||
Sleep(1000);
|
||||
} else if (error == ERROR_BROKEN_PIPE) {
|
||||
CloseHandle(hPipe);
|
||||
|
||||
hPipe = CreateNamedPipe(path, PIPE_ACCESS_DUPLEX|FILE_FLAG_FIRST_PIPE_INSTANCE, PIPE_WAIT|PIPE_TYPE_BYTE, 1, 4096, 4096, 30000, NULL);
|
||||
hPipe = CreateNamedPipe(path, PIPE_ACCESS_DUPLEX|FILE_FLAG_FIRST_PIPE_INSTANCE, PIPE_WAIT|PIPE_TYPE_BYTE, 1, 4096, 4096, 30000, NULL);
|
||||
|
||||
if (hPipe == INVALID_HANDLE_VALUE) {
|
||||
fprintf(stderr,"INVALID_HANDLE_VALUE\n");
|
||||
print_error(GetLastError());
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr,"error %lu\n",error);
|
||||
print_error(error);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hPipe == INVALID_HANDLE_VALUE) {
|
||||
fprintf(stderr,"INVALID_HANDLE_VALUE\n");
|
||||
print_error(GetLastError());
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr,"error %lu\n",error);
|
||||
print_error(error);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (read)
|
||||
fwrite(buffer, read, 1, stdout);
|
||||
}
|
||||
if (read)
|
||||
fwrite(buffer, read, 1, stdout);
|
||||
}
|
||||
|
||||
if (!CloseHandle(hPipe))
|
||||
print_error(GetLastError());
|
||||
if (!CloseHandle(hPipe))
|
||||
print_error(GetLastError());
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int pipeClient(char *path)
|
||||
{
|
||||
HANDLE hPipe=INVALID_HANDLE_VALUE;
|
||||
TCHAR chBuf[BUFSIZE];
|
||||
BOOL fSuccess = FALSE;
|
||||
DWORD cbRead;
|
||||
DWORD Err;
|
||||
int res = 0;
|
||||
HANDLE hPipe=INVALID_HANDLE_VALUE;
|
||||
TCHAR chBuf[BUFSIZE];
|
||||
BOOL fSuccess = FALSE;
|
||||
DWORD cbRead;
|
||||
DWORD Err;
|
||||
int res = 0;
|
||||
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
while (1) {
|
||||
hPipe = CreateFile(
|
||||
path, // pipe name
|
||||
GENERIC_READ,
|
||||
0, // no sharing
|
||||
NULL, // default security attributes
|
||||
OPEN_EXISTING, // opens existing pipe
|
||||
0, // default attributes
|
||||
NULL); // no template file
|
||||
|
||||
// Break if the pipe handle is valid.
|
||||
if (hPipe != INVALID_HANDLE_VALUE)
|
||||
break;
|
||||
|
||||
// Exit if an error other than ERROR_PIPE_BUSY occurs.
|
||||
Err = GetLastError();
|
||||
if (Err != ERROR_PIPE_BUSY) {
|
||||
if (ERROR_FILE_NOT_FOUND == Err)
|
||||
{
|
||||
res = PIPEREAD_NOPIPE;
|
||||
return res;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"Could not open pipe %s. Error=%lu\n", path, Err );
|
||||
res = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// All pipe instances are busy, so wait for 20 seconds.
|
||||
if ( ! WaitNamedPipe(path, 20000)) {
|
||||
fprintf(stderr,"Could not open pipe: 20 second wait timed out.");
|
||||
res = -2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!res) do {
|
||||
fSuccess = ReadFile(
|
||||
hPipe, // pipe handle
|
||||
chBuf, // buffer to receive reply
|
||||
BUFSIZE, // size of buffer
|
||||
&cbRead, // number of bytes read
|
||||
NULL); // not overlapped
|
||||
|
||||
if ( ! fSuccess ) {
|
||||
Err = GetLastError();
|
||||
if ( Err == ERROR_MORE_DATA ) {
|
||||
fSuccess = TRUE;
|
||||
} else {
|
||||
fprintf(stderr, "ReadFile: Error %lu \n", Err );
|
||||
res = -9;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fwrite(chBuf,1,cbRead,stdout);
|
||||
} while ( fSuccess);
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
while (1) {
|
||||
hPipe = CreateFile(path, // pipe name
|
||||
GENERIC_READ,
|
||||
0, // no sharing
|
||||
NULL, // default security attributes
|
||||
OPEN_EXISTING, // opens existing pipe
|
||||
0, // default attributes
|
||||
NULL); // no template file
|
||||
|
||||
if ( ! fSuccess) {
|
||||
fprintf(stderr, "ReadFile from pipe failed. Error=%lu\n", GetLastError() );
|
||||
}
|
||||
// Break if the pipe handle is valid.
|
||||
if (hPipe != INVALID_HANDLE_VALUE)
|
||||
break;
|
||||
|
||||
if (hPipe != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(hPipe);
|
||||
// Exit if an error other than ERROR_PIPE_BUSY occurs.
|
||||
Err = GetLastError();
|
||||
if (Err != ERROR_PIPE_BUSY) {
|
||||
if (ERROR_FILE_NOT_FOUND == Err)
|
||||
{
|
||||
res = PIPEREAD_NOPIPE;
|
||||
return res;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"Could not open pipe %s. Error=%lu\n", path, Err );
|
||||
res = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// All pipe instances are busy, so wait for 20 seconds.
|
||||
if ( ! WaitNamedPipe(path, 20000)) {
|
||||
fprintf(stderr,"Could not open pipe: 20 second wait timed out.");
|
||||
res = -2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!res) do {
|
||||
fSuccess = ReadFile(hPipe, // pipe handle
|
||||
chBuf, // buffer to receive reply
|
||||
BUFSIZE, // size of buffer
|
||||
&cbRead, // number of bytes read
|
||||
NULL); // not overlapped
|
||||
|
||||
if ( ! fSuccess ) {
|
||||
Err = GetLastError();
|
||||
if ( Err == ERROR_MORE_DATA ) {
|
||||
fSuccess = TRUE;
|
||||
} else {
|
||||
fprintf(stderr, "ReadFile: Error %lu \n", Err );
|
||||
res = -9;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fwrite(chBuf,1,cbRead,stdout);
|
||||
} while ( fSuccess);
|
||||
|
||||
if ( ! fSuccess) {
|
||||
fprintf(stderr, "ReadFile from pipe failed. Error=%lu\n", GetLastError() );
|
||||
}
|
||||
|
||||
if (hPipe != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(hPipe);
|
||||
|
||||
return res;
|
||||
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
static int fileClient(const char *path)
|
||||
{
|
||||
int res = 0;
|
||||
FILE *fin;
|
||||
int c;
|
||||
int res = 0;
|
||||
FILE *fin;
|
||||
int c;
|
||||
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
if (!(fin = fopen(path, "r"))) {
|
||||
fprintf(stderr,"Could not fopen %s (%s)\n", path, strerror(errno) );
|
||||
return -1;
|
||||
}
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
if (!(fin = fopen(path, "r"))) {
|
||||
fprintf(stderr,"Could not fopen %s (%s)\n", path, strerror(errno) );
|
||||
return -1;
|
||||
}
|
||||
|
||||
while ((c = fgetc(fin)) != EOF) {
|
||||
fputc(c, stdout);
|
||||
}
|
||||
while ((c = fgetc(fin)) != EOF) {
|
||||
fputc(c, stdout);
|
||||
}
|
||||
|
||||
fclose(fin);
|
||||
return res;
|
||||
fclose(fin);
|
||||
return res;
|
||||
}
|
||||
|
||||
void usage(void)
|
||||
{
|
||||
fprintf(stderr, "piperead " PIPEREAD_VERSION "\n\n");
|
||||
fprintf(stderr, "Usage: piperead [-c] <named pipe>\n");
|
||||
fprintf(stderr, "-c means Client mode\n");
|
||||
fprintf(stderr, "Example: piperead -c \\\\.\\pipe\\kdbg | log2lines -c\n\n");
|
||||
fprintf(stderr, "Usage: piperead [-c] <named pipe>\n");
|
||||
fprintf(stderr, "-c means Client mode\n");
|
||||
fprintf(stderr, "Example: piperead -c \\\\.\\pipe\\kdbg | log2lines -c\n\n");
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
char path[MAX_PATH];
|
||||
const char* pipe_name;
|
||||
const char* clientMode;
|
||||
int res = 0;
|
||||
char path[MAX_PATH];
|
||||
const char* pipe_name;
|
||||
const char* clientMode;
|
||||
int res = 0;
|
||||
|
||||
pipe_name = "com_1";
|
||||
clientMode = NULL;
|
||||
switch (argc) {
|
||||
case 3:
|
||||
clientMode = *++argv;
|
||||
if (strcmp(clientMode,"-c") != 0) {
|
||||
fprintf(stderr,"Invalid option: %s\n", clientMode);
|
||||
clientMode = NULL;
|
||||
res = -6;
|
||||
}
|
||||
//fall through
|
||||
case 2:
|
||||
pipe_name = *++argv;
|
||||
if (strcmp(pipe_name,"-h") == 0) {
|
||||
res = -7;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
res = -8;
|
||||
break;
|
||||
}
|
||||
if (res) {
|
||||
usage();
|
||||
return res;
|
||||
}
|
||||
pipe_name = "com_1";
|
||||
clientMode = NULL;
|
||||
switch (argc) {
|
||||
case 3:
|
||||
clientMode = *++argv;
|
||||
if (strcmp(clientMode,"-c") != 0) {
|
||||
fprintf(stderr,"Invalid option: %s\n", clientMode);
|
||||
clientMode = NULL;
|
||||
res = -6;
|
||||
}
|
||||
//fall through
|
||||
case 2:
|
||||
pipe_name = *++argv;
|
||||
if (strcmp(pipe_name,"-h") == 0) {
|
||||
res = -7;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
res = -8;
|
||||
break;
|
||||
}
|
||||
if (res) {
|
||||
usage();
|
||||
return res;
|
||||
}
|
||||
|
||||
if ( pipe_name[0] == '\\' ) {
|
||||
//assume caller specified full path
|
||||
sprintf(path, "%s", pipe_name);
|
||||
} else {
|
||||
sprintf(path, "\\\\.\\pipe\\%s", pipe_name);
|
||||
}
|
||||
if ( pipe_name[0] == '\\' ) {
|
||||
//assume caller specified full path
|
||||
sprintf(path, "%s", pipe_name);
|
||||
} else {
|
||||
sprintf(path, "\\\\.\\pipe\\%s", pipe_name);
|
||||
}
|
||||
|
||||
if ( clientMode ) {
|
||||
res = pipeClient(path);
|
||||
if (res == PIPEREAD_NOPIPE) {
|
||||
res = fileClient(pipe_name);
|
||||
}
|
||||
} else {
|
||||
res = pipeServer(path);
|
||||
}
|
||||
if ( clientMode ) {
|
||||
res = pipeClient(path);
|
||||
if (res == PIPEREAD_NOPIPE) {
|
||||
res = fileClient(pipe_name);
|
||||
}
|
||||
} else {
|
||||
res = pipeServer(path);
|
||||
}
|
||||
|
||||
return res;
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -31,221 +31,221 @@ CRITICAL_SECTION g_OutputLock;
|
|||
|
||||
void dumphex(const char *buf, int len, int pos)
|
||||
{
|
||||
int i, j;
|
||||
for(j = 0; j < len; j += 16) {
|
||||
for(i = 0; i < 16; i++) {
|
||||
if(i + j < len)
|
||||
printf("%02x%c", (unsigned char)buf[i + j], j + i + 1 == pos ? '*' : ' ');
|
||||
else
|
||||
printf(" ");
|
||||
}
|
||||
for(i = 0; i < 16; i++) {
|
||||
if(i + j < len)
|
||||
printf("%c", buf[i + j] >= ' ' ? buf[i + j] : '.');
|
||||
else
|
||||
printf(" ");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
int i, j;
|
||||
for(j = 0; j < len; j += 16) {
|
||||
for(i = 0; i < 16; i++) {
|
||||
if(i + j < len)
|
||||
printf("%02x%c", (unsigned char)buf[i + j], j + i + 1 == pos ? '*' : ' ');
|
||||
else
|
||||
printf(" ");
|
||||
}
|
||||
for(i = 0; i < 16; i++) {
|
||||
if(i + j < len)
|
||||
printf("%c", buf[i + j] >= ' ' ? buf[i + j] : '.');
|
||||
else
|
||||
printf(" ");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
enum {
|
||||
PIPEBUF_INITIAL_SIZE = 4096,
|
||||
PIPEBUF_MAX_SIZE = 16384
|
||||
PIPEBUF_INITIAL_SIZE = 4096,
|
||||
PIPEBUF_MAX_SIZE = 16384
|
||||
};
|
||||
|
||||
typedef struct _READ_OVERLAPPED {
|
||||
OVERLAPPED ReadOverlapped;
|
||||
char* Buffer;
|
||||
HANDLE Pipe, OtherPipe;
|
||||
bool Server;
|
||||
bool Connected;
|
||||
OVERLAPPED ReadOverlapped;
|
||||
char* Buffer;
|
||||
HANDLE Pipe, OtherPipe;
|
||||
bool Server;
|
||||
bool Connected;
|
||||
} READ_OVERLAPPED;
|
||||
|
||||
VOID WINAPI WritePipeCompletion(DWORD dwErrorCode, DWORD dwNumberOfBytesTransferred, LPOVERLAPPED lpOverlapped)
|
||||
{
|
||||
if(dwErrorCode) {
|
||||
EnterCriticalSection(&g_OutputLock);
|
||||
printf(lpOverlapped->hEvent ? "Server> Error %u writing to client pipe\n" : "Client> Error %u writing to server pipe\n", dwErrorCode);
|
||||
LeaveCriticalSection(&g_OutputLock);
|
||||
}
|
||||
if(dwErrorCode) {
|
||||
EnterCriticalSection(&g_OutputLock);
|
||||
printf(lpOverlapped->hEvent ? "Server> Error %u writing to client pipe\n" : "Client> Error %u writing to server pipe\n", dwErrorCode);
|
||||
LeaveCriticalSection(&g_OutputLock);
|
||||
}
|
||||
|
||||
free((void*)lpOverlapped);
|
||||
free((void*)lpOverlapped);
|
||||
}
|
||||
|
||||
VOID WINAPI ReadPipeCompletion(DWORD dwErrorCode, DWORD dwNumberOfBytesTransferred, LPOVERLAPPED lpOverlapped)
|
||||
{
|
||||
READ_OVERLAPPED* ReadOverlapped = (READ_OVERLAPPED*)lpOverlapped;
|
||||
LPOVERLAPPED WriteOverlapped;
|
||||
READ_OVERLAPPED* ReadOverlapped = (READ_OVERLAPPED*)lpOverlapped;
|
||||
LPOVERLAPPED WriteOverlapped;
|
||||
|
||||
EnterCriticalSection(&g_OutputLock);
|
||||
EnterCriticalSection(&g_OutputLock);
|
||||
|
||||
if(dwErrorCode) {
|
||||
printf(ReadOverlapped->Server ? "Server> Error %u reading from pipe\n" : "Client> Error %u reading from pipe\n", dwErrorCode);
|
||||
ReadOverlapped->Connected = false;
|
||||
} else {
|
||||
SYSTEMTIME SystemTime;
|
||||
if(dwErrorCode) {
|
||||
printf(ReadOverlapped->Server ? "Server> Error %u reading from pipe\n" : "Client> Error %u reading from pipe\n", dwErrorCode);
|
||||
ReadOverlapped->Connected = false;
|
||||
} else {
|
||||
SYSTEMTIME SystemTime;
|
||||
|
||||
GetLocalTime(&SystemTime);
|
||||
printf(ReadOverlapped->Server ? "Server> [%02u:%02u:%02u.%03u] Received %u byte message:\n" : "Client> [%02u:%02u:%02u.%03u] Received %u byte message:\n",
|
||||
SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond, SystemTime.wMilliseconds, dwNumberOfBytesTransferred);
|
||||
dumphex(ReadOverlapped->Buffer, (int)dwNumberOfBytesTransferred, -1);
|
||||
printf("\n");
|
||||
}
|
||||
GetLocalTime(&SystemTime);
|
||||
printf(ReadOverlapped->Server ? "Server> [%02u:%02u:%02u.%03u] Received %u byte message:\n" : "Client> [%02u:%02u:%02u.%03u] Received %u byte message:\n",
|
||||
SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond, SystemTime.wMilliseconds, dwNumberOfBytesTransferred);
|
||||
dumphex(ReadOverlapped->Buffer, (int)dwNumberOfBytesTransferred, -1);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&g_OutputLock);
|
||||
LeaveCriticalSection(&g_OutputLock);
|
||||
|
||||
WriteOverlapped = (LPOVERLAPPED)malloc(sizeof(OVERLAPPED)+dwNumberOfBytesTransferred);
|
||||
WriteOverlapped = (LPOVERLAPPED)malloc(sizeof(OVERLAPPED)+dwNumberOfBytesTransferred);
|
||||
|
||||
if(!WriteOverlapped)
|
||||
printf(ReadOverlapped->Server ? "Server> Out of memory\n" : "Client> Out of memory\n");
|
||||
else {
|
||||
ZeroMemory(WriteOverlapped, sizeof(OVERLAPPED));
|
||||
WriteOverlapped->hEvent = (HANDLE)ReadOverlapped->Server;
|
||||
memcpy(((char*)WriteOverlapped)+sizeof(OVERLAPPED), ReadOverlapped->Buffer, dwNumberOfBytesTransferred);
|
||||
WriteFileEx(ReadOverlapped->OtherPipe, ((char*)WriteOverlapped)+sizeof(OVERLAPPED), dwNumberOfBytesTransferred, WriteOverlapped,
|
||||
WritePipeCompletion);
|
||||
}
|
||||
if(!WriteOverlapped)
|
||||
printf(ReadOverlapped->Server ? "Server> Out of memory\n" : "Client> Out of memory\n");
|
||||
else {
|
||||
ZeroMemory(WriteOverlapped, sizeof(OVERLAPPED));
|
||||
WriteOverlapped->hEvent = (HANDLE)ReadOverlapped->Server;
|
||||
memcpy(((char*)WriteOverlapped)+sizeof(OVERLAPPED), ReadOverlapped->Buffer, dwNumberOfBytesTransferred);
|
||||
WriteFileEx(ReadOverlapped->OtherPipe, ((char*)WriteOverlapped)+sizeof(OVERLAPPED), dwNumberOfBytesTransferred, WriteOverlapped,
|
||||
WritePipeCompletion);
|
||||
}
|
||||
|
||||
if(!dwErrorCode) {
|
||||
ZeroMemory(ReadOverlapped, sizeof(OVERLAPPED));
|
||||
ReadFileEx(ReadOverlapped->Pipe, ReadOverlapped->Buffer, PIPEBUF_INITIAL_SIZE, &ReadOverlapped->ReadOverlapped, ReadPipeCompletion);
|
||||
}
|
||||
if(!dwErrorCode) {
|
||||
ZeroMemory(ReadOverlapped, sizeof(OVERLAPPED));
|
||||
ReadFileEx(ReadOverlapped->Pipe, ReadOverlapped->Buffer, PIPEBUF_INITIAL_SIZE, &ReadOverlapped->ReadOverlapped, ReadPipeCompletion);
|
||||
}
|
||||
}
|
||||
|
||||
void __cdecl pipeserver(void* param)
|
||||
{
|
||||
READ_OVERLAPPED ReadOverlapped;
|
||||
READ_OVERLAPPED ReadOverlapped;
|
||||
|
||||
ReadOverlapped.Pipe = (HANDLE)param, ReadOverlapped.OtherPipe = ReadOverlapped.Pipe == g_DebugServerPipe ? g_DebugClientPipe : g_DebugServerPipe;
|
||||
ReadOverlapped.Server = ReadOverlapped.Pipe == g_DebugServerPipe;
|
||||
ReadOverlapped.Buffer = (char*)malloc(PIPEBUF_INITIAL_SIZE);
|
||||
ReadOverlapped.Pipe = (HANDLE)param, ReadOverlapped.OtherPipe = ReadOverlapped.Pipe == g_DebugServerPipe ? g_DebugClientPipe : g_DebugServerPipe;
|
||||
ReadOverlapped.Server = ReadOverlapped.Pipe == g_DebugServerPipe;
|
||||
ReadOverlapped.Buffer = (char*)malloc(PIPEBUF_INITIAL_SIZE);
|
||||
|
||||
for(;;) {
|
||||
if(!ConnectNamedPipe(ReadOverlapped.Pipe, 0) && GetLastError() != ERROR_PIPE_CONNECTED) {
|
||||
printf(ReadOverlapped.Server ? "Server> Error %u accepting pipe connection\n" : "Client> Error %u accepting pipe connection\n",
|
||||
GetLastError());
|
||||
break;
|
||||
}
|
||||
for(;;) {
|
||||
if(!ConnectNamedPipe(ReadOverlapped.Pipe, 0) && GetLastError() != ERROR_PIPE_CONNECTED) {
|
||||
printf(ReadOverlapped.Server ? "Server> Error %u accepting pipe connection\n" : "Client> Error %u accepting pipe connection\n",
|
||||
GetLastError());
|
||||
break;
|
||||
}
|
||||
|
||||
ReadOverlapped.Connected = true;
|
||||
printf(ReadOverlapped.Server ? "Server> Connected\n" : "Client> Connected\n");
|
||||
ReadOverlapped.Connected = true;
|
||||
printf(ReadOverlapped.Server ? "Server> Connected\n" : "Client> Connected\n");
|
||||
|
||||
ZeroMemory(&ReadOverlapped.ReadOverlapped, sizeof(OVERLAPPED));
|
||||
ReadFileEx(ReadOverlapped.Pipe, ReadOverlapped.Buffer, PIPEBUF_INITIAL_SIZE, &ReadOverlapped.ReadOverlapped, ReadPipeCompletion);
|
||||
ZeroMemory(&ReadOverlapped.ReadOverlapped, sizeof(OVERLAPPED));
|
||||
ReadFileEx(ReadOverlapped.Pipe, ReadOverlapped.Buffer, PIPEBUF_INITIAL_SIZE, &ReadOverlapped.ReadOverlapped, ReadPipeCompletion);
|
||||
|
||||
do {
|
||||
SleepEx(INFINITE, TRUE);
|
||||
} while(ReadOverlapped.Connected) ;
|
||||
do {
|
||||
SleepEx(INFINITE, TRUE);
|
||||
} while(ReadOverlapped.Connected) ;
|
||||
|
||||
DisconnectNamedPipe(ReadOverlapped.Pipe);
|
||||
printf(ReadOverlapped.Server ? "Server> Disconnected\n" : "Client> Disconnected\n");
|
||||
}
|
||||
DisconnectNamedPipe(ReadOverlapped.Pipe);
|
||||
printf(ReadOverlapped.Server ? "Server> Disconnected\n" : "Client> Disconnected\n");
|
||||
}
|
||||
|
||||
printf(ReadOverlapped.Server ? "Server> Shutting down\n" : "Client> Shutting down\n");
|
||||
printf(ReadOverlapped.Server ? "Server> Shutting down\n" : "Client> Shutting down\n");
|
||||
|
||||
free(ReadOverlapped.Buffer);
|
||||
CloseHandle(ReadOverlapped.Pipe);
|
||||
SleepEx(0, TRUE);
|
||||
free(ReadOverlapped.Buffer);
|
||||
CloseHandle(ReadOverlapped.Pipe);
|
||||
SleepEx(0, TRUE);
|
||||
}
|
||||
|
||||
int main(int ac, char **av)
|
||||
{
|
||||
if(ac != 3) {
|
||||
printf("syntax: pipespy serverpipe clientpipe\n");
|
||||
return 0;
|
||||
}
|
||||
if(ac != 3) {
|
||||
printf("syntax: pipespy serverpipe clientpipe\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
g_DebugServerPipe = CreateNamedPipe(av[1], PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
|
||||
1, 4096, 4096, NMPWAIT_WAIT_FOREVER, 0);
|
||||
g_DebugServerPipe = CreateNamedPipe(av[1], PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
|
||||
1, 4096, 4096, NMPWAIT_WAIT_FOREVER, 0);
|
||||
|
||||
if(g_DebugServerPipe == INVALID_HANDLE_VALUE) {
|
||||
printf("Error %u creating server pipe\n", GetLastError());
|
||||
return 0;
|
||||
}
|
||||
if(g_DebugServerPipe == INVALID_HANDLE_VALUE) {
|
||||
printf("Error %u creating server pipe\n", GetLastError());
|
||||
return 0;
|
||||
}
|
||||
|
||||
g_DebugClientPipe = CreateNamedPipe(av[2], PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
|
||||
1, 4096, 4096, NMPWAIT_WAIT_FOREVER, 0);
|
||||
g_DebugClientPipe = CreateNamedPipe(av[2], PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
|
||||
1, 4096, 4096, NMPWAIT_WAIT_FOREVER, 0);
|
||||
|
||||
if(g_DebugClientPipe == INVALID_HANDLE_VALUE) {
|
||||
printf("Error %u creating client pipe\n", GetLastError());
|
||||
CloseHandle(g_DebugServerPipe);
|
||||
return 0;
|
||||
}
|
||||
if(g_DebugClientPipe == INVALID_HANDLE_VALUE) {
|
||||
printf("Error %u creating client pipe\n", GetLastError());
|
||||
CloseHandle(g_DebugServerPipe);
|
||||
return 0;
|
||||
}
|
||||
|
||||
InitializeCriticalSection(&g_OutputLock);
|
||||
_beginthread(pipeserver, 0, (void*)g_DebugServerPipe);
|
||||
pipeserver((void*)g_DebugClientPipe);
|
||||
DeleteCriticalSection(&g_OutputLock);
|
||||
return 0;
|
||||
InitializeCriticalSection(&g_OutputLock);
|
||||
_beginthread(pipeserver, 0, (void*)g_DebugServerPipe);
|
||||
pipeserver((void*)g_DebugClientPipe);
|
||||
DeleteCriticalSection(&g_OutputLock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
while(!Error) {
|
||||
SleepEx(0, TRUE);
|
||||
BufferPos = 0;
|
||||
while(!Error) {
|
||||
SleepEx(0, TRUE);
|
||||
BufferPos = 0;
|
||||
|
||||
if(BufferSize > PIPEBUF_MAX_SIZE) {
|
||||
char* NewBuf = (char*)realloc(Buffer, PIPEBUF_MAX_SIZE);
|
||||
if(BufferSize > PIPEBUF_MAX_SIZE) {
|
||||
char* NewBuf = (char*)realloc(Buffer, PIPEBUF_MAX_SIZE);
|
||||
|
||||
if(NewBuf) {
|
||||
Buffer = NewBuf;
|
||||
BufferSize = PIPEBUF_MAX_SIZE;
|
||||
}
|
||||
}
|
||||
if(NewBuf) {
|
||||
Buffer = NewBuf;
|
||||
BufferSize = PIPEBUF_MAX_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
char* NewBuf;
|
||||
for(;;) {
|
||||
char* NewBuf;
|
||||
|
||||
if(ReadFile(Pipe, Buffer+BufferPos, BufferSize-BufferPos, &Read, 0)) {
|
||||
BufferPos += Read;
|
||||
Error = 0;
|
||||
break;
|
||||
}
|
||||
if(ReadFile(Pipe, Buffer+BufferPos, BufferSize-BufferPos, &Read, 0)) {
|
||||
BufferPos += Read;
|
||||
Error = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
Error = GetLastError();
|
||||
Error = GetLastError();
|
||||
|
||||
printf("Error=%u read=%u\n", Error, Read);
|
||||
printf("Error=%u read=%u\n", Error, Read);
|
||||
|
||||
if(Error != ERROR_MORE_DATA) {
|
||||
printf(Server ? "Server> Error %u reading from pipe\n" : "Client> Error %u reading from pipe\n", GetLastError());
|
||||
break;
|
||||
}
|
||||
if(Error != ERROR_MORE_DATA) {
|
||||
printf(Server ? "Server> Error %u reading from pipe\n" : "Client> Error %u reading from pipe\n", GetLastError());
|
||||
break;
|
||||
}
|
||||
|
||||
NewBuf = (char*)realloc(Buffer, BufferSize << 1);
|
||||
NewBuf = (char*)realloc(Buffer, BufferSize << 1);
|
||||
|
||||
if(!NewBuf) {
|
||||
printf(Server ? "Server> Out of memory\n" : "Client> Out of memory\n");
|
||||
break;
|
||||
}
|
||||
if(!NewBuf) {
|
||||
printf(Server ? "Server> Out of memory\n" : "Client> Out of memory\n");
|
||||
break;
|
||||
}
|
||||
|
||||
BufferSize <<= 1;
|
||||
BufferPos += Read;
|
||||
Error = 0;
|
||||
}
|
||||
BufferSize <<= 1;
|
||||
BufferPos += Read;
|
||||
Error = 0;
|
||||
}
|
||||
|
||||
if(Error)
|
||||
break;
|
||||
if(Error)
|
||||
break;
|
||||
|
||||
WriteOverlapped = (LPOVERLAPPED)malloc(sizeof(OVERLAPPED)+BufferPos);
|
||||
WriteOverlapped = (LPOVERLAPPED)malloc(sizeof(OVERLAPPED)+BufferPos);
|
||||
|
||||
if(!WriteOverlapped)
|
||||
printf(Server ? "Server> Out of memory\n" : "Client> Out of memory\n");
|
||||
else {
|
||||
ZeroMemory(WriteOverlapped, sizeof(OVERLAPPED));
|
||||
memcpy(((char*)WriteOverlapped)+sizeof(OVERLAPPED), Buffer, BufferPos);
|
||||
WriteFileEx(OtherPipe, ((char*)WriteOverlapped)+sizeof(OVERLAPPED), BufferPos, WriteOverlapped, WritePipeCompletion);
|
||||
}
|
||||
if(!WriteOverlapped)
|
||||
printf(Server ? "Server> Out of memory\n" : "Client> Out of memory\n");
|
||||
else {
|
||||
ZeroMemory(WriteOverlapped, sizeof(OVERLAPPED));
|
||||
memcpy(((char*)WriteOverlapped)+sizeof(OVERLAPPED), Buffer, BufferPos);
|
||||
WriteFileEx(OtherPipe, ((char*)WriteOverlapped)+sizeof(OVERLAPPED), BufferPos, WriteOverlapped, WritePipeCompletion);
|
||||
}
|
||||
|
||||
EnterCriticalSection(&g_OutputLock);
|
||||
printf(Server ? "Server> Received %u byte message:\n" : "Client> Received %u byte message:\n", BufferPos);
|
||||
dumphex(Buffer, (int)BufferPos, -1);
|
||||
printf("\n");
|
||||
LeaveCriticalSection(&g_OutputLock);
|
||||
}
|
||||
EnterCriticalSection(&g_OutputLock);
|
||||
printf(Server ? "Server> Received %u byte message:\n" : "Client> Received %u byte message:\n", BufferPos);
|
||||
dumphex(Buffer, (int)BufferPos, -1);
|
||||
printf("\n");
|
||||
LeaveCriticalSection(&g_OutputLock);
|
||||
}
|
||||
|
||||
DisconnectNamedPipe(Pipe);
|
||||
printf(Server ? "Server> Disconnected\n" : "Client> Disconnected\n");
|
||||
DisconnectNamedPipe(Pipe);
|
||||
printf(Server ? "Server> Disconnected\n" : "Client> Disconnected\n");
|
||||
|
||||
*/
|
||||
|
|
|
@ -5,15 +5,15 @@
|
|||
//
|
||||
|
||||
//
|
||||
// Invoke as: "pipetunnel [pipe_name]",
|
||||
// for example: "pipetunnel com_2"
|
||||
// Invoke as: "pipetunnel [pipe_name]",
|
||||
// for example: "pipetunnel com_2"
|
||||
//
|
||||
// Then start up RectOS in VMWare, wait for the serial connect.
|
||||
// After that you can connect GDB using the command "target remote :9999".
|
||||
//
|
||||
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#include <winsock.h>
|
||||
|
@ -27,14 +27,14 @@
|
|||
|
||||
|
||||
// This definition currently missing in MinGW.
|
||||
#ifndef FILE_FLAG_FIRST_PIPE_INSTANCE
|
||||
#define FILE_FLAG_FIRST_PIPE_INSTANCE 0x00080000
|
||||
#ifndef FILE_FLAG_FIRST_PIPE_INSTANCE
|
||||
#define FILE_FLAG_FIRST_PIPE_INSTANCE 0x00080000
|
||||
#endif
|
||||
|
||||
|
||||
static void print_error(DWORD win32_error)
|
||||
{
|
||||
fprintf(stderr, "WIN32 error %lu\n", win32_error);
|
||||
fprintf(stderr, "WIN32 error %lu\n", win32_error);
|
||||
}
|
||||
|
||||
|
||||
|
@ -43,45 +43,45 @@ static void print_error(DWORD win32_error)
|
|||
// critical section wrapper
|
||||
struct CritSect : public CRITICAL_SECTION
|
||||
{
|
||||
CritSect()
|
||||
{
|
||||
InitializeCriticalSection(this);
|
||||
}
|
||||
CritSect()
|
||||
{
|
||||
InitializeCriticalSection(this);
|
||||
}
|
||||
|
||||
~CritSect()
|
||||
{
|
||||
DeleteCriticalSection(this);
|
||||
}
|
||||
~CritSect()
|
||||
{
|
||||
DeleteCriticalSection(this);
|
||||
}
|
||||
};
|
||||
|
||||
static void dbg_trace(char mode, const char* buffer, int l)
|
||||
{
|
||||
static char s_mode = '\0';
|
||||
static CritSect crit_sect;
|
||||
static char s_mode = '\0';
|
||||
static CritSect crit_sect;
|
||||
|
||||
EnterCriticalSection(&crit_sect);
|
||||
EnterCriticalSection(&crit_sect);
|
||||
|
||||
if (l) {
|
||||
for(const char*p=buffer; l--; ++p) {
|
||||
if (mode != s_mode) {
|
||||
putchar('\n');
|
||||
putchar(mode);
|
||||
putchar(' ');
|
||||
if (l) {
|
||||
for(const char*p=buffer; l--; ++p) {
|
||||
if (mode != s_mode) {
|
||||
putchar('\n');
|
||||
putchar(mode);
|
||||
putchar(' ');
|
||||
|
||||
s_mode = mode;
|
||||
}
|
||||
s_mode = mode;
|
||||
}
|
||||
|
||||
if (*p=='\n' || !*p /*|| *p=='#'*/) {
|
||||
/*if (*p == '#')
|
||||
putchar(*p);*/
|
||||
if (*p=='\n' || !*p /*|| *p=='#'*/) {
|
||||
/*if (*p == '#')
|
||||
putchar(*p);*/
|
||||
|
||||
s_mode = '\0';
|
||||
} else
|
||||
putchar(*p);
|
||||
}
|
||||
}
|
||||
s_mode = '\0';
|
||||
} else
|
||||
putchar(*p);
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&crit_sect);
|
||||
LeaveCriticalSection(&crit_sect);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -91,227 +91,227 @@ static SOCKET s_srv_socket = (SOCKET)-1;
|
|||
|
||||
SOCKET open_tcp_connect()
|
||||
{
|
||||
if (s_srv_socket == (SOCKET)-1) {
|
||||
SOCKADDR_IN srv_addr = {0};
|
||||
if (s_srv_socket == (SOCKET)-1) {
|
||||
SOCKADDR_IN srv_addr = {0};
|
||||
|
||||
srv_addr.sin_family = AF_INET;
|
||||
srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
srv_addr.sin_port = htons(9999);
|
||||
srv_addr.sin_family = AF_INET;
|
||||
srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
srv_addr.sin_port = htons(9999);
|
||||
|
||||
s_srv_socket = socket(PF_INET, SOCK_STREAM, 0);
|
||||
if (s_srv_socket == (SOCKET)-1) {
|
||||
perror("socket()");
|
||||
return 0;
|
||||
}
|
||||
s_srv_socket = socket(PF_INET, SOCK_STREAM, 0);
|
||||
if (s_srv_socket == (SOCKET)-1) {
|
||||
perror("socket()");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (bind(s_srv_socket, (struct sockaddr*) &srv_addr, sizeof(srv_addr)) == -1) {
|
||||
perror("bind()");
|
||||
return 0;
|
||||
}
|
||||
if (bind(s_srv_socket, (struct sockaddr*) &srv_addr, sizeof(srv_addr)) == -1) {
|
||||
perror("bind()");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (listen(s_srv_socket, 4) == -1) {
|
||||
perror("listen()");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (listen(s_srv_socket, 4) == -1) {
|
||||
perror("listen()");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
SOCKADDR_IN rem_addr;
|
||||
int rem_len = sizeof(rem_addr);
|
||||
SOCKADDR_IN rem_addr;
|
||||
int rem_len = sizeof(rem_addr);
|
||||
|
||||
for(;;) {
|
||||
SOCKET sock = accept(s_srv_socket, (struct sockaddr*)&rem_addr, &rem_len);
|
||||
for(;;) {
|
||||
SOCKET sock = accept(s_srv_socket, (struct sockaddr*)&rem_addr, &rem_len);
|
||||
|
||||
if (sock < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
if (sock < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
||||
perror("accept()");
|
||||
return 0;
|
||||
}
|
||||
perror("accept()");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return sock;
|
||||
}
|
||||
return sock;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct WriterThread
|
||||
{
|
||||
WriterThread(SOCKET sock, HANDLE hPipe)
|
||||
: _sock(sock),
|
||||
_hPipe(hPipe)
|
||||
{
|
||||
DWORD tid;
|
||||
WriterThread(SOCKET sock, HANDLE hPipe)
|
||||
: _sock(sock),
|
||||
_hPipe(hPipe)
|
||||
{
|
||||
DWORD tid;
|
||||
|
||||
HANDLE hThread = CreateThread(NULL, 0, WriterThreadRoutine, this, 0, &tid);
|
||||
HANDLE hThread = CreateThread(NULL, 0, WriterThreadRoutine, this, 0, &tid);
|
||||
|
||||
if (hThread) {
|
||||
SetThreadPriority(hThread, THREAD_PRIORITY_HIGHEST);
|
||||
if (hThread) {
|
||||
SetThreadPriority(hThread, THREAD_PRIORITY_HIGHEST);
|
||||
|
||||
CloseHandle(hThread);
|
||||
} else
|
||||
delete this;
|
||||
}
|
||||
CloseHandle(hThread);
|
||||
} else
|
||||
delete this;
|
||||
}
|
||||
|
||||
protected:
|
||||
SOCKET _sock;
|
||||
HANDLE _hPipe;
|
||||
SOCKET _sock;
|
||||
HANDLE _hPipe;
|
||||
|
||||
static DWORD WINAPI WriterThreadRoutine(LPVOID param)
|
||||
{
|
||||
WriterThread* pThis = (WriterThread*) param;
|
||||
static DWORD WINAPI WriterThreadRoutine(LPVOID param)
|
||||
{
|
||||
WriterThread* pThis = (WriterThread*) param;
|
||||
|
||||
DWORD ret = pThis->Run();
|
||||
DWORD ret = pThis->Run();
|
||||
|
||||
delete pThis;
|
||||
delete pThis;
|
||||
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
DWORD Run()
|
||||
{
|
||||
char buffer[1024];
|
||||
DWORD Run()
|
||||
{
|
||||
char buffer[1024];
|
||||
|
||||
for(;;) {
|
||||
int r = recv(_sock, buffer, sizeof(buffer), 0);
|
||||
for(;;) {
|
||||
int r = recv(_sock, buffer, sizeof(buffer), 0);
|
||||
|
||||
if (r == -1) {
|
||||
perror("recv()");
|
||||
fprintf(stderr, "debugger connection broken\n");
|
||||
_sock = (SOCKET)-1;
|
||||
return 1;
|
||||
}
|
||||
if (r == -1) {
|
||||
perror("recv()");
|
||||
fprintf(stderr, "debugger connection broken\n");
|
||||
_sock = (SOCKET)-1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (r) {
|
||||
DWORD wrote;
|
||||
if (r) {
|
||||
DWORD wrote;
|
||||
|
||||
if (!WriteFile(_hPipe, buffer, r, &wrote, NULL))
|
||||
break;
|
||||
if (!WriteFile(_hPipe, buffer, r, &wrote, NULL))
|
||||
break;
|
||||
|
||||
#ifdef _DEBUG
|
||||
dbg_trace('<', buffer, r);
|
||||
dbg_trace('<', buffer, r);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
LONG read_pipe(HANDLE hPipe, SOCKET sock)
|
||||
{
|
||||
for(;;) {
|
||||
DWORD read;
|
||||
char buffer[1024];
|
||||
for(;;) {
|
||||
DWORD read;
|
||||
char buffer[1024];
|
||||
|
||||
// wait for input data
|
||||
WaitForSingleObject(hPipe, INFINITE);
|
||||
// wait for input data
|
||||
WaitForSingleObject(hPipe, INFINITE);
|
||||
|
||||
if (!ReadFile(hPipe, buffer, sizeof(buffer), &read, NULL)) {
|
||||
DWORD error = GetLastError();
|
||||
if (!ReadFile(hPipe, buffer, sizeof(buffer), &read, NULL)) {
|
||||
DWORD error = GetLastError();
|
||||
|
||||
if (error == ERROR_PIPE_LISTENING)
|
||||
Sleep(1000);
|
||||
else
|
||||
return error;
|
||||
}
|
||||
if (error == ERROR_PIPE_LISTENING)
|
||||
Sleep(1000);
|
||||
else
|
||||
return error;
|
||||
}
|
||||
|
||||
if (read) {
|
||||
if (read) {
|
||||
#ifdef _DEBUG
|
||||
dbg_trace('>', buffer, read);
|
||||
dbg_trace('>', buffer, read);
|
||||
#endif
|
||||
|
||||
if (!send(sock, buffer, read, 0)) {
|
||||
perror("send()");
|
||||
return GetLastError();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!send(sock, buffer, read, 0)) {
|
||||
perror("send()");
|
||||
return GetLastError();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
char path[MAX_PATH];
|
||||
const char* pipe_name;
|
||||
char path[MAX_PATH];
|
||||
const char* pipe_name;
|
||||
|
||||
if (argc > 1)
|
||||
pipe_name = *++argv;
|
||||
else
|
||||
pipe_name = "com_2";
|
||||
if (argc > 1)
|
||||
pipe_name = *++argv;
|
||||
else
|
||||
pipe_name = "com_2";
|
||||
|
||||
sprintf(path, "\\\\.\\pipe\\%s", pipe_name);
|
||||
sprintf(path, "\\\\.\\pipe\\%s", pipe_name);
|
||||
|
||||
|
||||
// initialize winsock
|
||||
WSADATA wsa_data;
|
||||
// initialize winsock
|
||||
WSADATA wsa_data;
|
||||
|
||||
if (WSAStartup(MAKEWORD(2,2), &wsa_data)) {
|
||||
fprintf(stderr, "WSAStartup() failed\n");
|
||||
return 0;
|
||||
}
|
||||
if (WSAStartup(MAKEWORD(2,2), &wsa_data)) {
|
||||
fprintf(stderr, "WSAStartup() failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// increment priority to be faster than the cpu eating VMWare process
|
||||
SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
|
||||
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
|
||||
// increment priority to be faster than the cpu eating VMWare process
|
||||
SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
|
||||
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
|
||||
|
||||
|
||||
HANDLE hPipe = INVALID_HANDLE_VALUE;
|
||||
HANDLE hPipe = INVALID_HANDLE_VALUE;
|
||||
|
||||
for(;;) {
|
||||
DWORD read;
|
||||
for(;;) {
|
||||
DWORD read;
|
||||
|
||||
if (hPipe == INVALID_HANDLE_VALUE) {
|
||||
hPipe = CreateNamedPipe(path, PIPE_ACCESS_DUPLEX|FILE_FLAG_FIRST_PIPE_INSTANCE|FILE_FLAG_OVERLAPPED, PIPE_WAIT|PIPE_TYPE_BYTE, 1, 4096, 4096, 30000, NULL);
|
||||
if (hPipe == INVALID_HANDLE_VALUE) {
|
||||
hPipe = CreateNamedPipe(path, PIPE_ACCESS_DUPLEX|FILE_FLAG_FIRST_PIPE_INSTANCE|FILE_FLAG_OVERLAPPED, PIPE_WAIT|PIPE_TYPE_BYTE, 1, 4096, 4096, 30000, NULL);
|
||||
|
||||
if (hPipe == INVALID_HANDLE_VALUE) {
|
||||
print_error(GetLastError());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (hPipe == INVALID_HANDLE_VALUE) {
|
||||
print_error(GetLastError());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// wait for the client side of the pipe
|
||||
while(!ReadFile(hPipe, NULL, 0, &read, NULL) &&
|
||||
GetLastError()==ERROR_PIPE_LISTENING)
|
||||
Sleep(1000);
|
||||
// wait for the client side of the pipe
|
||||
while(!ReadFile(hPipe, NULL, 0, &read, NULL) &&
|
||||
GetLastError()==ERROR_PIPE_LISTENING)
|
||||
Sleep(1000);
|
||||
|
||||
puts("\nnamed pipe connected, now waiting for TCP connection...");
|
||||
puts("\nnamed pipe connected, now waiting for TCP connection...");
|
||||
|
||||
SOCKET sock = open_tcp_connect();
|
||||
if (sock == (SOCKET)-1)
|
||||
break;
|
||||
SOCKET sock = open_tcp_connect();
|
||||
if (sock == (SOCKET)-1)
|
||||
break;
|
||||
|
||||
puts("TCP connection established.");
|
||||
puts("TCP connection established.");
|
||||
|
||||
// launch writer thread
|
||||
new WriterThread(sock, hPipe);
|
||||
// launch writer thread
|
||||
new WriterThread(sock, hPipe);
|
||||
|
||||
// launch reader loop
|
||||
LONG error = read_pipe(hPipe, sock);
|
||||
// launch reader loop
|
||||
LONG error = read_pipe(hPipe, sock);
|
||||
|
||||
|
||||
// close TCP connectiom
|
||||
closesocket(sock);
|
||||
sock = (SOCKET)-1;
|
||||
// close TCP connectiom
|
||||
closesocket(sock);
|
||||
sock = (SOCKET)-1;
|
||||
|
||||
// close named pipe
|
||||
CloseHandle(hPipe);
|
||||
hPipe = INVALID_HANDLE_VALUE;
|
||||
// close named pipe
|
||||
CloseHandle(hPipe);
|
||||
hPipe = INVALID_HANDLE_VALUE;
|
||||
|
||||
|
||||
if (error == ERROR_BROKEN_PIPE)
|
||||
puts("\nconnection closed."); // normal connection termination
|
||||
else {
|
||||
print_error(GetLastError());
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (error == ERROR_BROKEN_PIPE)
|
||||
puts("\nconnection closed."); // normal connection termination
|
||||
else {
|
||||
print_error(GetLastError());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hPipe != INVALID_HANDLE_VALUE)
|
||||
if (!CloseHandle(hPipe))
|
||||
print_error(GetLastError());
|
||||
if (hPipe != INVALID_HANDLE_VALUE)
|
||||
if (!CloseHandle(hPipe))
|
||||
print_error(GetLastError());
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -9,166 +9,166 @@
|
|||
#endif
|
||||
|
||||
typedef struct _stub {
|
||||
char *name;
|
||||
char *origin;
|
||||
struct _stub *next;
|
||||
char *name;
|
||||
char *origin;
|
||||
struct _stub *next;
|
||||
} stub;
|
||||
|
||||
void usage( char *name ) {
|
||||
fprintf( stderr,
|
||||
"Usage: %s [-n nm] [-m make] libs...\n"
|
||||
"nm -- The command used to run nm on reactos objects\n"
|
||||
"make -- The command used to build reactos\n\n"
|
||||
"libs are import libraries (.a files) typically from\n"
|
||||
"dk/lib/nkm and dk/lib/w32\n",
|
||||
name );
|
||||
fprintf( stderr,
|
||||
"Usage: %s [-n nm] [-m make] libs...\n"
|
||||
"nm -- The command used to run nm on reactos objects\n"
|
||||
"make -- The command used to build reactos\n\n"
|
||||
"libs are import libraries (.a files) typically from\n"
|
||||
"dk/lib/nkm and dk/lib/w32\n",
|
||||
name );
|
||||
}
|
||||
|
||||
int main( int argc, char **argv ) {
|
||||
char line[1024];
|
||||
char *make = "make";
|
||||
char *nm = "nm";
|
||||
char *origin = "unknown.a";
|
||||
stub *functions = NULL, *new_f, *imports = NULL, *search;
|
||||
FILE *make_f, *nm_f;
|
||||
int i, libstart = argc;
|
||||
FILE *out = fopen("tests/stubs.tst","w");
|
||||
char line[1024];
|
||||
char *make = "make";
|
||||
char *nm = "nm";
|
||||
char *origin = "unknown.a";
|
||||
stub *functions = NULL, *new_f, *imports = NULL, *search;
|
||||
FILE *make_f, *nm_f;
|
||||
int i, libstart = argc;
|
||||
FILE *out = fopen("tests/stubs.tst","w");
|
||||
|
||||
if( argc == 1 ) {
|
||||
if( out ) fclose( out );
|
||||
usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
if( argc == 1 ) {
|
||||
if( out ) fclose( out );
|
||||
usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( !out ) {
|
||||
fprintf( stderr, "Could not write file tests/stubs.tst\n" );
|
||||
return 1;
|
||||
}
|
||||
if( !out ) {
|
||||
fprintf( stderr, "Could not write file tests/stubs.tst\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
fprintf( out, "# Automatically generated by stubgen\n" );
|
||||
fprintf( out, "# Automatically generated by stubgen\n" );
|
||||
|
||||
for( i = 1; i < argc; i++ ) {
|
||||
if( !strcmp( argv[i], "-m" ) ) {
|
||||
make = argv[i+1];
|
||||
i++;
|
||||
} else if( !strcmp( argv[i], "-n" ) ) {
|
||||
nm = argv[i+1];
|
||||
i++;
|
||||
} else { libstart = i; break; }
|
||||
}
|
||||
for( i = 1; i < argc; i++ ) {
|
||||
if( !strcmp( argv[i], "-m" ) ) {
|
||||
make = argv[i+1];
|
||||
i++;
|
||||
} else if( !strcmp( argv[i], "-n" ) ) {
|
||||
nm = argv[i+1];
|
||||
i++;
|
||||
} else { libstart = i; break; }
|
||||
}
|
||||
|
||||
snprintf( line, sizeof(line), "%s test 2>&1", make );
|
||||
make_f = popen( line, "r" );
|
||||
snprintf( line, sizeof(line), "%s test 2>&1", make );
|
||||
make_f = popen( line, "r" );
|
||||
|
||||
if( !make_f ) {
|
||||
fclose( out );
|
||||
fprintf( stderr, "Could not run %s test\n", make );
|
||||
return 1;
|
||||
}
|
||||
if( !make_f ) {
|
||||
fclose( out );
|
||||
fprintf( stderr, "Could not run %s test\n", make );
|
||||
return 1;
|
||||
}
|
||||
|
||||
while( fgets( line, sizeof(line), make_f ) ) {
|
||||
char *end_of_location;
|
||||
char *begin_q, *end_q;
|
||||
while( fgets( line, sizeof(line), make_f ) ) {
|
||||
char *end_of_location;
|
||||
char *begin_q, *end_q;
|
||||
|
||||
if( !strstr( line, "undefined reference to" ) ) continue;
|
||||
if( !strstr( line, "undefined reference to" ) ) continue;
|
||||
|
||||
end_of_location = strrchr( line, ':' );
|
||||
end_of_location = strrchr( line, ':' );
|
||||
|
||||
if( !end_of_location ) continue;
|
||||
if( !end_of_location ) continue;
|
||||
|
||||
begin_q = strchr( end_of_location, '`' );
|
||||
end_q = strchr( end_of_location, '\'' );
|
||||
begin_q = strchr( end_of_location, '`' );
|
||||
end_q = strchr( end_of_location, '\'' );
|
||||
|
||||
if( !begin_q || !end_q ) continue;
|
||||
if( !begin_q || !end_q ) continue;
|
||||
|
||||
begin_q += 2; /* skip `_ */
|
||||
begin_q += 2; /* skip `_ */
|
||||
|
||||
memmove( line, begin_q, end_q - begin_q );
|
||||
line[end_q - begin_q] = 0;
|
||||
memmove( line, begin_q, end_q - begin_q );
|
||||
line[end_q - begin_q] = 0;
|
||||
|
||||
for( new_f = functions; new_f; new_f = new_f->next )
|
||||
if( !strcmp( new_f->name, line ) ) break;
|
||||
for( new_f = functions; new_f; new_f = new_f->next )
|
||||
if( !strcmp( new_f->name, line ) ) break;
|
||||
|
||||
if( new_f ) continue;
|
||||
if( new_f ) continue;
|
||||
|
||||
new_f = (stub *)malloc( sizeof(stub) );
|
||||
if( !new_f )
|
||||
{
|
||||
fprintf( stderr, "Out of memory\n" );
|
||||
fclose( out );
|
||||
pclose( make_f );
|
||||
return 1;
|
||||
}
|
||||
new_f = (stub *)malloc( sizeof(stub) );
|
||||
if( !new_f )
|
||||
{
|
||||
fprintf( stderr, "Out of memory\n" );
|
||||
fclose( out );
|
||||
pclose( make_f );
|
||||
return 1;
|
||||
}
|
||||
|
||||
new_f->name = strdup( line );
|
||||
new_f->next = functions;
|
||||
functions = new_f;
|
||||
}
|
||||
new_f->name = strdup( line );
|
||||
new_f->next = functions;
|
||||
functions = new_f;
|
||||
}
|
||||
|
||||
/* Scan libraries and collect available import sections */
|
||||
for( i = libstart; i < argc; i++ ) {
|
||||
snprintf( line, sizeof(line), "%s %s", nm, argv[i] );
|
||||
nm_f = popen( line, "r" );
|
||||
/* Scan libraries and collect available import sections */
|
||||
for( i = libstart; i < argc; i++ ) {
|
||||
snprintf( line, sizeof(line), "%s %s", nm, argv[i] );
|
||||
nm_f = popen( line, "r" );
|
||||
|
||||
for( origin = argv[i]; *argv[i]; argv[i]++ )
|
||||
if( *argv[i] == '/' || *argv[i] == '\\' )
|
||||
origin = argv[i] + 1;
|
||||
for( origin = argv[i]; *argv[i]; argv[i]++ )
|
||||
if( *argv[i] == '/' || *argv[i] == '\\' )
|
||||
origin = argv[i] + 1;
|
||||
|
||||
|
||||
if( !nm_f ) {
|
||||
fprintf( stderr, "Could not run %s\n", line );
|
||||
continue;
|
||||
}
|
||||
if( !nm_f ) {
|
||||
fprintf( stderr, "Could not run %s\n", line );
|
||||
continue;
|
||||
}
|
||||
|
||||
while( fgets( line, sizeof(line), nm_f ) ) {
|
||||
char *import_sign, *eol;
|
||||
while( fgets( line, sizeof(line), nm_f ) ) {
|
||||
char *import_sign, *eol;
|
||||
|
||||
if( !(import_sign = strstr( line, " I " )) ) continue;
|
||||
if( !(import_sign = strstr( line, " I " )) ) continue;
|
||||
|
||||
import_sign += 3;
|
||||
while( *import_sign && isspace(*import_sign) ) import_sign++;
|
||||
import_sign += 3;
|
||||
while( *import_sign && isspace(*import_sign) ) import_sign++;
|
||||
|
||||
/* Strip ws after name */
|
||||
for( eol = import_sign; *eol && !isspace(*eol); eol++ );
|
||||
/* Strip ws after name */
|
||||
for( eol = import_sign; *eol && !isspace(*eol); eol++ );
|
||||
|
||||
*eol = 0;
|
||||
*eol = 0;
|
||||
|
||||
for( new_f = imports; new_f; new_f = new_f->next )
|
||||
if( !strcmp( new_f->name, import_sign ) ) break;
|
||||
for( new_f = imports; new_f; new_f = new_f->next )
|
||||
if( !strcmp( new_f->name, import_sign ) ) break;
|
||||
|
||||
if( new_f ) continue;
|
||||
if( new_f ) continue;
|
||||
|
||||
new_f = (stub *)malloc( sizeof(stub) );
|
||||
if( !new_f )
|
||||
{
|
||||
fprintf( stderr, "Out of memory\n" );
|
||||
fclose( out );
|
||||
pclose( make_f );
|
||||
pclose( nm_f );
|
||||
return 1;
|
||||
}
|
||||
new_f = (stub *)malloc( sizeof(stub) );
|
||||
if( !new_f )
|
||||
{
|
||||
fprintf( stderr, "Out of memory\n" );
|
||||
fclose( out );
|
||||
pclose( make_f );
|
||||
pclose( nm_f );
|
||||
return 1;
|
||||
}
|
||||
|
||||
new_f->name = strdup( import_sign + 1 );
|
||||
new_f->origin = origin;
|
||||
new_f->next = imports;
|
||||
imports = new_f;
|
||||
}
|
||||
new_f->name = strdup( import_sign + 1 );
|
||||
new_f->origin = origin;
|
||||
new_f->next = imports;
|
||||
imports = new_f;
|
||||
}
|
||||
|
||||
pclose( nm_f );
|
||||
}
|
||||
pclose( nm_f );
|
||||
}
|
||||
|
||||
/* Now we have a list of unique functions and a list of imports,
|
||||
lookup each function and output the entry from the import list. */
|
||||
for( new_f = functions; new_f; new_f = new_f->next ) {
|
||||
for( search = imports; search; search = search->next ) {
|
||||
if( !strcmp( new_f->name, search->name ) ) {
|
||||
fprintf( out, "%s %s\n", search->origin, search->name );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Now we have a list of unique functions and a list of imports,
|
||||
lookup each function and output the entry from the import list. */
|
||||
for( new_f = functions; new_f; new_f = new_f->next ) {
|
||||
for( search = imports; search; search = search->next ) {
|
||||
if( !strcmp( new_f->name, search->name ) ) {
|
||||
fprintf( out, "%s %s\n", search->origin, search->name );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose( out );
|
||||
pclose( make_f );
|
||||
return 0;
|
||||
fclose( out );
|
||||
pclose( make_f );
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* i.e. on Linux gcc and not mingw-gcc (cross-compiler).
|
||||
* It's a converter from utf-8, utf-16 (LE/BE) and utf-32 (LE/BE)
|
||||
* to utf-16 LE and especially made for automatic conversions of
|
||||
* INF-files from utf-8 to utf-16LE (so we can furthermore
|
||||
* INF-files from utf-8 to utf-16LE (so we can furthermore
|
||||
* store the INF files in utf-8 for subversion.
|
||||
*
|
||||
* Author: Matthias Kupfer (mkupfer@reactos.org)
|
||||
|
@ -20,271 +20,269 @@ using namespace std;
|
|||
|
||||
class utf_converter
|
||||
{
|
||||
public:
|
||||
// detect can detect utf-8 and both utf-16 variants, but assume utf-32 only
|
||||
// due to ambiguous BOM
|
||||
enum enc_types { detect, utf8, utf16le, utf16be, utf32le, utf32be };
|
||||
enum err_types { none, iopen, oopen, eof, read, write, decode };
|
||||
protected:
|
||||
err_types error;
|
||||
enc_types encoding;
|
||||
unsigned char buffer[4], fill, index; // need 4 char buffer for optional BOM handling
|
||||
fstream inputfile,outputfile;
|
||||
static const unsigned char utf8table[64];
|
||||
public:
|
||||
utf_converter(string ifname, string ofname, enc_types enc = detect) : error(none), encoding(enc), fill(0), index(0)
|
||||
{
|
||||
enc_types tmp_enc;
|
||||
inputfile.open(ifname.c_str(), ios::in | ios::binary);
|
||||
if (!inputfile)
|
||||
{
|
||||
error = iopen;
|
||||
return;
|
||||
}
|
||||
outputfile.open(ofname.c_str(), ios::out | ios::binary);
|
||||
if (!outputfile)
|
||||
{
|
||||
error = oopen;
|
||||
return;
|
||||
}
|
||||
tmp_enc = getBOM();
|
||||
if (enc != detect)
|
||||
{
|
||||
if (enc != tmp_enc)
|
||||
cerr << "Warning: UTF-BOM doesn't match encoding setting, but given encoding forced" << endl;
|
||||
}
|
||||
else
|
||||
encoding = tmp_enc;
|
||||
}
|
||||
err_types getError()
|
||||
{
|
||||
return error;
|
||||
}
|
||||
enc_types getBOM()
|
||||
{
|
||||
index = 0;
|
||||
/* first byte can also detect with:
|
||||
if ((buffer[0] & 0x11) || !buffer[0]))
|
||||
valid values are 0xef, 0xff, 0xfe, 0x00
|
||||
*/
|
||||
inputfile.read(reinterpret_cast<char*>(&buffer),4);
|
||||
fill =inputfile.gcount();
|
||||
// stupid utf8 bom
|
||||
if ((fill > 2) &&
|
||||
(buffer[0] == 0xef) &&
|
||||
(buffer[1] == 0xbb) &&
|
||||
(buffer[2] == 0xbf))
|
||||
{
|
||||
index += 3;
|
||||
fill -=3;
|
||||
public:
|
||||
// detect can detect utf-8 and both utf-16 variants, but assume utf-32 only
|
||||
// due to ambiguous BOM
|
||||
enum enc_types { detect, utf8, utf16le, utf16be, utf32le, utf32be };
|
||||
enum err_types { none, iopen, oopen, eof, read, write, decode };
|
||||
protected:
|
||||
err_types error;
|
||||
enc_types encoding;
|
||||
unsigned char buffer[4], fill, index; // need 4 char buffer for optional BOM handling
|
||||
fstream inputfile,outputfile;
|
||||
static const unsigned char utf8table[64];
|
||||
public:
|
||||
utf_converter(string ifname, string ofname, enc_types enc = detect) : error(none), encoding(enc), fill(0), index(0)
|
||||
{
|
||||
enc_types tmp_enc;
|
||||
inputfile.open(ifname.c_str(), ios::in | ios::binary);
|
||||
if (!inputfile)
|
||||
{
|
||||
error = iopen;
|
||||
return;
|
||||
}
|
||||
outputfile.open(ofname.c_str(), ios::out | ios::binary);
|
||||
if (!outputfile)
|
||||
{
|
||||
error = oopen;
|
||||
return;
|
||||
}
|
||||
tmp_enc = getBOM();
|
||||
if (enc != detect)
|
||||
{
|
||||
if (enc != tmp_enc)
|
||||
cerr << "Warning: UTF-BOM doesn't match encoding setting, but given encoding forced" << endl;
|
||||
}
|
||||
else
|
||||
encoding = tmp_enc;
|
||||
}
|
||||
err_types getError()
|
||||
{
|
||||
return error;
|
||||
}
|
||||
enc_types getBOM()
|
||||
{
|
||||
index = 0;
|
||||
/* first byte can also detect with:
|
||||
if ((buffer[0] & 0x11) || !buffer[0]))
|
||||
valid values are 0xef, 0xff, 0xfe, 0x00
|
||||
*/
|
||||
inputfile.read(reinterpret_cast<char*>(&buffer),4);
|
||||
fill =inputfile.gcount();
|
||||
// stupid utf8 bom
|
||||
if ((fill > 2) &&
|
||||
(buffer[0] == 0xef) &&
|
||||
(buffer[1] == 0xbb) &&
|
||||
(buffer[2] == 0xbf))
|
||||
{
|
||||
index += 3;
|
||||
fill -=3;
|
||||
#ifdef DISPLAY_DETECTED_UNICODE
|
||||
cerr << "UTF-8 BOM found" << endl;
|
||||
cerr << "UTF-8 BOM found" << endl;
|
||||
#endif
|
||||
return utf8;
|
||||
}
|
||||
if ((fill > 1) &&
|
||||
(buffer[0] == 0xfe) &&
|
||||
(buffer[1] == 0xff))
|
||||
{
|
||||
index += 2;
|
||||
fill -= 2;
|
||||
return utf8;
|
||||
}
|
||||
if ((fill > 1) &&
|
||||
(buffer[0] == 0xfe) &&
|
||||
(buffer[1] == 0xff))
|
||||
{
|
||||
index += 2;
|
||||
fill -= 2;
|
||||
#ifdef DISPLAY_DETECTED_UNICODE
|
||||
cerr << "UTF-16BE BOM found" << endl;
|
||||
cerr << "UTF-16BE BOM found" << endl;
|
||||
#endif
|
||||
return utf16be;
|
||||
}
|
||||
if ((fill > 1) &&
|
||||
(buffer[0] == 0xff) &&
|
||||
(buffer[1] == 0xfe))
|
||||
{
|
||||
if ((fill == 4) &&
|
||||
(buffer[2] == 0x00) &&
|
||||
(buffer[3] == 0x00))
|
||||
{
|
||||
cerr << "UTF Error: ambiguous BOM UTF-16 or UTF-32; assume UTF-32" << endl;
|
||||
fill = 0;
|
||||
index = 0;
|
||||
return utf32le;
|
||||
}
|
||||
fill -= 2;
|
||||
index += 2;
|
||||
return utf16be;
|
||||
}
|
||||
if ((fill > 1) &&
|
||||
(buffer[0] == 0xff) &&
|
||||
(buffer[1] == 0xfe))
|
||||
{
|
||||
if ((fill == 4) &&
|
||||
(buffer[2] == 0x00) &&
|
||||
(buffer[3] == 0x00))
|
||||
{
|
||||
cerr << "UTF Error: ambiguous BOM UTF-16 or UTF-32; assume UTF-32" << endl;
|
||||
fill = 0;
|
||||
index = 0;
|
||||
return utf32le;
|
||||
}
|
||||
fill -= 2;
|
||||
index += 2;
|
||||
#ifdef DISPLAY_DETECTED_UNICODE
|
||||
cerr << "UTF-16LE BOM found" << endl;
|
||||
cerr << "UTF-16LE BOM found" << endl;
|
||||
#endif
|
||||
return utf16le;
|
||||
}
|
||||
if ((fill == 4) &&
|
||||
(buffer[0] == 0x00) &&
|
||||
(buffer[1] == 0x00) &&
|
||||
(buffer[2] == 0xfe) &&
|
||||
(buffer[3] == 0xff))
|
||||
{
|
||||
fill = 0;
|
||||
index = 0;
|
||||
return utf16le;
|
||||
}
|
||||
if ((fill == 4) &&
|
||||
(buffer[0] == 0x00) &&
|
||||
(buffer[1] == 0x00) &&
|
||||
(buffer[2] == 0xfe) &&
|
||||
(buffer[3] == 0xff))
|
||||
{
|
||||
fill = 0;
|
||||
index = 0;
|
||||
#ifdef DISPLAY_DETECTED_UNICODE
|
||||
cerr << "UTF-32BE BOM found" << endl;
|
||||
cerr << "UTF-32BE BOM found" << endl;
|
||||
#endif
|
||||
return utf32be;
|
||||
}
|
||||
return utf8; // no valid bom so use utf8 as default
|
||||
}
|
||||
int getByte(unsigned char &c)
|
||||
{
|
||||
if (fill)
|
||||
{
|
||||
index %= 4;
|
||||
--fill;
|
||||
c = buffer[index++];
|
||||
return 1;
|
||||
} else
|
||||
{
|
||||
inputfile.read(reinterpret_cast<char*>(&c),1);
|
||||
return inputfile.gcount();
|
||||
}
|
||||
}
|
||||
int getWord(unsigned short &w)
|
||||
{
|
||||
unsigned char c[2];
|
||||
if (!getByte(c[0]))
|
||||
return 0;
|
||||
if (!getByte(c[1]))
|
||||
return 1;
|
||||
if (encoding == utf16le)
|
||||
w = c[0] | (c[1] << 8);
|
||||
else
|
||||
w = c[1] | (c[0] << 8);
|
||||
return 2;
|
||||
}
|
||||
int getDWord(wchar_t &d)
|
||||
{
|
||||
unsigned char c[4];
|
||||
for (int i=0;i<4;i++)
|
||||
if (!getByte(c[i]))
|
||||
return i;
|
||||
if (encoding == utf32le)
|
||||
d = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24);
|
||||
else
|
||||
d = c[3] | (c[2] << 8) | (c[1] << 16) | (c[0] << 24);
|
||||
return 4;
|
||||
}
|
||||
wchar_t get_wchar_t()
|
||||
{
|
||||
wchar_t ret = (wchar_t)-1;
|
||||
switch (encoding)
|
||||
{
|
||||
case detect: // if still unknwon
|
||||
encoding = utf8; // assume utf8 as default
|
||||
case utf8:
|
||||
unsigned char c, tmp;
|
||||
if (!getByte(tmp))
|
||||
return ret;
|
||||
// table for 64 bytes (all 11xxxxxx resp. >=192)
|
||||
// resulting byte is determined:
|
||||
// lower 3 bits: number of following bytes (max.8) 0=error
|
||||
// upper 5 bits: data filled with 0
|
||||
if (tmp & 0x80)
|
||||
{
|
||||
if ((tmp & 0xc0) != 0xc0)
|
||||
{
|
||||
cerr << "UTF-8 Error: invalid data byte" << endl;
|
||||
return ret;
|
||||
}
|
||||
unsigned char i = utf8table[tmp & 0x3f];
|
||||
ret = i >> 3;
|
||||
i &= 7;
|
||||
while (i--)
|
||||
{
|
||||
ret <<= 6;
|
||||
if (!getByte(c))
|
||||
return wchar_t(-1);
|
||||
ret |= c & 0x3f;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
return wchar_t(tmp);
|
||||
case utf16le:
|
||||
case utf16be:
|
||||
unsigned short w,w2;
|
||||
if (getWord(w) != 2)
|
||||
return ret;
|
||||
if ((w & 0xfc00) == 0xd800) // high surrogate first
|
||||
{
|
||||
if (getWord(w2) != 2)
|
||||
return ret;
|
||||
if ((w2 & 0xfc00) != 0xdc00)
|
||||
{
|
||||
cerr << "UTF-16 Error: invalid low surrogate" << endl;
|
||||
return ret;
|
||||
}
|
||||
return (((w & 0x3ff) + 0x40) << 10) | (w2 & 0x3ff);
|
||||
}
|
||||
return w;
|
||||
case utf32le:
|
||||
case utf32be:
|
||||
if (getDWord(ret) != 4)
|
||||
return wchar_t (-1);
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
void convert2utf16le()
|
||||
{
|
||||
wchar_t c;
|
||||
unsigned char buffer[2] = {0xff, 0xfe};
|
||||
outputfile.write(reinterpret_cast<char*>(&buffer),2); // write BOM
|
||||
c = get_wchar_t();
|
||||
while (!inputfile.eof())
|
||||
{
|
||||
buffer[0] = c & 0xff;
|
||||
buffer[1] = (c >> 8) & 0xff; // create utf16-le char
|
||||
outputfile.write(reinterpret_cast<char*>(&buffer),2); // write char
|
||||
c = get_wchar_t();
|
||||
}
|
||||
}
|
||||
~utf_converter()
|
||||
{
|
||||
if (inputfile)
|
||||
inputfile.close();
|
||||
if (outputfile)
|
||||
outputfile.close();
|
||||
}
|
||||
return utf32be;
|
||||
}
|
||||
return utf8; // no valid bom so use utf8 as default
|
||||
}
|
||||
int getByte(unsigned char &c)
|
||||
{
|
||||
if (fill)
|
||||
{
|
||||
index %= 4;
|
||||
--fill;
|
||||
c = buffer[index++];
|
||||
return 1;
|
||||
} else
|
||||
{
|
||||
inputfile.read(reinterpret_cast<char*>(&c),1);
|
||||
return inputfile.gcount();
|
||||
}
|
||||
}
|
||||
int getWord(unsigned short &w)
|
||||
{
|
||||
unsigned char c[2];
|
||||
if (!getByte(c[0]))
|
||||
return 0;
|
||||
if (!getByte(c[1]))
|
||||
return 1;
|
||||
if (encoding == utf16le)
|
||||
w = c[0] | (c[1] << 8);
|
||||
else
|
||||
w = c[1] | (c[0] << 8);
|
||||
return 2;
|
||||
}
|
||||
int getDWord(wchar_t &d)
|
||||
{
|
||||
unsigned char c[4];
|
||||
for (int i=0;i<4;i++)
|
||||
if (!getByte(c[i]))
|
||||
return i;
|
||||
if (encoding == utf32le)
|
||||
d = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24);
|
||||
else
|
||||
d = c[3] | (c[2] << 8) | (c[1] << 16) | (c[0] << 24);
|
||||
return 4;
|
||||
}
|
||||
wchar_t get_wchar_t()
|
||||
{
|
||||
wchar_t ret = (wchar_t)-1;
|
||||
switch (encoding)
|
||||
{
|
||||
case detect: // if still unknwon
|
||||
encoding = utf8; // assume utf8 as default
|
||||
case utf8:
|
||||
unsigned char c, tmp;
|
||||
if (!getByte(tmp))
|
||||
return ret;
|
||||
// table for 64 bytes (all 11xxxxxx resp. >=192)
|
||||
// resulting byte is determined:
|
||||
// lower 3 bits: number of following bytes (max.8) 0=error
|
||||
// upper 5 bits: data filled with 0
|
||||
if (tmp & 0x80)
|
||||
{
|
||||
if ((tmp & 0xc0) != 0xc0)
|
||||
{
|
||||
cerr << "UTF-8 Error: invalid data byte" << endl;
|
||||
return ret;
|
||||
}
|
||||
unsigned char i = utf8table[tmp & 0x3f];
|
||||
ret = i >> 3;
|
||||
i &= 7;
|
||||
while (i--)
|
||||
{
|
||||
ret <<= 6;
|
||||
if (!getByte(c))
|
||||
return wchar_t(-1);
|
||||
ret |= c & 0x3f;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
return wchar_t(tmp);
|
||||
case utf16le:
|
||||
case utf16be:
|
||||
unsigned short w,w2;
|
||||
if (getWord(w) != 2)
|
||||
return ret;
|
||||
if ((w & 0xfc00) == 0xd800) // high surrogate first
|
||||
{
|
||||
if (getWord(w2) != 2)
|
||||
return ret;
|
||||
if ((w2 & 0xfc00) != 0xdc00)
|
||||
{
|
||||
cerr << "UTF-16 Error: invalid low surrogate" << endl;
|
||||
return ret;
|
||||
}
|
||||
return (((w & 0x3ff) + 0x40) << 10) | (w2 & 0x3ff);
|
||||
}
|
||||
return w;
|
||||
case utf32le:
|
||||
case utf32be:
|
||||
if (getDWord(ret) != 4)
|
||||
return wchar_t (-1);
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
void convert2utf16le()
|
||||
{
|
||||
wchar_t c;
|
||||
unsigned char buffer[2] = {0xff, 0xfe};
|
||||
outputfile.write(reinterpret_cast<char*>(&buffer),2); // write BOM
|
||||
c = get_wchar_t();
|
||||
while (!inputfile.eof())
|
||||
{
|
||||
buffer[0] = c & 0xff;
|
||||
buffer[1] = (c >> 8) & 0xff; // create utf16-le char
|
||||
outputfile.write(reinterpret_cast<char*>(&buffer),2); // write char
|
||||
c = get_wchar_t();
|
||||
}
|
||||
}
|
||||
~utf_converter()
|
||||
{
|
||||
if (inputfile)
|
||||
inputfile.close();
|
||||
if (outputfile)
|
||||
outputfile.close();
|
||||
}
|
||||
};
|
||||
|
||||
const unsigned char utf_converter::utf8table[64] = {
|
||||
1, 9, 17, 25, 33, 41, 49, 57, 65, 73, 81, 89, 97, 105, 113, 121,
|
||||
129, 137, 145, 153, 161, 169, 177, 185, 193, 201, 209, 217, 225, 233, 241, 249,
|
||||
2, 10, 18, 26, 34, 42, 50, 58, 66, 74, 82, 90, 98, 106, 114, 122,
|
||||
3, 11, 19, 27, 35, 43, 51, 59, 4, 12, 20, 28, 5, 13, 6, 7
|
||||
3, 11, 19, 27, 35, 43, 51, 59, 4, 12, 20, 28, 5, 13, 6, 7
|
||||
};
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
utf_converter::err_types err;
|
||||
if (argc < 3)
|
||||
{
|
||||
cout << "usage: " << argv[0] << " inputfile outputfile" << endl;
|
||||
return -1;
|
||||
}
|
||||
utf_converter conv(argv[1],argv[2]);
|
||||
if ((err = conv.getError())!=utf_converter::none)
|
||||
{
|
||||
switch (err)
|
||||
{
|
||||
case utf_converter::iopen:
|
||||
cerr << "Couldn't open input file." << endl;
|
||||
break;
|
||||
case utf_converter::oopen:
|
||||
cerr << "Couldn't open output file." << endl;
|
||||
break;
|
||||
default:
|
||||
cerr << "Unknown error." << endl;
|
||||
}
|
||||
return -1;
|
||||
} else
|
||||
conv.convert2utf16le();
|
||||
return 0;
|
||||
utf_converter::err_types err;
|
||||
if (argc < 3)
|
||||
{
|
||||
cout << "usage: " << argv[0] << " inputfile outputfile" << endl;
|
||||
return -1;
|
||||
}
|
||||
utf_converter conv(argv[1],argv[2]);
|
||||
if ((err = conv.getError())!=utf_converter::none)
|
||||
{
|
||||
switch (err)
|
||||
{
|
||||
case utf_converter::iopen:
|
||||
cerr << "Couldn't open input file." << endl;
|
||||
break;
|
||||
case utf_converter::oopen:
|
||||
cerr << "Couldn't open output file." << endl;
|
||||
break;
|
||||
default:
|
||||
cerr << "Unknown error." << endl;
|
||||
}
|
||||
return -1;
|
||||
} else
|
||||
conv.convert2utf16le();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// vim:set ts=4 sw=4:
|
||||
|
|
Loading…
Reference in a new issue