summaryrefslogtreecommitdiffstats
path: root/private/sdktools/zd
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/sdktools/zd
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/sdktools/zd')
-rw-r--r--private/sdktools/zd/makefile6
-rw-r--r--private/sdktools/zd/makefile.inc1
-rw-r--r--private/sdktools/zd/sources44
-rw-r--r--private/sdktools/zd/zdbnch.dlg74
-rw-r--r--private/sdktools/zd/zdbnch.h74
-rw-r--r--private/sdktools/zd/zdbnch.rc2
-rw-r--r--private/sdktools/zd/zdbnch.resbin0 -> 2316 bytes
-rw-r--r--private/sdktools/zd/zdsim.c934
-rw-r--r--private/sdktools/zd/zdsimp.h125
9 files changed, 1260 insertions, 0 deletions
diff --git a/private/sdktools/zd/makefile b/private/sdktools/zd/makefile
new file mode 100644
index 000000000..6ee4f43fa
--- /dev/null
+++ b/private/sdktools/zd/makefile
@@ -0,0 +1,6 @@
+#
+# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
+# file to this component. This file merely indirects to the real make file
+# that is shared by all the components of NT OS/2
+#
+!INCLUDE $(NTMAKEENV)\makefile.def
diff --git a/private/sdktools/zd/makefile.inc b/private/sdktools/zd/makefile.inc
new file mode 100644
index 000000000..33fa130f4
--- /dev/null
+++ b/private/sdktools/zd/makefile.inc
@@ -0,0 +1 @@
+zdbnch.rc: zdbnch.dlg
diff --git a/private/sdktools/zd/sources b/private/sdktools/zd/sources
new file mode 100644
index 000000000..14c9dc8d5
--- /dev/null
+++ b/private/sdktools/zd/sources
@@ -0,0 +1,44 @@
+!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:
+
+ Steve Wood (stevewo) 12-Apr-1990
+
+NOTE: Commented description of this file is in \nt\bak\bin\sources.tpl
+
+!ENDIF
+
+TARGETNAME=zdsim
+TARGETPATH=obj
+TARGETTYPE=LIBRARY
+TARGETLIBS=
+
+INCLUDES=.
+C_DEFINES=-DWIN32
+
+SOURCES=zdsim.c \
+ zdbnch.rc
+
+UMENTRY=winmain
+UMTYPE=windows
+UMAPPL=zdsim
+UMLIBS=obj\*\zdbnch.res \
+ obj\*\zdsim.lib \
+ $(BASEDIR)\public\sdk\lib\*\wsock32.lib
+
+NTTARGETFILE0=zdbnch.rc
+USE_CRTDLL=1
diff --git a/private/sdktools/zd/zdbnch.dlg b/private/sdktools/zd/zdbnch.dlg
new file mode 100644
index 000000000..3adb74bba
--- /dev/null
+++ b/private/sdktools/zd/zdbnch.dlg
@@ -0,0 +1,74 @@
+1 DLGINCLUDE "zdbnch.h"
+
+ID_ZDSIM_DLG DIALOG 25, 33, 343, 204
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "ZD Multi-Thread Simulation"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LTEXT "Number Clients", 102, 4, 6, 72, 10
+ SCROLLBAR ID_NUM_CLIENTS, 122, 6, 72, 10
+ LISTBOX ID_OUTPUT_WINDOW, 6, 153, 327, 48, WS_VSCROLL |
+ WS_TABSTOP
+ PUSHBUTTON "Start", ID_START_SIM, 208, 3, 46, 14
+ PUSHBUTTON "End", ID_END_SIM, 258, 3, 46, 14
+ EDITTEXT ID_NNOC, 85, 6, 32, 12, ES_AUTOHSCROLL | NOT WS_BORDER
+ AUTORADIOBUTTON "1", THREAD_1, 21, 102, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "2", THREAD_2, 21, 112, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "3", THREAD_3, 21, 122, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "4", THREAD_4, 21, 132, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "5", THREAD_5, 46, 102, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "6", THREAD_6, 46, 112, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "7", THREAD_7, 46, 122, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "8", THREAD_8, 46, 132, 23, 10, WS_GROUP
+ LTEXT "Busy Threads", 131, 147, 87, 47, 8
+ AUTORADIOBUTTON "9", THREAD_9, 70, 102, 23, 10
+ AUTORADIOBUTTON "10", THREAD_10, 70, 112, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "11", THREAD_11, 70, 122, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "12", THREAD_12, 70, 132, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "13", THREAD_13, 98, 103, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "14", THREAD_14, 98, 113, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "15", THREAD_15, 98, 123, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "16", THREAD_16, 98, 133, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "17", THREAD_17, 126, 102, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "18", THREAD_18, 126, 112, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "19", THREAD_19, 126, 122, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "20", THREAD_20, 126, 132, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "21", THREAD_21, 152, 102, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "22", THREAD_22, 152, 112, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "23", THREAD_23, 152, 122, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "24", THREAD_24, 152, 132, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "25", THREAD_25, 177, 102, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "26", THREAD_26, 177, 112, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "27", THREAD_27, 177, 122, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "28", THREAD_28, 177, 132, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "29", THREAD_29, 204, 102, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "30", THREAD_30, 204, 112, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "31", THREAD_31, 204, 122, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "32", THREAD_32, 204, 132, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "33", THREAD_33, 230, 102, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "34", THREAD_34, 230, 112, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "35", THREAD_35, 230, 122, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "36", THREAD_36, 230, 132, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "37", THREAD_37, 255, 102, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "38", THREAD_38, 255, 112, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "39", THREAD_39, 255, 122, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "40", THREAD_40, 255, 132, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "41", THREAD_41, 283, 102, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "42", THREAD_42, 283, 112, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "43", THREAD_43, 283, 122, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "44", THREAD_44, 283, 132, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "45", THREAD_45, 310, 102, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "46", THREAD_46, 310, 112, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "47", THREAD_47, 310, 122, 23, 10, WS_GROUP
+ AUTORADIOBUTTON "48", THREAD_48, 310, 132, 23, 10, WS_GROUP
+ LTEXT "", ID_NUMBER_OF_THREADS, 286, 27, 35, 8
+ AUTORADIOBUTTON "Thread Per Client", ID_RAD_THREAD_PER_CLIENT, 10, 44,
+ 71, 10
+ AUTORADIOBUTTON "Dynamic Threads", ID_RAD_DYNAMIC_THREADS, 10, 54, 71,
+ 10
+ GROUPBOX "Thread Mode", 176, 4, 33, 85, 35
+ AUTORADIOBUTTON "Tcp Mode", ID_RAD_TCP, 112, 44, 49, 10, WS_GROUP
+ AUTORADIOBUTTON "Spx Mode", ID_RAD_SPX, 112, 54, 49, 10
+ GROUPBOX "Network Mode", 179, 106, 33, 85, 35
+END
diff --git a/private/sdktools/zd/zdbnch.h b/private/sdktools/zd/zdbnch.h
new file mode 100644
index 000000000..e49a948d4
--- /dev/null
+++ b/private/sdktools/zd/zdbnch.h
@@ -0,0 +1,74 @@
+#define ID_MAX_CONNECTIONS 101
+#define ID_NUMBER_OF_QUEUES 103
+#define ID_THREADS_PER_QUEUE 105
+#define ID_WORK_LOAD 107
+#define ID_NUM_CONNECTIONS 109
+#define ID_NUM_CLIENTS 110
+#define ID_OUTPUT_WINDOW 111
+#define ID_START_SIM 112
+#define ID_ZDSIM_DLG 100
+#define ID_END_SIM 113
+#define ID_NNOQ 114
+#define ID_NNOC 115
+#define ID_NTPQ 116
+#define ID_NWL 117
+#define THREAD_1 118
+#define THREAD_2 119
+#define THREAD_3 120
+#define THREAD_4 121
+#define THREAD_5 122
+#define THREAD_6 123
+#define THREAD_7 124
+#define THREAD_8 125
+#define ID_CLIENT_LOAD 126
+#define ID_NCWL 127
+#define ID_NSWL 128
+#define ID_SERVER_WORK_LOAD 129
+#define ID_CLIENT_WORK_LOAD 130
+#define ID_LAB_NUMBER_OF_THREADS 104
+#define THREAD_9 132
+#define THREAD_10 133
+#define THREAD_11 134
+#define THREAD_12 135
+#define THREAD_13 136
+#define THREAD_14 137
+#define THREAD_15 138
+#define THREAD_16 139
+#define THREAD_17 140
+#define THREAD_18 141
+#define THREAD_19 142
+#define THREAD_20 143
+#define THREAD_21 144
+#define THREAD_22 145
+#define THREAD_23 146
+#define THREAD_24 147
+#define THREAD_25 148
+#define THREAD_26 149
+#define THREAD_27 150
+#define THREAD_28 151
+#define THREAD_29 152
+#define THREAD_30 153
+#define THREAD_31 154
+#define THREAD_32 155
+#define THREAD_33 156
+#define THREAD_34 157
+#define THREAD_35 158
+#define THREAD_36 159
+#define THREAD_37 160
+#define THREAD_38 161
+#define THREAD_39 162
+#define THREAD_40 163
+#define THREAD_41 164
+#define THREAD_42 165
+#define THREAD_43 166
+#define THREAD_44 167
+#define THREAD_45 168
+#define THREAD_46 169
+#define THREAD_47 170
+#define THREAD_48 171
+#define ID_DYNAMIC_THREADS 172
+#define ID_NUMBER_OF_THREADS 173
+#define ID_RAD_THREAD_PER_CLIENT 174
+#define ID_RAD_DYNAMIC_THREADS 175
+#define ID_RAD_TCP 177
+#define ID_RAD_SPX 178
diff --git a/private/sdktools/zd/zdbnch.rc b/private/sdktools/zd/zdbnch.rc
new file mode 100644
index 000000000..76d9d7613
--- /dev/null
+++ b/private/sdktools/zd/zdbnch.rc
@@ -0,0 +1,2 @@
+#include "zdsimp.h"
+#include "zdbnch.dlg"
diff --git a/private/sdktools/zd/zdbnch.res b/private/sdktools/zd/zdbnch.res
new file mode 100644
index 000000000..eae894c39
--- /dev/null
+++ b/private/sdktools/zd/zdbnch.res
Binary files differ
diff --git a/private/sdktools/zd/zdsim.c b/private/sdktools/zd/zdsim.c
new file mode 100644
index 000000000..571df10f1
--- /dev/null
+++ b/private/sdktools/zd/zdsim.c
@@ -0,0 +1,934 @@
+#include "zdsimp.h"
+
+int
+APIENTRY
+WinMain (
+ HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPSTR lpszCmdLine,
+ int nCmdShow
+ )
+{
+
+ DialogBox(hInstance, MAKEINTRESOURCE(ID_ZDSIM_DLG),NULL, ZdDlgProc);
+ return(0);
+}
+
+
+BOOL
+CALLBACK
+ZdDlgProc(
+ HWND hDlg,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam
+ )
+{
+
+ BOOL ReturnValue;
+
+ ReturnValue = TRUE;
+
+ HwndDlg = hDlg;
+ switch (uMsg) {
+ HANDLE_MSG(hDlg, WM_INITDIALOG, ZdDlgInit);
+ HANDLE_MSG(hDlg, WM_COMMAND, ZdDlgCommand);
+ HANDLE_MSG(hDlg, WM_HSCROLL, ZdDlgParamChange);
+
+ default:
+ ReturnValue = FALSE;
+ break;
+ }
+ return ReturnValue;
+}
+
+
+BOOL
+ZdDlgInit(
+ HWND hwnd,
+ HWND hwndFocus,
+ LPARAM lParam
+ )
+{
+
+ HWND hwndSB;
+
+
+ //
+ // Get output window handle
+ //
+
+ hwndOutput = GetDlgItem(hwnd, ID_OUTPUT_WINDOW);
+
+ SelNumberOfClients = DEF_CLIENTS;
+ fSimulationStarted = FALSE;
+
+ //
+ // Setup simulation parameters
+ //
+
+ hwndSB = GetDlgItem(hwnd, ID_NUM_CLIENTS);
+ SetScrollRange(hwndSB, SB_CTL, MIN_CLIENTS, MAX_CLIENTS, TRUE);
+ SendMessage(hwnd,WM_HSCROLL,MAKEWPARAM(SB_THUMBTRACK,DEF_CLIENTS),(LPARAM)hwndSB);
+
+ CheckRadioButton(hwnd,ID_RAD_TCP,ID_RAD_SPX,ID_RAD_TCP);
+ fTcp = TRUE;
+ fSpx = FALSE;
+
+ CheckRadioButton(hwnd,ID_RAD_THREAD_PER_CLIENT,ID_RAD_DYNAMIC_THREADS,ID_RAD_DYNAMIC_THREADS);
+ fDynamicThreadMode = TRUE;
+ fOneThreadPerClient = FALSE;
+ SelThreadsPerQueue = 2;
+ InitializeCriticalSection(&DynamicCritSect);
+
+
+ EnableWindow(GetDlgItem(hwnd, ID_END_SIM),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_1),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_2),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_3),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_4),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_5),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_6),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_7),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_8),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_9),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_10),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_11),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_12),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_13),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_14),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_15),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_16),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_17),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_18),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_19),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_20),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_21),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_22),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_23),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_24),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_25),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_26),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_27),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_28),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_29),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_30),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_31),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_32),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_33),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_34),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_35),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_36),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_37),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_38),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_39),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_40),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_41),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_42),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_43),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_44),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_45),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_46),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_47),FALSE);
+ EnableWindow(GetDlgItem(hwnd, THREAD_48),FALSE);
+
+ return(TRUE);
+}
+
+
+void
+ZdDlgParamChange(
+ HWND hwnd,
+ HWND hwndCtl,
+ UINT code,
+ int pos
+ )
+{
+
+ CHAR szBuf[10];
+ int nPosCrnt, nPosMin, nPosMax;
+ DWORD ControlId;
+ HWND hwndText;
+
+ ControlId = GetWindowLong(hwndCtl,GWL_ID);
+
+ //
+ // Get the current position and the legal range for the
+ // scrollbar that the user is changing.
+ //
+
+ nPosCrnt = GetScrollPos(hwndCtl,SB_CTL);
+ GetScrollRange(hwndCtl, SB_CTL, &nPosMin, &nPosMax);
+
+ switch (code) {
+ case SB_LINELEFT:
+ nPosCrnt--;
+ break;
+
+ case SB_LINERIGHT:
+ nPosCrnt++;
+ break;
+
+ case SB_PAGELEFT:
+ nPosCrnt += (nPosMax - nPosMin + 1) / 10;
+ break;
+
+ case SB_PAGERIGHT:
+ nPosCrnt -= (nPosMax - nPosMin + 1) / 10;
+ break;
+
+ case SB_THUMBTRACK:
+ nPosCrnt = pos;
+ break;
+
+ case SB_LEFT:
+ nPosCrnt = nPosMin;
+ break;
+
+ case SB_RIGHT:
+ nPosCrnt = nPosMax;
+ break;
+ }
+
+ //
+ // Make sure that the new scroll position
+ // is within the legal range.
+ //
+
+ if (nPosCrnt < nPosMin) {
+ nPosCrnt = nPosMin;
+ }
+
+ if (nPosCrnt > nPosMax) {
+ nPosCrnt = nPosMax;
+ }
+
+ switch (ControlId) {
+ case ID_NUM_CLIENTS:
+ hwndText = GetDlgItem(hwnd,ID_NNOC);
+ SelNumberOfClients = nPosCrnt;
+ _stprintf(szBuf, "%d", nPosCrnt);
+ break;
+
+ default:
+ return;
+
+ }
+
+ //
+ // Set the new scroll position.
+ //
+
+ SetScrollPos(hwndCtl, SB_CTL, nPosCrnt, TRUE);
+
+ //
+ // Change the value displayed in the text box to
+ // reflect the value in the scrollbar.
+ //
+
+
+ SetWindowText(hwndText, szBuf);
+}
+
+
+void
+ZdDlgCommand (
+ HWND hwnd,
+ int id,
+ HWND hwndCtl,
+ UINT codeNotify
+ )
+{
+
+ switch (id) {
+
+ case ID_START_SIM:
+ case IDOK:
+
+ EnableWindow(hwndCtl,FALSE);
+ EnableWindow(GetDlgItem(hwnd, ID_END_SIM),TRUE);
+ EnableWindow(GetDlgItem(hwnd, ID_NUM_CLIENTS),FALSE);
+ EnableWindow(GetDlgItem(hwnd, ID_RAD_DYNAMIC_THREADS),FALSE);
+ EnableWindow(GetDlgItem(hwnd, ID_RAD_THREAD_PER_CLIENT),FALSE);
+ EnableWindow(GetDlgItem(hwnd, ID_RAD_TCP),FALSE);
+ EnableWindow(GetDlgItem(hwnd, ID_RAD_SPX),FALSE);
+
+ SelNumberOfClients = GetScrollPos(GetDlgItem(hwnd, ID_NUM_CLIENTS),SB_CTL);
+ if ( fOneThreadPerClient ) {
+ SelThreadsPerQueue = SelNumberOfClients;
+ }
+
+ SendMessage(hwndOutput, LB_RESETCONTENT, 0L, 0L);
+
+ //
+ // Disable the StartSimulation button
+ //
+
+
+ if (NULL == GetFocus()) {
+ SetFocus(GetDlgItem(hwnd, ID_END_SIM));
+ }
+
+ fSimulationStarted = TRUE;
+
+ CreateNetConnections();
+
+ CreateWorkers();
+
+ break;
+
+ case ID_RAD_DYNAMIC_THREADS:
+ SelThreadsPerQueue = 2;
+ fDynamicThreadMode = TRUE;
+ fOneThreadPerClient = FALSE;
+ break;
+
+ case ID_RAD_THREAD_PER_CLIENT:
+ SelThreadsPerQueue = GetScrollPos(GetDlgItem(hwnd, ID_NUM_CLIENTS),SB_CTL);;
+ fDynamicThreadMode = FALSE;
+ fOneThreadPerClient = TRUE;
+ break;
+
+ case ID_RAD_TCP:
+ fTcp = TRUE;
+ fSpx = FALSE;
+ break;
+
+ case ID_RAD_SPX:
+ fTcp = FALSE;
+ fSpx = TRUE;
+ break;
+
+ case ID_END_SIM:
+ EnableWindow(GetDlgItem(hwnd, ID_END_SIM),FALSE);
+ fSimulationStarted = FALSE;
+ break;
+
+ case IDCANCEL:
+ EndDialog(hwnd, id);
+ break;
+ }
+}
+
+//
+// This function constructs a string using the format string
+// passed and the variable number of arguments and adds the
+// string to the output window list box identified by the
+// global hwndOutput variable.
+//
+
+void
+OutputString(
+ LPCSTR szFmt,
+ ...
+ )
+{
+ CHAR szBuf[150];
+ int nIndex;
+ va_list va_params;
+
+ //
+ // Make va_params point to the first argument after szFmt.
+ //
+
+ va_start(va_params, szFmt);
+
+ //
+ // Build the string to be displayed.
+ //
+
+ _vstprintf(szBuf, szFmt, va_params);
+ do {
+
+ //
+ // Add the string to the end of the list box.
+ //
+
+ nIndex = SendMessage(hwndOutput,LB_ADDSTRING, 0L, (LPARAM)szBuf);
+
+ //
+ // If the list box is full, delete the first item in it.
+ //
+
+ if (nIndex == LB_ERR) {
+ SendMessage(hwndOutput, LB_DELETESTRING, (WPARAM)0, 0);
+ }
+
+ } while (nIndex == LB_ERR);
+
+ //
+ // Select the newly added item.
+ //
+
+ SendMessage(hwndOutput, LB_SETCURSEL, (WPARAM)nIndex, 0);
+
+ //
+ // Indicate that we are done referencing
+ // the variable arguments.
+ //
+
+ va_end(va_params);
+}
+
+DWORD
+WINAPI
+NetWorkThread(
+ LPVOID WorkContext
+ )
+{
+ PZD_WORK_QUEUE MyQueue;
+ PZD_THREAD Me;
+ DWORD WorkIndex;
+ INT err;
+ DWORD ResponseLength;
+ BOOL b;
+ LPOVERLAPPED lpo;
+ DWORD nbytes;
+
+ Me = (PZD_THREAD)WorkContext;
+ MyQueue = Me->WorkQueue;
+
+ for(;;){
+
+ b = GetQueuedCompletionStatus(
+ CompletionPort,
+ &nbytes,
+ &WorkIndex,
+ &lpo,
+ INFINITE
+ );
+
+ if ( b || lpo ) {
+
+ WorkerStartWork(Me);
+
+ //
+ // Don't send a response if we received 0 bytes (end of
+ // transmission).
+ //
+
+ if ( b && nbytes == 4 ) {
+
+ //
+ // Determine how long a response was desired by the client.
+ // The first four bytes of the received packet contain the
+ // number of bytes desired by the client.
+ //
+
+ ResponseLength = *(PDWORD)(ZdWorkQueue.IoBuffer[WorkIndex]);
+
+ //
+ // Send a response and post another asynchronous read on the
+ // socket.
+ //
+
+ err = send( MyQueue->Sockets[WorkIndex],
+ MyQueue->IoBuffer[WorkIndex], ResponseLength, 0 );
+ if ( err == SOCKET_ERROR ) {
+ MessageBox(HwndDlg,"Send Failed. Simulation Should Stop","Send Failed",MB_ICONSTOP|MB_OK);
+ }
+
+ ZdWorkQueue.Overlapped[WorkIndex].hEvent = NULL;
+
+ err = ReadFile( (HANDLE)ZdWorkQueue.Sockets[WorkIndex],
+ ZdWorkQueue.IoBuffer[WorkIndex], 4,
+ &ZdWorkQueue.Overlapped[WorkIndex].InternalHigh,
+ &ZdWorkQueue.Overlapped[WorkIndex] );
+ if ( !err && GetLastError( ) != ERROR_IO_PENDING ) {
+ MessageBox(HwndDlg,"ReadFile Failed. Simulation Should Stop","ReadFile Failed",MB_ICONSTOP|MB_OK);
+ }
+ }
+
+ WorkerEndWork(Me);
+
+ } else {
+
+ MessageBox(HwndDlg,"netWorkThread Wait Failed. Simulation Should Stop","Wait Failed",MB_ICONSTOP|MB_OK);
+ }
+ }
+}
+
+DWORD
+WINAPI
+NetWorkThread2(
+ LPVOID WorkContext
+ )
+{
+ PZD_WORK_QUEUE MyQueue;
+ PZD_THREAD Me;
+ DWORD WorkIndex;
+ INT err;
+ DWORD ResponseLength;
+
+ Me = (PZD_THREAD)WorkContext;
+ MyQueue = Me->WorkQueue;
+ WorkIndex = Me->ThreadIndex;
+
+ for(;;){
+
+ err = recv( MyQueue->Sockets[WorkIndex],
+ MyQueue->IoBuffer[WorkIndex], 4, 0 );
+ if ( err == SOCKET_ERROR ) {
+ MessageBox(HwndDlg,"Recv Failed. Simulation Should Stop","Recv Failed",MB_ICONSTOP|MB_OK);
+ break;
+ }
+
+ if ( err < 4 ) {
+ return;
+ }
+
+ WorkerStartWork(Me);
+
+ //
+ // Determine how long a response was desired by the client. The
+ // first four bytes of the received packet contain the number of
+ // bytes desired by the client.
+ //
+
+ ResponseLength = *(PDWORD)(ZdWorkQueue.IoBuffer[WorkIndex]);
+
+ //
+ // Send a response and post another asynchronous read on the
+ // socket.
+ //
+
+ err = send( MyQueue->Sockets[WorkIndex],
+ MyQueue->IoBuffer[WorkIndex], ResponseLength, 0 );
+
+ if ( err == SOCKET_ERROR ) {
+ MessageBox(HwndDlg,"Send Failed. Simulation Should Stop","Send Failed",MB_ICONSTOP|MB_OK);
+ break;
+ }
+
+ WorkerEndWork(Me);
+
+ }
+}
+
+VOID
+CreateNetConnections(
+ void
+ )
+{
+ DWORD i;
+ SOCKET listener;
+ INT err;
+ WSADATA WsaData;
+
+ err = WSAStartup( 0x0101, &WsaData );
+ if ( err == SOCKET_ERROR ) {
+ MessageBox(HwndDlg,"WSAStartup Failed. Simulation Should Stop","WSAStartup Failed",MB_ICONSTOP|MB_OK);
+ return;
+ }
+
+ //
+ // Open a socket to listen for incoming connections.
+ //
+
+ if ( fTcp ) {
+
+ SOCKADDR_IN localAddr;
+
+ listener = socket( AF_INET, SOCK_STREAM, 0 );
+ if ( listener == INVALID_SOCKET ) {
+ MessageBox(HwndDlg,"Socket Create Failed. Simulation Should Stop","Socket Create Failed",MB_ICONSTOP|MB_OK);
+ return;
+ }
+
+ RtlZeroMemory( &localAddr, sizeof(localAddr) );
+ localAddr.sin_port = htons( 7 );
+ localAddr.sin_family = AF_INET;
+
+ err = bind( listener, (PSOCKADDR)&localAddr, sizeof(localAddr) );
+ if ( err ==SOCKET_ERROR ) {
+ MessageBox(HwndDlg,"Socket Bind Failed. Simulation Should Stop","Socket Bind Failed",MB_ICONSTOP|MB_OK);
+ return;
+ }
+
+ } else {
+
+ SOCKADDR_IPX localAddr;
+
+ listener = socket( AF_IPX, SOCK_STREAM, NSPROTO_SPX );
+ if ( listener == INVALID_SOCKET ) {
+ MessageBox(HwndDlg,"Socket Create Failed. Simulation Should Stop","Socket Create Failed",MB_ICONSTOP|MB_OK);
+ return;
+ }
+
+ RtlZeroMemory( &localAddr, sizeof(localAddr) );
+ localAddr.sa_socket = htons( 7 );
+ localAddr.sa_family = AF_IPX;
+
+ err = bind( listener, (PSOCKADDR)&localAddr, sizeof(localAddr) );
+ if ( err ==SOCKET_ERROR ) {
+ MessageBox(HwndDlg,"Socket Bind Failed. Simulation Should Stop","Socket Bind Failed",MB_ICONSTOP|MB_OK);
+ return;
+ }
+ }
+
+ err = listen( listener, 5 );
+ if ( err == SOCKET_ERROR ) {
+ MessageBox(HwndDlg,"Socket Listen Failed. Simulation Should Stop","Socket Listen Failed",MB_ICONSTOP|MB_OK);
+ return;
+ }
+
+
+ //
+ // Only Handle a single Queue
+ //
+
+ for(i=0;i<SelNumberOfClients;i++) {
+
+ //
+ // Accept incoming connect requests and create wait events for each.
+ //
+
+ ZdWorkQueue.Sockets[i] = accept( listener, NULL, NULL );
+ if ( ZdWorkQueue.Sockets[i] == INVALID_SOCKET ) {
+ MessageBox(HwndDlg,"Accept Failed. Simulation Should Stop","Accept Failed",MB_ICONSTOP|MB_OK);
+ }
+
+ //
+ // note the 16 says how many concurrent cpu bound threads to allow thru
+ // this should be tunable based on the requests. CPU bound requests will
+ // really really honor this.
+ //
+
+ CompletionPort = CreateIoCompletionPort(
+ (HANDLE)ZdWorkQueue.Sockets[i],
+ CompletionPort,
+ (DWORD)i,
+ 16
+ );
+
+ if ( !CompletionPort ) {
+ MessageBox(HwndDlg,"CompletionPort Create Failed. Simulation Should Stop","Completion Port Create Failed",MB_ICONSTOP|MB_OK);
+ }
+
+ //
+ // Start off an asynchronous read on the socket.
+ //
+
+ if (!fOneThreadPerClient) {
+ ZdWorkQueue.Overlapped[i].hEvent = NULL;
+ err = ReadFile( (HANDLE)ZdWorkQueue.Sockets[i],
+ ZdWorkQueue.IoBuffer[i], 4,
+ &ZdWorkQueue.Overlapped[i].InternalHigh,
+ &ZdWorkQueue.Overlapped[i] );
+ if ( !err && GetLastError( ) != ERROR_IO_PENDING ) {
+ MessageBox(HwndDlg,"ReadFile Failed. Simulation Should Stop","ReadFile Failed",MB_ICONSTOP|MB_OK);
+ }
+ }
+
+ ZdWorkQueue.NumberOfConnections++;
+ }
+
+ //
+ // Tell the clients to proceed with the test.
+ //
+
+ for(i=0;i<SelNumberOfClients;i++) {
+ err = send( ZdWorkQueue.Sockets[i], "go", 2, 0 );
+ if ( err != 2 ) {
+ MessageBox(HwndDlg,"send() Failed. Simulation Should Stop","send() Failed",MB_ICONSTOP|MB_OK);
+ }
+ }
+
+ //closesocket( listener );
+}
+
+VOID
+CreateWorkers(
+ void
+ )
+{
+ DWORD ThreadId;
+ HANDLE ThreadHandle;
+ DWORD i;
+ CHAR szBuf[10];
+ LPTHREAD_START_ROUTINE workRoutine;
+
+ if ( fDynamicThreadMode ) {
+ _stprintf(szBuf, "%d", SelThreadsPerQueue);
+ SetWindowText(GetDlgItem(HwndDlg,ID_NUMBER_OF_THREADS), szBuf);
+ }
+
+
+ for (i=0;i<SelThreadsPerQueue;i++) {
+ if ( ZdThreads[i].WorkQueue ) {
+ continue;
+ }
+ else {
+ ZdThreads[i].WorkQueue = &ZdWorkQueue;
+ switch (i) {
+ case 0:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_1);
+ break;
+
+ case 1:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_2);
+ break;
+
+ case 2:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_3);
+ break;
+
+ case 3:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_4);
+ break;
+
+ case 4:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_5);
+ break;
+
+ case 5:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_6);
+ break;
+
+ case 6:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_7);
+ break;
+
+ case 7:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_8);
+ break;
+
+ case 8:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_9);
+ break;
+
+ case 9:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_10);
+ break;
+
+ case 10:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_11);
+ break;
+
+ case 11:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_12);
+ break;
+
+ case 12:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_13);
+ break;
+
+ case 13:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_14);
+ break;
+
+ case 14:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_15);
+ break;
+
+ case 15:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_16);
+ break;
+
+ case 16:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_17);
+ break;
+
+ case 17:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_18);
+ break;
+
+ case 18:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_19);
+ break;
+
+ case 19:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_20);
+ break;
+
+ case 20:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_21);
+ break;
+
+ case 21:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_22);
+ break;
+
+ case 22:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_23);
+ break;
+
+ case 23:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_24);
+ break;
+
+ case 24:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_25);
+ break;
+
+ case 25:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_26);
+ break;
+
+ case 26:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_27);
+ break;
+
+ case 27:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_28);
+ break;
+
+ case 28:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_29);
+ break;
+
+ case 29:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_30);
+ break;
+
+ case 30:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_31);
+ break;
+
+ case 31:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_32);
+ break;
+
+ case 32:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_33);
+ break;
+
+ case 33:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_34);
+ break;
+
+ case 34:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_35);
+ break;
+
+ case 35:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_36);
+ break;
+
+ case 36:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_37);
+ break;
+
+ case 37:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_38);
+ break;
+
+ case 38:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_39);
+ break;
+
+ case 39:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_40);
+ break;
+
+ case 40:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_41);
+ break;
+
+ case 41:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_42);
+ break;
+
+ case 42:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_43);
+ break;
+
+ case 43:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_44);
+ break;
+
+ case 44:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_45);
+ break;
+
+ case 45:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_46);
+ break;
+
+ case 46:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_47);
+ break;
+
+ case 47:
+ ZdThreads[i].YourControl = GetDlgItem(HwndDlg,THREAD_48);
+ break;
+ }
+
+ if ( fOneThreadPerClient ) {
+ workRoutine = NetWorkThread2;
+ }
+ else {
+ workRoutine = NetWorkThread;
+ }
+
+ EnableWindow(ZdThreads[i].YourControl,TRUE);
+ ZdThreads[i].DynamicMode = fDynamicThreadMode;
+ ZdThreads[i].ThreadIndex = i;
+
+ ThreadHandle = CreateThread(
+ NULL,
+ 0,
+ workRoutine,
+ &ZdThreads[i],
+ 0,
+ &ThreadId
+ );
+ if ( !ThreadHandle ) {
+ MessageBox(HwndDlg,"Create Worker Thread Failed. Simulation Should Stop","Thread Create Failed",MB_ICONSTOP|MB_OK);
+ }
+
+ CloseHandle(ThreadHandle);
+ }
+ }
+
+}
+
+VOID
+WorkerStartWork(
+ PZD_THREAD WorkThread
+ )
+{
+ SendMessage(WorkThread->YourControl, BM_SETCHECK, 1, 0);
+
+ SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_HIGHEST);
+ if ( WorkThread->DynamicMode ) {
+ EnterCriticalSection(&DynamicCritSect);
+ ActiveThreadCount++;
+ if ( ActiveThreadCount == SelThreadsPerQueue ) {
+ ThreadsLoaded++;
+ if ( ThreadsLoaded > ZdThreadAddThreshold ) {
+ ThreadsLoaded = 0;
+ if ( SelThreadsPerQueue < MAX_THREADS_PER_QUEUE ) {
+ SelThreadsPerQueue++;
+ OutputString("Threads Oveloaded. New Thread Added");
+ if ((SelThreadsPerQueue & 1) == 0) {
+ ZdThreadAddThreshold++;
+ OutputString("New threshold %d", ZdThreadAddThreshold);
+ }
+ CreateWorkers();
+ }
+ }
+ }
+ else {
+ ThreadsLoaded = 0;
+ }
+ LeaveCriticalSection(&DynamicCritSect);
+ }
+
+}
+
+VOID
+WorkerEndWork(
+ PZD_THREAD WorkThread
+ )
+{
+ SendMessage(WorkThread->YourControl, BM_SETCHECK, 0, 0);
+
+ SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_NORMAL);
+ if ( WorkThread->DynamicMode ) {
+ EnterCriticalSection(&DynamicCritSect);
+ ActiveThreadCount--;
+ LeaveCriticalSection(&DynamicCritSect);
+ }
+
+}
diff --git a/private/sdktools/zd/zdsimp.h b/private/sdktools/zd/zdsimp.h
new file mode 100644
index 000000000..afa3ebdf6
--- /dev/null
+++ b/private/sdktools/zd/zdsimp.h
@@ -0,0 +1,125 @@
+#include <windows.h>
+#include <windowsx.h>
+#include <tchar.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <winsock.h>
+#include <wsipx.h>
+#include "zdbnch.h"
+
+//
+// Simulation Parameters
+//
+#define MIN_CLIENTS 1
+#define MAX_CLIENTS 48
+#define DEF_CLIENTS 16
+
+#define MIN_QUEUES 1
+#define MAX_QUEUES 16
+#define DEF_QUEUES 1
+
+#define MIN_THREADS_PER_QUEUE 1
+#define MAX_THREADS_PER_QUEUE 48
+#define DEF_THREADS_PER_QUEUE 1
+
+#define MAX_PACKET_SIZE 4096
+#define DEFAULT_THREAD_ADD_THRESHOLD 3
+
+DWORD SelNumberOfClients;
+DWORD SelThreadsPerQueue;
+
+HWND hwndOutput;
+BOOL fSimulationStarted;
+HWND HwndDlg;
+BOOL fSpx;
+BOOL fTcp;
+BOOL fDynamicThreadMode;
+BOOL fOneThreadPerClient;
+CRITICAL_SECTION DynamicCritSect;
+DWORD ActiveThreadCount;
+DWORD ThreadsLoaded;
+DWORD ZdThreadAddThreshold = DEFAULT_THREAD_ADD_THRESHOLD;
+HANDLE CompletionPort;
+
+typedef struct _ZD_WORK_QUEUE {
+ DWORD NumberOfConnections;
+ SOCKET Sockets[MAX_CLIENTS];
+ OVERLAPPED Overlapped[MAX_CLIENTS];
+ BYTE IoBuffer[MAX_CLIENTS][MAX_PACKET_SIZE];
+} ZD_WORK_QUEUE, *PZD_WORK_QUEUE;
+
+typedef struct _ZD_THREAD {
+ PZD_WORK_QUEUE WorkQueue;
+ BOOL DynamicMode;
+ HWND YourControl;
+ DWORD ThreadIndex;
+} ZD_THREAD, *PZD_THREAD;
+
+ZD_WORK_QUEUE ZdWorkQueue;
+ZD_THREAD ZdThreads[MAX_THREADS_PER_QUEUE];
+
+BOOL
+CALLBACK
+ZdDlgProc(
+ HWND hDlg,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam
+ );
+
+BOOL
+ZdDlgInit(
+ HWND hwnd,
+ HWND hwndFocus,
+ LPARAM lParam
+ );
+
+void
+ZdDlgParamChange(
+ HWND hwnd,
+ HWND hwndCtl,
+ UINT code,
+ int pos
+ );
+
+void
+ZdDlgCommand (
+ HWND hwnd,
+ int id,
+ HWND hwndCtl,
+ UINT codeNotify
+ );
+
+
+DWORD
+Random (
+ DWORD nMaxValue
+ );
+
+void
+OutputString(
+ LPCSTR szFmt,
+ ...
+ );
+
+VOID
+CreateNetConnections(
+ void
+ );
+
+VOID
+CreateWorkers(
+ void
+ );
+
+VOID
+WorkerStartWork(
+ PZD_THREAD WorkThread
+ );
+
+VOID
+WorkerEndWork(
+ PZD_THREAD WorkThread
+ );