Remove kernel32 dependency on user32 by implementing family of k32
functions as callouts to user32.
diff --git a/dlls/kernel/Makefile.in b/dlls/kernel/Makefile.in
index ba34885..9f64aab 100644
--- a/dlls/kernel/Makefile.in
+++ b/dlls/kernel/Makefile.in
@@ -13,6 +13,7 @@
format_msg.c \
kernel_main.c \
stress.c \
+ string.c \
sync.c \
thunk.c \
time.c \
diff --git a/dlls/kernel/kernel32.spec b/dlls/kernel/kernel32.spec
index 2b23718..8201bca 100644
--- a/dlls/kernel/kernel32.spec
+++ b/dlls/kernel/kernel32.spec
@@ -26,13 +26,13 @@
7 register -i386 VxDCall6(long) VxDCall
8 register -i386 VxDCall7(long) VxDCall
9 register -i386 VxDCall8(long) VxDCall
- 10 forward k32CharToOemA user32.CharToOemA
- 11 forward k32CharToOemBuffA user32.CharToOemBuffA
- 12 forward k32OemToCharA user32.OemToCharA
- 13 forward k32OemToCharBuffA user32.OemToCharBuffA
- 14 forward k32LoadStringA user32.LoadStringA
- 15 forward k32wsprintfA user32.wsprintfA
- 16 forward k32wvsprintfA user32.wvsprintfA
+ 10 stdcall k32CharToOemA(str ptr) k32CharToOemA
+ 11 stdcall k32CharToOemBuffA(str ptr long) k32CharToOemBuffA
+ 12 stdcall k32OemToCharA(ptr ptr) k32OemToCharA
+ 13 stdcall k32OemToCharBuffA(ptr ptr long) k32OemToCharBuffA
+ 14 stdcall k32LoadStringA(long long ptr long) k32LoadStringA
+ 15 varargs k32wsprintfA(str str) k32wsprintfA
+ 16 stdcall k32wvsprintfA(ptr str ptr) k32wvsprintfA
17 register -i386 CommonUnimpStub() CommonUnimpStub
18 stdcall GetProcessDword(long long) GetProcessDword
19 stub ThunkTheTemplateHandle
diff --git a/dlls/kernel/kernel_main.c b/dlls/kernel/kernel_main.c
index 0a69fa9..2789616 100644
--- a/dlls/kernel/kernel_main.c
+++ b/dlls/kernel/kernel_main.c
@@ -110,72 +110,7 @@
*
* Entry point for kernel functions that do nothing.
*/
-LONG WINAPI KERNEL_nop(void) { return 0; }
-
-
-/***************************************************************************
- *
- * Win 2.x string functions now moved to USER
- *
- * We rather want to implement them here instead of doing Callouts
- */
-
-/***********************************************************************
- * KERNEL_AnsiNext16 (KERNEL.77)
- */
-SEGPTR WINAPI KERNEL_AnsiNext16(SEGPTR current)
+LONG WINAPI KERNEL_nop(void)
{
- return (*(char *)MapSL(current)) ? current + 1 : current;
-}
-
-/***********************************************************************
- * KERNEL_AnsiPrev16(KERNEL.78)
- */
-SEGPTR WINAPI KERNEL_AnsiPrev16( SEGPTR start, SEGPTR current )
-{
- return (current==start)?start:current-1;
-}
-
-/***********************************************************************
- * KERNEL_AnsiUpper16 (KERNEL.79)
- */
-SEGPTR WINAPI KERNEL_AnsiUpper16( SEGPTR strOrChar )
-{
- /* uppercase only one char if strOrChar < 0x10000 */
- if (HIWORD(strOrChar))
- {
- char *s = MapSL(strOrChar);
- while (*s) {
- *s = toupper(*s);
- s++;
- }
- return strOrChar;
- }
- else return toupper((char)strOrChar);
-}
-
-/***********************************************************************
- * KERNEL_AnsiLower16 (KERNEL.80)
- */
-SEGPTR WINAPI KERNEL_AnsiLower16( SEGPTR strOrChar )
-{
- /* lowercase only one char if strOrChar < 0x10000 */
- if (HIWORD(strOrChar))
- {
- char *s = MapSL(strOrChar);
- while (*s) {
- *s = tolower(*s);
- s++;
- }
- return strOrChar;
- }
- else return tolower((char)strOrChar);
-}
-
-/***********************************************************************
- * KERNEL_lstrcmp16 (KERNEL.87)
- */
-INT16 WINAPI KERNEL_lstrcmp16( LPCSTR str1, LPCSTR str2 )
-{
- return (INT16)strcmp( str1, str2 );
+ return 0;
}
diff --git a/dlls/kernel/string.c b/dlls/kernel/string.c
new file mode 100644
index 0000000..4cdd139
--- /dev/null
+++ b/dlls/kernel/string.c
@@ -0,0 +1,184 @@
+/*
+ * Kernel string functions
+ */
+
+#include <ctype.h>
+#include <string.h>
+
+#include "winbase.h"
+#include "wine/winbase16.h"
+
+
+static INT WINAPI (*pLoadStringA)(HINSTANCE, UINT, LPSTR, INT);
+static INT WINAPI (*pwvsprintfA)(LPSTR, LPCSTR, va_list);
+
+/***********************************************************************
+ * Helper for k32 family functions
+ */
+static void *user32_proc_address(const char *proc_name)
+{
+ static HMODULE hUser32;
+
+ if(!hUser32) hUser32 = LoadLibraryA("user32.dll");
+ return GetProcAddress(hUser32, proc_name);
+}
+
+
+/***********************************************************************
+ * KERNEL_lstrcmp16 (KERNEL.87)
+ */
+INT16 WINAPI KERNEL_lstrcmp16( LPCSTR str1, LPCSTR str2 )
+{
+ return (INT16)strcmp( str1, str2 );
+}
+
+
+/***********************************************************************
+ * k32CharToOemBuffA (KERNEL32.@)
+ */
+BOOL WINAPI k32CharToOemBuffA(LPCSTR s, LPSTR d, DWORD len)
+{
+ WCHAR *bufW;
+
+ if ((bufW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
+ {
+ MultiByteToWideChar( CP_ACP, 0, s, len, bufW, len );
+ WideCharToMultiByte( CP_OEMCP, 0, bufW, len, d, len, NULL, NULL );
+ HeapFree( GetProcessHeap(), 0, bufW );
+ }
+ return TRUE;
+}
+
+
+/***********************************************************************
+ * k32CharToOemA (KERNEL32.@)
+ */
+BOOL WINAPI k32CharToOemA(LPCSTR s, LPSTR d)
+{
+ if (!s || !d) return TRUE;
+ return k32CharToOemBuffA( s, d, strlen(s) + 1 );
+}
+
+
+/***********************************************************************
+ * k32OemToCharBuffA (KERNEL32.@)
+ */
+BOOL WINAPI k32OemToCharBuffA(LPCSTR s, LPSTR d, DWORD len)
+{
+ WCHAR *bufW;
+
+ if ((bufW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
+ {
+ MultiByteToWideChar( CP_OEMCP, 0, s, len, bufW, len );
+ WideCharToMultiByte( CP_ACP, 0, bufW, len, d, len, NULL, NULL );
+ HeapFree( GetProcessHeap(), 0, bufW );
+ }
+ return TRUE;
+}
+
+
+/***********************************************************************
+ * k32OemToCharA (KERNEL32.@)
+ */
+BOOL WINAPI k32OemToCharA(LPCSTR s, LPSTR d)
+{
+ return k32OemToCharBuffA( s, d, strlen(s) + 1 );
+}
+
+
+/**********************************************************************
+ * k32LoadStringA (KERNEL32.@)
+ */
+INT WINAPI k32LoadStringA(HINSTANCE instance, UINT resource_id,
+ LPSTR buffer, INT buflen)
+{
+ if(!pLoadStringA) pLoadStringA = user32_proc_address("LoadStringA");
+ return pLoadStringA(instance, resource_id, buffer, buflen);
+}
+
+
+/***********************************************************************
+ * k32wvsprintfA (KERNEL32.@)
+ */
+INT WINAPI k32wvsprintfA(LPSTR buffer, LPCSTR spec, va_list args)
+{
+ if(!pwvsprintfA) pwvsprintfA = user32_proc_address("wvsprintfA");
+ return (*pwvsprintfA)(buffer, spec, args);
+}
+
+
+/***********************************************************************
+ * k32wsprintfA (KERNEL32.@)
+ */
+INT WINAPIV k32wsprintfA(LPSTR buffer, LPCSTR spec, ...)
+{
+ va_list args;
+ INT res;
+
+ va_start(args, spec);
+ res = k32wvsprintfA(buffer, spec, args);
+ va_end(args);
+ return res;
+}
+
+
+/***************************************************************************
+ *
+ * Win 2.x string functions now moved to USER
+ *
+ * We rather want to implement them here instead of doing Callouts
+ */
+
+/***********************************************************************
+ * KERNEL_AnsiNext16 (KERNEL.77)
+ */
+SEGPTR WINAPI KERNEL_AnsiNext16(SEGPTR current)
+{
+ return (*(char *)MapSL(current)) ? current + 1 : current;
+}
+
+/***********************************************************************
+ * KERNEL_AnsiPrev16(KERNEL.78)
+ */
+SEGPTR WINAPI KERNEL_AnsiPrev16( SEGPTR start, SEGPTR current )
+{
+ return (current==start)?start:current-1;
+}
+
+/***********************************************************************
+ * KERNEL_AnsiUpper16 (KERNEL.79)
+ */
+SEGPTR WINAPI KERNEL_AnsiUpper16( SEGPTR strOrChar )
+{
+ /* uppercase only one char if strOrChar < 0x10000 */
+ if (HIWORD(strOrChar))
+ {
+ char *s = MapSL(strOrChar);
+ while (*s)
+ {
+ *s = toupper(*s);
+ s++;
+ }
+ return strOrChar;
+ }
+ else return toupper((char)strOrChar);
+}
+
+/***********************************************************************
+ * KERNEL_AnsiLower16 (KERNEL.80)
+ */
+SEGPTR WINAPI KERNEL_AnsiLower16( SEGPTR strOrChar )
+{
+ /* lowercase only one char if strOrChar < 0x10000 */
+ if (HIWORD(strOrChar))
+ {
+ char *s = MapSL(strOrChar);
+ while (*s)
+ {
+ *s = tolower(*s);
+ s++;
+ }
+ return strOrChar;
+ }
+ else return tolower((char)strOrChar);
+}