summaryrefslogtreecommitdiffstats
path: root/private/tapi/dev/sp/tsp3216/tsp3216l
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/tapi/dev/sp/tsp3216/tsp3216l
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/tapi/dev/sp/tsp3216/tsp3216l')
-rw-r--r--private/tapi/dev/sp/tsp3216/tsp3216l/debug.c135
-rw-r--r--private/tapi/dev/sp/tsp3216/tsp3216l/debug.h25
-rw-r--r--private/tapi/dev/sp/tsp3216/tsp3216l/depend.mk11
-rw-r--r--private/tapi/dev/sp/tsp3216/tsp3216l/makefile29
-rw-r--r--private/tapi/dev/sp/tsp3216/tsp3216l/makefile.def56
-rw-r--r--private/tapi/dev/sp/tsp3216/tsp3216l/sources47
-rw-r--r--private/tapi/dev/sp/tsp3216/tsp3216l/tpiint32.old760
-rw-r--r--private/tapi/dev/sp/tsp3216/tsp3216l/tsp3216l.c1282
-rw-r--r--private/tapi/dev/sp/tsp3216/tsp3216l/tsp3216l.def130
-rw-r--r--private/tapi/dev/sp/tsp3216/tsp3216l/tsp3216l.h49
-rw-r--r--private/tapi/dev/sp/tsp3216/tsp3216l/tsp3216l.mak177
-rw-r--r--private/tapi/dev/sp/tsp3216/tsp3216l/tsp3216l.rc24
12 files changed, 2725 insertions, 0 deletions
diff --git a/private/tapi/dev/sp/tsp3216/tsp3216l/debug.c b/private/tapi/dev/sp/tsp3216/tsp3216l/debug.c
new file mode 100644
index 000000000..595700d07
--- /dev/null
+++ b/private/tapi/dev/sp/tsp3216/tsp3216l/debug.c
@@ -0,0 +1,135 @@
+//
+//
+
+#if DBG
+
+
+#include <windows.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <tapi.h>
+#include "debug.h"
+
+
+
+extern TCHAR gszProviderKey[];
+extern DWORD gdwPermanentProviderID;
+
+
+
+VOID
+DbgPrt(
+ IN DWORD dwDbgLevel,
+ IN PUCHAR lpszFormat,
+ IN ...
+ )
+/*++
+
+Routine Description:
+
+ Formats the incoming debug message & calls DbgPrint
+
+Arguments:
+
+ DbgLevel - level of message verboseness
+
+ DbgMessage - printf-style format string, followed by appropriate
+ list of arguments
+
+Return Value:
+
+
+--*/
+
+{
+ static fTSP3216lDebugLevelValid = FALSE;
+ static char buf[128] = "TSP3216l: ";
+ static DWORD TSP3216lDebugLevel = 0;
+
+ if (!fTSP3216lDebugLevelValid)
+ {
+
+ DWORD dwDataSize;
+ DWORD dwDataType;
+ HKEY hKey;
+ TCHAR KeyName[128];
+
+
+ //
+ // We determine if we should translate by simply trying to retrive a
+ // value with the name of lpszDeviceClass. If we succeed, we'll
+ // translate.
+ //
+ wsprintf(KeyName, "%s%d", gszProviderKey, gdwPermanentProviderID);
+
+
+//{
+// TCHAR buf[500];
+// wsprintf(buf, "Looking in key [%s] for it", KeyName);
+// OutputDebugString(buf);
+//}
+
+ RegOpenKeyEx(
+ HKEY_LOCAL_MACHINE,
+ KeyName,
+ 0,
+ KEY_ALL_ACCESS,
+ &hKey
+ );
+
+ dwDataSize = sizeof(TSP3216lDebugLevel);
+
+ RegQueryValueEx(
+ hKey,
+ "DebugLevel",
+ 0,
+ &dwDataType,
+ (LPVOID)&TSP3216lDebugLevel,
+ &dwDataSize
+ );
+
+ RegCloseKey( hKey );
+
+
+ if ( TSP3216lDebugLevel > 0 )
+ {
+ wsprintf(
+ &buf[10],
+ "TSP3216lDebugLevel= %d\n\r",
+ TSP3216lDebugLevel);
+
+ OutputDebugString((LPSTR)buf);
+
+ fTSP3216lDebugLevelValid = TRUE;
+ }
+
+ }
+
+
+ //
+ // Is the message otherwise "low" enough to display?
+ //
+ if (dwDbgLevel <= TSP3216lDebugLevel)
+ {
+ char buf[128] = "TSP3216l: ";
+ va_list ap;
+
+
+ va_start(ap, lpszFormat);
+
+ wvsprintf (&buf[10],
+ lpszFormat,
+ ap
+ );
+
+ lstrcat (buf, "\n");
+
+ OutputDebugString(buf);
+
+ va_end(ap);
+ }
+
+ return;
+}
+
+#endif
diff --git a/private/tapi/dev/sp/tsp3216/tsp3216l/debug.h b/private/tapi/dev/sp/tsp3216/tsp3216l/debug.h
new file mode 100644
index 000000000..11abf22ec
--- /dev/null
+++ b/private/tapi/dev/sp/tsp3216/tsp3216l/debug.h
@@ -0,0 +1,25 @@
+#if DBG
+
+
+#if !WIN32
+#define IN
+#define PUCHAR char *
+#endif
+
+
+
+#define DBGOUT(arg) DbgPrt arg
+
+extern VOID
+DbgPrt(
+ IN DWORD dwDbgLevel,
+ IN PUCHAR DbgMessage,
+ IN ...
+ );
+
+#else
+
+#define DBGOUT(arg)
+
+#endif
+
diff --git a/private/tapi/dev/sp/tsp3216/tsp3216l/depend.mk b/private/tapi/dev/sp/tsp3216/tsp3216l/depend.mk
new file mode 100644
index 000000000..90679717a
--- /dev/null
+++ b/private/tapi/dev/sp/tsp3216/tsp3216l/depend.mk
@@ -0,0 +1,11 @@
+.\tapi32.obj: ..\..\script\$(VERDIR)\tapi32.asm
+
+.\tapithk.obj: ..\..\script\$(VERDIR)\tapithk.asm
+
+.\tapifthk.obj: ..\..\script\$(VERDIR)\tapifthk.asm
+
+.\tsp3216l.obj: ..\tsp3216l.c ..\debug.h
+
+.\debug.obj: ..\debug.c ..\debug.h
+
+.\tsp3216l.res: ..\tsp3216l.rc
diff --git a/private/tapi/dev/sp/tsp3216/tsp3216l/makefile b/private/tapi/dev/sp/tsp3216/tsp3216l/makefile
new file mode 100644
index 000000000..3ad36ddab
--- /dev/null
+++ b/private/tapi/dev/sp/tsp3216/tsp3216l/makefile
@@ -0,0 +1,29 @@
+!if "$(OS)" == "Windows_NT"
+
+!INCLUDE $(NTMAKEENV)\makefile.def
+
+!else
+
+##############################################################################
+#
+# tsp3216l.tsp Make file
+#
+##############################################################################
+
+#Ok, we're doing a Win9x build.
+
+ROOT=..\..\..\..\..\..
+
+VERSIONLIST=debug retail
+
+DEPENDNAME=depend.mk
+
+COMMONMKFILE=makefile.def
+
+IS_OEM=TRUE
+IS_32 = TRUE
+
+!include $(ROOT)\dev\master.mk
+
+!endif
+
diff --git a/private/tapi/dev/sp/tsp3216/tsp3216l/makefile.def b/private/tapi/dev/sp/tsp3216/tsp3216l/makefile.def
new file mode 100644
index 000000000..fe108c0cf
--- /dev/null
+++ b/private/tapi/dev/sp/tsp3216/tsp3216l/makefile.def
@@ -0,0 +1,56 @@
+ROOT=..\..\..\..\..\..\..
+
+IS_OEM=1
+MASM6=1
+IS_32 = 1
+WANT_C1032=1
+WIN32=1
+
+
+BUILDDLL=1
+DLLENTRY=DllEntryPoint
+
+
+DEPENDNAME=..\depend.mk
+
+TARGETS=tsp3216l.tsp tsp3216l.sym
+
+
+ALTSRCDIR=..\..\script\$(VERDIR)
+SRCDIR=..
+
+SYMDIR=.
+
+BUILD_COFF=1
+
+
+L32EXE=tsp3216l.tsp # Name of exe.
+L32DEF=..\tsp3216l.def # Our def file.
+L32MAP=tsp3216l.map # Our map file.
+L32SYM=tsp3216l.sym # Our sym file.
+L32RES=tsp3216l.res # Resource file.
+
+L32OBJS = tapi32.obj tapithk.obj tapifthk.obj tsp3216l.obj debug.obj
+
+L32LIBS= \
+ $(DEVROOT)\lib\kernel32.lib \
+ $(DEVROOT)\lib\advapi32.lib \
+ $(DEVROOT)\lib\wow32.lib \
+ $(DEVROOT)\lib\user32.lib
+
+
+L32FLAGS=-MAP
+
+!include $(ROOT)\dev\master.mk
+#!include $(ROOT)\win\win32\win32.mk
+
+
+#INCLUDE=..\..\script;$(ROOT)\win\thunk;$(INCLUDE)
+#INCLUDE=$(ROOT)\win\thunk;$(INCLUDE);.;..
+INCLUDE=..\..\tsp3216s;$(INCLUDE)
+
+CFLAGS=$(CFLAGS) -DWIN32=100 -DWIN_32=100 -Ox
+
+!IF "$(VERDIR)" == "debug"
+CFLAGS = $(CFLAGS) -DDBG=1
+!endif
diff --git a/private/tapi/dev/sp/tsp3216/tsp3216l/sources b/private/tapi/dev/sp/tsp3216/tsp3216l/sources
new file mode 100644
index 000000000..e9568dcca
--- /dev/null
+++ b/private/tapi/dev/sp/tsp3216/tsp3216l/sources
@@ -0,0 +1,47 @@
+!IF 0
+
+Copyright (c) 1989-1993 Microsoft Corporation
+
+Module Name:
+
+ sources.
+
+Abstract:
+
+ This file specifies the target component being built and the list of
+ sources files needed to build that component. Also specifies optional
+ compiler switches and libraries that are unique for the component being
+ built.
+
+Author:
+
+ John Rogers (JohnRo) 25-Oct-1991
+
+NOTE: Commented description of this file is in \nt\public\oak\bin\sources.tpl
+
+Revision History:
+
+!ENDIF
+
+MAJORCOMP=net
+MINORCOMP=tapi
+
+TARGETNAME=tsp3216l
+TARGETPATH=\nt\public\sdk\lib
+TARGETTYPE=PROGRAM
+TARGETLIBS=\nt\public\sdk\lib\*\kernel32.lib
+
+INCLUDES=..\..\..\inc;\nt\public\sdk\inc;.
+
+C_DEFINES=-DWINVER=0x0400
+
+USE_CRTDLL=1
+
+SOURCES=tsp3216l.c \
+ tsp3216l.rc
+
+UMTYPE=windows
+
+!IFNDEF 386_WARNING_LEVEL
+386_WARNING_LEVEL=/W3
+!ENDIF
diff --git a/private/tapi/dev/sp/tsp3216/tsp3216l/tpiint32.old b/private/tapi/dev/sp/tsp3216/tsp3216l/tpiint32.old
new file mode 100644
index 000000000..8fbf38a3e
--- /dev/null
+++ b/private/tapi/dev/sp/tsp3216/tsp3216l/tpiint32.old
@@ -0,0 +1,760 @@
+ page ,132
+ TITLE $tapii32.asm
+ .listall
+
+ .386
+ OPTION READONLY
+ option oldstructs
+
+
+ .model FLAT
+
+
+
+; .fardata callbacks
+;.data
+CALLBACK SEGMENT PARA USE32 PUBLIC ''
+
+ public LineCallbackList
+ public PhoneCallbackList
+
+LineCallbackList dd 0
+PhoneCallbackList dd 0
+
+CALLBACK_NEXT equ 0
+CALLBACK_CALLBACK equ 4
+CALLBACK_HAPP equ 8
+CALLBACK_STRUCT_SIZE equ 0ch
+
+CALLBACK ENDS
+
+
+
+;GetpWin16Lock proto APIENTRY :ptr dword
+
+
+externDef STDCALL lineInitialize16@20:near32
+externDef STDCALL lineShutdown16@4:near32
+externDef STDCALL phoneInitialize16@20:near32
+externDef STDCALL phoneShutdown16@4:near32
+
+; ; ;IsBadCodePtr proto APIENTRY :ptr dword
+; ; ;
+; ; ;GlobalAlloc PROTO NEAR APIENTRY :DWORD, :DWORD
+; ; ;GlobalLock PROTO NEAR APIENTRY :DWORD
+; ; ;GlobalHandle PROTO NEAR APIENTRY :DWORD
+; ; ;GlobalUnlock PROTO NEAR APIENTRY :DWORD
+; ; ;GlobalFree PROTO NEAR APIENTRY :DWORD
+
+AllocSLCallback PROTO NEAR APIENTRY :DWORD, :DWORD
+FreeSLCallback PROTO NEAR APIENTRY :DWORD
+Tapi32ConnectPeerSL PROTO near pszDll16:dword, pszDll32:dword
+
+
+externDef InitThkSL :near32
+externDef FdThkCommon :near32
+
+;TapiThunkInit PROTO near pCB32Tab:dword
+;TapiThunkTerminate PROTO near pCB32Tab:dword
+
+TapiThkConnectPeerLS PROTO near pszDll16:dword, pszDll32:dword
+FT_TapiFThkConnectToFlatThkPeer proto near pszDll16:dword, pszDll32:dword
+NewData PROTO near
+NewData2 PROTO near
+FreeLibrary16 PROTO NEAR STDCALL :DWORD
+
+;* externDef TapiCB32BitTable :near32
+
+
+ .data
+
+
+lp16TapiCallbackThunk dd 0
+
+
+;
+; Pointer to the Win16 heirarchical critical section.
+;
+; public Win16Lock
+;Win16Lock dd 0
+
+
+
+pszDll16 db 'TSP3216s.DLL',0
+pszDll32 db 'TSP3216l.TSP',0
+
+
+cProcessAttach dw 0 ;Count of processes attached to our lib.
+
+
+ .code THUNK32
+
+
+
+;-----------------------------------------------------------------------;
+; Tapi DLL init routine
+; We expect lReason to be either DLL_PROCESS_ATTACH/DETACH (we take
+; action on these values) or DLL_THREAD_ATTACH/DETACH (we ignore
+; and return success). If there is anything else, we need to check
+; specifically and take appropriate action.
+;-----------------------------------------------------------------------;
+DllEntryPoint proc near32 hModule:DWORD, lReason:DWORD, lContext:DWORD
+
+
+;**** invoke GetpWin16Lock, ADDR Win16Lock
+
+ mov eax, lReason
+ or eax, eax
+ jz dec_cProcess ;DLL_PROCESS_DETACH?
+ cmp eax, 1 ;DLL_PROCESS_ATTACH?
+ jne initok ;DLL_THREAD_ATTACH/DETACH (we don't do anything)
+
+
+ inc cProcessAttach ;Keep count of how many processes attach to our lib.
+
+; Do once-only initialization.
+;
+; mov al, 0
+; xchg al, fFirstTime
+; or al, al
+; jnz initThunk
+
+ cmp cProcessAttach, 1
+ jne initok
+
+; This means that we've done our once only initialization before, but
+; that cProcessAttach went down to zero at some point and is now back
+; to 1. When cProcessAttach becomes 0, TapiThunkTerminate gets called
+; which frees up our thunk table (by calling UnRegisterCBClient). So
+; now we need to do that initialization again by calling TapiThunkInit.
+; pushd offset TapiCB32BitTable
+; call TapiThunkInit
+; jmp initok
+
+
+initThunk:
+ invoke TapiThkConnectPeerLS, ADDR pszDll16, ADDR pszDll32
+ or eax,eax
+ jz exit
+
+; Now call our first thunk to further initialize.
+;******************* pushd offset TapiCB32BitTable
+;******************* call TapiThunkInit
+
+; Initialize the flat thunks.
+ invoke FT_TapiFThkConnectToFlatThkPeer, ADDR pszDll16, ADDR pszDll32
+ or eax,eax
+ jz exit
+
+; Initialize the 16->32 thunks.
+ invoke Tapi32ConnectPeerSL, ADDR pszDll16, ADDR pszDll32
+ or eax,eax
+ jz exit
+
+ invoke NewData2
+ mov word ptr lp16TapiCallbackThunk+2, dx
+ mov word ptr lp16TapiCallbackThunk , ax
+
+ jmp initok
+
+
+dec_cProcess:
+
+;* pushd offset TapiCB32BitTable
+;* call TapiThunkTerminate ;needed just for UnRegisterCBClient
+
+
+;
+; Well, we know we have to get rid of all inits and thunk callbacks for
+; this process...
+;
+
+;********************************** free all the callback thunks
+; ; ; ;
+; ; ; ; Run the linked list of callbacks & free 'em all.
+; ; ; ;
+; ; ;
+; ; ; push ebx ; Be polite and save this.
+; ; ;
+; ; ; mov ebx, LineCallbackList ; Get the line list anchor
+; ; ;
+; ; ;FreeEmAll:
+; ; ; or ebx, ebx ; At last entry?
+; ; ; jz DoneFreez ; Yup, go away.
+; ; ;
+; ; ; ;
+; ; ; ; Call lineShutdown on this behalf
+; ; ; ;
+; ; ; push ebx ; Save this - just in case
+; ; ; push [ebx+CALLBACK_HAPP] ; Push the hLineApp
+; ; ; call lineShutdown16@4 ; Shut em down.
+; ; ; pop ebx ; Get back our value.
+; ; ;
+; ; ; push [ebx+CALLBACK_CALLBACK] ; Push the thunk thing.
+; ; ; call FreeSLCallback ; Be free...
+; ; ;
+; ; ; push ebx ; Use this before freeing it.
+; ; ;
+; ; ; mov ebx, [ebx+CALLBACK_NEXT] ; Get next node in the list.
+; ; ;
+; ; ; ;
+; ; ; ; Free the node's memory chunk.
+; ; ; ;
+; ; ; call GlobalHandle
+; ; ; push eax
+; ; ; push eax
+; ; ; call GlobalUnlock
+; ; ; call GlobalFree
+; ; ;
+; ; ; jmp FreeEmAll ; Do the walk of life.
+; ; ;
+; ; ;DoneFreez:
+; ; ;
+; ; ; mov LineCallbackList, 0 ; Just in case...
+; ; ;
+; ; ;
+; ; ; mov ebx, PhoneCallbackList ; Get the phone list anchor
+; ; ;FreeEmAll2:
+; ; ; or ebx, ebx ; At last entry?
+; ; ; jz DoneFreez2 ; Yup, go away.
+; ; ;
+; ; ; ;
+; ; ; ; Call phoneShutdown on this behalf
+; ; ; ;
+; ; ; push ebx ; Save this - just in case
+; ; ; push [ebx+CALLBACK_HAPP] ; Push the hPhoneApp
+; ; ; call phoneShutdown16@4
+; ; ; pop ebx ; Get back our value.
+; ; ;
+; ; ; push [ebx+CALLBACK_CALLBACK] ; Push the thunk thing.
+; ; ; call FreeSLCallback ; Be free...
+; ; ;
+; ; ; push ebx ; Use this before freeing it.
+; ; ;
+; ; ; mov ebx, [ebx+CALLBACK_NEXT] ; Get next node in the list.
+; ; ;
+; ; ; ;
+; ; ; ; Free the node's memory chunk.
+; ; ; ;
+; ; ; call GlobalHandle
+; ; ; push eax
+; ; ; push eax
+; ; ; call GlobalUnlock
+; ; ; call GlobalFree
+; ; ;
+; ; ; jmp FreeEmAll2 ; Do the walk of life.
+; ; ;
+; ; ;DoneFreez2:
+; ; ;
+; ; ; mov PhoneCallbackList, 0 ; Just in case...
+; ; ;
+; ; ; pop ebx ; Get the saved value.
+
+
+
+ dec cProcessAttach ;Update count of attached processes.
+ cmp cProcessAttach, 0
+ jne initok
+
+
+;**********************************
+
+
+;
+; It would have been really cool to have implemented orthogonal thunks, but
+; that didn't happen in M7 because of time pressure and because of potential
+; destabilizing effects.
+; The load count of tapi.dll at this point is 2 (one each for the two
+; thunk scripts that we have (flat and 16-bit thunks)). So we need to
+; call FreeLibrary16 twice to make sure that tapi.dll gets unloaded after
+; this point.
+; So why does tapi.dll hang around even after the last app. that attached
+; to it is gone? Well, per AtsushiK, that's because it uses the same loading
+; technology as kernel, gdi and user. Those libraries never needed to be
+; freed, so no one ever wrote the code to free them. That means that the
+; following hack will work. What's more, it will always work.
+; ---DeepakA
+; invoke GetTapiHInst
+ invoke NewData
+ push eax
+ push eax
+ push eax
+ call FreeLibrary16
+ call FreeLibrary16
+ call FreeLibrary16
+
+
+
+initok:
+ mov eax, 1 ;return success
+exit:
+ ret
+
+
+
+
+DllEntryPoint endp
+; end DllEntryPoint
+
+
+
+
+
+
+
+; ; ;;****************************************************************************
+; ; ;;****************************************************************************
+; ; ;lineInitialize proc near32 lphApp:DWORD, hInstance:DWORD, lpfnCallback:DWORD, lpsAppName:DWORD, lpdwNumDevs:DWORD
+; ; ;
+; ; ; ;
+; ; ; ; First, check the code pointer
+; ; ; ;
+; ; ; push lpfnCallback ; Push the apps callback address
+; ; ; call IsBadCodePtr ; Is is a valid code pointer?
+; ; ; or eax, eax
+; ; ; jnz BadCodePointer ; Nope. Go away.
+; ; ;
+; ; ;
+; ; ; push CALLBACK_STRUCT_SIZE
+; ; ; push 42h ;(GMEM_MOVABLE + GMEM_ZEROINIT)
+; ; ; call GlobalAlloc ; Get some memory for a new node.
+; ; ; push eax
+; ; ; call GlobalLock
+; ; ;
+; ; ; or eax, eax ; Did the call fail?
+; ; ; jz No_mo_mem ; Yerp - go away.
+; ; ;
+; ; ; push ebx ; Be polite and save this.
+; ; ;
+; ; ; push eax ; We'll need this later (newnode ptr)
+; ; ; mov ebx, eax ; We'll also be using it very soon.
+; ; ;
+; ; ; push lpfnCallback ; Save 32bit address of callback
+; ; ; push lp16TapiCallbackThunk ; 16bit callback gotten at init time
+; ; ; call AllocSLCallback ; Get a callback
+; ; ;
+; ; ; ; check return code (0 = failed)
+; ; ; or eax, eax ; Did we fail?
+; ; ; jz No_mo_callbacks ; Yes, go away.
+; ; ;
+; ; ; mov [ebx+CALLBACK_CALLBACK], eax ;Save the callback address
+; ; ;
+; ; ; push lpdwNumDevs ; Prepare to call lineInitialize
+; ; ; push lpsAppName ; Prepare to call lineInitialize
+; ; ; push eax ; Prepare to call lineInitialize
+; ; ; push hInstance ; Prepare to call lineInitialize
+; ; ; push lphApp ; Prepare to call lineInitialize
+; ; ; call lineInitialize16@20
+; ; ;
+; ; ; or eax, eax ; Did lineInit fail?
+; ; ; jnz BadReturnCode ; Yup, go away.
+; ; ;
+; ; ; ;
+; ; ; ; Now that everything went well, add the new node to the list.
+; ; ; ;
+; ; ; pop ebx ; Get the node pointer
+; ; ;
+; ; ; mov eax, LineCallbackList ; Get pointer to first node
+; ; ; mov [ebx+CALLBACK_NEXT], eax ; Fix chain
+; ; ; mov LineCallbackList, ebx ; Insert this new node as first
+; ; ;
+; ; ; mov eax, [lphApp]
+; ; ; mov eax, [eax]
+; ; ; mov [ebx+CALLBACK_HAPP], eax ; Save the hLineApp
+; ; ;
+; ; ; xor eax, eax ; Set return code (we got 0 from init).
+; ; ; pop ebx ; Get back the saved value.
+; ; ;
+; ; ; ret
+; ; ;
+; ; ;
+; ; ;BadReturnCode:
+; ; ; xchg [esp], eax ; Get the struct pointer
+; ; ;
+; ; ; push eax ; We're gonna use this in a sec...
+; ; ;
+; ; ; push [eax+CALLBACK_CALLBACK] ; Push the callback address
+; ; ; call FreeSLCallback ; Free the thunk callback
+; ; ;
+; ; ; ;
+; ; ; ; We've already pushed eax (the newnode pointer) so we don't gotta do
+; ; ; ; it here.
+; ; ; ;
+; ; ;
+; ; ; ;
+; ; ; ; Free the newnode chunk of mem.
+; ; ; ;
+; ; ; call GlobalHandle
+; ; ; push eax
+; ; ; push eax
+; ; ; call GlobalUnlock
+; ; ; call GlobalFree
+; ; ;
+; ; ; pop eax ; Get return code.
+; ; ; pop ebx ; Get back the saved value.
+; ; ; ret
+; ; ;
+; ; ;
+; ; ;BadCodePointer:
+; ; ; mov eax, 80000035h
+; ; ; pop ebx ; Get back the saved value.
+; ; ; ret
+; ; ;
+; ; ;
+; ; ;No_mo_callbacks:
+; ; ; pop eax ; Get out struct pointer
+; ; ;
+; ; ; ; Free it.
+; ; ; call GlobalHandle
+; ; ; push eax
+; ; ; push eax
+; ; ; call GlobalUnlock
+; ; ; call GlobalFree
+; ; ;
+; ; ; pop ebx ; Get back the saved value.
+; ; ;
+; ; ;No_mo_mem:
+; ; ; mov eax, 80000044h
+; ; ; ret
+; ; ;
+; ; ;lineInitialize endp
+; ; ;
+; ; ;
+; ; ;;****************************************************************************
+; ; ;;****************************************************************************
+; ; ;lineShutdown proc near32 hApp:DWORD
+; ; ;
+; ; ; push ebx ; Be polite and save this.
+; ; ; push ecx ; Be polite and save this.
+; ; ;
+; ; ; push hApp
+; ; ;
+; ; ; call lineShutdown16@4
+; ; ;
+; ; ; push eax ; Save the return code.
+; ; ;
+; ; ; ;
+; ; ; ; Run the linked list of callbacks looking for this hLineApp
+; ; ; ;
+; ; ;
+; ; ; mov eax, LineCallbackList ; Get the list anchor
+; ; ; mov ebx, offset LineCallbackList ; The previous node.
+; ; ; mov ecx, hApp ; That which we seek.
+; ; ;
+; ; ;LoopAMundo:
+; ; ; or eax, eax ; At last entry?
+; ; ; jz NotFound ; Yup. Musta not been found.
+; ; ;
+; ; ; cmp [eax+CALLBACK_HAPP], ecx ; Is this that which we seek?
+; ; ; je GotIt ; Yep - shure is.
+; ; ;
+; ; ; mov ebx, eax ; Update the "previous" pointer.
+; ; ; mov eax, [eax+CALLBACK_NEXT] ; Get next node in the list
+; ; ; jmp LoopAMundo ; Do the walk of life.
+; ; ;
+; ; ;GotIt:
+; ; ; push eax ; We're gonna need this in a sec...
+; ; ;
+; ; ; push [eax+CALLBACK_CALLBACK] ; Push the thunk thing.
+; ; ; call FreeSLCallback ; Be free...
+; ; ;
+; ; ; ;
+; ; ; ; Now take it out of the list.
+; ; ; ;
+; ; ;
+; ; ; pop eax ; Get back the node pointer.
+; ; ;
+; ; ; push [eax+CALLBACK_NEXT] ; Get this "next" pointer.
+; ; ; pop [ebx+CALLBACK_NEXT] ; and fix the chain.
+; ; ;
+; ; ; push eax ; Push the trash node pointer
+; ; ;
+; ; ; ; Free it.
+; ; ;
+; ; ; call GlobalHandle
+; ; ; push eax
+; ; ; push eax
+; ; ; call GlobalUnlock
+; ; ; call GlobalFree
+; ; ;
+; ; ;
+; ; ;NotFound:
+; ; ; ;
+; ; ; ; How is this possible?
+; ; ; ; Oh well. We can do nothing here.
+; ; ; ;
+; ; ;
+; ; ;
+; ; ; pop eax ; Retrieve the return code.
+; ; ;
+; ; ; pop ecx ; Get the saved value.
+; ; ; pop ebx ; Get the saved value.
+; ; ;
+; ; ; ret
+; ; ;
+; ; ;
+; ; ;lineShutdown endp
+; ; ;
+; ; ;
+; ; ;;****************************************************************************
+; ; ;;****************************************************************************
+; ; ;phoneInitialize proc near32 lphApp:DWORD, hInstance:DWORD, lpfnCallback:DWORD, lpsAppName:DWORD, lpdwNumDevs:DWORD
+; ; ;
+; ; ; ;
+; ; ; ; First, check the code pointer
+; ; ; ;
+; ; ; push lpfnCallback ; Push the apps callback address
+; ; ; call IsBadCodePtr ; Is is a valid code pointer?
+; ; ; or eax, eax
+; ; ; jnz BadCodePointer ; Nope. Go away.
+; ; ;
+; ; ;
+; ; ; push CALLBACK_STRUCT_SIZE
+; ; ; push 42h ;(GMEM_MOVABLE + GMEM_ZEROINIT)
+; ; ; call GlobalAlloc ; Get some memory for a new node.
+; ; ; push eax
+; ; ; call GlobalLock
+; ; ;
+; ; ; or eax, eax ; Did the call fail?
+; ; ; jz No_mo_mem ; Yerp - go away.
+; ; ;
+; ; ; push ebx ; Be polite and save this.
+; ; ;
+; ; ; push eax ; We'll need this later (newnode ptr)
+; ; ; mov ebx, eax ; We'll also be using it very soon.
+; ; ;
+; ; ; push lpfnCallback ; Save 32bit address of callback
+; ; ; push lp16TapiCallbackThunk ; 16bit callback gotten at init time
+; ; ; call AllocSLCallback ; Get a callback
+; ; ;
+; ; ; ; check return code (0 = failed)
+; ; ; or eax, eax ; Did we fail?
+; ; ; jz No_mo_callbacks ; Yes, go away.
+; ; ;
+; ; ; mov [ebx+CALLBACK_CALLBACK], eax ;Save the callback address
+; ; ;
+; ; ; push lpdwNumDevs ; Prepare to call phoneInitialize
+; ; ; push lpsAppName ; Prepare to call phoneInitialize
+; ; ; push eax ; Prepare to call phoneInitialize
+; ; ; push hInstance ; Prepare to call phoneInitialize
+; ; ; push lphApp ; Prepare to call phoneInitialize
+; ; ; call phoneInitialize16@20
+; ; ;
+; ; ; or eax, eax ; Did phoneInit fail?
+; ; ; jnz BadReturnCode ; Yup, go away.
+; ; ;
+; ; ; ;
+; ; ; ; Now that everything went well, add the new node to the list.
+; ; ; ;
+; ; ; pop ebx ; Get the node pointer
+; ; ; mov eax, PhoneCallbackList ; Get pointer to first node
+; ; ; mov [ebx+CALLBACK_NEXT], eax ; Fix chain
+; ; ; mov PhoneCallbackList, ebx ; Insert this new node as first
+; ; ;
+; ; ; mov eax, [lphApp]
+; ; ; mov eax, [eax]
+; ; ; mov [ebx+CALLBACK_HAPP], eax ; Save the hPhoneApp
+; ; ;
+; ; ; xor eax, eax ; Set return code (we got 0 from init).
+; ; ; pop ebx ; Get back the saved value.
+; ; ;
+; ; ; ret
+; ; ;
+; ; ;
+; ; ;BadReturnCode:
+; ; ; xchg [esp], eax ; Get the struct pointer
+; ; ;
+; ; ; push eax ; We're gonna use this in a sec...
+; ; ;
+; ; ; push [eax+CALLBACK_CALLBACK] ; Push the callback address
+; ; ; call FreeSLCallback ; Free the thunk callback
+; ; ;
+; ; ; ;
+; ; ; ; We've already pushed eax (the newnode pointer) so we don't gotta do
+; ; ; ; it here.
+; ; ; ;
+; ; ;
+; ; ; ;
+; ; ; ; Free the newnode chunk of mem.
+; ; ; ;
+; ; ; call GlobalHandle
+; ; ; push eax
+; ; ; push eax
+; ; ; call GlobalUnlock
+; ; ; call GlobalFree
+; ; ;
+; ; ; pop eax ; Get return code.
+; ; ; pop ebx ; Get back the saved value.
+; ; ; ret
+; ; ;
+; ; ;
+; ; ;BadCodePointer:
+; ; ; mov eax, 90000035h
+; ; ; pop ebx ; Get back the saved value.
+; ; ; ret
+; ; ;
+; ; ;
+; ; ;No_mo_callbacks:
+; ; ; pop eax ; Get out struct pointer
+; ; ;
+; ; ; ; Free it.
+; ; ; call GlobalHandle
+; ; ; push eax
+; ; ; push eax
+; ; ; call GlobalUnlock
+; ; ; call GlobalFree
+; ; ;
+; ; ; pop ebx ; Get back the saved value.
+; ; ;
+; ; ;No_mo_mem:
+; ; ; mov eax, 90000044h
+; ; ; ret
+; ; ;
+; ; ;phoneInitialize endp
+; ; ;
+; ; ;
+; ; ;;phoneInitialize proc near32 lphApp:DWORD, hInstance:DWORD, lpfnCallback:DWORD, lpsAppName:DWORD, lpdwNumDevs:DWORD
+; ; ;;
+; ; ;; ;
+; ; ;; ; First, check the code pointer
+; ; ;; ;
+; ; ;; push lpfnCallback
+; ; ;; call IsBadCodePtr
+; ; ;; or eax, eax
+; ; ;; jz GoodPointer
+; ; ;;
+; ; ;; mov eax, 90000035h
+; ; ;; ret
+; ; ;;
+; ; ;;GoodPointer:
+; ; ;; push lpdwNumDevs
+; ; ;; push lpsAppName
+; ; ;;
+; ; ;; push lpfnCallback
+; ; ;; push lp16TapiCallbackThunk
+; ; ;; call AllocSLCallback
+; ; ;;
+; ; ;; ; check return code (0 = failed)
+; ; ;; or eax, eax
+; ; ;; jz No_mo_callbacks
+; ; ;;
+; ; ;;
+; ; ;; mov TapiCallbackThunk, eax
+; ; ;; push eax
+; ; ;;
+; ; ;; push hInstance
+; ; ;; push lphApp
+; ; ;;
+; ; ;; call phoneInitialize16@20
+; ; ;;
+; ; ;; ret
+; ; ;;
+; ; ;;
+; ; ;;No_mo_callbacks:
+; ; ;; mov eax, 90000044h
+; ; ;; ret
+; ; ;;
+; ; ;;phoneInitialize endp
+; ; ;
+; ; ;
+; ; ;;****************************************************************************
+; ; ;;****************************************************************************
+; ; ;phoneShutdown proc near32 hApp:DWORD
+; ; ;
+; ; ; push ebx ; Be polite and save this.
+; ; ; push ecx ; Be polite and save this.
+; ; ;
+; ; ; push hApp
+; ; ;
+; ; ; call phoneShutdown16@4
+; ; ;
+; ; ; push eax ; Save the return code.
+; ; ;
+; ; ; ;
+; ; ; ; Run the linked list of callbacks looking for this hPhoneApp
+; ; ; ;
+; ; ;
+; ; ; mov eax, PhoneCallbackList ; Get the list anchor
+; ; ; mov ebx, offset PhoneCallbackList ; The previous node.
+; ; ; mov ecx, hApp ; That which we seek.
+; ; ;
+; ; ;LoopAMundo:
+; ; ; or eax, eax ; At last entry?
+; ; ; jz NotFound ; Yup. Musta not been found.
+; ; ;
+; ; ; cmp [eax+CALLBACK_HAPP], ecx ; Is this that which we seek?
+; ; ; je GotIt ; Yep - shure is.
+; ; ;
+; ; ; mov ebx, eax ; Update the "previous" pointer.
+; ; ; mov eax, [eax+CALLBACK_NEXT] ; Get next node in the list
+; ; ; jmp LoopAMundo ; Do the walk of life.
+; ; ;
+; ; ;GotIt:
+; ; ; push eax ; We're gonna need this in a sec...
+; ; ;
+; ; ; push [eax+CALLBACK_CALLBACK] ; Push the thunk thing.
+; ; ; call FreeSLCallback ; Be free...
+; ; ;
+; ; ; ;
+; ; ; ; Now take it out of the list.
+; ; ; ;
+; ; ;
+; ; ; pop eax ; Get back the node pointer.
+; ; ;
+; ; ; push [eax+CALLBACK_NEXT] ; Get this "next" pointer.
+; ; ; pop [ebx+CALLBACK_NEXT] ; and fix the chain.
+; ; ;
+; ; ; push eax ; Push the trash node pointer
+; ; ;
+; ; ; ; Free it.
+; ; ;
+; ; ; call GlobalHandle
+; ; ; push eax
+; ; ; push eax
+; ; ; call GlobalUnlock
+; ; ; call GlobalFree
+; ; ;
+; ; ;
+; ; ;NotFound:
+; ; ; ;
+; ; ; ; How is this possible?
+; ; ; ; Oh well. We can do nothing here.
+; ; ; ;
+; ; ;
+; ; ;
+; ; ; pop eax ; Retrieve the return code.
+; ; ;
+; ; ; pop ecx ; Get the saved value.
+; ; ; pop ebx ; Get the saved value.
+; ; ;
+; ; ; ret
+; ; ;
+; ; ;
+; ; ;
+; ; ;; push hApp
+; ; ;;
+; ; ;; call phoneShutdown16@4
+; ; ;;
+; ; ;; cmp TapiCallbackThunk, 0
+; ; ;; je Dont_free_me
+; ; ;;
+; ; ;; push eax ; We're gonna need this...
+; ; ;;
+; ; ;; push TapiCallbackThunk
+; ; ;; call FreeSLCallback
+; ; ;;
+; ; ;; pop eax ; Get back our _real_ return code...
+; ; ;;
+; ; ;; mov TapiCallbackThunk, 0
+; ; ;;
+; ; ;;
+; ; ;;Dont_free_me:
+; ; ;;
+; ; ;; ret
+; ; ;;
+; ; ;phoneShutdown endp
+; ; ;
+
+
+end
+
diff --git a/private/tapi/dev/sp/tsp3216/tsp3216l/tsp3216l.c b/private/tapi/dev/sp/tsp3216/tsp3216l/tsp3216l.c
new file mode 100644
index 000000000..4180d8114
--- /dev/null
+++ b/private/tapi/dev/sp/tsp3216/tsp3216l/tsp3216l.c
@@ -0,0 +1,1282 @@
+#include <windows.h>
+#include <windowsx.h>
+#include <winuser.h>
+#include <wownt32.h>
+
+#include <tapi.h>
+#include <tspi.h>
+
+#include "tsp3216.h"
+#include "debug.h"
+
+
+LONG PASCAL TapiThk_ThunkConnect32 (
+ LPSTR pszDll16,
+ LPSTR pszDll32,
+ DWORD hInstance,
+ DWORD lReason
+ );
+
+LONG PASCAL TapiFThk_ThunkConnect32 (
+ LPSTR pszDll16,
+ LPSTR pszDll32,
+ DWORD hInstance,
+ DWORD lReason
+ );
+
+LONG PASCAL Tapi32_ThunkConnect32 (
+ LPSTR pszDll16,
+ LPSTR pszDll32,
+ DWORD hInstance,
+ DWORD lReason
+ );
+
+const char pszDll16[] = "TSP3216S.DLL";
+const char pszDll32[] = "TSP3216L.TSP";
+
+
+
+//***************************************************************************
+//***************************************************************************
+enum {
+ MYMSG_STARTER = TSP3216L_MESSAGE,
+ MYMSG_PROVIDERINIT,
+ MYMSG_PROVIDERSHUTDOWN,
+ MYMSG_PROVIDERCONFIG,
+ MYMSG_LINECONFIGDIALOG,
+ MYMSG_LINECONFIGDIALOGEDIT,
+ MYMSG_PHONECONFIGDIALOG,
+ MYMSG_LINEMAKECALL
+ };
+
+
+//***************************************************************************
+DWORD cProcessAttach = 0;
+
+
+//***************************************************************************
+HWND ghWnd = NULL;
+CRITICAL_SECTION gcs;
+
+
+//***************************************************************************
+TCHAR gszProviderKey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\"
+ "Telephony\\Providers\\Provider";
+
+DWORD gdwPermanentProviderID;
+
+
+DWORD gdwThreadParms[2];
+enum {
+ THE_HINST,
+ THE_LREASON
+ };
+
+
+
+//***************************************************************************
+LRESULT CALLBACK MyWndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam );
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+LPVOID TspAlloc( UINT nSize )
+{
+ return LocalAlloc( LPTR, nSize );
+}
+
+
+
+LPVOID TspFree( LPVOID p )
+{
+ return LocalFree( p );
+}
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+void InitThunks( void )
+{
+ TapiThk_ThunkConnect32(
+ (LPSTR)pszDll16,
+ (LPSTR)pszDll32,
+ gdwThreadParms[THE_HINST],
+ gdwThreadParms[THE_LREASON]
+ );
+
+ TapiFThk_ThunkConnect32(
+ (LPSTR)pszDll16,
+ (LPSTR)pszDll32,
+ gdwThreadParms[THE_HINST],
+ gdwThreadParms[THE_LREASON]
+ );
+
+ Tapi32_ThunkConnect32(
+ (LPSTR)pszDll16,
+ (LPSTR)pszDll32,
+ gdwThreadParms[THE_HINST],
+ gdwThreadParms[THE_LREASON]
+ );
+
+ InitializeCriticalSection( &gcs );
+}
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+
+UINT PASCAL NewData( void );
+
+
+void FreeThunks( void )
+{
+ HINSTANCE hInst;
+ hInst = (HINSTANCE)NewData();
+ FreeLibrary16( hInst );
+ FreeLibrary16( hInst );
+ FreeLibrary16( hInst );
+
+
+ DeleteCriticalSection( &gcs );
+
+}
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+DWORD WINAPI TheUIThread( LPVOID lpThreadParameter )
+{
+ MSG msg;
+
+ WNDCLASS wndclass = {
+ 0,
+ MyWndProc,
+ 0,
+ 0,
+ (HANDLE)gdwThreadParms[THE_HINST],
+ 0,
+ 0,
+ 0,
+ 0,
+ "Tsp3216LWindowClass"
+ };
+
+
+DBGOUT((2, "The UI thread"));
+
+
+ //
+ // We need _another_ goddamn window.
+ //
+
+ RegisterClass( &wndclass );
+
+ ghWnd = CreateWindow(
+ "Tsp3216LWindowClass",
+ "Tsp3216LWindow",
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ (HANDLE)gdwThreadParms[THE_HINST],
+ NULL
+ );
+
+
+DBGOUT((2, "Starting message loop in ui thread"));
+
+ while (GetMessage(&msg, 0, 0, 0) != 0)
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+DBGOUT((2, "Done message loop in ui thread"));
+
+ ghWnd = NULL;
+
+ return (msg.wParam);
+}
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+LONG WINAPI DllEntryPoint(
+ DWORD hModule,
+ DWORD lReason,
+ DWORD lContext
+ )
+{
+
+
+DBGOUT((2, "Entering DllEntryPoint reason=0x%08lx", lReason));
+
+
+ switch ( lReason )
+ {
+ case 0:
+ {
+#if DBG
+{
+TCHAR cName[MAX_PATH];
+TCHAR buf[256];
+GetModuleFileName( NULL, cName, MAX_PATH);
+wsprintf(buf, "DllEntryPoint - 0 process detach [%s]\r\n", cName);
+OutputDebugString(buf);
+}
+#endif
+
+
+ FreeThunks();
+ }
+ break;
+
+
+
+ case 1:
+ {
+#if DBG
+{
+TCHAR cName[MAX_PATH];
+TCHAR buf[256];
+GetModuleFileName( NULL, cName, MAX_PATH);
+wsprintf(buf, "DllEntryPoint - 1 process attach [%s]\r\n", cName);
+OutputDebugString(buf);
+}
+#endif
+
+
+ //
+ // Yeah, I know it's not threadsafe. Ask me if I care.
+ //
+ gdwThreadParms[THE_HINST] = (DWORD)hModule;
+ gdwThreadParms[THE_LREASON] = (DWORD)lReason;
+
+
+ InitThunks();
+ }
+ break;
+
+ }
+
+DBGOUT((2, "Leaving DllEntryPoint"));
+
+ return TRUE;
+}
+
+
+//****************************************************************************
+//****************************************************************************
+//****************************************************************************
+LONG PASCAL TSPI_lineConfigDialog (
+ DWORD dwDeviceID,
+ HWND hwndOwner,
+ LPCSTR lpszDeviceClass
+ );
+
+LONG PASCAL TSPI_lineConfigDialogEdit(
+ DWORD dwDeviceID,
+ HWND hwndOwner,
+ LPCSTR lpszDeviceClass,
+ LPVOID lpDeviceConfigIn,
+ DWORD dwSize,
+ LPVARSTRING lpDeviceConfigOut
+ );
+
+
+LONG
+TSPIAPI
+TSPI_providerGenericDialogData(
+ DWORD dwObjectID,
+ DWORD dwObjectType,
+ LPVOID lpParams,
+ DWORD dwSize
+ )
+{
+// LONG lResult = LINEERR_OPERATIONUNAVAIL;
+
+
+ DBGOUT((2, "In TSPI_providerGenericDialogData"));
+
+ DBGOUT((11, " Msg=0x%08lx", ((LPDWORD)lpParams)[0]));
+
+// return SendMessage( ghWnd, ((LPDWORD)lpParams)[0], 0, (LPARAM)&(((LPDWORD)lpParams)[1]) );
+// return
+ PostMessage( ghWnd, ((LPDWORD)lpParams)[0], 0, (LPARAM)&(((LPDWORD)lpParams)[1]) );
+ return 0;
+
+// return lResult;
+}
+
+
+//****************************************************************************
+//****************************************************************************
+//****************************************************************************
+LONG
+TSPIAPI
+TSPI_providerUIIdentify(
+ LPSTR pszUIDllName
+ )
+{
+
+ DBGOUT((2, "In TSPI_providerUIIdentify"));
+
+ lstrcpy( pszUIDllName, "TSP3216L.TSP" );
+
+ return 0;
+
+}
+
+
+//****************************************************************************
+//****************************************************************************
+//****************************************************************************
+LONG
+TSPIAPI
+TUISPI_lineConfigDialog(
+ TUISPIDLLCALLBACK lpfnUIDLLCallback,
+ DWORD dwDeviceID,
+ HWND hwndOwner,
+ LPCSTR lpszDeviceClass
+ )
+{
+ DWORD dwParms[] = {
+ MYMSG_LINECONFIGDIALOG,
+ dwDeviceID,
+ (DWORD)hwndOwner,
+ (DWORD)lpszDeviceClass
+ };
+
+
+//BUGBUG: Can't pass strings across a callback
+
+ DBGOUT((2, "In TUISPI_lineConfigDialog"));
+ DBGOUT((11, " dwDeviceID=0x%08lx", dwDeviceID));
+ DBGOUT((11, " hwndOwner =0x%08lx", hwndOwner));
+ DBGOUT((11, " lpszDeviceClass=0x%08lx", lpszDeviceClass));
+
+ (*lpfnUIDLLCallback)(
+ dwDeviceID,
+ TUISPIDLL_OBJECT_LINEID,
+ dwParms,
+ sizeof(dwParms)
+ );
+
+//BUGBUG how do we wait and/or return error code?
+ return 0;
+
+}
+
+
+//****************************************************************************
+//****************************************************************************
+//****************************************************************************
+LONG
+TSPIAPI
+TUISPI_lineConfigDialogEdit(
+ TUISPIDLLCALLBACK lpfnUIDLLCallback,
+ DWORD dwDeviceID,
+ HWND hwndOwner,
+ LPCSTR lpszDeviceClass,
+ LPVOID const lpDeviceConfigIn,
+ DWORD dwSize,
+ LPVARSTRING lpDeviceConfigOut
+ )
+{
+ DWORD dwParms[] = {
+ MYMSG_LINECONFIGDIALOGEDIT,
+ dwDeviceID,
+ (DWORD)hwndOwner,
+ (DWORD)lpszDeviceClass,
+ (DWORD)lpDeviceConfigIn,
+ dwSize,
+ (DWORD)lpDeviceConfigOut
+ };
+
+
+ DBGOUT((2, "In TUISPI_lineConfigDialogEdit"));
+
+ (*lpfnUIDLLCallback)(
+ dwDeviceID,
+ TUISPIDLL_OBJECT_LINEID,
+ dwParms,
+ sizeof(dwParms)
+ );
+
+//BUGBUG how do we wait and/or return error code?
+ return 0;
+
+
+}
+
+
+//****************************************************************************
+//****************************************************************************
+//****************************************************************************
+LONG
+TSPIAPI
+TSPI_phoneConfigDialog(
+ DWORD dwDeviceID,
+ HWND hwndOwner,
+ LPCSTR lpszDeviceClass
+ );
+
+LONG
+TSPIAPI
+TUISPI_phoneConfigDialog(
+ TUISPIDLLCALLBACK lpfnUIDLLCallback,
+ DWORD dwDeviceID,
+ HWND hwndOwner,
+ LPCSTR lpszDeviceClass
+ )
+{
+ DWORD dwParms[] = {
+ MYMSG_PHONECONFIGDIALOG,
+ dwDeviceID,
+ (DWORD)hwndOwner,
+ (DWORD)lpszDeviceClass
+ };
+
+
+//BUGBUG: Can't pass strings across a callback
+
+ DBGOUT((2, "In TUISPI_phoneConfigDialog"));
+ DBGOUT((11, " dwDeviceID=0x%08lx", dwDeviceID));
+ DBGOUT((11, " hwndOwner =0x%08lx", hwndOwner));
+ DBGOUT((11, " lpszDeviceClass=0x%08lx", lpszDeviceClass));
+
+ (*lpfnUIDLLCallback)(
+ dwDeviceID,
+ TUISPIDLL_OBJECT_PHONEID,
+ dwParms,
+ sizeof(dwParms)
+ );
+
+//BUGBUG how do we wait and/or return error code?
+
+ return 0;
+
+}
+
+
+//****************************************************************************
+//****************************************************************************
+//****************************************************************************
+LONG
+TSPIAPI
+TSPI_providerConfig(
+ HWND hwndOwner,
+ DWORD dwPermanentProviderID
+ );
+
+LONG
+TSPIAPI
+TUISPI_providerConfig(
+ TUISPIDLLCALLBACK lpfnUIDLLCallback,
+ HWND hwndOwner,
+ DWORD dwPermanentProviderID
+ )
+{
+ DWORD dwParms[] = {
+ MYMSG_PROVIDERCONFIG,
+ (DWORD)hwndOwner,
+ dwPermanentProviderID
+ };
+
+
+//BUGBUG: Can't pass strings across a callback
+
+ DBGOUT((2, "In TUISPI_providerConfig"));
+ DBGOUT((11, " hwndOwner =0x%08lx", hwndOwner));
+ DBGOUT((11, " dwPermanentProviderID=0x%08lx", dwPermanentProviderID));
+
+ (*lpfnUIDLLCallback)(
+ 0, //BUGBUG Is this correct?
+ TUISPIDLL_OBJECT_LINEID,
+ dwParms,
+ sizeof(dwParms)
+ );
+
+//BUGBUG how do we wait and/or return error code?
+
+ return 0;
+}
+
+
+//****************************************************************************
+//****************************************************************************
+//****************************************************************************
+LONG
+TSPIAPI
+TUISPI_providerInstall(
+ TUISPIDLLCALLBACK lpfnUIDLLCallback,
+ HWND hwndOwner,
+ DWORD dwPermanentProviderID
+ )
+{
+
+ DBGOUT((2, "In TUISPI_providerInstall"));
+
+ return 0;
+}
+
+
+//****************************************************************************
+//****************************************************************************
+//****************************************************************************
+LONG
+TSPIAPI
+TUISPI_providerRemove(
+ TUISPIDLLCALLBACK lpfnUIDLLCallback,
+ HWND hwndOwner,
+ DWORD dwPermanentProviderID
+ )
+{
+
+ DBGOUT((2, "In TUISPI_providerRemove"));
+
+ return 0;
+}
+
+
+//****************************************************************************
+//****************************************************************************
+//****************************************************************************
+
+
+
+LONG
+PASCAL
+TSPI_providerEnumDevices16( // TSPI v1.4
+ DWORD dwPermanentProviderID,
+ LPDWORD lpdwNumLines,
+ LPDWORD lpdwNumPhones,
+ HPROVIDER hProvider,
+ LINEEVENT lpfnLineCreateProc,
+ PHONEEVENT lpfnPhoneCreateProc,
+ HWND hSecretWnd
+ );
+
+
+LONG PASCAL TSPI_providerEnumDevices(
+ DWORD dwPermanentProviderID,
+ LPDWORD lpdwNumLines,
+ LPDWORD lpdwNumPhones,
+ HPROVIDER hProvider,
+ LINEEVENT lpfnLineCreateProc,
+ PHONEEVENT lpfnPhoneCreateProc
+ )
+{
+ DWORD dwThreadID;
+
+
+ DBGOUT((2, "In TSPI_providerEnumDevices"));
+
+ //
+ // BUGBUG There's gotta be a better way to earn a buck...
+ //
+
+ if ( NULL == CreateThread( NULL,
+ 0,
+ TheUIThread,
+ (LPVOID)&gdwThreadParms,
+ 0,
+ &dwThreadID
+ )
+ )
+ {
+ //
+ // The CreateThread failed!!
+ //
+ DBGOUT((1, "CreateThread() failed!!!!"));
+ return LINEERR_OPERATIONFAILED;
+ }
+
+
+ while ( !ghWnd)
+ {
+ Sleep(0);
+ }
+
+
+ return TSPI_providerEnumDevices16(
+ dwPermanentProviderID,
+ lpdwNumLines,
+ lpdwNumPhones,
+ hProvider,
+ lpfnLineCreateProc,
+ lpfnPhoneCreateProc,
+ ghWnd
+ );
+
+}
+
+
+//****************************************************************************
+//****************************************************************************
+//****************************************************************************
+
+
+
+LONG
+PASCAL
+TSPI_lineGetID16(
+ HDRVLINE hdLine,
+ DWORD dwAddressID,
+ HDRVCALL hdCall,
+ DWORD dwSelect,
+ LPVARSTRING lpDeviceID,
+ LPCSTR lpszDeviceClass
+ );
+
+
+LONG
+PASCAL
+TSPI_lineGetID(
+ HDRVLINE hdLine,
+ DWORD dwAddressID,
+ HDRVCALL hdCall,
+ DWORD dwSelect,
+ LPVARSTRING lpDeviceID,
+ LPCSTR lpszDeviceClass,
+ HANDLE hTargetProcess
+
+ )
+{
+ LONG lResult;
+
+ DBGOUT((2, "Entering TSPI_lineGetID"));
+
+
+ DBGOUT((20, "lpszDeviceClass=[%s]", lpszDeviceClass));
+
+ lResult = TSPI_lineGetID16(
+ hdLine,
+ dwAddressID,
+ hdCall,
+ dwSelect,
+ lpDeviceID,
+ lpszDeviceClass
+ );
+
+ //
+ // Only continue if the operation was successful
+ //
+ if ( 0 == lResult )
+ {
+
+ //
+ // Is this a handle that we should translate?
+ //
+
+ DWORD dwDataSize;
+ DWORD dwDataType;
+ HKEY hKey;
+ TCHAR buf[64];
+ TCHAR KeyName[128];
+
+
+ //
+ // We determine if we should translate by simply trying to retrive a
+ // value with the name of lpszDeviceClass. If we succeed, we'll
+ // translate.
+ //
+ // We'll use the value as an offset into the string part (AN OFFSET
+ // FROM THE START OF VAR DATA, NOT FROM THE START OF THE STRUCT!!!)
+ // of where we can find the handle.
+ //
+ wsprintf(KeyName, "%s%d", gszProviderKey, gdwPermanentProviderID);
+
+ RegOpenKeyEx(
+ HKEY_LOCAL_MACHINE,
+ KeyName,
+ 0,
+ KEY_ALL_ACCESS,
+ &hKey
+ );
+
+ dwDataSize = sizeof(buf);
+
+
+ DBGOUT((11, "Looking in key [%s] for [%s]", KeyName, lpszDeviceClass));
+
+
+ lResult = RegQueryValueEx(
+ hKey,
+ lpszDeviceClass,
+ 0,
+ &dwDataType,
+ buf,
+ &dwDataSize
+ );
+
+ RegCloseKey( hKey );
+
+
+ if ( 0 == lResult )
+ {
+ HANDLE hTemp;
+#if DBG
+ LONG lRet;
+
+ lRet =
+#endif
+ DuplicateHandle( GetCurrentProcess(),
+ *(LPHANDLE)((LPBYTE)lpDeviceID +
+ lpDeviceID->dwStringOffset +
+ *(LPDWORD)buf
+ ),
+ hTargetProcess,
+ &hTemp,
+ 0,
+ TRUE,
+ DUPLICATE_SAME_ACCESS |
+ DUPLICATE_CLOSE_SOURCE
+ );
+
+// CloseHandle( *(LPHANDLE)( (LPBYTE)lpDeviceID +
+// lpDeviceID->dwStringOffset +
+// *(LPDWORD)buf ) );
+
+
+ *(LPHANDLE)( (LPBYTE)lpDeviceID +
+ lpDeviceID->dwStringOffset +
+ *(LPDWORD)buf ) =
+ hTemp;
+
+ DBGOUT((2, " Duplicate handle return code=0x%08lx", lRet));
+ }
+#if DBG
+ else
+ {
+ DBGOUT((2, " We won't dupe this handle. [%s]", lpszDeviceClass));
+ }
+#endif
+
+ lResult = 0; //What else can we do? Do we fail this if the dupe failed?
+
+ }
+
+
+ DBGOUT((2, "Leaving TSPI_lineGetID - lResult=0x%08lx", lResult));
+
+ return lResult;
+}
+
+
+//****************************************************************************
+//****************************************************************************
+//****************************************************************************
+LONG
+PASCAL
+TSPI_phoneGetID16(
+ HDRVPHONE hdPhone,
+ LPVARSTRING lpDeviceID,
+ LPCSTR lpszDeviceClass
+ );
+
+
+LONG
+PASCAL
+TSPI_phoneGetID(
+ HDRVPHONE hdPhone,
+ LPVARSTRING lpDeviceID,
+ LPCSTR lpszDeviceClass,
+ HANDLE hTargetProcess
+
+ )
+{
+ LONG lResult;
+
+ DBGOUT((2, "Entering TSPI_phoneGetID"));
+
+
+ DBGOUT((20, "lpszDeviceClass=[%s]", lpszDeviceClass));
+
+ lResult = TSPI_phoneGetID16(
+ hdPhone,
+ lpDeviceID,
+ lpszDeviceClass
+ );
+
+ //
+ // Only continue if the operation was successful
+ //
+ if ( 0 == lResult )
+ {
+
+ //
+ // Is this a handle that we should translate?
+ //
+
+ DWORD dwDataSize;
+ DWORD dwDataType;
+ HKEY hKey;
+ TCHAR buf[64];
+ TCHAR KeyName[128];
+
+
+ //
+ // We determine if we should translate by simply trying to retrive a
+ // value with the name of lpszDeviceClass. If we succeed, we'll
+ // translate.
+ //
+ // We'll use the value as an offset into the string part (AN OFFSET
+ // FROM THE START OF VAR DATA, NOT FROM THE START OF THE STRUCT!!!)
+ // of where we can find the handle.
+ //
+ wsprintf(KeyName, "%s%d", gszProviderKey, gdwPermanentProviderID);
+
+ RegOpenKeyEx(
+ HKEY_LOCAL_MACHINE,
+ KeyName,
+ 0,
+ KEY_ALL_ACCESS,
+ &hKey
+ );
+
+ dwDataSize = sizeof(buf);
+
+
+ DBGOUT((20, "Looking in key [%s] for [%s]", KeyName, lpszDeviceClass));
+
+
+ lResult = RegQueryValueEx(
+ hKey,
+ lpszDeviceClass,
+ 0,
+ &dwDataType,
+ buf,
+ &dwDataSize
+ );
+
+ RegCloseKey( hKey );
+
+
+ if ( 0 == lResult )
+ {
+ HANDLE hTemp;
+#if DBG
+ LONG lRet;
+
+ lRet =
+#endif
+ DuplicateHandle( GetCurrentProcess(),
+ *(LPHANDLE)((LPBYTE)lpDeviceID +
+ lpDeviceID->dwStringOffset +
+ *(LPDWORD)buf
+ ),
+ hTargetProcess,
+ &hTemp,
+ 0,
+ TRUE,
+ DUPLICATE_SAME_ACCESS
+// DUPLICATE_CLOSE_SOURCE
+ );
+
+ CloseHandle( *(LPHANDLE)( (LPBYTE)lpDeviceID +
+ lpDeviceID->dwStringOffset +
+ *(LPDWORD)buf ) );
+
+ *(LPHANDLE)( (LPBYTE)lpDeviceID +
+ lpDeviceID->dwStringOffset +
+ *(LPDWORD)buf ) =
+ hTemp;
+
+ DBGOUT((20, " Duplicate handle return code=0x%08lx", lRet));
+ }
+#if DBG
+ else
+ {
+ DBGOUT((20, " We won't dupe this handle. [%s]", lpszDeviceClass));
+ }
+#endif
+
+ lResult = 0; //What else can we do? Do we fail this if the dupe failed?
+
+ }
+
+
+ DBGOUT((2, "Leaving TSPI_phoneGetID - lResult=0x%08lx", lResult));
+
+ return lResult;
+}
+
+
+
+//****************************************************************************
+//****************************************************************************
+//****************************************************************************
+
+LONG
+PASCAL
+TSPI_providerInit16(
+ DWORD dwTSPIVersion,
+ DWORD dwPermanentProviderID,
+ DWORD dwLineDeviceBaseID,
+ DWORD dwPhoneDeviceBaseID,
+ DWORD dwNumLines,
+ DWORD dwNumPhones,
+ ASYNC_COMPLETION lpfnCompletionProc
+ );
+
+LONG
+TSPIAPI
+TSPI_providerInit(
+ DWORD dwTSPIVersion,
+ DWORD dwPermanentProviderID,
+ DWORD dwLineDeviceIDBase,
+ DWORD dwPhoneDeviceIDBase,
+ DWORD dwNumLines,
+ DWORD dwNumPhones,
+ ASYNC_COMPLETION lpfnCompletionProc,
+ LPDWORD lpdwTSPIOptions // TAPI v2.0
+ )
+{
+ DWORD pParams[7];
+
+ DBGOUT((2, "In 32-providerinit"));
+ DBGOUT((11, " dwTSPIVersion =0x%08lx", dwTSPIVersion));
+ DBGOUT((11, " dwPermanentProviderID=0x%08lx", dwPermanentProviderID));
+
+
+ gdwPermanentProviderID = dwPermanentProviderID;
+
+ *lpdwTSPIOptions = 0;
+
+ pParams[0] = dwTSPIVersion;
+ pParams[1] = dwPermanentProviderID;
+ pParams[2] = dwLineDeviceIDBase;
+ pParams[3] = dwPhoneDeviceIDBase;
+ pParams[4] = dwNumLines;
+ pParams[5] = dwNumPhones;
+ pParams[6] = (DWORD)lpfnCompletionProc;
+
+ return SendMessage( ghWnd, MYMSG_PROVIDERINIT, 0, (LPARAM)pParams);
+
+}
+
+
+//****************************************************************************
+//****************************************************************************
+//****************************************************************************
+
+LONG
+PASCAL
+TSPI_providerShutdown16(
+ DWORD dwTSPIVersion
+ );
+
+LONG
+TSPIAPI
+TSPI_providerShutdown(
+ DWORD dwTSPIVersion
+ )
+{
+ LONG lResult;
+
+ DBGOUT((2, "In 32-providerShutdown"));
+
+
+ lResult = SendMessage( ghWnd, MYMSG_PROVIDERSHUTDOWN, 0, dwTSPIVersion);
+
+ //
+ // Is the UI thread still around?
+ //
+ if ( ghWnd )
+ {
+ SendMessage(ghWnd, WM_CLOSE, 0, 0);
+
+ //
+ // Verify that the other thread has done its work and killed
+ // the window
+ //
+ while ( ghWnd )
+ {
+ Sleep(0);
+ }
+ }
+
+ return lResult;
+}
+
+
+//****************************************************************************
+//****************************************************************************
+//****************************************************************************
+
+LONG
+PASCAL
+TSPI_lineMakeCall16(
+ DRV_REQUESTID dwRequestID,
+ HDRVLINE hdLine,
+ HTAPICALL htCall,
+ LPHDRVCALL lphdCall,
+ LPCSTR lpszDestAddress,
+ DWORD dwCountryCode,
+ LPLINECALLPARAMS const lpCallParams
+ );
+
+LONG
+TSPIAPI
+TSPI_lineMakeCall(
+ DRV_REQUESTID dwRequestID,
+ HDRVLINE hdLine,
+ HTAPICALL htCall,
+ LPHDRVCALL lphdCall,
+ LPCSTR lpszDestAddress,
+ DWORD dwCountryCode,
+ LPLINECALLPARAMS const lpCallParams
+ )
+{
+ LONG lResult;
+ DWORD pParams[7];
+
+
+ DBGOUT((2, "In 32-linemakecall"));
+
+ pParams[0] = (DWORD)dwRequestID;
+ pParams[1] = (DWORD)hdLine;
+ pParams[2] = (DWORD)htCall;
+ pParams[3] = (DWORD)lphdCall;
+ pParams[4] = (DWORD)lpszDestAddress;
+ pParams[5] = (DWORD)dwCountryCode;
+ pParams[6] = (DWORD)lpCallParams;
+
+
+ lResult = SendMessage( ghWnd, MYMSG_LINEMAKECALL, 0, (LPARAM)pParams);
+
+
+ return lResult;
+}
+
+
+//****************************************************************************
+//****************************************************************************
+//****************************************************************************
+LONG PASCAL TapiCallbackThunk( DWORD dwDevice,
+ DWORD dwMessage,
+ DWORD dwInstance,
+ DWORD dwParam1,
+ DWORD dwParam2,
+ DWORD dwParam3,
+ DWORD dwjunk
+ )
+{
+
+
+ DBGOUT((2, "TapiCallbackThunk <<<----------------"));
+
+ return 0;
+}
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+void HandleCallback( PCOPYDATASTRUCT pCds )
+{
+ DWORD dwCallbackType = ((LPDWORD)pCds->lpData)[0];
+ LPDWORD lpdwCallbackData = (LPDWORD)pCds->lpData;
+
+
+
+ switch ( dwCallbackType )
+ {
+
+ case CALLBACK_ASYNCCOMPLETION:
+ DBGOUT((2, "AsyncCompletion"));
+ (((ASYNC_COMPLETION)(pCds->dwData)))( lpdwCallbackData[1],
+ lpdwCallbackData[2]
+ );
+ break;
+
+
+
+ case CALLBACK_LINEEVENT:
+
+ DBGOUT((2, "LineEvent"));
+
+ if ( lpdwCallbackData[3] == LINE_NEWCALL )
+ {
+ lpdwCallbackData[5] = (DWORD)WOWGetVDMPointer(
+ lpdwCallbackData[5],
+ sizeof(DWORD),
+ 1
+ );
+ }
+
+ //FALTHROUGH!!!
+
+ case CALLBACK_LINECREATE:
+
+ if ( dwCallbackType == CALLBACK_LINECREATE )
+ {
+ DBGOUT((2, "LineCreate"));
+ }
+
+
+ (((FARPROC)(pCds->dwData)))( lpdwCallbackData[1],
+ lpdwCallbackData[2],
+ lpdwCallbackData[3],
+ lpdwCallbackData[4],
+ lpdwCallbackData[5],
+ lpdwCallbackData[6]
+ );
+
+#if DBG
+ if ( dwCallbackType == CALLBACK_LINEEVENT &&
+ lpdwCallbackData[3] == LINE_NEWCALL )
+ DBGOUT((11, "Returned htCall=0x%08lx", *(LPDWORD)(lpdwCallbackData[5])));
+#endif
+ break;
+
+
+ case CALLBACK_PHONEEVENT:
+ DBGOUT((2, "PhoneEvent"));
+ case CALLBACK_PHONECREATE:
+ DBGOUT((2, "PhoneCreate?"));
+ (((FARPROC)(pCds->dwData)))( lpdwCallbackData[1],
+ lpdwCallbackData[2],
+ lpdwCallbackData[3],
+ lpdwCallbackData[4],
+ lpdwCallbackData[5]
+ );
+ break;
+
+
+#if DBG
+ default:
+ DBGOUT((1, "Invalid callback type!!"));
+ // Should rip or assert?
+ break;
+#endif
+ }
+}
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+LRESULT CALLBACK _loadds MyWndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
+{
+
+ DBGOUT((91, "msggg"));
+
+ switch( nMsg )
+ {
+
+ case TSP3216L_MESSAGE:
+ if ((wParam == 1) && (lParam == 2) )
+ DBGOUT((0," Got a message thingy"));
+ break;
+
+
+ case MYMSG_PROVIDERINIT:
+ DBGOUT((2, "Got a providerInit message"));
+ return TSPI_providerInit16(
+ ((LPDWORD)lParam)[0],
+ ((LPDWORD)lParam)[1],
+ ((LPDWORD)lParam)[2],
+ ((LPDWORD)lParam)[3],
+ ((LPDWORD)lParam)[4],
+ ((LPDWORD)lParam)[5],
+ (ASYNC_COMPLETION)((LPDWORD)lParam)[6]
+ );
+ break;
+
+
+ case MYMSG_PROVIDERSHUTDOWN:
+ DBGOUT((2, "Got a providerShutdown message"));
+ return TSPI_providerShutdown16(
+ lParam
+ );
+ break;
+
+
+ case MYMSG_PROVIDERCONFIG:
+ DBGOUT((2, "Got a providerConfig message"));
+ return TSPI_providerConfig(
+ (HWND)((LPDWORD)lParam)[0],
+ ((LPDWORD)lParam)[1]
+ );
+ break;
+
+
+ case MYMSG_LINEMAKECALL:
+ DBGOUT((2, "Got a lineMakeCall message"));
+ return TSPI_lineMakeCall16(
+ (DRV_REQUESTID)((LPDWORD)lParam)[0],
+ (HDRVLINE)((LPDWORD)lParam)[1],
+ (HTAPICALL)((LPDWORD)lParam)[2],
+ (LPHDRVCALL)((LPDWORD)lParam)[3],
+ (LPCSTR)((LPDWORD)lParam)[4],
+ (DWORD)((LPDWORD)lParam)[5],
+ (LPLINECALLPARAMS)((LPDWORD)lParam)[6]
+ );
+ break;
+
+
+ case MYMSG_LINECONFIGDIALOG:
+ DBGOUT((2, "Got a lineConfigDialog message"));
+ return TSPI_lineConfigDialog(
+ ((LPDWORD)lParam)[0],
+ (HWND)((LPDWORD)lParam)[1],
+ (LPCSTR)((LPDWORD)lParam)[2]
+ );
+ break;
+
+
+ case MYMSG_PHONECONFIGDIALOG:
+ DBGOUT((2, "Got a phoneConfigDialog message"));
+ return TSPI_phoneConfigDialog(
+ ((LPDWORD)lParam)[0],
+ (HWND)((LPDWORD)lParam)[1],
+ (LPCSTR)((LPDWORD)lParam)[2]
+ );
+ break;
+
+
+ case WM_COPYDATA:
+ DBGOUT((11, "VaHoo!"));
+
+ HandleCallback( (PCOPYDATASTRUCT)lParam );
+
+ break;
+
+
+ case WM_CLOSE:
+ DestroyWindow( hWnd );
+ break;
+
+
+ case WM_DESTROY:
+ PostQuitMessage(0);
+ break;
+
+
+ default:
+ return DefWindowProc( hWnd, nMsg, wParam, lParam);
+ }
+ DBGOUT((2, "msggg done"));
+
+ return(FALSE);
+}
+
+
+
+
+
+
diff --git a/private/tapi/dev/sp/tsp3216/tsp3216l/tsp3216l.def b/private/tapi/dev/sp/tsp3216/tsp3216l/tsp3216l.def
new file mode 100644
index 000000000..5ac7556a6
--- /dev/null
+++ b/private/tapi/dev/sp/tsp3216/tsp3216l/tsp3216l.def
@@ -0,0 +1,130 @@
+LIBRARY TSP3216l
+PROTMODE
+CODE MOVEABLE DISCARDABLE
+DATA PRELOAD
+
+EXPORTS
+ TSPI_lineAccept @500
+ TSPI_lineAddToConference @501
+ TSPI_lineAnswer @502
+ TSPI_lineBlindTransfer @503
+ TSPI_lineClose @504
+ TSPI_lineCloseCall @505
+ TSPI_lineCompleteCall @506
+ TSPI_lineCompleteTransfer @507
+ TSPI_lineConditionalMediaDetection @508
+ TSPI_lineConfigDialog @509
+ TSPI_lineDevSpecific @510
+ TSPI_lineDevSpecificFeature @511
+ TSPI_lineDial @512
+ TSPI_lineDrop @513
+ TSPI_lineForward @514
+ TSPI_lineGatherDigits @515
+ TSPI_lineGenerateDigits @516
+ TSPI_lineGenerateTone @517
+ TSPI_lineGetAddressCaps @518
+ TSPI_lineGetAddressID @519
+ TSPI_lineGetAddressStatus @520
+ TSPI_lineGetCallAddressID @521
+ TSPI_lineGetCallInfo @522
+ TSPI_lineGetCallStatus @523
+ TSPI_lineGetDevCaps @524
+ TSPI_lineGetDevConfig @525
+ TSPI_lineGetExtensionID @526
+ TSPI_lineGetIcon @527
+ TSPI_lineGetID @528
+ TSPI_lineGetLineDevStatus @529
+ TSPI_lineGetNumAddressIDs @530
+ TSPI_lineHold @531
+ TSPI_lineMakeCall @532
+ TSPI_lineMonitorDigits @533
+ TSPI_lineMonitorMedia @534
+ TSPI_lineMonitorTones @535
+ TSPI_lineNegotiateExtVersion @536
+ TSPI_lineNegotiateTSPIVersion @537
+ TSPI_lineOpen @538
+ TSPI_linePark @539
+ TSPI_linePickup @540
+ TSPI_linePrepareAddToConference @541
+ TSPI_lineRedirect @542
+ TSPI_lineRemoveFromConference @543
+ TSPI_lineSecureCall @544
+ TSPI_lineSelectExtVersion @545
+ TSPI_lineSendUserUserInfo @546
+ TSPI_lineSetAppSpecific @547
+ TSPI_lineSetCallParams @548
+ TSPI_lineSetDefaultMediaDetection @549
+ TSPI_lineSetDevConfig @550
+ TSPI_lineSetMediaControl @551
+ TSPI_lineSetMediaMode @552
+ TSPI_lineSetStatusMessages @553
+ TSPI_lineSetTerminal @554
+ TSPI_lineSetupConference @555
+ TSPI_lineSetupTransfer @556
+ TSPI_lineSwapHold @557
+ TSPI_lineUncompleteCall @558
+ TSPI_lineUnhold @559
+ TSPI_lineUnpark @560
+
+ TSPI_phoneClose @561
+ TSPI_phoneConfigDialog @562
+ TSPI_phoneDevSpecific @563
+ TSPI_phoneGetButtonInfo @564
+ TSPI_phoneGetData @565
+ TSPI_phoneGetDevCaps @566
+ TSPI_phoneGetDisplay @567
+ TSPI_phoneGetExtensionID @568
+ TSPI_phoneGetGain @569
+ TSPI_phoneGetHookSwitch @570
+ TSPI_phoneGetIcon @571
+ TSPI_phoneGetID @572
+ TSPI_phoneGetLamp @573
+ TSPI_phoneGetRing @574
+ TSPI_phoneGetStatus @575
+ TSPI_phoneGetVolume @576
+ TSPI_phoneNegotiateExtVersion @577
+ TSPI_phoneNegotiateTSPIVersion @578
+ TSPI_phoneOpen @579
+ TSPI_phoneSelectExtVersion @580
+ TSPI_phoneSetButtonInfo @581
+ TSPI_phoneSetData @582
+ TSPI_phoneSetDisplay @583
+ TSPI_phoneSetGain @584
+ TSPI_phoneSetHookSwitch @585
+ TSPI_phoneSetLamp @586
+ TSPI_phoneSetRing @587
+ TSPI_phoneSetStatusMessages @588
+ TSPI_phoneSetVolume @589
+
+ TSPI_providerConfig @590
+ TSPI_providerInit @591
+ TSPI_providerInstall @592
+ TSPI_providerRemove @593
+ TSPI_providerShutdown @594
+
+ TSPI_providerEnumDevices @595
+ TSPI_lineDropOnClose @596
+ TSPI_lineDropNoOwner @597
+ TSPI_providerCreateLineDevice @598
+ TSPI_providerCreatePhoneDevice @599
+ TSPI_lineSetCurrentLocation @600
+ TSPI_lineConfigDialogEdit @601
+ TSPI_lineReleaseUserUserInfo @602
+
+ TSPI_providerGenericDialogData @608
+ TSPI_providerUIIdentify @609
+
+ TUISPI_lineConfigDialog @610
+ TUISPI_lineConfigDialogEdit @611
+ TUISPI_phoneConfigDialog @612
+ TUISPI_providerConfig @613
+ TUISPI_providerInstall @616
+ TUISPI_providerRemove @617
+
+
+
+
+ TapiThk_ThunkData32
+ TapiFThk_ThunkData32
+
+ Tapi32_ThunkData32
diff --git a/private/tapi/dev/sp/tsp3216/tsp3216l/tsp3216l.h b/private/tapi/dev/sp/tsp3216/tsp3216l/tsp3216l.h
new file mode 100644
index 000000000..99744d0ff
--- /dev/null
+++ b/private/tapi/dev/sp/tsp3216/tsp3216l/tsp3216l.h
@@ -0,0 +1,49 @@
+/* TSP3216L.H
+ Copyright 1995 (C) Microsoft Corporation
+
+ 32-bit TAPI service provider to act as a cover for a system's 16-bit SPs
+
+ 16-bit part: TSP3216S.DLL
+ 32-bit part: TSP3216L.DLL
+
+ t-jereh 20-July-1995
+
+ TODO:
+ 1) allow debug levels
+ 2) if oom in InitializeSPs(), fail
+
+ */
+
+#define ERR_NONE 0 /* success return value */
+
+#define TSPI_PROC_LAST 103 /* there are TSPI functions from 500 to 602 */
+
+
+// structs
+
+typedef struct tagMYLINE
+ {
+ HDRVLINE hdLine;
+ int iProvider;
+ DWORD dwDeviceID;
+ LINEEVENT lpfnEventProc;
+ HTAPILINE htLine;
+ } MYLINE, *LPMYLINE;
+
+
+typedef struct tagMYPHONE
+ {
+ HDRVPHONE hdPhone;
+ int iProvider;
+ DWORD dwDeviceID;
+ PHONEEVENT lpfnEventProc;
+ HTAPIPHONE htPhone;
+ } MYPHONE, *LPMYPHONE;
+
+
+typedef struct tagMYCALL
+ {
+ HDRVCALL hdCall;
+ int iProvider;
+ DWORD dwDeviceID;
+ } MYCALL, *LPMYCALL;
diff --git a/private/tapi/dev/sp/tsp3216/tsp3216l/tsp3216l.mak b/private/tapi/dev/sp/tsp3216/tsp3216l/tsp3216l.mak
new file mode 100644
index 000000000..81db3f3af
--- /dev/null
+++ b/private/tapi/dev/sp/tsp3216/tsp3216l/tsp3216l.mak
@@ -0,0 +1,177 @@
+# Microsoft Visual C++ Generated NMAKE File, Format Version 2.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+!IF "$(CFG)" == ""
+CFG=Win32 Debug
+!MESSAGE No configuration specified. Defaulting to Win32 Debug.
+!ENDIF
+
+!IF "$(CFG)" != "Win32 Release" && "$(CFG)" != "Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE on this makefile
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "tsp3216l.mak" CFG="Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+################################################################################
+# Begin Project
+# PROP Target_Last_Scanned "Win32 Debug"
+MTL=MkTypLib.exe
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "WinRel"
+# PROP BASE Intermediate_Dir "WinRel"
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "WinRel"
+# PROP Intermediate_Dir "WinRel"
+OUTDIR=.\WinRel
+INTDIR=.\WinRel
+
+ALL : $(OUTDIR)/tsp3216l.dll $(OUTDIR)/tsp3216l.bsc
+
+$(OUTDIR) :
+ if not exist $(OUTDIR)/nul mkdir $(OUTDIR)
+
+# ADD BASE MTL /nologo /D "NDEBUG" /win32
+# ADD MTL /nologo /D "NDEBUG" /win32
+MTL_PROJ=/nologo /D "NDEBUG" /win32
+# ADD BASE CPP /nologo /MT /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR /c
+# ADD CPP /nologo /MT /W3 /GX /YX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "DEBUG" /FR /c
+CPP_PROJ=/nologo /MT /W3 /GX /YX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D\
+ "DEBUG" /FR$(INTDIR)/ /Fp$(OUTDIR)/"tsp3216l.pch" /Fo$(INTDIR)/ /c
+CPP_OBJS=.\WinRel/
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+BSC32_FLAGS=/nologo /o$(OUTDIR)/"tsp3216l.bsc"
+BSC32_SBRS= \
+ $(INTDIR)/tsp3216l.sbr
+
+$(OUTDIR)/tsp3216l.bsc : $(OUTDIR) $(BSC32_SBRS)
+ $(BSC32) @<<
+ $(BSC32_FLAGS) $(BSC32_SBRS)
+<<
+
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:windows /DLL /MACHINE:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wow32.lib /NOLOGO /SUBSYSTEM:windows /DLL /MACHINE:I386
+LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
+ advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\
+ odbccp32.lib wow32.lib /NOLOGO /SUBSYSTEM:windows /DLL /INCREMENTAL:no\
+ /PDB:$(OUTDIR)/"tsp3216l.pdb" /MACHINE:I386 /DEF:".\TSP3216L.DEF"\
+ /OUT:$(OUTDIR)/"tsp3216l.dll" /IMPLIB:$(OUTDIR)/"tsp3216l.lib"
+DEF_FILE=.\TSP3216L.DEF
+LINK32_OBJS= \
+ $(INTDIR)/tsp3216l.obj
+
+$(OUTDIR)/tsp3216l.dll : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF "$(CFG)" == "Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "WinDebug"
+# PROP BASE Intermediate_Dir "WinDebug"
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "WinDebug"
+# PROP Intermediate_Dir "WinDebug"
+OUTDIR=.\WinDebug
+INTDIR=.\WinDebug
+
+ALL : $(OUTDIR)/tsp3216l.dll $(OUTDIR)/tsp3216l.bsc
+
+$(OUTDIR) :
+ if not exist $(OUTDIR)/nul mkdir $(OUTDIR)
+
+# ADD BASE MTL /nologo /D "_DEBUG" /win32
+# ADD MTL /nologo /D "_DEBUG" /win32
+MTL_PROJ=/nologo /D "_DEBUG" /win32
+# ADD BASE CPP /nologo /MT /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /c
+# ADD CPP /nologo /MT /W3 /GX /Zi /YX /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "DEBUG" /FR /c
+CPP_PROJ=/nologo /MT /W3 /GX /Zi /YX /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS"\
+ /D "DEBUG" /FR$(INTDIR)/ /Fp$(OUTDIR)/"tsp3216l.pch" /Fo$(INTDIR)/\
+ /Fd$(OUTDIR)/"tsp3216l.pdb" /c
+CPP_OBJS=.\WinDebug/
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+BSC32_FLAGS=/nologo /o$(OUTDIR)/"tsp3216l.bsc"
+BSC32_SBRS= \
+ $(INTDIR)/tsp3216l.sbr
+
+$(OUTDIR)/tsp3216l.bsc : $(OUTDIR) $(BSC32_SBRS)
+ $(BSC32) @<<
+ $(BSC32_FLAGS) $(BSC32_SBRS)
+<<
+
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:windows /DLL /DEBUG /MACHINE:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wow32.lib /NOLOGO /SUBSYSTEM:windows /DLL /DEBUG /MACHINE:I386
+LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
+ advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\
+ odbccp32.lib wow32.lib /NOLOGO /SUBSYSTEM:windows /DLL /INCREMENTAL:yes\
+ /PDB:$(OUTDIR)/"tsp3216l.pdb" /DEBUG /MACHINE:I386 /DEF:".\TSP3216L.DEF"\
+ /OUT:$(OUTDIR)/"tsp3216l.dll" /IMPLIB:$(OUTDIR)/"tsp3216l.lib"
+DEF_FILE=.\TSP3216L.DEF
+LINK32_OBJS= \
+ $(INTDIR)/tsp3216l.obj
+
+$(OUTDIR)/tsp3216l.dll : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ENDIF
+
+.c{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+.cpp{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+.cxx{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+################################################################################
+# Begin Group "Source Files"
+
+################################################################################
+# Begin Source File
+
+SOURCE=.\tsp3216l.c
+
+$(INTDIR)/tsp3216l.obj : $(SOURCE) $(INTDIR)
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\TSP3216L.DEF
+# End Source File
+# End Group
+# End Project
+################################################################################
diff --git a/private/tapi/dev/sp/tsp3216/tsp3216l/tsp3216l.rc b/private/tapi/dev/sp/tsp3216/tsp3216l/tsp3216l.rc
new file mode 100644
index 000000000..fa099ea3f
--- /dev/null
+++ b/private/tapi/dev/sp/tsp3216/tsp3216l/tsp3216l.rc
@@ -0,0 +1,24 @@
+//
+// (c) 1995 Microsoft Corporation. All Rights Reserved.
+//
+/* Version Numbering stuff */
+
+
+#include <windows.h>
+
+// Is the following FLAG good to use for this?
+#if WINNT
+#include <ntverp.h>
+#else
+#include <version.h>
+#endif
+
+#define VER_FILEDESCRIPTION_STR "Microsoft\256 Windows(TM) Telephony 16bit SP support"
+#define VER_INTERNALNAME_STR "16bit SP support"
+#define VER_ORIGINALFILENAME_STR "tsp3216l.tsp"
+#define VER_LEGALCOPYRIGHT_STR "Copyright \251 Microsoft Corporation 1995. All Rights Reserved."
+
+#define VER_FILETYPE VFT_APP
+#define VER_FILESUBTYPE VFT2_UNKNOWN
+
+#include <common.ver>