mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
2004-10-02 Casper S. Hornstrup <chorns@users.sourceforge.net>
* lib/gdiplus/tests/.cvsignore: Ignore _hooks.c and _stubs.S. * lib/gdiplus/tests/Makefile (TARGET_OBJECTS): Remove passthrough.o and add _hooks.o and _stubs.o. * lib/gdiplus/tests/tests/test-1.c: Test API hooking. * regtests/shared/regtests.h: Add support for API hooking. * tools/helper.mk: Generate stubs. * tools/regtests.c: Add support for generating stubs and hooks. * lib/gdiplus/tests/passthrough.c: Remove. * lib/gdiplus/tests/stubs.tst: New file. svn path=/trunk/; revision=11147
This commit is contained in:
parent
d12bb0393c
commit
9495493fde
9 changed files with 371 additions and 62 deletions
|
@ -1,3 +1,15 @@
|
||||||
|
2004-10-02 Casper S. Hornstrup <chorns@users.sourceforge.net>
|
||||||
|
|
||||||
|
* lib/gdiplus/tests/.cvsignore: Ignore _hooks.c and _stubs.S.
|
||||||
|
* lib/gdiplus/tests/Makefile (TARGET_OBJECTS): Remove passthrough.o and
|
||||||
|
add _hooks.o and _stubs.o.
|
||||||
|
* lib/gdiplus/tests/tests/test-1.c: Test API hooking.
|
||||||
|
* regtests/shared/regtests.h: Add support for API hooking.
|
||||||
|
* tools/helper.mk: Generate stubs.
|
||||||
|
* tools/regtests.c: Add support for generating stubs and hooks.
|
||||||
|
* lib/gdiplus/tests/passthrough.c: Remove.
|
||||||
|
* lib/gdiplus/tests/stubs.tst: New file.
|
||||||
|
|
||||||
2004-09-23 Casper S. Hornstrup <chorns@users.sourceforge.net>
|
2004-09-23 Casper S. Hornstrup <chorns@users.sourceforge.net>
|
||||||
|
|
||||||
* lib/msafd/makefile (TARGET_CFLAGS): Don't define DBG.
|
* lib/msafd/makefile (TARGET_CFLAGS): Don't define DBG.
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
_hooks.c
|
||||||
_regtests.c
|
_regtests.c
|
||||||
_rtstub.c
|
_rtstub.c
|
||||||
|
_stubs.S
|
||||||
Makefile.tests
|
Makefile.tests
|
||||||
*.d
|
*.d
|
||||||
*.o
|
*.o
|
||||||
|
|
|
@ -15,20 +15,23 @@ TARGET_CFLAGS = \
|
||||||
-D__USE_W32API \
|
-D__USE_W32API \
|
||||||
-DWINVER=0x0600 \
|
-DWINVER=0x0600 \
|
||||||
-D_WIN32_WINNT=0x0501 \
|
-D_WIN32_WINNT=0x0501 \
|
||||||
-I$(REGTESTS_PATH_INC)
|
-I$(REGTESTS_PATH_INC)
|
||||||
|
|
||||||
-include Makefile.tests
|
-include Makefile.tests
|
||||||
|
|
||||||
TARGET_OBJECTS = \
|
TARGET_OBJECTS = \
|
||||||
_regtests.o \
|
_regtests.o \
|
||||||
passthrough.o \
|
_hooks.o \
|
||||||
|
_stubs.o \
|
||||||
$(addprefix tests/, $(TESTS))
|
$(addprefix tests/, $(TESTS))
|
||||||
|
|
||||||
include $(PATH_TO_TOP)/rules.mak
|
include $(PATH_TO_TOP)/rules.mak
|
||||||
|
|
||||||
include $(TOOLS_PATH)/helper.mk
|
include $(TOOLS_PATH)/helper.mk
|
||||||
|
|
||||||
|
LIBS = ../gdiplus.a
|
||||||
|
|
||||||
run: all
|
run: all
|
||||||
@$(CC) -o _runtest.exe _rtstub.o regtests.a $(SDK_PATH_LIB)/rtshared.a ../gdiplus.a
|
@$(CC) -o _runtest.exe _rtstub.o regtests.a $(SDK_PATH_LIB)/rtshared.a $(LIBS)
|
||||||
@_runtest.exe
|
@_runtest.exe
|
||||||
@$(RM) _runtest.exe
|
@$(RM) _runtest.exe
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
#include <windows.h>
|
|
||||||
#define NTOS_MODE_USER
|
|
||||||
#include <ntos.h>
|
|
||||||
#include "regtests.h"
|
|
||||||
|
|
||||||
static PVOID
|
|
||||||
GetFunction(LPSTR FileName,
|
|
||||||
LPSTR FunctionName)
|
|
||||||
{
|
|
||||||
HMODULE hModule;
|
|
||||||
PVOID Function;
|
|
||||||
|
|
||||||
hModule = GetModuleHandleA(FileName);
|
|
||||||
if (hModule != NULL)
|
|
||||||
{
|
|
||||||
Function = GetProcAddress(hModule, FunctionName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
hModule = LoadLibraryA(FileName);
|
|
||||||
if (hModule != NULL)
|
|
||||||
{
|
|
||||||
Function = GetProcAddress(hModule, FunctionName);
|
|
||||||
//FreeLibrary(hModule);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Function;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef PVOID STDCALL (*RTL_ALLOCATE_HEAP)(PVOID a1, ULONG a2, ULONG a3);
|
|
||||||
|
|
||||||
PVOID STDCALL
|
|
||||||
RtlAllocateHeap(PVOID a1,
|
|
||||||
ULONG a2,
|
|
||||||
ULONG a3)
|
|
||||||
{
|
|
||||||
RTL_ALLOCATE_HEAP p;
|
|
||||||
p = GetFunction("ntdll.dll", "RtlAllocateHeap");
|
|
||||||
return p(a1, a2, a3);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOLEAN STDCALL
|
|
||||||
RtlFreeHeap(
|
|
||||||
HANDLE heap,
|
|
||||||
ULONG flags,
|
|
||||||
PVOID ptr)
|
|
||||||
{
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
3
reactos/lib/gdiplus/tests/stubs.tst
Normal file
3
reactos/lib/gdiplus/tests/stubs.tst
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
ntdll.dll RtlAllocateHeap@12
|
||||||
|
ntdll.dll RtlFreeHeap@12
|
||||||
|
msvcrt.dll printf
|
|
@ -3,9 +3,36 @@
|
||||||
|
|
||||||
#include "regtests.h"
|
#include "regtests.h"
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
ReturnTrue()
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL MyRtlFreeHeapCalled = FALSE;
|
||||||
|
|
||||||
|
VOID STDCALL
|
||||||
|
MyRtlFreeHeap(ULONG a1, ULONG a2, ULONG a3)
|
||||||
|
{
|
||||||
|
MyRtlFreeHeapCalled = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern VOID STDCALL
|
||||||
|
RtlFreeHeap(ULONG a1, ULONG a2, ULONG a3);
|
||||||
|
|
||||||
|
HOOK Hooks[] =
|
||||||
|
{
|
||||||
|
{"RtlFreeHeap", MyRtlFreeHeap}
|
||||||
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
RunTest(char *Buffer)
|
RunTest(char *Buffer)
|
||||||
{
|
{
|
||||||
|
_SetHooks(Hooks);
|
||||||
|
RtlFreeHeap(0,0,0);
|
||||||
|
FAIL_IF_FALSE(MyRtlFreeHeapCalled, "RtlFreeHeap() must be called.");
|
||||||
|
|
||||||
|
FAIL_IF_FALSE(ReturnTrue(), "ReturnTrue() must always return TRUE.");
|
||||||
return TS_OK;
|
return TS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
* 06-07-2003 CSH Created
|
* 06-07-2003 CSH Created
|
||||||
*/
|
*/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
/* Valid values for Command parameter of TestRoutine */
|
/* Valid values for Command parameter of TestRoutine */
|
||||||
|
@ -84,3 +85,103 @@ extern VOID PerformTests(TestOutputRoutine OutputRoutine, LPSTR TestName);
|
||||||
/* Routines provided by the driver */
|
/* Routines provided by the driver */
|
||||||
extern PVOID AllocateMemory(ULONG Size);
|
extern PVOID AllocateMemory(ULONG Size);
|
||||||
extern VOID FreeMemory(PVOID Base);
|
extern VOID FreeMemory(PVOID Base);
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _API_DESCRIPTION
|
||||||
|
{
|
||||||
|
PCHAR FileName;
|
||||||
|
PCHAR FunctionName;
|
||||||
|
PVOID FunctionAddress;
|
||||||
|
PVOID MockFunctionAddress;
|
||||||
|
} API_DESCRIPTION, *PAPI_DESCRIPTION;
|
||||||
|
|
||||||
|
extern API_DESCRIPTION ExternalDependencies[];
|
||||||
|
extern ULONG MaxExternalDependency;
|
||||||
|
|
||||||
|
static inline PVOID
|
||||||
|
FrameworkGetFunction(PAPI_DESCRIPTION ApiDescription)
|
||||||
|
{
|
||||||
|
HMODULE hModule;
|
||||||
|
PVOID Function;
|
||||||
|
|
||||||
|
hModule = GetModuleHandleA(ApiDescription->FileName);
|
||||||
|
if (hModule != NULL)
|
||||||
|
{
|
||||||
|
Function = GetProcAddress(hModule, ApiDescription->FunctionName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hModule = LoadLibraryA(ApiDescription->FileName);
|
||||||
|
if (hModule != NULL)
|
||||||
|
{
|
||||||
|
Function = GetProcAddress(hModule, ApiDescription->FunctionName);
|
||||||
|
//FreeLibrary(hModule);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Function;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline PVOID STDCALL
|
||||||
|
FrameworkGetHookInternal(ULONG index)
|
||||||
|
{
|
||||||
|
PVOID address;
|
||||||
|
|
||||||
|
if (index > MaxExternalDependency)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (ExternalDependencies[index].MockFunctionAddress != NULL)
|
||||||
|
return ExternalDependencies[index].MockFunctionAddress;
|
||||||
|
|
||||||
|
if (ExternalDependencies[index].FunctionAddress != NULL)
|
||||||
|
return ExternalDependencies[index].FunctionAddress;
|
||||||
|
|
||||||
|
address = FrameworkGetFunction(&ExternalDependencies[index]);
|
||||||
|
ExternalDependencies[index].FunctionAddress = address;
|
||||||
|
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline VOID
|
||||||
|
_SetHook(PCHAR name,
|
||||||
|
PVOID address)
|
||||||
|
{
|
||||||
|
PAPI_DESCRIPTION api;
|
||||||
|
ULONG index;
|
||||||
|
|
||||||
|
for (index = 0; index <= MaxExternalDependency; index++)
|
||||||
|
{
|
||||||
|
api = &ExternalDependencies[index];
|
||||||
|
if (strcmp(api->FunctionName, name) == 0)
|
||||||
|
{
|
||||||
|
api->FunctionAddress = address;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct _HOOK
|
||||||
|
{
|
||||||
|
PCHAR FunctionName;
|
||||||
|
PVOID FunctionAddress;
|
||||||
|
} HOOK, *PHOOK;
|
||||||
|
|
||||||
|
static inline VOID
|
||||||
|
_SetHooks(PHOOK hookTable)
|
||||||
|
{
|
||||||
|
PHOOK hook;
|
||||||
|
|
||||||
|
hook = &hookTable[0];
|
||||||
|
_SetHook(hook->FunctionName,
|
||||||
|
hook->FunctionAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline VOID
|
||||||
|
_UnsetHooks(PHOOK hookTable)
|
||||||
|
{
|
||||||
|
PHOOK hook;
|
||||||
|
|
||||||
|
hook = &hookTable[0];
|
||||||
|
_SetHook(hook->FunctionName,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $Id: helper.mk,v 1.80 2004/09/16 10:25:17 gvg Exp $
|
# $Id: helper.mk,v 1.81 2004/10/02 08:44:54 chorns Exp $
|
||||||
#
|
#
|
||||||
# Helper makefile for ReactOS modules
|
# Helper makefile for ReactOS modules
|
||||||
# Variables this makefile accepts:
|
# Variables this makefile accepts:
|
||||||
|
@ -977,6 +977,7 @@ $(REGTEST_TARGETS): $(REGTEST_TESTS)
|
||||||
ifeq ($(MK_MODE),user)
|
ifeq ($(MK_MODE),user)
|
||||||
ifeq ($(TARGET_BUILDENV_TEST),yes)
|
ifeq ($(TARGET_BUILDENV_TEST),yes)
|
||||||
$(REGTESTS) ./tests/tests ./tests/_regtests.c ./tests/Makefile.tests -e ./tests/_rtstub.c
|
$(REGTESTS) ./tests/tests ./tests/_regtests.c ./tests/Makefile.tests -e ./tests/_rtstub.c
|
||||||
|
$(REGTESTS) -s ./tests/stubs.tst ./tests/_stubs.S ./tests/_hooks.c
|
||||||
else
|
else
|
||||||
$(REGTESTS) ./tests/tests ./tests/_regtests.c ./tests/Makefile.tests -u ./tests/_rtstub.c
|
$(REGTESTS) ./tests/tests ./tests/_regtests.c ./tests/Makefile.tests -u ./tests/_rtstub.c
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
|
@ -20,7 +21,6 @@
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
#include <ctype.h>
|
|
||||||
#ifndef MAX_PATH
|
#ifndef MAX_PATH
|
||||||
#define MAX_PATH 260
|
#define MAX_PATH 260
|
||||||
#endif
|
#endif
|
||||||
|
@ -556,17 +556,208 @@ static char EXESTUB[] =
|
||||||
" return 0;\n"
|
" return 0;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
|
static char STUBS_HEADER[] =
|
||||||
|
"/* This file is autogenerated. */\n"
|
||||||
|
"passthrough:\n"
|
||||||
|
" call _FrameworkGetHook@4\n"
|
||||||
|
" test %eax, %eax\n"
|
||||||
|
" je .return\n"
|
||||||
|
" jmp *%eax\n"
|
||||||
|
".return:\n"
|
||||||
|
" /* This will most likely corrupt the stack */\n"
|
||||||
|
" ret\n"
|
||||||
|
"\n";
|
||||||
|
|
||||||
|
static char HOOKS_HEADER[] =
|
||||||
|
"/* This file is autogenerated. */\n"
|
||||||
|
"#include <windows.h>\n"
|
||||||
|
"#include \"regtests.h\"\n"
|
||||||
|
"\n"
|
||||||
|
"API_DESCRIPTION ExternalDependencies[] =\n"
|
||||||
|
"{\n";
|
||||||
|
|
||||||
|
static char HOOKS_FOOTER[] =
|
||||||
|
"};\n"
|
||||||
|
"\n"
|
||||||
|
"#define ExternalDependencyCount %d\n"
|
||||||
|
"ULONG MaxExternalDependency = ExternalDependencyCount - 1;\n"
|
||||||
|
"\n"
|
||||||
|
"PVOID STDCALL\n"
|
||||||
|
"FrameworkGetHook(ULONG index)\n"
|
||||||
|
"{\n"
|
||||||
|
" return FrameworkGetHookInternal(index);\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
static char HELP[] =
|
static char HELP[] =
|
||||||
"REGTESTS path file makefile [-u umstubfile] [-k kmstubfile] [-e exestubfile]\n"
|
"REGTESTS path file makefile [-u umstubfile] [-k kmstubfile] [-e exestubfile]\n"
|
||||||
|
"REGTESTS -s stublistfile stubsfile hooksfile\n"
|
||||||
"\n"
|
"\n"
|
||||||
" path Path to files\n"
|
" path Path to files\n"
|
||||||
" file Registration file to create\n"
|
" file Registration file to create\n"
|
||||||
" makefile Makefile to create\n"
|
" makefile Makefile to create\n"
|
||||||
" umstubfile Optional stub for running tests internal to a user-mode module\n"
|
" umstubfile Optional stub for running tests internal to a user-mode module\n"
|
||||||
" kmstubfile Optional stub for running tests internal to a kernel-mode module\n"
|
" kmstubfile Optional stub for running tests internal to a kernel-mode module\n"
|
||||||
" exestubfile Optional stub for running tests internal to a module in the build environment\n";
|
" exestubfile Optional stub for running tests internal to a module in the build environment\n"
|
||||||
|
" stublistfile File with descriptions of stubs\n"
|
||||||
|
" stubsfile File with stubs to create\n"
|
||||||
|
" hooksfile File with hooks to create\n";
|
||||||
|
|
||||||
int main(int argc,
|
#define INPUT_BUFFER_SIZE 255
|
||||||
|
|
||||||
|
void
|
||||||
|
write_stubs_header(FILE * out)
|
||||||
|
{
|
||||||
|
fputs(STUBS_HEADER, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
write_hooks_header(FILE * out)
|
||||||
|
{
|
||||||
|
fputs(HOOKS_HEADER, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
write_hooks_footer(FILE *hooks_out, unsigned long nr_stubs)
|
||||||
|
{
|
||||||
|
fprintf(hooks_out, HOOKS_FOOTER, nr_stubs);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
get_undecorate_name(char *buf,
|
||||||
|
char *decoratedname)
|
||||||
|
{
|
||||||
|
int start = 0;
|
||||||
|
int end = 0;
|
||||||
|
|
||||||
|
while (start < strlen(decoratedname) && decoratedname[start] == '@')
|
||||||
|
{
|
||||||
|
start++;
|
||||||
|
}
|
||||||
|
strcpy(buf, &decoratedname[start]);
|
||||||
|
end = strlen(buf) - 1;
|
||||||
|
while (end > 0 && isdigit(buf[end]))
|
||||||
|
{
|
||||||
|
end--;
|
||||||
|
}
|
||||||
|
if (buf[end] == '@')
|
||||||
|
{
|
||||||
|
buf[end] = 0;
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
write_stub(FILE *stubs_out, FILE *hooks_out, char *dllname,
|
||||||
|
char *decoratedname, unsigned int stub_index)
|
||||||
|
{
|
||||||
|
char buf[300];
|
||||||
|
|
||||||
|
fprintf(stubs_out, ".globl _%s\n", decoratedname);
|
||||||
|
fprintf(stubs_out, "_%s:\n", decoratedname);
|
||||||
|
fprintf(stubs_out, " pushl $%d\n", stub_index);
|
||||||
|
fprintf(stubs_out, " jmp passthrough\n");
|
||||||
|
fprintf(stubs_out, "\n");
|
||||||
|
|
||||||
|
fprintf(hooks_out, " {\"%s\", \"%s\", NULL, NULL},\n",
|
||||||
|
dllname, get_undecorate_name(buf, decoratedname));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
create_stubs_and_hooks(
|
||||||
|
FILE *in,
|
||||||
|
FILE *stubs_out,
|
||||||
|
FILE *hooks_out)
|
||||||
|
{
|
||||||
|
char line[INPUT_BUFFER_SIZE];
|
||||||
|
char *s;
|
||||||
|
char *dllname;
|
||||||
|
char *decoratedname;
|
||||||
|
int stub_index;
|
||||||
|
|
||||||
|
write_stubs_header(stubs_out);
|
||||||
|
|
||||||
|
write_hooks_header(hooks_out);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Scan the database. The database is a text file; each
|
||||||
|
* line is a record, which contains data for one stub.
|
||||||
|
* Each record has two columns:
|
||||||
|
*
|
||||||
|
* DLLNAME (e.g. ntdll.dll)
|
||||||
|
* DECORATED NAME (e.g. NtCreateProcess@32, @InterlockedIncrement@4 or printf)
|
||||||
|
*/
|
||||||
|
for (
|
||||||
|
/* First stub has index zero */
|
||||||
|
stub_index = 0;
|
||||||
|
/* Go on until EOF or read zero bytes */
|
||||||
|
((!feof(in)) && (fgets(line, sizeof line, in) != NULL));
|
||||||
|
/* Next stub index */
|
||||||
|
stub_index++)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Remove, if present, the trailing CR.
|
||||||
|
* (os specific?)
|
||||||
|
*/
|
||||||
|
if ((s = (char *) strchr(line,'\r')) != NULL)
|
||||||
|
{
|
||||||
|
*s = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Skip comments (#) and empty lines.
|
||||||
|
*/
|
||||||
|
s = & line[0];
|
||||||
|
if ((*s) != '#' && (*s) != '\0')
|
||||||
|
{
|
||||||
|
/* Extract the DLL name */
|
||||||
|
dllname = (char *) strtok(s," \t");
|
||||||
|
/* Extract the decorated function name */
|
||||||
|
decoratedname = (char *) strtok(NULL," \t");
|
||||||
|
/* Extract the argument count */
|
||||||
|
write_stub(stubs_out, hooks_out, dllname, decoratedname, stub_index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
write_hooks_footer(hooks_out, stub_index + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int run_stubs(int argc,
|
||||||
|
char **argv)
|
||||||
|
{
|
||||||
|
FILE *in;
|
||||||
|
FILE *stubs_out;
|
||||||
|
FILE *hooks_out;
|
||||||
|
|
||||||
|
in = fopen(argv[2], "rb");
|
||||||
|
if (in == NULL)
|
||||||
|
{
|
||||||
|
perror("Failed to open stub description input file");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
stubs_out = fopen(argv[3], "wb");
|
||||||
|
if (stubs_out == NULL)
|
||||||
|
{
|
||||||
|
perror("Failed to open stubs output file");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
hooks_out = fopen(argv[4], "wb");
|
||||||
|
if (hooks_out == NULL)
|
||||||
|
{
|
||||||
|
perror("Failed to open hooks output file");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
create_stubs_and_hooks(in, stubs_out, hooks_out);
|
||||||
|
|
||||||
|
fclose(stubs_out);
|
||||||
|
fclose(hooks_out);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int run_registrations(int argc,
|
||||||
char **argv)
|
char **argv)
|
||||||
{
|
{
|
||||||
char buf[MAX_PATH];
|
char buf[MAX_PATH];
|
||||||
|
@ -578,7 +769,6 @@ int main(int argc,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
strcpy(buf, convert_path(argv[1]));
|
strcpy(buf, convert_path(argv[1]));
|
||||||
if (buf[strlen(buf)] != DIR_SEPARATOR_CHAR)
|
if (buf[strlen(buf)] != DIR_SEPARATOR_CHAR)
|
||||||
{
|
{
|
||||||
|
@ -728,3 +918,22 @@ int main(int argc,
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int main(int argc,
|
||||||
|
char **argv)
|
||||||
|
{
|
||||||
|
if (argc < 2)
|
||||||
|
{
|
||||||
|
puts(HELP);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(argv[1]) > 1 && argv[1][0] == '-' && argv[1][1] == 's')
|
||||||
|
{
|
||||||
|
return run_stubs(argc, argv);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return run_registrations(argc, argv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue