diff options
author | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
---|---|---|
committer | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
commit | e611b132f9b8abe35b362e5870b74bce94a1e58e (patch) | |
tree | a5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/oleutest/perf | |
download | NT4.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/oleutest/perf')
23 files changed, 3010 insertions, 0 deletions
diff --git a/private/oleutest/perf/dirs b/private/oleutest/perf/dirs new file mode 100644 index 000000000..c478c620d --- /dev/null +++ b/private/oleutest/perf/dirs @@ -0,0 +1,41 @@ +!IF 0 + +Copyright (c) 1989 Microsoft Corporation + +Module Name: + + dirs. + +Abstract: + + This file specifies the subdirectories of the current directory that + contain component makefiles. + + +Author: + + Dean Edwards (DeanE) 11-Jan-1994 + +!ENDIF + +# +# This is a list of all subdirectories that build required components. +# Each subdirectory name should appear on a line by itself. The build +# follows the order in which the subdirectories are specified. +# + +DIRS= \ + idl \ + perfuuid \ + proxy \ + perfsrv \ + perfcli \ + +# +# This is a list of all subdirectories that build optional components. +# Each subdirectory name should appear on a line by itself. The build +# follows the order in which the subdirectories are specified. +# + +OPTIONAL_DIRS= + diff --git a/private/oleutest/perf/idl/iperf.idl b/private/oleutest/perf/idl/iperf.idl new file mode 100644 index 000000000..bb6d0affa --- /dev/null +++ b/private/oleutest/perf/idl/iperf.idl @@ -0,0 +1,32 @@ +//[ IPerf_itf +//+------------------------------------------------------------------- +// +// Interface: IPerf (ib) +// +// Purpose: Interface for manipulating performance +// +// History: 5-Oct-93 AlexMit Created +// +// Notes: +// +//-------------------------------------------------------------------- + +[ object, + uuid(91062994-A3E7-101A-B4AC-08002B30612C), + pointer_default(unique) ] + +interface IPerf : IUnknown +{ + import "unknwn.idl"; + + HRESULT NullCall(); + + HRESULT HResultCall(); + + HRESULT GetAnotherObject( [out] IPerf **another ); + + HRESULT PassMoniker( IMoniker * ); +} + +//] +
\ No newline at end of file diff --git a/private/oleutest/perf/idl/makefile b/private/oleutest/perf/idl/makefile new file mode 100644 index 000000000..510cce95d --- /dev/null +++ b/private/oleutest/perf/idl/makefile @@ -0,0 +1,9 @@ +############################################################################ +# +# Copyright (C) 1992, Microsoft Corporation. +# +# All rights reserved. +# +############################################################################ + +!include $(NTMAKEENV)\makefile.def diff --git a/private/oleutest/perf/idl/makefile.inc b/private/oleutest/perf/idl/makefile.inc new file mode 100644 index 000000000..535a56369 --- /dev/null +++ b/private/oleutest/perf/idl/makefile.inc @@ -0,0 +1,32 @@ +CPP_CMD=cl + +!if $(386) +CPP_CMD=cl386 +!endif + +!if $(ALPHA) +CPP_CMD=$(ALPHA_CC) +!endif + +iperf.h: iperf.idl + midl iperf.idl \ + -Zp8 \ + -I$(INCLUDES) \ + -ms_ext \ + -c_ext \ + -out ..\proxy \ + -header ..\idl\iperf.h \ + -iid ..\perfuuid\iperf_i.c \ + $(C_DEFINES) \ + -cpp_cmd $(CPP_CMD) \ + -cpp_opt "-nologo -DMIDL_PASS $(C_DEFINES) -I$(INCLUDES) -E -Tc" + +# +# This target compiles all .idl files into their corresponding _?.c?? and +# .h components +# +allidl: iperf.h + + +clean: + erase iperf.h >NUL 2>NUL diff --git a/private/oleutest/perf/idl/perf.reg b/private/oleutest/perf/idl/perf.reg new file mode 100644 index 000000000..2a09ca044 --- /dev/null +++ b/private/oleutest/perf/idl/perf.reg @@ -0,0 +1,22 @@ + +; registry entries for IPerf interface. these map the interfaces +; to the proxy/stub code in iperf.dll + + +\Registry\MACHINE\SOFTWARE\Classes\Interface\{91062994-A3E7-101A-B4AC-08002B30612C} + = IPerf +\Registry\MACHINE\SOFTWARE\Classes\Interface\{91062994-A3E7-101A-B4AC-08002B30612C}\ProxyStubClsid32 + = {91062994-A3E7-101A-B4AC-08002B30612C} + +\Registry\MACHINE\SOFTWARE\Classes\CLSID\{91062994-A3E7-101A-B4AC-08002B30612C} + = CPrxyIPerf +\Registry\MACHINE\SOFTWARE\Classes\CLSID\{91062994-A3E7-101A-B4AC-08002B30612C}\InprocServer32 + = iperf.dll + +\Registry\MACHINE\SOFTWARE\Classes\CLSID\{1AFDBB80-AA32-101A-B4AD-08002B30612C} + = CPerfClassFactory +\Registry\MACHINE\SOFTWARE\Classes\CLSID\{1AFDBB80-AA32-101A-B4AD-08002B30612C}\LocalServer32 + = perfsrv.exe + + +
\ No newline at end of file diff --git a/private/oleutest/perf/idl/sources b/private/oleutest/perf/idl/sources new file mode 100644 index 000000000..5dff48ad5 --- /dev/null +++ b/private/oleutest/perf/idl/sources @@ -0,0 +1,66 @@ +!IF 0 + +Copyright (c) 1989 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: + + Dean Edwards (DeanE) 11-Jan-1993 + +!ENDIF + +MAJORCOMP = comutest +MINORCOMP = channelperf + +# +# This is the name of the target built from the source files specified +# below. The name should include neither the path nor the file extension. +# + +TARGETNAME= idl + +# +# This specifies where the target is to be built. A private target of +# type LIBRARY or DYNLINK should go to obj, whereas a public target of +# type LIBRARY or DYNLINK should go to $(BASEDIR)\public\sdk\lib. +# + +TARGETPATH= obj + +# +# This specifies the type of the target, such as PROGRAM, DYNLINK, LIBRARY, +# etc. +# + +TARGETTYPE= LIBRARY + +INCLUDES= $(BASEDIR)\public\sdk\inc;$(BASEDIR)\private\types\compobj + +C_DEFINES= $(C_DEFINES) + +BLDCRT= 1 + +SOURCES= + +UMTYPE= windows +UMAPPL= +UMTEST= +UMLIBS= + +USE_LIBCMT= + +NTTARGETFILE0= allidl + +PRECOMPILED_INCLUDE= + diff --git a/private/oleutest/perf/perfcli/makefile b/private/oleutest/perf/perfcli/makefile new file mode 100644 index 000000000..8991c0d2e --- /dev/null +++ b/private/oleutest/perf/perfcli/makefile @@ -0,0 +1,20 @@ +############################################################################ +# +# Copyright (C) 1992, Microsoft Corporation. +# +# All rights reserved. +# +############################################################################ + +!ifdef NTMAKEENV + +!include $(NTMAKEENV)\makefile.def + +!else # NTMAKEENV + +default: all + +!include $(CAIROLE)\com\makefile +!include $(DEPENDFILE) + +!endif # NTMAKEENV diff --git a/private/oleutest/perf/perfcli/perfcli.cxx b/private/oleutest/perf/perfcli/perfcli.cxx new file mode 100644 index 000000000..0df59c724 --- /dev/null +++ b/private/oleutest/perf/perfcli/perfcli.cxx @@ -0,0 +1,549 @@ +//+------------------------------------------------------------- +// +// File: perfcli.cxx +// +// Contents: First attempt at getting perfcliing to work +// +// This is the client side +// +// +//--------------------------------------------------------------- + +#include <windows.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.h> +#include <io.h> + +#include <ole2.h> +#include "iperf.h" +#include "..\perfsrv\perfsrv.hxx" +#include <memalloc.h> + +#pragma hdrstop + +#define TEST_FILE L"\\tmp\\test" + +void QueryMsg( void ); + +// These are Cairo symbols. Just define them here so I don't have to rip +// out or conditionally compile all references to them. +#define COINIT_MULTITHREADED 0 +#define COINIT_SINGLETHREADED 1 + +DWORD thread_mode = COINIT_SINGLETHREADED; +int num_objects = 1; +int num_iterations = 1000; +HANDLE helper_wait; +HANDLE main_wait; + +/*************************************************************************/ +int DoTest() +{ + IPerf **perf; + HRESULT result; + DWORD time_first; + DWORD waste; + int i; + int j; + BOOL success; + LARGE_INTEGER frequency; + LARGE_INTEGER count_first; + LARGE_INTEGER count_last; + LARGE_INTEGER dummy; + + // Allocate memory to hold the object and interface pointers. + perf = (IPerf **) malloc( sizeof(void *) * num_objects ); + if (perf == NULL) + { + printf( "Could not get memory.\n" ); + return 1; + } + + // Get a test object. + result = CoCreateInstance( CLSID_IPerf, NULL, CLSCTX_LOCAL_SERVER, IID_IPerf, + (void **) &perf[0] ); + if (!SUCCEEDED(result)) + { + printf( "Could not create instance of performance server: %x\n", result ); + return 1; + } + + // Create the required number of objects. + for (i = 1; i < num_objects; i++) + { + result = perf[0]->GetAnotherObject( &perf[i] ); + if (!SUCCEEDED(result)) + { + printf( "Could not get enough objects: 0x%x\n", result ); + return 1; + } + perf[i]->NullCall(); + } + + // Prompt to start when the user is ready. + // printf( "Ready? " ); + // gets( s ); + + // Compute the time spent just looping. + waste = GetTickCount(); + for (i = 0; i < num_iterations; i++) + ; + waste = GetTickCount() - waste; + + // Repeatedly call the first object to time it. + time_first = GetTickCount(); + for (i = 0; i < num_iterations; i++) + perf[0]->NullCall(); + time_first = GetTickCount() - time_first - waste; + + // Print the results. + printf( "%d uS/Call\n", time_first*1000/num_iterations ); + +/* + // Measure the same thing using the performance counter. + success = QueryPerformanceFrequency( &frequency ); + if (!success) + { + printf( "Could not query performance frequency.\n" ); + goto free; + } + success = QueryPerformanceCounter( &count_first ); + if (!success) + { + printf( "Could not query performance counter.\n" ); + goto free; + } + perf[0]->NullCall(); + success = QueryPerformanceCounter( &count_last ); + if (!success) + { + printf( "Could not query performance counter.\n" ); + goto free; + } + if (count_last.HighPart != count_first.HighPart || + frequency.HighPart != 0) + printf( "\n\n***** Overflow *****\n\n\n" ); + count_last.LowPart = (count_last.LowPart - count_first.LowPart) * 1000000 / + frequency.LowPart; + printf( "\nFrequency %d\n", frequency.LowPart ); + printf( "%d uS/Call\n", count_last.LowPart ); + + // How long does it take to query the performance counter? + success = QueryPerformanceCounter( &count_first ); + if (!success) + { + printf( "Could not query performance counter.\n" ); + goto free; + } + for (i = 0; i < num_iterations; i++) + QueryPerformanceCounter( &dummy ); + success = QueryPerformanceCounter( &count_last ); + if (!success) + { + printf( "Could not query performance counter.\n" ); + goto free; + } + if (count_last.HighPart != count_first.HighPart || + frequency.HighPart != 0) + printf( "\n\n***** Overflow *****\n\n\n" ); + count_last.LowPart = (count_last.LowPart - count_first.LowPart) / + num_iterations * 1000000 / frequency.LowPart; + printf( "%d uS/Query\n", count_last.LowPart ); +*/ + + // Prompt to let the user peruse the results. + // printf( "Done? " ); + // gets( s ); + + // Free the objects. +free: + for (i = 0; i < num_objects; i++) + perf[i]->Release(); + return 0; +} + +/*************************************************************************/ +void EventTest() +{ + DWORD time_first; + DWORD waste; + int i; + HANDLE helper; + + // Measure how long it takes to loop. + waste = GetTickCount(); + for (i = 0; i < num_iterations; i++) + ; + waste = GetTickCount() - waste; + + // Measure how long it takes to get an event + time_first = GetTickCount(); + for (i = 0; i < num_iterations; i++) + { + helper = CreateEvent( NULL, FALSE, FALSE, NULL ); + if (helper == NULL) + { + printf( "Could not create event %d.\n", i ); + return; + } + CloseHandle( helper ); + } + time_first = GetTickCount() - time_first - waste; + printf( "%d uS/CreateEvent\n", time_first*1000/num_iterations ); + + // Don't bother cleaning up. +} + +/*************************************************************************/ +/* Parse the arguments. */ +BOOL parse( int argc, char *argv[] ) +{ + int i; + int len; + TCHAR buffer[80]; + +#if 0 + // Look up the thread mode from the win.ini file. + len = GetProfileString( L"My Section", L"ThreadMode", L"MultiThreaded", buffer, + sizeof(buffer) ); + if (lstrcmp(buffer, L"SingleThreaded") == 0) + thread_mode = COINIT_SINGLETHREADED; + else if (lstrcmp(buffer, L"MultiThreaded") == 0) + thread_mode = COINIT_MULTITHREADED; +#endif + + // Parse each item, skip the command name + for (i = 1; i < argc; i++) + { + if (strcmp( argv[i], "Single" ) == 0) + thread_mode = COINIT_SINGLETHREADED; + else if (strcmp( argv[i], "Multi" ) == 0) + thread_mode = COINIT_MULTITHREADED; + else if (strcmp( argv[i], "-o" ) == 0) + { + if (argv[++i] == NULL) + { + printf( "You must include an object count after the -o option.\n" ); + return FALSE; + } + sscanf( argv[i], "%d", &num_objects ); + } + else if (strcmp( argv[i], "-i" ) == 0) + { + if (argv[++i] == NULL) + { + printf( "You must include an object count after the -i option.\n" ); + return FALSE; + } + sscanf( argv[i], "%d", &num_iterations ); + } + else + { + printf( "You don't know what you are doing!\n" ); + } + } + + return TRUE; +} + +/*************************************************************************/ +void MarshalTest() +{ + HANDLE file; + HRESULT result; + IMoniker *moniker; + IBindCtx *bindctx; + WCHAR *wide_name; + unsigned char *name; + int i; + IPerf *perf; + + // Initialize OLE. + result = OleInitialize(NULL); + if (FAILED(result)) + { + printf( "Could not initialize OLE: 0x%x\n", result ); + return; + } + + // Create file. + file = CreateFile( TEST_FILE, 0, 0, NULL, CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, NULL ); + if (file == INVALID_HANDLE_VALUE) + { + printf( "Could not create file." ); + return; + } + + // Create file moniker. + result = CreateFileMoniker( TEST_FILE, &moniker ); + if (FAILED(result)) + { + printf( "Could not create file moniker: 0x%x\n", result ); + return; + } + + // Get a bind context. + result = CreateBindCtx( NULL, &bindctx ); + if (FAILED(result)) + { + printf( "Could not create bind context: 0x%x\n", result ); + return; + } + + // Display name. + result = moniker->GetDisplayName( bindctx, NULL, &wide_name ); + if (FAILED(result)) + { + printf( "Could not get display name: 0x%x\n", result ); + return; + } + + // Convert the string to ascii and print it. + name = (unsigned char *) wide_name; + i = 0; + while (wide_name[i] != 0) + name[i] = wide_name[i++]; + name[i] = 0; + printf( "The moniker is called <%s>\n", name ); + + // Free string. + CoTaskMemFree( wide_name ); + + // Get a test object. + result = CoCreateInstance( CLSID_IPerf, NULL, CLSCTX_LOCAL_SERVER, IID_IPerf, + (void **) &perf ); + if (!SUCCEEDED(result)) + { + printf( "Could not create instance of performance server: %x\n", result ); + return; + } + + // Pass moniker to server. + result = perf->PassMoniker( moniker ); + if (FAILED(result)) + { + printf( "Could not give moniker to server: 0x%x\n", result ); + return; + } + + // Release everything. + CloseHandle( file ); + moniker->Release(); + bindctx->Release(); + perf->Release(); + OleUninitialize(); +} + + +//+-------------------------------------------------------------- +// Function: Main +// +// Synopsis: Executes the BasicBnd test +// +// Effects: None +// +// +// Returns: Exits with exit code 0 if success, 1 otherwise +// +// History: 05-Mar-92 Sarahj Created +// +//--------------------------------------------------------------- + +int _cdecl main(int argc, char *argv[]) +{ + BOOL initialized = FALSE; + HRESULT hresult = S_OK; + BOOL fFailed = FALSE; + + // Parse the command line arguments. + if (!parse( argc, argv )) + return 0; + + // Print the process id. + printf( "Hi, I am %x.\n", GetCurrentProcessId() ); + + // Time event creation. +// EventTest(); +// return 1; + + // Pass around monikers. +// MarshalTest(); + + // Measure message queue APIs. +// QueryMsg(); + + + // Print the thread mode. + if (thread_mode == COINIT_SINGLETHREADED) + { + printf( "Measuring performance for the single threaded mode.\n" ); + } + else + { + printf( "Measuring performance for the multithreaded mode.\n" ); + } + + // must be called before any other OLE API + hresult = OleInitialize(NULL); + + if (FAILED(hresult)) + { + printf("OleInitialize Failed with %lx\n", hresult); + goto exit_main; + } + initialized = TRUE; + + if (fFailed = DoTest()) + goto exit_main; + +/* + // Uninitialize and rerun in the other thread mode. + OleUninitialize(); + if (thread_mode == COINIT_SINGLETHREADED) + thread_mode = COINIT_MULTITHREADED; + else + thread_mode = COINIT_SINGLETHREADED; + + // Print the thread mode. + if (thread_mode == COINIT_SINGLETHREADED) + printf( "Measuring performance for the single threaded mode.\n" ); + else + printf( "Measuring performance for the multithreaded mode.\n" ); + + // must be called before any other OLE API + hresult = OleInitialize(NULL); + + if (FAILED(hresult)) + { + printf("OleInitialize Failed with %lx\n", hresult); + goto exit_main; + } + + if (fFailed = DoTest()) + goto exit_main; +*/ + +exit_main: + + if (initialized) + OleUninitialize(); + + if (!fFailed) + { + printf("\nCairole: PASSED\n"); + } + else + { + printf("\nCairole: FAILED\n"); + } + + return fFailed; +} + +/*************************************************************************/ +DWORD _stdcall MsgHelper( void *param ) +{ + int i; + + // Alternately signal and wait on an event. Do it one time too many + // because the main thread calls once to let us get set up. + for (i = 0; i < num_iterations+1; i++) + { + WaitForSingleObject( helper_wait, INFINITE ); + SetEvent( main_wait ); + } + +#define must_return_a_value return 0 + must_return_a_value; +} + +/*************************************************************************/ +void QueryMsg() +{ + DWORD time_first; + DWORD waste; + int i; + HANDLE helper; + DWORD thread_id; + + // Create an event. + helper_wait = CreateEvent( NULL, FALSE, FALSE, NULL ); + if (helper_wait == NULL) + { + printf( "Could not create event.\n" ); + return; + } + main_wait = CreateEvent( NULL, FALSE, FALSE, NULL ); + if (main_wait == NULL) + { + printf( "Could not create event.\n" ); + return; + } + + // Measure how long it takes to loop. + waste = GetTickCount(); + for (i = 0; i < num_iterations; i++) + ; + waste = GetTickCount() - waste; + + // Measure how long it takes to query the message queue. + time_first = GetTickCount(); + for (i = 0; i < num_iterations; i++) + GetQueueStatus( QS_ALLINPUT ); + time_first = GetTickCount() - time_first - waste; + printf( "%d uS/GetQueueStatus\n", time_first*1000/num_iterations ); + + // Start a thread to wake up this one. + helper = CreateThread( NULL, 0, MsgHelper, 0, 0, + &thread_id ); + if (helper == NULL) + { + printf( "Could not create helper thread.\n" ); + return; + } + + // Call MsgWaitForMultipleObjects once to let the thread get started. + SetEvent( helper_wait ); + MsgWaitForMultipleObjects( 1, &main_wait, FALSE, + INFINITE, QS_ALLINPUT ); + + // Measure how long it takes to call MsgWaitForMultipleObjects. + time_first = GetTickCount(); + for (i = 0; i < num_iterations; i++) + { + SetEvent( helper_wait ); + MsgWaitForMultipleObjects( 1, &main_wait, FALSE, + INFINITE, QS_ALLINPUT ); + } + time_first = GetTickCount() - time_first - waste; + printf( "%d uS/MsgWaitForMultipleObjects\n", time_first*1000/num_iterations ); + + // Start a thread to wake up this one. + helper = CreateThread( NULL, 0, MsgHelper, 0, 0, + &thread_id ); + if (helper == NULL) + { + printf( "Could not create helper thread.\n" ); + return; + } + + // Let the thread get started. + SetEvent( helper_wait ); + WaitForSingleObject( main_wait, INFINITE ); + + // Measure how long it takes to switch threads just using events. + time_first = GetTickCount(); + for (i = 0; i < num_iterations; i++) + { + SetEvent( helper_wait ); + WaitForSingleObject( main_wait, INFINITE ); + } + time_first = GetTickCount() - time_first - waste; + printf( "%d uS/MsgWaitForMultipleObjects\n", time_first*1000/num_iterations ); + + // Don't bother cleaning up. +} + diff --git a/private/oleutest/perf/perfcli/sources b/private/oleutest/perf/perfcli/sources new file mode 100644 index 000000000..1a3157b1e --- /dev/null +++ b/private/oleutest/perf/perfcli/sources @@ -0,0 +1,62 @@ + +MAJORCOMP = cairole +MINORCOMP = com + +# +# This is the name of the target built from the source files specified +# below. The name should include neither the path nor the file extension. +# + +TARGETNAME= perfcli + +# +# This specifies where the target is to be built. A private target of +# type LIBRARY or DYNLINK should go to obj, whereas a public target of +# type LIBRARY or DYNLINK should go to $(BASEDIR)\public\sdk\lib. +# + +TARGETPATH= obj + +# +# This specifies the type of the target, such as PROGRAM, DYNLINK, LIBRARY, +# etc. +# + +TARGETTYPE= PROGRAM + +INCLUDES= ..\idl;$(BASEDIR)\private\cinc + +C_DEFINES= \ + $(C_DEFINES) \ + -DFLAT \ + -DWIN32=100 \ + -D_NT1X_=100 \ + -DUNICODE \ + -D_UNICODE \ + -DNOEXCEPTIONS \ + -DCAIROLE_DOWNLEVEL + +BLDCRT= 1 + +SOURCES= \ + perfcli.cxx + + +UMTYPE= console +UMENTRY= +UMAPPL= +UMTEST= +UMLIBS= \ + ..\perfuuid\obj\*\perfuuid.lib \ + $(BASEDIR)\public\sdk\lib\*\uuid.lib \ + $(BASEDIR)\public\sdk\lib\*\ole32.lib \ + $(BASEDIR)\public\sdk\lib\*\rpcndr.lib \ + $(BASEDIR)\public\sdk\lib\*\rpcrt4.lib \ + $(BASEDIR)\public\sdk\lib\*\rpcns4.lib \ + $(BASEDIR)\public\sdk\lib\*\mpr.lib \ + $(BASEDIR)\public\sdk\lib\*\netapi32.lib \ + $(BASEDIR)\public\sdk\lib\*\kernel32.lib \ + $(BASEDIR)\public\sdk\lib\*\user32.lib \ + $(BASEDIR)\public\sdk\lib\*\advapi32.lib \ + $(BASEDIR)\public\sdk\lib\*\libc.lib + diff --git a/private/oleutest/perf/perfsrv/makefile b/private/oleutest/perf/perfsrv/makefile new file mode 100644 index 000000000..8991c0d2e --- /dev/null +++ b/private/oleutest/perf/perfsrv/makefile @@ -0,0 +1,20 @@ +############################################################################ +# +# Copyright (C) 1992, Microsoft Corporation. +# +# All rights reserved. +# +############################################################################ + +!ifdef NTMAKEENV + +!include $(NTMAKEENV)\makefile.def + +!else # NTMAKEENV + +default: all + +!include $(CAIROLE)\com\makefile +!include $(DEPENDFILE) + +!endif # NTMAKEENV diff --git a/private/oleutest/perf/perfsrv/perfsrv.cxx b/private/oleutest/perf/perfsrv/perfsrv.cxx new file mode 100644 index 000000000..5dfc9e188 --- /dev/null +++ b/private/oleutest/perf/perfsrv/perfsrv.cxx @@ -0,0 +1,475 @@ +//+------------------------------------------------------------------- +// +// File: perfsrv.cxx +// +// Contents: This file contins the DLL entry points +// LibMain +// DllGetClassObject (Bindings key func) +// CPerfCF (class factory) +// CPerf (actual class implementation) +// +// Classes: CPerfCF, CPerf +// +// +// History: 30-Nov-92 SarahJ Created +// +//--------------------------------------------------------------------- + +// Turn off ole Cairol IUnknown +#define __IUNKNOWN_TMP__ + + +#include <windows.h> +#include <ole2.h> +#include "perfsrv.hxx" +extern "C" { +#include <stdio.h> +#include <stdarg.h> +#include "wterm.h" +} + +// These are Cairo symbols. Just define them here so I don't have to rip +// out or conditionally compile all references to them. +#define COINIT_MULTITHREADED 0 +#define COINIT_SINGLETHREADED 1 + +#define IDM_DEBUG 0x100 + +// Count of objects we have instantiated. When we detect 0, we quit. +ULONG g_cUsage = 0; + +const TCHAR *szAppName = L"Performance Server"; + +HWND g_hMain; +DWORD thread_mode = COINIT_SINGLETHREADED; +DWORD MainThread; +DWORD junk; + + +void Display(TCHAR *pszFmt, ...) +{ + va_list marker; + TCHAR szBuffer[256]; + + va_start(marker, pszFmt); + + int iLen = vswprintf(szBuffer, pszFmt, marker); + + va_end(marker); + + // Display the message on terminal window + SendMessage(g_hMain, WM_PRINT_LINE, iLen, (LONG) szBuffer); +} + + + + +//+------------------------------------------------------------------------- +// +// Function: ProcessMenu +// +// Synopsis: Gets called when a WM_COMMAND message received. +// +// Arguments: [hWindow] - handle for the window +// [uiMessage] - message id +// [wParam] - word parameter +// [lParam] - long parameter +// +// Returns: DefWindowProc result +// +// History: 06-Aug-92 Ricksa Created +// +//-------------------------------------------------------------------------- +long ProcessMenu(HWND hWindow, UINT uiMessage, WPARAM wParam, LPARAM lParam, + void *) +{ + if ((uiMessage == WM_SYSCOMMAND) && (wParam == IDM_DEBUG)) + { + // Request for a debug breakpoint! + DebugBreak(); + } + + + return (DefWindowProc(hWindow, uiMessage, wParam, lParam)); +} + + +//+------------------------------------------------------------------------- +// +// Function: ProcessChar +// +// Synopsis: Gets called when a WM_CHAR message received. +// +// Arguments: [hWindow] - handle for the window +// [uiMessage] - message id +// [wParam] - word parameter +// [lParam] - long parameter +// +// Returns: DefWindowProc result +// +// History: 06-Aug-92 Ricksa Created +// +//-------------------------------------------------------------------------- +long ProcessChar(HWND hWindow, UINT uiMessage, WPARAM wParam, LPARAM lParam, + void *) +{ + return (DefWindowProc(hWindow, uiMessage, wParam, lParam)); +} + + +//+------------------------------------------------------------------------- +// +// Function: ProcessClose +// +// Synopsis: Gets called when a NC_DESTROY message received. +// +// Arguments: [hWindow] - handle for the window +// [uiMessage] - message id +// [wParam] - word parameter +// [lParam] - long parameter +// +// Returns: DefWindowProc result +// +// History: 06-Aug-92 Ricksa Created +// +//-------------------------------------------------------------------------- +long ProcessClose( + HWND hWindow, + UINT uiMessage, + WPARAM wParam, + LPARAM lParam, + void *pvCallBackData) +{ + // Take default action with message + return (DefWindowProc(hWindow, uiMessage, wParam, lParam)); +} + +//+------------------------------------------------------------------- +// +// Function: WinMain +// +// Synopsis: Entry point to DLL - does little else +// +// Arguments: +// +// Returns: TRUE +// +// History: 21-Nov-92 SarahJ Created +// +//-------------------------------------------------------------------- +int WINAPI WinMain( + HINSTANCE hInstance, + HINSTANCE hPrevInstance, + char *lpCmdLine, + int nCmdShow) +{ + // For windows message + MSG msg; + DWORD dwRegistration; + int len; + TCHAR buffer[80]; + MainThread = GetCurrentThreadId(); + + // Look up the thread mode from the win.ini file. +#if 0 + len = GetProfileString( L"My Section", L"ThreadMode", L"MultiThreaded", buffer, + sizeof(buffer) ); + if (lstrcmp(buffer, L"SingleThreaded") == 0) + thread_mode = COINIT_SINGLETHREADED; + else if (lstrcmp(buffer, L"MultiThreaded") == 0) + thread_mode = COINIT_MULTITHREADED; +#endif + + // Initialize the OLE libraries + OleInitialize(NULL); + + // Create our class factory + CPerfCF *perf_cf = new CPerfCF(); + + // Register our class with OLE + CoRegisterClassObject(CLSID_IPerf, perf_cf, CLSCTX_LOCAL_SERVER, + REGCLS_MULTIPLEUSE, &dwRegistration); + + // CoRegister bumps reference count so we don't have to! + perf_cf->Release(); + + // Register the window class + TermRegisterClass(hInstance, (LPTSTR) szAppName, + (LPTSTR) szAppName, (LPTSTR) (1)); + + // Create the server window + TermCreateWindow( + (LPTSTR) szAppName, + (LPTSTR) szAppName, + NULL, + ProcessMenu, + ProcessChar, + ProcessClose, + SW_SHOWNORMAL, + &g_hMain, + NULL); + + // Add debug option to system menu + HMENU hmenu = GetSystemMenu(g_hMain, FALSE); + + AppendMenu(hmenu, MF_SEPARATOR, 0, NULL); + AppendMenu(hmenu, MF_STRING | MF_ENABLED, IDM_DEBUG, L"Debug"); + + // Print the process id. + Display( L"Hi, I am %x.\n", GetCurrentProcessId() ); + + // Echo the mode. + if (thread_mode == COINIT_SINGLETHREADED) + Display(L"Server running in single threaded mode.\n"); + else + Display(L"Server running in multithreaded mode.\n"); + + // Message processing loop + while (GetMessage (&msg, NULL, 0, 0)) + { + TranslateMessage (&msg); + DispatchMessage (&msg); + } + + // Deregister out class - should release object as well + CoRevokeClassObject(dwRegistration); + + // Tell OLE we are going away. + OleUninitialize(); + + return (msg.wParam); /* Returns the value from PostQuitMessage */ +} + + + +/***************************************************************************/ +void CheckThread( TCHAR *name ) +{ + if (thread_mode == COINIT_SINGLETHREADED) + { + if (GetCurrentThreadId() != MainThread) + goto complain; + } + else + { + if (GetCurrentThreadId() == MainThread) + goto complain; + } + return; + +complain: + Display( L"*********************************************************\n" ); + Display( L"* *\n" ); + Display( L"* Error *\n" ); + Display( L"* *\n" ); + Display( L"* Method called on wrong thread. *\n" ); + Display( name ); + Display( L"* *\n" ); + Display( L"*********************************************************\n" ); +} + +/***************************************************************************/ +STDMETHODIMP_(ULONG) CPerf::AddRef( THIS ) +{ + CheckThread(L"STDMETHODIMP_(ULONG) CPerf::AddRef( THIS )"); + InterlockedIncrement( (long *) &ref_count ); + return ref_count; +} + +/***************************************************************************/ +CPerf::CPerf() +{ + ref_count = 1; + g_cUsage++; +} + +/***************************************************************************/ +CPerf::~CPerf() +{ + if (--g_cUsage == 0) + { + SendMessage(g_hMain, WM_TERM_WND, 0, 0); + } +} + +/***************************************************************************/ +STDMETHODIMP CPerf::GetAnotherObject( IPerf **another ) +{ + CheckThread(L"STDMETHODIMP CPerf::GetAnotherObject( IPerf **another )"); + *another = NULL; + CPerf *perf = new FAR CPerf(); + + if (perf == NULL) + { + return E_OUTOFMEMORY; + } + + *another = perf; + return S_OK; +} + +/***************************************************************************/ +STDMETHODIMP CPerf::HResultCall() +{ + CheckThread(L"STDMETHODIMP CPerf::HResultCall()"); + return S_OK; +} + +/***************************************************************************/ +STDMETHODIMP CPerf::NullCall() +{ + return S_OK; +} + +/***************************************************************************/ +STDMETHODIMP CPerf::PassMoniker( IMoniker *moniker ) +{ + HRESULT result; + IBindCtx *bindctx; + WCHAR *wide_name; + + // Get a bind context. + result = CreateBindCtx( NULL, &bindctx ); + if (FAILED(result)) + { + Display( L"Could not create bind context: 0x%x\n", result ); + return E_FAIL; + } + + // Display name. + result = moniker->GetDisplayName( bindctx, NULL, &wide_name ); + if (FAILED(result)) + { + Display( L"Could not get display name: 0x%x\n", result ); + return E_FAIL; + } + + // Display the name. + Display( L"The moniker is called <%s>\n", wide_name ); + + // Free string. + CoTaskMemFree( wide_name ); + + // Release everything. + moniker->Release(); + bindctx->Release(); + return S_OK; +} + +/***************************************************************************/ +STDMETHODIMP CPerf::QueryInterface( THIS_ REFIID riid, LPVOID FAR* ppvObj) +{ + CheckThread(L"STDMETHODIMP CPerf::QueryInterface( THIS_ REFIID riid, LPVOID FAR* ppvObj)" ); + if (IsEqualIID(riid, IID_IUnknown) || + IsEqualIID(riid, IID_IPerf)) + { + *ppvObj = (IUnknown *) this; + AddRef(); + return S_OK; + } + else + { + *ppvObj = NULL; + return E_NOINTERFACE; + } +} + +/***************************************************************************/ +STDMETHODIMP_(ULONG) CPerf::Release( THIS ) +{ + CheckThread(L"STDMETHODIMP_(ULONG) CPerf::Release( THIS )"); + if (InterlockedDecrement( (long*) &ref_count ) == 0) + { + delete this; + return 0; + } + else + return ref_count; +} + +/***************************************************************************/ +STDMETHODIMP_(ULONG) CPerfCF::AddRef( THIS ) +{ + CheckThread(L"STDMETHODIMP_(ULONG) CPerfCF::AddRef( THIS )"); + InterlockedIncrement( (long *) &ref_count ); + return ref_count; +} + +/***************************************************************************/ +CPerfCF::CPerfCF() +{ + ref_count = 1; +} + +/***************************************************************************/ +CPerfCF::~CPerfCF() +{ +} + +/***************************************************************************/ +STDMETHODIMP CPerfCF::CreateInstance( + IUnknown FAR* pUnkOuter, + REFIID iidInterface, + void FAR* FAR* ppv) +{ + CheckThread(L"STDMETHODIMP CPerfCF::CreateInstance(" ); + Display(L"CPerfCF::CreateInstance called\n"); + + *ppv = NULL; + if (pUnkOuter != NULL) + { + return E_FAIL; + } + + if (!IsEqualIID( iidInterface, IID_IPerf )) + return E_NOINTERFACE; + + CPerf *perf = new FAR CPerf(); + + if (perf == NULL) + { + return E_OUTOFMEMORY; + } + + *ppv = perf; + return S_OK; +} + +/***************************************************************************/ +STDMETHODIMP CPerfCF::LockServer(BOOL fLock) +{ + CheckThread( L"STDMETHODIMP CPerfCF::LockServer(BOOL fLock)" ); + return E_FAIL; +} + + +/***************************************************************************/ +STDMETHODIMP CPerfCF::QueryInterface( THIS_ REFIID riid, LPVOID FAR* ppvObj) +{ + CheckThread(L"STDMETHODIMP CPerfCF::QueryInterface( THIS_ REFIID riid, LPVOID FAR* ppvObj)"); + if (IsEqualIID(riid, IID_IUnknown) || + IsEqualIID(riid, IID_IClassFactory)) + { + *ppvObj = (IUnknown *) this; + AddRef(); + return S_OK; + } + + *ppvObj = NULL; + return E_NOINTERFACE; +} + +/***************************************************************************/ +STDMETHODIMP_(ULONG) CPerfCF::Release( THIS ) +{ + CheckThread(L"STDMETHODIMP_(ULONG) CPerfCF::Release( THIS )"); + if (InterlockedDecrement( (long*) &ref_count ) == 0) + { + delete this; + return 0; + } + else + return ref_count; +} + + diff --git a/private/oleutest/perf/perfsrv/perfsrv.hxx b/private/oleutest/perf/perfsrv/perfsrv.hxx new file mode 100644 index 000000000..9926a4094 --- /dev/null +++ b/private/oleutest/perf/perfsrv/perfsrv.hxx @@ -0,0 +1,101 @@ +//+------------------------------------------------------------------- +// +// File: perfsrv.hxx +// +// Contents: This file contins the DLL entry points +// LibMain +// DllGetClassObject (Bindings key func) +// DllCanUnloadNow +// CBasicBndCF (class factory) +// History: 30-Mar-92 SarahJ Created +// +//--------------------------------------------------------------------- + +#ifndef __PERFSRV_H__ +#define __PERFSRV_H__ + +#include "iperf.h" + +extern "C" const IID CLSID_IPerf; + +#define SINGLE_THREADED L"Single Threaded" +#define MULTI_THREADED L"Multi Threaded" +#define KEY L"SOFTWARE\\Microsoft\\PerfCli" + +//+------------------------------------------------------------------- +// +// Class: CPerfCF +// +// Synopsis: Class Factory for CPerf +// +// Methods: IUnknown - QueryInterface, AddRef, Release +// IClassFactory - CreateInstance +// +// History: 21-Mar-92 SarahJ Created +// +//-------------------------------------------------------------------- + + +class FAR CPerfCF: public IClassFactory +{ +public: + + // Constructor/Destructor + CPerfCF(); + ~CPerfCF(); + + // IUnknown + STDMETHODIMP QueryInterface(REFIID iid, void FAR * FAR * ppv); + STDMETHOD_(ULONG,AddRef) ( void ); + STDMETHOD_(ULONG,Release) ( void ); + + // IClassFactory + STDMETHODIMP CreateInstance( + IUnknown FAR* pUnkOuter, + REFIID iidInterface, + void FAR* FAR* ppv); + + STDMETHODIMP LockServer(BOOL fLock); + +private: + + ULONG ref_count; +}; + +//+------------------------------------------------------------------- +// +// Class: CPerf +// +// Synopsis: Test class +// +// Methods: +// +// History: 21-Mar-92 SarahJ Created +// +//-------------------------------------------------------------------- + + +class FAR CPerf: public IPerf +{ +public: + CPerf(); + ~CPerf(); + + // IUnknown + STDMETHODIMP QueryInterface(REFIID iid, void FAR * FAR * ppv); + STDMETHOD_(ULONG,AddRef) ( void ); + STDMETHOD_(ULONG,Release) ( void ); + + // IPerf + STDMETHOD (NullCall) ( void ); + STDMETHOD (HResultCall) ( void ); + STDMETHOD (GetAnotherObject) ( IPerf ** ); + STDMETHOD (PassMoniker) ( IMoniker * ); + +private: + + ULONG ref_count; +}; + + +#endif diff --git a/private/oleutest/perf/perfsrv/sources b/private/oleutest/perf/perfsrv/sources new file mode 100644 index 000000000..4cc1f9fd8 --- /dev/null +++ b/private/oleutest/perf/perfsrv/sources @@ -0,0 +1,62 @@ + +MAJORCOMP = cairole +MINORCOMP = com + +# +# This is the name of the target built from the source files specified +# below. The name should include neither the path nor the file extension. +# + +TARGETNAME= perfsrv + +# +# This specifies where the target is to be built. A private target of +# type LIBRARY or DYNLINK should go to obj, whereas a public target of +# type LIBRARY or DYNLINK should go to $(BASEDIR)\public\sdk\lib. +# + +TARGETPATH= obj + +# +# This specifies the type of the target, such as PROGRAM, DYNLINK, LIBRARY, +# etc. +# + +TARGETTYPE= PROGRAM + +INCLUDES= ..\idl;$(BASEDIR)\private\cinc + +C_DEFINES= \ + $(C_DEFINES) \ + -DFLAT \ + -DWIN32=100 \ + -D_NT1X_=100 \ + -DUNICODE \ + -D_UNICODE \ + -DNOEXCEPTIONS \ + -DCAIROLE_DOWNLEVEL + +BLDCRT= 1 + +SOURCES= \ + perfsrv.cxx \ + wterm.c + + +UMTYPE= windows +UMENTRY= winmain +UMAPPL= +UMTEST= +UMLIBS= \ + ..\perfuuid\obj\*\perfuuid.lib \ + $(BASEDIR)\public\sdk\lib\*\uuid.lib \ + $(BASEDIR)\public\sdk\lib\*\ole32.lib \ + $(BASEDIR)\public\sdk\lib\*\rpcndr.lib \ + $(BASEDIR)\public\sdk\lib\*\rpcrt4.lib \ + $(BASEDIR)\public\sdk\lib\*\rpcns4.lib \ + $(BASEDIR)\public\sdk\lib\*\mpr.lib \ + $(BASEDIR)\public\sdk\lib\*\netapi32.lib \ + $(BASEDIR)\public\sdk\lib\*\kernel32.lib \ + $(BASEDIR)\public\sdk\lib\*\user32.lib \ + $(BASEDIR)\public\sdk\lib\*\advapi32.lib + diff --git a/private/oleutest/perf/perfsrv/wterm.c b/private/oleutest/perf/perfsrv/wterm.c new file mode 100644 index 000000000..336f1e574 --- /dev/null +++ b/private/oleutest/perf/perfsrv/wterm.c @@ -0,0 +1,1027 @@ +/**************************************************************************** + + PROGRAM: wterm.c + + PURPOSE: Implementation of TermWClass Windows + + FUNCTIONS: + + + COMMENTS: + + +****************************************************************************/ + +#include "windows.h" +#include "stdlib.h" +#include "memory.h" +#include "wterm.h" + +#define MAX_ROWS 24 +#define MAX_COLS 80 + +typedef struct WData +{ + // Function to execute for processing a menu + MFUNCP pMenuProc; + + // Function to execute for processing a single character + CFUNCP pCharProc; + + // Function to execute when window is closed (terminated) + TFUNCP pCloseProc; + + // Pass on callback + void *pvCallBackData; + + BOOL fGotFocus; + + BOOL fCaretHidden; + + // Rows on the screen + int cRows; + + // Columns on the screen + int cCols; + + // Row at top of screen + int iTopRow; + + // Row at bottom of the screen + int iBottomRow; + + // First Column on screen + int iFirstCol; + + // Column at bottom of the screen + int iBottomCol; + + // Row for next character + int iNextRow; + + // Row for next column + int iNextCol; + + // Width of character + int cxChar; + + // Height of character + int cyChar; + + // Memory image of screen this is treated as a circular buffer + TCHAR aImage[MAX_ROWS] [MAX_COLS]; + + // First row in circular screen buffer + int iBufferTop; +} WData; + +static HANDLE hInst = 0; +TCHAR BlankLine[80]; + +static int +row_diff( + int row1, + int row2) +{ + return (row2 > row1) + ? MAX_ROWS - (row2 - row1) + : row1 - row2; +} + +static void +set_vscroll_pos( + HWND hwnd, + WData *pwdata) +{ + if (pwdata->cRows != 0) + { + // Save a few indirections by caching cRows + register int cRows = pwdata->cRows; + + // calculate distance bottom of screen from top of data buffer + register int top_from_row = row_diff(pwdata->iBottomRow, + pwdata->iBufferTop); + + // Output position of scroll bar + int new_pos = 0; + + if (top_from_row >= cRows) + { + // Calculate number of screens to display entire buffer + int screens_for_data = MAX_ROWS / cRows + + ((MAX_ROWS % cRows != 0) ? 1 : 0); + + // Figure out which screen the row falls in + int screen_loc = top_from_row / cRows + + ((top_from_row % cRows != 0) ? 1 : 0); + + // If the screen is in the last one set box to max + new_pos = (screen_loc == screens_for_data) + ? MAX_ROWS : screen_loc * cRows; + } + + SetScrollPos(hwnd, SB_VERT, new_pos, TRUE); + } +} + +static int +calc_row( + register int row, + WData *pwdata) +{ + register int top = pwdata->iTopRow; + static int boopa = 0; + + if (top > row) + boopa++; + + return (row >= top) ? row - top : (MAX_ROWS - (top - row)); +} + +static void +display_text( + HWND hwnd, + int row, + int col, + LPTSTR text, + int text_len, + WData *pWData) +{ + // Get the DC to display the text + HDC hdc = GetDC(hwnd); + + // Select Font + SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT)); + + // Hide caret while we are printing + HideCaret(hwnd); + + // Update the screen + TextOut(hdc, (col - pWData->iFirstCol) * pWData->cxChar, + calc_row(row, pWData) * pWData->cyChar, text, text_len); + + // Done with DC + ReleaseDC(hwnd, hdc); + + // Put the caret back now that we are done + ShowCaret(hwnd); +} + +static void +display_char( + HWND hwnd, + TCHAR char_to_display, + WData *pWData) +{ + // Update image buffer + pWData->aImage[pWData->iNextRow][pWData->iNextCol] = char_to_display; + + display_text(hwnd, pWData->iNextRow, pWData->iNextCol, + &char_to_display, 1, pWData); +} + +static void +do_backspace( + HWND hwnd, + WData *pWData) +{ + // Point to the previous character in the line + if (--pWData->iNextCol < 0) + { + // Can't backspace beyond the current line + pWData->iNextCol = 0; + return; + } + + display_char(hwnd, ' ', pWData); + + // Null character for repaint + pWData->aImage[pWData->iNextRow][pWData->iNextCol] = '\0'; +} + +static int +inc_row( + int row, + int increment) +{ + row += increment; + + if (row >= MAX_ROWS) + { + row -= MAX_ROWS; + } + else if (row < 0) + { + row += MAX_ROWS; + } + + return row; +} + +void +inc_next_row( + HWND hwnd, + WData *pWData) +{ + if (pWData->iNextRow == pWData->iBottomRow) + { + // Line is at bottom -- scroll the client area one row + ScrollWindow(hwnd, 0, -pWData->cyChar, NULL, NULL); + + // Increment the top & bottom of the screen + pWData->iTopRow = inc_row(pWData->iTopRow, 1); + pWData->iBottomRow = inc_row(pWData->iBottomRow, 1); + } + + // Increment the row + pWData->iNextRow = inc_row(pWData->iNextRow, 1); + + if (pWData->iNextRow == pWData->iBufferTop) + { + // Have to reset circular buffer to next + pWData->iBufferTop = inc_row(pWData->iBufferTop, 1); + + // Reset line to nulls for repaint + memset(&pWData->aImage[pWData->iNextRow][0], '\0', MAX_COLS); + } + + pWData->iNextCol = 0; +} + +static void +do_cr( + HWND hwnd, + WData *pWData) +{ + // Set position to next row + inc_next_row(hwnd, pWData); + pWData->iNextCol = 0; + + // Make sure next character is null for repaint of line + pWData->aImage[pWData->iNextRow][pWData->iNextCol] = '\0'; + + // Update the vertical scroll bar's position + set_vscroll_pos(hwnd, pWData); +} + +static void +do_char( + HWND hwnd, + WPARAM wParam, + WData *pWData) +{ + display_char(hwnd, (TCHAR) wParam, pWData); + + // Point to the next character in the line + if (++pWData->iNextCol > MAX_COLS) + { + // Handle switch to next line + inc_next_row(hwnd, pWData); + } +} + +static void +do_tab( + HWND hwnd, + WData *pWData) +{ + int c = pWData->iNextCol % 8; + + if ((pWData->iNextCol + c) <= MAX_COLS) + { + for ( ; c; c--) + { + do_char(hwnd, ' ', pWData); + } + } + else + { + do_cr(hwnd, pWData); + } +} + +static void +EchoChar( + HWND hwnd, + WORD cRepeats, + WPARAM wParam, + WData *pWData) +{ + for ( ; cRepeats; cRepeats--) + { + switch (wParam) + { + // Backspace + case '\b': + do_backspace(hwnd, pWData); + break; + + // Carriage return + case '\n': + case '\r': + do_cr(hwnd, pWData); + break; + + // Tab + case '\t': + do_tab(hwnd, pWData); + break; + + // Regular characters + default: + do_char(hwnd, wParam, pWData); + } + } + + // The row is guaranteed to be on the screen because we will + // scroll on a CR. However, the next column for input may be + // beyond the window we are working in. + if (pWData->iNextCol > pWData->iBottomCol) + { + // We are out of the window so scroll the window one + // column to the right. + SendMessage(hwnd, WM_HSCROLL, SB_LINEDOWN, 0L); + } + else if (pWData->iNextCol < pWData->iFirstCol) + { + // We are out of the window so repaint the window using + // iNextCol as the first column for the screen. + pWData->iFirstCol = pWData->iNextCol; + pWData->iBottomCol = pWData->iFirstCol + pWData->cCols - 1; + + // Reset scroll bar + SetScrollPos(hwnd, SB_HORZ, pWData->iFirstCol, TRUE); + + // Tell window to update itself. + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + } + else + { + // Reset Caret's position + SetCaretPos((pWData->iNextCol - pWData->iFirstCol) * pWData->cxChar, + calc_row(pWData->iNextRow, pWData) * pWData->cyChar); + } +} + +/**************************************************************************** + + FUNCTION: WmCreate(HWND) + + PURPOSE: Initializes control structures for a TermWClass Window + + MESSAGES: + WM_CREATE + + COMMENTS: + + This prepares a window for processing character based + I/O. In particular it does stuff like calculate the + size of the window needed. + +****************************************************************************/ +static void +WmCreate( + HWND hwnd, + CREATESTRUCT *pInit) +{ + WData *pData = (WData *) (pInit->lpCreateParams); + HDC hdc = GetDC(hwnd); + TEXTMETRIC tm; + + // Store pointer to window data + SetWindowLong(hwnd, 0, (LONG) pData); + + // Set font to system fixed font + SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT)); + + // Calculate size of a character + GetTextMetrics(hdc, &tm); + pData->cxChar = tm.tmAveCharWidth; + pData->cyChar = tm.tmHeight; + ReleaseDC(hwnd, hdc); + + // Set up vertical scroll bars + SetScrollRange(hwnd, SB_VERT, 0, MAX_ROWS, TRUE); + SetScrollPos(hwnd, SB_VERT, 0, TRUE); + + // Set up horizontal scroll bars + SetScrollRange(hwnd, SB_HORZ, 0, MAX_COLS, TRUE); + SetScrollPos(hwnd, SB_HORZ, 0, TRUE); +} + +/**************************************************************************** + + FUNCTION: WmSize(HWND, WORD, LONG) + + PURPOSE: Processes a size message + + MESSAGES: + + COMMENTS: + +****************************************************************************/ +static void +WmSize( + HWND hwnd, + WPARAM wParam, + LONG lParam, + WData *pwdata) +{ + // Get the new size of the window + int cxClient; + int cyClient; + int cRowChange = pwdata->cRows; + RECT rect; + + // Get size of client area + GetClientRect(hwnd, &rect); + + // Calculate size of client area + cxClient = rect.right - rect.left; + cyClient = rect.bottom - rect.top; + + // Calculate size of area in rows + pwdata->cCols = cxClient / pwdata->cxChar; + pwdata->cRows = min(MAX_ROWS, cyClient / pwdata->cyChar); + pwdata->iBottomCol = min(pwdata->iFirstCol + pwdata->cCols, MAX_COLS); + cRowChange = pwdata->cRows - cRowChange; + + // Keep input line toward bottom of screen + if (cRowChange < 0) + { + // Screen has shrunk in size. + if (pwdata->iNextRow != pwdata->iTopRow) + { + // Has input row moved out of screen? + if (row_diff(pwdata->iNextRow, pwdata->iTopRow) >= pwdata->cRows) + { + // Yes -- Calculate top new top that puts input line on + // the bottom. + pwdata->iTopRow = + inc_row(pwdata->iNextRow, 1 - pwdata->cRows); + } + } + } + else + { + // Screen has gotten bigger -- Display more text if possible + if (pwdata->iTopRow != pwdata->iBufferTop) + { + pwdata->iTopRow = inc_row(pwdata->iTopRow, + -(min(row_diff(pwdata->iTopRow, pwdata->iBufferTop), + cRowChange))); + } + } + + // Calculate new bottom + pwdata->iBottomRow = inc_row(pwdata->iTopRow, pwdata->cRows - 1); + + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); +} + +static void +WmSetFocus( + HWND hwnd, + WData *pwdata) +{ + // save indirections + register int cxchar = pwdata->cxChar; + register int cychar = pwdata->cyChar; + pwdata->fGotFocus = TRUE; + CreateCaret(hwnd, NULL, cxchar, cychar); + + if (!pwdata->fCaretHidden) + { + SetCaretPos(pwdata->iNextCol * cxchar, + calc_row(pwdata->iNextRow, pwdata) * cychar); + } + + ShowCaret(hwnd); +} + +static void +WmKillFocus( + HWND hwnd, + WData *pwdata) +{ + pwdata->fGotFocus = FALSE; + + if (!pwdata->fCaretHidden) + { + HideCaret(hwnd); + } + + DestroyCaret(); +} + +static void +WmVscroll( + HWND hwnd, + WPARAM wParam, + LONG lParam, + WData *pwdata) +{ + int cVscrollInc = 0; + register int top_diff = row_diff(pwdata->iTopRow, pwdata->iBufferTop); + register int bottom_diff = MAX_ROWS - (top_diff + pwdata->cRows); + + switch(wParam) + { + case SB_TOP: + + if (top_diff != 0) + { + cVscrollInc = -top_diff; + } + + break; + + case SB_BOTTOM: + + if (bottom_diff != 0) + { + cVscrollInc = bottom_diff; + } + + break; + + case SB_LINEUP: + + if (top_diff != 0) + { + cVscrollInc = -1; + } + + break; + + case SB_LINEDOWN: + + if (bottom_diff != 0) + { + cVscrollInc = 1; + } + + break; + + case SB_PAGEUP: + + if (top_diff != 0) + { + cVscrollInc = - ((top_diff > pwdata->cRows) + ? pwdata->cRows : top_diff); + } + + break; + + case SB_PAGEDOWN: + + if (bottom_diff != 0) + { + cVscrollInc = (bottom_diff > pwdata->cRows) + ? pwdata->cRows : bottom_diff; + } + + break; + + case SB_THUMBTRACK: + + if (LOWORD(lParam) != 0) + { + cVscrollInc = LOWORD(lParam) + - row_diff(pwdata->iTopRow, pwdata->iBufferTop); + } + } + + // Cacluate new top row + if (cVscrollInc != 0) + { + // Calculate new top and bottom + pwdata->iTopRow = inc_row(pwdata->iTopRow, cVscrollInc); + pwdata->iBottomRow = inc_row(pwdata->iTopRow, pwdata->cRows); + + // Scroll window + ScrollWindow(hwnd, 0, pwdata->cyChar * cVscrollInc, NULL, NULL); + + // Reset scroll bar + set_vscroll_pos(hwnd, pwdata); + + // Tell window to update itself. + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + } +} + +static void +WmHscroll( + HWND hwnd, + WPARAM wParam, + LONG lParam, + WData *pwdata) +{ + register int cHscrollInc = 0; + + switch(wParam) + { + case SB_LINEUP: + + cHscrollInc = -1; + break; + + case SB_LINEDOWN: + + cHscrollInc = 1; + break; + + case SB_PAGEUP: + + cHscrollInc = -8; + break; + + case SB_PAGEDOWN: + + cHscrollInc = 8; + break; + + case SB_THUMBTRACK: + + if (LOWORD(lParam) != 0) + { + cHscrollInc = LOWORD(lParam) - pwdata->iFirstCol; + } + } + + if (cHscrollInc != 0) + { + // Cacluate new first column + register int NormalizedScrollInc = cHscrollInc + pwdata->iFirstCol; + + if (NormalizedScrollInc < 0) + { + cHscrollInc = -pwdata->iFirstCol; + } + else if (NormalizedScrollInc > MAX_COLS - pwdata->cCols) + { + cHscrollInc = (MAX_COLS - pwdata->cCols) - pwdata->iFirstCol; + } + + pwdata->iFirstCol += cHscrollInc; + pwdata->iBottomCol = pwdata->iFirstCol + pwdata->cCols - 1; + + // Scroll window + ScrollWindow(hwnd, -(pwdata->cxChar * cHscrollInc), 0, NULL, NULL); + + // Reset scroll bar + SetScrollPos(hwnd, SB_HORZ, pwdata->iFirstCol, TRUE); + + // Tell window to update itself. + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + } +} + +static void +WmPaint( + HWND hwnd, + WData *pwdata) +{ + PAINTSTRUCT ps; + HDC hdc = BeginPaint(hwnd, &ps); + register int row = pwdata->iTopRow; + register int col = pwdata->iFirstCol; + int bottom_row = pwdata->iBottomRow; + int cxChar = pwdata->cxChar; + int cyChar = pwdata->cyChar; + int y; + + // Select System Font + SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT)); + + while (TRUE) + { + int len = lstrlen(&pwdata->aImage[row][col]); + + if (len != 0) + { + y = calc_row(row, pwdata) * cyChar; + TextOut(hdc, 0, y, &pwdata->aImage[row][col], len); + } + + if (row == bottom_row) + { + break; + } + + row = inc_row(row, 1); + } + + if (pwdata->fGotFocus) + { + if ((pwdata->iNextCol >= pwdata->iFirstCol) + && (row_diff(pwdata->iNextRow, pwdata->iTopRow) < pwdata->cRows)) + { + if (pwdata->fCaretHidden) + { + pwdata->fCaretHidden = FALSE; + ShowCaret(hwnd); + } + + SetCaretPos( + (pwdata->iNextCol - pwdata->iFirstCol) * pwdata->cxChar, + calc_row(pwdata->iNextRow, pwdata) * pwdata->cyChar); + } + else + { + if (!pwdata->fCaretHidden) + { + pwdata->fCaretHidden = TRUE; + HideCaret(hwnd); + } + } + } + + EndPaint(hwnd, &ps); +} + + + + + +// +// FUNCTION: WmPrintLine +// +// PURPOSE: Print a line on the screen. +// +// Note: this is a user message not an intrinsic Window's message. +// +void +WmPrintLine( + HWND hwnd, + WPARAM wParam, + LONG lParam, + WData *pTermData) +{ + TCHAR *pBuf = (TCHAR *) lParam; + + // MessageBox(hwnd, L"WmPrintLine", L"Debug", MB_OK); + + // DebugBreak(); + + while (wParam--) + { + // Is character a lf? + if (*pBuf == '\n') + { + // Convert to cr since that is what this window uses + *pBuf = '\r'; + } + + // Write the character to the window + EchoChar(hwnd, 1, *pBuf++, pTermData); + } + +} + +// +// FUNCTION: WmPutc +// +// PURPOSE: Print a single character on the screen +// +// Note: this is a user message not an intrinsic Window's message. +// +void +WmPutc( + HWND hwnd, + WPARAM wParam, + WData *pTermData) +{ + // Is character a lf? + if (wParam == '\n') + { + // Convert to cr since that is what this window uses + wParam = '\r'; + } + + // Write the character to the window + EchoChar(hwnd, 1, wParam, pTermData); +} + + +/**************************************************************************** + + FUNCTION: TermWndProc(HWND, unsigned, WORD, LONG) + + PURPOSE: Processes messages + + MESSAGES: + + COMMENTS: + +****************************************************************************/ + +long TermWndProc( + HWND hWnd, + UINT message, + WPARAM wParam, + LPARAM lParam) +{ + WData *pTerm = (WData *) GetWindowLong(hWnd, 0); + + switch (message) + { + case WM_CREATE: + WmCreate(hWnd, (CREATESTRUCT *) lParam); + break; + + case WM_COMMAND: + case WM_SYSCOMMAND: + // Call procedure that processes the menus + return (*(pTerm->pMenuProc))(hWnd, message, wParam, lParam, + pTerm->pvCallBackData); + + case WM_SIZE: + WmSize(hWnd, wParam, lParam, pTerm); + break; + + case WM_SETFOCUS: + WmSetFocus(hWnd, pTerm); + break; + + case WM_KILLFOCUS: + WmKillFocus(hWnd, pTerm); + break; + + case WM_VSCROLL: + WmVscroll(hWnd, wParam, lParam, pTerm); + break; + + case WM_HSCROLL: + WmHscroll(hWnd, wParam, lParam, pTerm); + break; + + case WM_CHAR: + // Character message echo and put in buffer + return (*(pTerm->pCharProc))(hWnd, message, wParam, lParam, + pTerm->pvCallBackData); + + case WM_PAINT: + WmPaint(hWnd, pTerm); + break; + + case WM_CLOSE: + DestroyWindow(hWnd); + break; + + case WM_NCDESTROY: + // Call close notification procedure + return (*(pTerm->pCloseProc))(hWnd, message, wParam, lParam, + pTerm->pvCallBackData); + + case WM_PRINT_LINE: + WmPrintLine(hWnd, wParam, lParam, pTerm); + break; + + case WM_PUTC: + WmPutc(hWnd, wParam, pTerm); + break; + + case WM_DESTROY: + PostQuitMessage(0); + break; + + case WM_TERM_WND: + DestroyWindow(hWnd); + break; + + default: /* Passes it on if unproccessed */ + return (DefWindowProc(hWnd, message, wParam, lParam)); + } + + return 0; +} + + +/**************************************************************************** + + FUNCTION: TermRegisterClass(HANDLE) + + PURPOSE: Register a class for a terminal window + + COMMENTS: + + +****************************************************************************/ + +BOOL TermRegisterClass( + HANDLE hInstance, + LPTSTR MenuName, + LPTSTR ClassName, + LPTSTR Icon) +{ + WNDCLASS wc; + BOOL retVal; + + // Make sure blank line is blank + memset(BlankLine, ' ', 80); + + /* Fill in window class structure with parameters that describe the */ + /* main window. */ + + wc.style = 0; + wc.lpfnWndProc = TermWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = sizeof(WData *); + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(NULL, Icon); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = GetStockObject(WHITE_BRUSH); + wc.lpszMenuName = MenuName; + wc.lpszClassName = ClassName; + + /* Register the window class and return success/failure code. */ + if (retVal = RegisterClass(&wc)) + { + // Class got registered -- so finish set up + hInst = hInstance; + } + + return retVal; +} + + +/**************************************************************************** + + FUNCTION: TermCreateWindow(LPWSTR, LPWSTR, HMENU, void *, void *, int) + + PURPOSE: Create a window of a previously registered window class + + COMMENTS: + + +****************************************************************************/ + +BOOL +TermCreateWindow( + LPTSTR lpClassName, + LPTSTR lpWindowName, + HMENU hMenu, + MFUNCP MenuProc, + CFUNCP CharProc, + TFUNCP CloseProc, + int nCmdShow, + HWND *phNewWindow, + void *pvCallBackData) +{ + HWND hWnd; // Main window handle. + WData *pTermData; + + // Allocate control structure for the window + if ((pTermData = malloc(sizeof(WData))) == NULL) + { + return FALSE; + } + + // Set entire structure to nulls + memset((TCHAR *) pTermData, '\0', sizeof(WData)); + + // Initialize function pointers + pTermData->pMenuProc = MenuProc; + pTermData->pCharProc = CharProc; + pTermData->pCloseProc = CloseProc; + + // Initialize callback data + pTermData->pvCallBackData = pvCallBackData; + + // Create a main window for this application instance. + hWnd = CreateWindow( + lpClassName, + lpWindowName, + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + NULL, + hMenu, + hInst, + (LPTSTR) pTermData + ); + + // If window could not be created, return "failure" + + if (!hWnd) + { + free(pTermData); + return FALSE; + } + + SetFocus(hWnd); + + // Make the window visible; update its client area; and return "success" + + ShowWindow(hWnd, nCmdShow); + UpdateWindow(hWnd); + *phNewWindow = hWnd; + return (TRUE); +} diff --git a/private/oleutest/perf/perfsrv/wterm.h b/private/oleutest/perf/perfsrv/wterm.h new file mode 100644 index 000000000..4085c7d9a --- /dev/null +++ b/private/oleutest/perf/perfsrv/wterm.h @@ -0,0 +1,40 @@ +#ifndef __WTERM__ +#define __WTERM__ + +// Message to print a line on the window +#define WM_PRINT_LINE (WM_USER + 1) + +// Message to print a character on the window +#define WM_PUTC (WM_USER + 2) + +// Message used to terminate this window +#define WM_TERM_WND (WM_USER + 3) + +// +// Typedefs for call back functions for the window +// +typedef long (*MFUNCP)(HWND, UINT, WPARAM, LPARAM, void *); +typedef long (*CFUNCP)(HWND, UINT, WPARAM, LPARAM, void *); +typedef long (*TFUNCP)(HWND, UINT, WPARAM, LPARAM, void *); + +// Register the terminal window class +BOOL TermRegisterClass( + HANDLE hInstance, + LPTSTR MenuName, + LPTSTR ClassName, + LPTSTR ICON); + +// Create a window for the terminal +BOOL +TermCreateWindow( + LPTSTR lpClassName, + LPTSTR lpWindowName, + HMENU hMenu, + MFUNCP MenuProc, + CFUNCP CharProc, + TFUNCP CloseProc, + int nCmdShow, + HWND *phNewWindow, + void *pvCallBackData); + +#endif // __WTERM__ diff --git a/private/oleutest/perf/perfuuid/makefile b/private/oleutest/perf/perfuuid/makefile new file mode 100644 index 000000000..510cce95d --- /dev/null +++ b/private/oleutest/perf/perfuuid/makefile @@ -0,0 +1,9 @@ +############################################################################ +# +# Copyright (C) 1992, Microsoft Corporation. +# +# All rights reserved. +# +############################################################################ + +!include $(NTMAKEENV)\makefile.def diff --git a/private/oleutest/perf/perfuuid/perfsrvi.c b/private/oleutest/perf/perfuuid/perfsrvi.c new file mode 100644 index 000000000..98e1ef33c --- /dev/null +++ b/private/oleutest/perf/perfuuid/perfsrvi.c @@ -0,0 +1,24 @@ +#pragma warning(disable:4101) // Ignore variable not use warning + +//+------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1993. +// +// File: iperf_i.c +// +// Contents: IID_IPerf +// +// History: Created by Microsoft (R) MIDL Compiler Version 1.10.83 +// +//-------------------------------------------------------------------------- +typedef struct _IID +{ + unsigned long x; + unsigned short s1; + unsigned short s2; + unsigned char c[8]; +} IID; + + +const IID CLSID_IPerf = {0x1AFDBB80, 0xAA32, 0x101A, {0xB4, 0xAD, 0x08, 0x00, 0x2B, 0x30, 0x61, 0x2C}}; diff --git a/private/oleutest/perf/perfuuid/sources b/private/oleutest/perf/perfuuid/sources new file mode 100644 index 000000000..051a17b4a --- /dev/null +++ b/private/oleutest/perf/perfuuid/sources @@ -0,0 +1,68 @@ +!IF 0 + +Copyright (c) 1989 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: + + Dean Edwards (DeanE) 11-Jan-1993 + +!ENDIF + +MAJORCOMP= cairole +MINORCOMP= com + +# +# This is the name of the target built from the source files specified +# below. The name should include neither the path nor the file extension. +# + +TARGETNAME= perfuuid + +# +# This specifies where the target is to be built. A private target of +# type LIBRARY or DYNLINK should go to obj, whereas a public target of +# type LIBRARY or DYNLINK should go to $(BASEDIR)\public\sdk\lib. +# + +TARGETPATH= obj + +# +# This specifies the type of the target, such as PROGRAM, DYNLINK, LIBRARY, +# etc. +# + +TARGETTYPE= LIBRARY + +INCLUDES= \ + ..\.; \ + $(BASEDIR)\public\sdk\inc; \ + $(BASEDIR)\private\cinc + +C_DEFINES= $(C_DEFINES) + +BLDCRT= 1 + +SOURCES= iperf_i.c \ + perfsrvi.c + +UMTYPE= windows +UMAPPL= +UMTEST= +UMLIBS= + +USE_LIBCMT= 1 + +PRECOMPILED_INCLUDE= + diff --git a/private/oleutest/perf/proxy/dllentry.c b/private/oleutest/perf/proxy/dllentry.c new file mode 100644 index 000000000..0a129f9be --- /dev/null +++ b/private/oleutest/perf/proxy/dllentry.c @@ -0,0 +1,224 @@ +//+------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1991 - 1992. +// +// File: dllentry.c +// +// Contents: Dll Entry point code. Calls the appropriate run-time +// init/term code and then defers to LibMain for further +// processing. +// +// Classes: <none> +// +// Functions: DllEntryPoint - Called by loader +// +// History: 10-May-92 BryanT Created +// 22-Jul-92 BryanT Switch to calling _cexit/_mtdeletelocks +// on cleanup. +// 06-Oct-92 BryanT Call RegisterWithCommnot on entry +// and DeRegisterWithCommnot on exit. +// This should fix the heap dump code. +// 12-23-93 TerryRu Replace LockExit, and UnLockExit +// with critial sections for Daytona. +// 12-28-93 TerryRu Place Regiter/DeRegister WinCommnot apis +// Inside WIN32 endifs for Daytona builds. +// +//-------------------------------------------------------------------- +#include <windows.h> +//#include <win4p.h> +#include <process.h> +#include <string.h> +#include <stdlib.h> +#include <malloc.h> + + +BOOL WINAPI _CRT_INIT (HANDLE hDll, DWORD dwReason, LPVOID lpReserved); + +BOOL __stdcall DllEntryPoint (HANDLE hDll, DWORD dwReason, LPVOID lpReserved); + +BOOL _CRTAPI1 LibMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved); + +void _CRTAPI1 _mtdeletelocks(void); + +DWORD WINAPI +GetModuleFileNameCtC( + HMODULE hModule, + LPWSTR pwszFilename, + DWORD nSize); + +#ifdef USE_CRTDLL + +#define _RT_ONEXIT 24 + +/* + * routine in DLL to do initialization (in this case, C++ constructors) + */ + +typedef void (_CRTAPI1 *PF)(void); + +/* + * pointers to initialization sections + */ + +PF *__onexitbegin; +PF *__onexitend; + +/* + * Define increment (in entries) for growing the _onexit/atexit table + */ +#define ONEXITTBLINCR 4 + +static void _CRTAPI1 _onexitinit ( void ); +extern void _CRTAPI1 _initterm(PF *, PF *); +extern void _CRTAPI1 _amsg_exit(int); +extern void _CRTAPI1 _lockexit(void); +extern void _CRTAPI1 _unlockexit(void); + +#endif + +// BUGBUG: defined in $(COMMON)\src\except\memory.cxx + +void RegisterWithCommnot(void); +void DeRegisterWithCommnot(void); + +CRITICAL_SECTION __gCriticalSection; + +BOOL __stdcall DllEntryPoint (HANDLE hDll, DWORD dwReason, LPVOID lpReserved) +{ + BOOL fRc = FALSE; + + switch (dwReason) + { + case DLL_PROCESS_ATTACH: + +#ifdef USE_CRTDLL + // + // Assumption: The run-time is sufficiantly up and running to + // support malloc that _onexitinit will perform. + // + _onexitinit(); + InitializeCriticalSection(&__gCriticalSection ); +#endif + + _CRT_INIT(hDll, dwReason, lpReserved); +#if WIN32==300 + RegisterWithCommnot(); +#endif + + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + fRc = LibMain (hDll, dwReason, lpReserved); + break; + + case DLL_PROCESS_DETACH: + fRc = LibMain (hDll, dwReason, lpReserved); + + // + // BUGBUG: What a hack. In order to make sure we don't kill + // commnot's objects while still in use (_cexit will do + // the atexit list processing where the compiler stores + // pointers to all the static destructors), test the + // module name. If not commnot, call _cexit(). + // DeRegisterWithCommnot will call it for commnot... + // + +#ifdef USE_CRTDLL + + { + wchar_t pwszModName[512]; + GetModuleFileName(hDll, pwszModName, 512); + + if (!wcswcs(wcsupr(pwszModName), L"COMMNOT")) + if (__onexitbegin) + _initterm(__onexitbegin, __onexitend); + } + + DeleteCriticalSection( & __gCriticalSection ); +#else + + { + wchar_t pwszModName[512]; + GetModuleFileName(hDll, pwszModName, 512); + + if (!wcswcs(wcsupr(pwszModName), L"COMMNOT")) + _cexit(); + } + + _mtdeletelocks(); +#endif +#if WIN32==300 + DeRegisterWithCommnot(); +#endif + break; + } + + return(fRc); +} + +#ifdef USE_CRTDLL + +_onexit_t _CRTAPI1 _onexit ( _onexit_t func ) +{ + PF *p; + + EnterCriticalSection( &__gCriticalSection ); /* lock the exit code */ + + /* + * First, make sure the table has room for a new entry + */ + if ( _msize(__onexitbegin) <= (unsigned)((char *)__onexitend - + (char *)__onexitbegin) ) { + /* + * not enough room, try to grow the table + */ + if ( (p = (PF *) realloc(__onexitbegin, _msize(__onexitbegin) + + ONEXITTBLINCR * sizeof(PF))) == NULL ) { + /* + * didn't work. don't do anything rash, just fail + */ + LeaveCriticalSection(&__gCriticalSection ); + + return NULL; + } + + /* + * update __onexitend and __onexitbegin + */ + + __onexitend = p + (__onexitend - __onexitbegin); + __onexitbegin = p; + } + + /* + * Put the new entry into the table and update the end-of-table + * pointer. + */ + + *(__onexitend++) = (PF)func; + + LeaveCriticalSection( &__gCriticalSection ); + + return func; + +} + +int _CRTAPI1 atexit ( PF func ) +{ + return (_onexit((_onexit_t)func) == NULL) ? -1 : 0; +} + +static void _CRTAPI1 _onexitinit ( void ) +{ + if ( (__onexitbegin = (PF *)malloc(32 * sizeof(PF))) == NULL ) + /* + * cannot allocate minimal required size. generate + * fatal runtime error. + */ + _amsg_exit(_RT_ONEXIT); + + *(__onexitbegin) = (PF) NULL; + __onexitend = __onexitbegin; +} + +#endif // USE_CRTDLL diff --git a/private/oleutest/perf/proxy/makefile b/private/oleutest/perf/proxy/makefile new file mode 100644 index 000000000..510cce95d --- /dev/null +++ b/private/oleutest/perf/proxy/makefile @@ -0,0 +1,9 @@ +############################################################################ +# +# Copyright (C) 1992, Microsoft Corporation. +# +# All rights reserved. +# +############################################################################ + +!include $(NTMAKEENV)\makefile.def diff --git a/private/oleutest/perf/proxy/prxydll.def b/private/oleutest/perf/proxy/prxydll.def new file mode 100644 index 000000000..c0feeaa0c --- /dev/null +++ b/private/oleutest/perf/proxy/prxydll.def @@ -0,0 +1,9 @@ +LIBRARY IPERF + +DESCRIPTION 'Microsoft (R) OLE 2.0 Proxy/Stub DLL 1.00' + +EXPORTS + + DllGetClassObject @1 + DllCanUnloadNow @2 + diff --git a/private/oleutest/perf/proxy/sources b/private/oleutest/perf/proxy/sources new file mode 100644 index 000000000..2849e7bd4 --- /dev/null +++ b/private/oleutest/perf/proxy/sources @@ -0,0 +1,105 @@ +!IF 0 + +Copyright (c) 1989 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: + + Dean Edwards (DeanE) 11-Jan-1993 + +!ENDIF + +MAJORCOMP= comutest +MINORCOMP= channelperf + +# +# This is the name of the target built from the source files specified +# below. The name should include neither the path nor the file extension. +# + +TARGETNAME= iperf + +# +# This specifies where the target is to be built. A private target of +# type LIBRARY or DYNLINK should go to obj, whereas a public target of +# type LIBRARY or DYNLINK should go to $(BASEDIR)\public\sdk\lib. +# + +TARGETPATH= obj + +# +# This specifies the type of the target, such as PROGRAM, DYNLINK, LIBRARY, +# etc. +# + +TARGETTYPE= DYNLINK + +# +# This specifies the target of a release +# + +DLLDEF= prxydll.def + +DLLBASE= @$(BASEDIR)\public\sdk\lib\coffbase.txt,ole32 + +INCLUDES= .;\ + ..\idl;\ + $(BASEDIR)\public\sdk\inc; \ + $(BASEDIR)\private\cinc; \ + $(BASEDIR)\private\types\oleprx32\daytona + + +C_DEFINES= $(C_DEFINES) \ + -DFLAT \ + -D_NT1X_=100 \ + -DUNICODE \ + -D_UNICODE \ + -DINC_OLE2 + + +BLDCRT= 1 + +SOURCES= \ + iperf_p.cxx \ + dlldata.c + +UMTYPE= windows +#UMENTRY= _CRTDLL_INIT +UMAPPL= +UMTEST= +UMLIBS= + +LINKLIBS= \ + ..\perfuuid\obj\*\perfuuid.lib \ + $(BASEDIR)\public\sdk\lib\*\uuid.lib \ + $(BASEDIR)\public\sdk\lib\*\stdclass.lib \ + $(BASEDIR)\public\sdk\lib\*\ole32.lib \ + $(BASEDIR)\public\sdk\lib\*\rpcrt4.lib \ + $(BASEDIR)\public\sdk\lib\*\kernel32.lib \ + $(BASEDIR)\public\sdk\lib\*\libcmt.lib +# $(BASEDIR)\public\sdk\lib\*\crtdll.lib + + +# +# We are linking with libcmt explicitly because makefile.def/build.exe +# is so wonderful that it sets the proper -Ddefines on C_DEFINES but +# never uses the $%#@ CRT lib when it builds the DLL... We still need +# to set USE_LIBCMT to 1 so the proper defines are set +# +USE_LIBCMT= 1 + +PRECOMPILED_INCLUDE= + + + diff --git a/private/oleutest/perf/rel.cmd b/private/oleutest/perf/rel.cmd new file mode 100644 index 000000000..50d6f95a0 --- /dev/null +++ b/private/oleutest/perf/rel.cmd @@ -0,0 +1,4 @@ +copy proxy\obj\i386\iperf.dll \tmp +copy perfsrv\obj\i386\perfsrv.exe \tmp +copy perfcli\obj\i386\perfcli.exe \tmp +copy idl\perf.reg \tmp |