static char *path;
static char *file;
static char *makefile;
-static char *umstubfile;
-static char *kmstubfile;
static char *exestubfile;
static char*
return 0;
}
-static char KMSTUB[] =
- "/* This file is autogenerated. */\n"
- "\n"
- "#include <roskrnl.h>\n"
- "#include <../kmregtests/kmregtests.h>\n"
- "\n"
- "typedef int (*TestRoutine)(int Command, char *Buffer);\n"
- "\n"
- "extern void RegisterTests();\n"
- "\n"
- "static PDEVICE_OBJECT KMRegTestsDeviceObject = NULL;\n"
- "static PFILE_OBJECT KMRegTestsFileObject = NULL;\n"
- "\n"
- "void AddTest(TestRoutine Routine)\n"
- "{\n"
- " UNICODE_STRING DriverName;\n"
- " IO_STATUS_BLOCK IoStatus;\n"
- " NTSTATUS Status;\n"
- " KEVENT Event;\n"
- " PIRP Irp;\n"
- "\n"
- " if (KMRegTestsDeviceObject == NULL)\n"
- " {\n"
- " RtlInitUnicodeString(&DriverName, L\"\\\\Device\\\\KMRegTests\");\n"
- " Status = IoGetDeviceObjectPointer(&DriverName, FILE_WRITE_ATTRIBUTES,\n"
- " &KMRegTestsFileObject, &KMRegTestsDeviceObject);\n"
- " if (!NT_SUCCESS(Status)) return;\n"
- " }\n"
- " KeInitializeEvent(&Event, NotificationEvent, FALSE);\n"
- " Irp = IoBuildDeviceIoControlRequest(IOCTL_KMREGTESTS_REGISTER,\n"
- " KMRegTestsDeviceObject, &Routine, sizeof(TestRoutine), NULL, 0, FALSE, &Event, &IoStatus);\n"
- " Status = IoCallDriver(KMRegTestsDeviceObject, Irp);\n"
- "}\n"
- "\n"
- "void PrepareTests()\n"
- "{\n"
- " RegisterTests();\n"
- "}\n";
-
-static char UMSTUB[] =
- "/* This file is autogenerated. */\n"
- "\n"
- "#include <windows.h>\n"
- "#define NTOS_MODE_USER\n"
- "#include <ntos.h>\n"
- "#include \"regtests.h\"\n"
- "\n"
- "PVOID\n"
- "AllocateMemory(ULONG Size)\n"
- "{\n"
- " return (PVOID) RtlAllocateHeap(RtlGetProcessHeap(), 0, Size);\n"
- "}\n"
- "\n"
- "VOID\n"
- "FreeMemory(PVOID Base)\n"
- "{\n"
- " RtlFreeHeap(RtlGetProcessHeap(), 0, Base);\n"
- "}\n"
- "\n"
- "/* This function will be called several times */\n"
- "void PrepareTests()\n"
- "{\n"
- " static int testsRegistered = 0;\n"
- " if (testsRegistered == 0)\n"
- " {\n"
- " HANDLE hEvent;\n"
- " hEvent = OpenEventW(\n"
- " EVENT_ALL_ACCESS,\n"
- " FALSE,\n"
- " L\"WinRegTests\");\n"
- " if (hEvent != NULL)\n"
- " {\n"
- " SetEvent(hEvent);\n"
- " CloseHandle(hEvent);\n"
- " testsRegistered = 1;\n"
- " InitializeTests();\n"
- " RegisterTests();\n"
- " PerformTests(NULL, NULL);\n"
- " }\n"
- " }\n"
- "}\n";
-
static char EXESTUB[] =
"/* This file is autogenerated. */\n"
"\n"
- "#include <stdio.h>\n"
- "#include <windows.h>\n"
- "#define NTOS_MODE_USER\n"
- "#include <ntos.h>\n"
"#include \"regtests.h\"\n"
"\n"
- "PVOID\n"
- "AllocateMemory(ULONG Size)\n"
- "{\n"
- " return (PVOID) RtlAllocateHeap(RtlGetProcessHeap(), 0, Size);\n"
- "}\n"
- "\n"
- "VOID\n"
- "FreeMemory(PVOID Base)\n"
- "{\n"
- " RtlFreeHeap(RtlGetProcessHeap(), 0, Base);\n"
- "}\n"
- "\n"
"void\n"
"ConsoleWrite(char *Buffer)\n"
"{\n"
"}\n"
"\n"
"int\n"
- "main()\n"
+ "mainCRTStartup(HANDLE hInstance,\n"
+ " HANDLE hPrevInstance,\n"
+ " LPSTR lpszCmdParam,\n"
+ " int nCmdShow)\n"
"{\n"
" InitializeTests();\n"
" RegisterTests();\n"
+ " SetupOnce();\n"
" PerformTests(ConsoleWrite, NULL);\n"
- " NtTerminateProcess (NtCurrentProcess(), 0);\n"
+ " _ExitProcess(0);\n"
" return 0;\n"
"}\n";
"};\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";
+ "ULONG MaxExternalDependency = ExternalDependencyCount - 1;\n";
static char HELP[] =
- "REGTESTS path file makefile [-u umstubfile] [-k kmstubfile] [-e exestubfile]\n"
+ "REGTESTS path file makefile [-e exestubfile]\n"
"REGTESTS -s stublistfile stubsfile hooksfile\n"
"\n"
" path Path to files\n"
" file Registration file to create\n"
" makefile Makefile to create\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"
- " exestubfile Optional stub for running tests internal to a module in the build environment\n"
+ " exestubfile Optional stub for running tests 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";
}
char *
-get_undecorate_name(char *buf,
+get_symbolname(char *decoratedname)
+{
+ char buf[300];
+
+ if (decoratedname[0] == '@')
+ return strdup(decoratedname);
+ strcpy(buf, "_");
+ strcat(buf, decoratedname);
+ return strdup(buf);
+}
+
+char *
+get_undecorated_name(char *buf,
char *decoratedname)
{
int start = 0;
return buf;
}
+char *
+get_forwarded_export(char *forwardedexport)
+{
+ char buf[300];
+
+ if (forwardedexport == NULL)
+ {
+ strcpy(buf, "NULL");
+ }
+ else
+ {
+ sprintf(buf, "\"%s\"", forwardedexport);
+ }
+ return strdup(buf);
+}
+
void
write_stub(FILE *stubs_out, FILE *hooks_out, char *dllname,
- char *decoratedname, unsigned int stub_index)
+ char *decoratedname_and_forward, unsigned int stub_index)
{
char buf[300];
+ char *p;
+ char *decoratedname = NULL;
+ char *forwardedexport = NULL;
+ char *symbolname = NULL;
+
+ p = strtok(decoratedname_and_forward, "=");
+ if (p != NULL)
+ {
+ decoratedname = p;
+
+ p = strtok(NULL, "=");
+ forwardedexport = p;
+ }
+ else
+ {
+ decoratedname = decoratedname_and_forward;
+ forwardedexport = decoratedname_and_forward;
+ }
- fprintf(stubs_out, ".globl _%s\n", decoratedname);
- fprintf(stubs_out, "_%s:\n", decoratedname);
+ symbolname = get_symbolname(decoratedname);
+ fprintf(stubs_out, ".globl %s\n", symbolname);
+ fprintf(stubs_out, "%s:\n", symbolname);
+ free(symbolname);
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));
+ forwardedexport = get_forwarded_export(forwardedexport);
+ fprintf(hooks_out, " {\"%s\", \"%s\", %s, NULL, NULL},\n",
+ dllname,
+ get_undecorated_name(buf, decoratedname),
+ forwardedexport);
+ free(forwardedexport);
}
void
char line[INPUT_BUFFER_SIZE];
char *s;
char *dllname;
- char *decoratedname;
+ char *decoratedname_and_forward;
int stub_index;
write_stubs_header(stubs_out);
* DLLNAME (e.g. ntdll.dll)
* DECORATED NAME (e.g. NtCreateProcess@32, @InterlockedIncrement@4 or printf)
*/
+ stub_index = 0; /* First stub has index zero */
+
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 LF.
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);
+ /* Extract the DLL name */
+ dllname = (char *) strtok(s, " \t");
+ if (dllname != NULL && strlen(dllname) > 0)
+ {
+ /*
+ * Extract the decorated function name and possibly forwarded export.
+ * Format:
+ * decoratedname=forwardedexport (no DLL name)
+ */
+ decoratedname_and_forward = (char *) strtok(NULL, " \t");
+ /* Extract the argument count */
+ write_stub(stubs_out, hooks_out, dllname, decoratedname_and_forward, stub_index);
+ stub_index++;
+ }
}
}
- write_hooks_footer(hooks_out, stub_index + 1);
+ write_hooks_footer(hooks_out, stub_index);
}
int run_stubs(int argc,
return 1;
}
- umstubfile = NULL;
- kmstubfile = NULL;
exestubfile = NULL;
for (i = 4; i < argc; i++)
{
if (argv[i][0] == '-')
{
- if (argv[i][1] == 'u')
- {
- umstubfile = convert_path(argv[++i]);
- if (umstubfile[0] == 0)
- {
- printf("Missing umstubfile\n");
- return 1;
- }
- }
- else if (argv[i][1] == 'k')
- {
- kmstubfile = convert_path(argv[++i]);
- if (kmstubfile[0] == 0)
- {
- printf("Missing kmstubfile\n");
- return 1;
- }
- }
- else if (argv[i][1] == 'e')
- {
- exestubfile = convert_path(argv[++i]);
- if (exestubfile[0] == 0)
- {
- printf("Missing exestubfile\n");
- return 1;
- }
- }
- else
- {
- printf("Unknown switch\n");
- return 1;
- }
+ if (argv[i][1] == 'e')
+ {
+ exestubfile = convert_path(argv[++i]);
+ if (exestubfile[0] == 0)
+ {
+ printf("Missing exestubfile\n");
+ return 1;
+ }
+ }
+ else
+ {
+ printf("Unknown switch -%c\n", argv[i][1]);
+ return 1;
+ }
}
}
fclose(out);
- /* User-mode stubfile */
- if (umstubfile != NULL)
- {
- if (write_file_if_changed(umstubfile, UMSTUB) != 0)
- {
- perror("Cannot create output user-mode stubfile");
- return 1;
- }
- }
-
- /* Kernel-mode stubfile */
- if (kmstubfile != NULL)
- {
- if (write_file_if_changed(kmstubfile, KMSTUB) != 0)
- {
- perror("Cannot create output kernel-mode stubfile");
- return 1;
- }
- }
-
/* Executable stubfile */
if (exestubfile != NULL)
{