diff --git a/reactos/tools/spec2def/spec2def.c b/reactos/tools/spec2def/spec2def.c index 61357a2c328..73646670965 100644 --- a/reactos/tools/spec2def/spec2def.c +++ b/reactos/tools/spec2def/spec2def.c @@ -38,6 +38,7 @@ enum _ARCH typedef int (*PFNOUTLINE)(FILE *, EXPORT *); int gbMSComp = 0; int gbImportLib = 0; +int gbTracing = 0; int giArch = ARCH_X86; char *pszArchString = "i386"; char *pszArchString2; @@ -52,6 +53,9 @@ enum FL_STUB = 2, FL_NONAME = 4, FL_ORDINAL = 8, + FL_NORELAY = 16, + FL_RET64 = 32, + FL_REGISTER = 64, }; enum @@ -161,52 +165,126 @@ void OutputHeader_stub(FILE *file) { fprintf(file, "/* This file is autogenerated, do not edit. */\n\n" - "#include \n\n"); + "#include \n"); + + if (gbTracing) + { + fprintf(file, "#include \n"); + fprintf(file, "#include \n"); + fprintf(file, "WINE_DECLARE_DEBUG_CHANNEL(relay);\n"); + } + + fprintf(file, "\n"); } int OutputLine_stub(FILE *file, EXPORT *pexp) { int i; + int bRelay = 0; + int bInPrototype; if (pexp->nCallingConvention != CC_STUB && - (pexp->uFlags & FL_STUB) == 0) return 0; - - fprintf(file, "int "); - if ((giArch == ARCH_X86) && - pexp->nCallingConvention == CC_STDCALL) + (pexp->uFlags & FL_STUB) == 0) { - fprintf(file, "__stdcall "); + /* Only relay trace stdcall C functions */ + if (!gbTracing || (pexp->nCallingConvention != CC_STDCALL) + || (pexp->uFlags & FL_NORELAY) + || (pexp->strName.buf[0] == '?')) + { + return 0; + } + bRelay = 1; } - /* Check for C++ */ - if (pexp->strName.buf[0] == '?') + /* Declare the "real" function */ + if (bRelay) { - fprintf(file, "stub_function%d(", pexp->nNumber); + fprintf(file, "extern "); + bInPrototype = 1; + } + + do + { + if (pexp->uFlags & FL_REGISTER) + { + /* FIXME: Not sure this is right */ + fprintf(file, "void "); + } + else if (pexp->uFlags & FL_RET64) + { + fprintf(file, "__int64 "); + } + else + { + fprintf(file, "int "); + } + + if ((giArch == ARCH_X86) && + pexp->nCallingConvention == CC_STDCALL) + { + fprintf(file, "__stdcall "); + } + + /* Check for C++ */ + if (pexp->strName.buf[0] == '?') + { + fprintf(file, "stub_function%d(", pexp->nNumber); + } + else + { + if (!bRelay || bInPrototype) + fprintf(file, "%.*s(", pexp->strName.len, pexp->strName.buf); + else + fprintf(file, "$relaytrace$%.*s(", pexp->strName.len, pexp->strName.buf); + } + + for (i = 0; i < pexp->nArgCount; i++) + { + if (i != 0) fprintf(file, ", "); + switch (pexp->anArgs[i]) + { + case ARG_LONG: fprintf(file, "long"); break; + case ARG_PTR: fprintf(file, "void*"); break; + case ARG_STR: fprintf(file, "char*"); break; + case ARG_WSTR: fprintf(file, "wchar_t*"); break; + case ARG_DBL: fprintf(file, "double"); break; + case ARG_INT64 : fprintf(file, "__int64"); break; + case ARG_INT128 : fprintf(file, "__int128"); break; + case ARG_FLOAT: fprintf(file, "float"); break; + } + fprintf(file, " a%d", i); + } + + if (bInPrototype) + { + fprintf(file, ");\n\n"); + } + } while (bInPrototype--); + + if (!bRelay) + { + fprintf(file, ")\n{\n\tDbgPrint(\"WARNING: calling stub %.*s(", + pexp->strName.len, pexp->strName.buf); } else { - fprintf(file, "%.*s(", pexp->strName.len, pexp->strName.buf); - } - - for (i = 0; i < pexp->nArgCount; i++) - { - if (i != 0) fprintf(file, ", "); - switch (pexp->anArgs[i]) + fprintf(file, ")\n{\n"); + if (pexp->uFlags & FL_REGISTER) { - case ARG_LONG: fprintf(file, "long"); break; - case ARG_PTR: fprintf(file, "void*"); break; - case ARG_STR: fprintf(file, "char*"); break; - case ARG_WSTR: fprintf(file, "wchar_t*"); break; - case ARG_DBL: - case ARG_INT64 : fprintf(file, "__int64"); break; - case ARG_INT128 : fprintf(file, "__int128"); break; - case ARG_FLOAT: fprintf(file, "float"); break; + /* No return value */ } - fprintf(file, " a%d", i); + else if (pexp->uFlags & FL_RET64) + { + fprintf(file, "\t__int64 retval;\n"); + } + else + { + fprintf(file, "\tint retval;\n"); + } + fprintf(file, "\tif(TRACE_ON(relay))\n\t\tDPRINTF(\"%s: %.*s(", + pszDllName, pexp->strName.len, pexp->strName.buf); } - fprintf(file, ")\n{\n\tDbgPrint(\"WARNING: calling stub %.*s(", - pexp->strName.len, pexp->strName.buf); for (i = 0; i < pexp->nArgCount; i++) { @@ -246,8 +324,42 @@ OutputLine_stub(FILE *file, EXPORT *pexp) { fprintf(file, "\t__wine_spec_unimplemented_stub(\"%s\", __FUNCTION__);\n", pszDllName); } + else if (bRelay) + { + if (pexp->uFlags & FL_REGISTER) + { + fprintf(file,"\t"); + } + else + { + fprintf(file, "\tretval = "); + } + fprintf(file, "%.*s(", pexp->strName.len, pexp->strName.buf); - fprintf(file, "\treturn 0;\n}\n\n"); + for (i = 0; i < pexp->nArgCount; i++) + { + if (i != 0) fprintf(file, ", "); + fprintf(file, "a%d", i); + } + fprintf(file, ");\n"); + } + + if (!bRelay) + fprintf(file, "\treturn 0;\n}\n\n"); + else if ((pexp->uFlags & FL_REGISTER) == 0) + { + if (pexp->uFlags & FL_RET64) + { + fprintf(file, "\tif(TRACE_ON(relay))\n\t\t(\"%s: %.*s: retval = %%\"PRIx64\"\\n\", retval);\n", + pszDllName, pexp->strName.len, pexp->strName.buf); + } + else + { + fprintf(file, "\tTRACE_(relay)(\"%.*s: retval = 0x%%lx\\n\", retval);\n", + pexp->strName.len, pexp->strName.buf); + } + fprintf(file, "\treturn retval;\n}\n\n"); + } return 1; } @@ -458,11 +570,18 @@ OutputLine_def_MS(FILE *fileDest, EXPORT *pexp) /* C++ stubs are forwarded to C stubs */ fprintf(fileDest, "=stub_function%d", pexp->nNumber); } + else if (gbTracing && ((pexp->uFlags & FL_NORELAY) == 0) && (pexp->nCallingConvention == CC_STDCALL) && + (pexp->strName.buf[0] != '?')) + { + /* Redirect it to the relay-tracing trampoline */ + fprintf(fileDest, "=$relaytrace$%.*s", pexp->strName.len, pexp->strName.buf); + } } void OutputLine_def_GCC(FILE *fileDest, EXPORT *pexp) { + int bTracing = 0; /* Print the function name, with decoration for export libs */ PrintName(fileDest, pexp, &pexp->strName, gbImportLib); DbgPrint("Generating def line for '%.*s'\n", pexp->strName.len, pexp->strName.buf); @@ -483,6 +602,19 @@ OutputLine_def_GCC(FILE *fileDest, EXPORT *pexp) /* C++ stubs are forwarded to C stubs */ fprintf(fileDest, "=stub_function%d", pexp->nNumber); } + else if (gbTracing && ((pexp->uFlags & FL_NORELAY) == 0) && (pexp->nCallingConvention == CC_STDCALL) && + (pexp->strName.buf[0] != '?')) + { + /* Redirect it to the relay-tracing trampoline */ + char buf[256]; + STRING strTarget; + fprintf(fileDest, "="); + sprintf(buf, "$relaytrace$%.*s", pexp->strName.len, pexp->strName.buf); + strTarget.buf = buf; + strTarget.len = pexp->strName.len + 12; + PrintName(fileDest, pexp, &strTarget, 1); + bTracing = 1; + } /* Special handling for stdcall and fastcall */ if ((giArch == ARCH_X86) && @@ -500,7 +632,7 @@ OutputLine_def_GCC(FILE *fileDest, EXPORT *pexp) fprintf(fileDest, "==%.*s", pexp->strName.len, pexp->strName.buf); } } - else if (!pexp->strTarget.buf) + else if ((!pexp->strTarget.buf) && !(bTracing)) { /* Write a forwarder to the actual decorated symbol */ fprintf(fileDest, "="); @@ -694,11 +826,17 @@ ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine) { exp.uFlags |= FL_STUB; } - else if (CompareToken(pc, "-norelay") || - CompareToken(pc, "-register") || - CompareToken(pc, "-ret64")) + else if (CompareToken(pc, "-norelay")) { - /* silently ignore these */ + exp.uFlags |= FL_NORELAY; + } + else if (CompareToken(pc, "-ret64")) + { + exp.uFlags |= FL_RET64; + } + else if (CompareToken(pc, "-register")) + { + exp.uFlags |= FL_REGISTER; } else { @@ -862,6 +1000,9 @@ ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine) fprintf(stderr, "error: line %d, additional tokens after ')'\n", nLine); return -17; } + + /* Don't relay-trace forwarded functions */ + exp.uFlags |= FL_NORELAY; } else { @@ -886,16 +1027,17 @@ ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine) void usage(void) { - printf("syntax: spec2pdef [ ...] \n" + printf("syntax: spec2def [ ...] \n" "Possible options:\n" - " -h --help prints this screen\n" - " -l= generates an asm lib stub\n" - " -d= generates a def file\n" - " -s= generates a stub file\n" - " --ms msvc compatibility\n" - " -n= name of the dll\n" - " --implib generate a def file for an import library\n" - " -a= Set architecture to . (i386, x86_64, arm)\n"); + " -h --help prints this screen\n" + " -l= generates an asm lib stub\n" + " -d= generates a def file\n" + " -s= generates a stub file\n" + " --ms msvc compatibility\n" + " -n= name of the dll\n" + " --implib generate a def file for an import library\n" + " -a= Set architecture to . (i386, x86_64, arm)\n" + " --with-tracing generates wine-like \"+relay\" trace trampolines. (necessitates -s)\n"); } int main(int argc, char *argv[]) @@ -945,6 +1087,15 @@ int main(int argc, char *argv[]) { gbMSComp = 1; } + else if ((strcasecmp(argv[i], "--with-tracing") == 0)) + { + if (!pszStubFileName) + { + fprintf(stderr, "Error: cannot use --with-tracing without -s option.\n"); + return -1; + } + gbTracing = 1; + } else if (argv[i][1] == 'a' && argv[i][2] == '=') { pszArchString = argv[i] + 3; diff --git a/reactos/win32ss/user/ntuser/prop.c b/reactos/win32ss/user/ntuser/prop.c index 105aa8972e7..6c668818a00 100644 --- a/reactos/win32ss/user/ntuser/prop.c +++ b/reactos/win32ss/user/ntuser/prop.c @@ -19,9 +19,18 @@ IntGetProp(PWND Window, ATOM Atom) int i; ListEntry = Window->PropListHead.Flink; + for (i = 0; i < Window->PropListItems; i++ ) { Property = CONTAINING_RECORD(ListEntry, PROPERTY, PropListEntry); + + if (ListEntry == NULL) + { + ERR("Corrupted (or uninitialized?) property list for window %p. Prop count %d. Atom %d.\n", + Window, Window->PropListItems, Atom); + return NULL; + } + if (Property->Atom == Atom) { return(Property); @@ -84,16 +93,14 @@ IntRemoveWindowProp(PWND Window) { PLIST_ENTRY ListEntry; PPROPERTY Property; - int i, Count = Window->PropListItems; - ListEntry = Window->PropListHead.Flink; - for (i = 0; i < Count; i++ ) + while (!IsListEmpty(&Window->PropListHead)) { - Property = CONTAINING_RECORD(ListEntry, PROPERTY, PropListEntry); - ListEntry = ListEntry->Flink; - RemoveEntryList(&Property->PropListEntry); - UserHeapFree(Property); - Window->PropListItems--; + ListEntry = Window->PropListHead.Flink; + Property = CONTAINING_RECORD(ListEntry, PROPERTY, PropListEntry); + RemoveEntryList(&Property->PropListEntry); + UserHeapFree(Property); + Window->PropListItems--; } return; }