1 /*
2  * Public domain
3  *
4  * Dongsheng Song <dongsheng.song@gmail.com>
5  * Brent Cook <bcook@openbsd.org>
6  */
7 
8 #include <windows.h>
9 
10 #include <io.h>
11 #include <fcntl.h>
12 
13 #include "apps.h"
14 
15 double
app_timer_real(int get)16 app_timer_real(int get)
17 {
18 	static __int64 start;
19 	__int64 now;
20 
21 	now = GetTickCount64();
22 	if (get) {
23 		return (now - start) / 1000.0;
24 	}
25 	start = now;
26 	return 0.0;
27 }
28 
29 double
app_timer_user(int stop)30 app_timer_user(int stop)
31 {
32 	static unsigned __int64 tmstart;
33 	union {
34 		unsigned __int64 u64;
35 		FILETIME ft;
36 	} ct, et, kt, ut;
37 
38 	GetProcessTimes(GetCurrentProcess(), &ct.ft, &et.ft, &kt.ft, &ut.ft);
39 	if (stop)
40 		return (ut.u64 + kt.u64 - tmstart) / (double) 10000000;
41 
42 	tmstart = ut.u64 + kt.u64;
43 	return 0.0;
44 }
45 
46 int
setup_ui(void)47 setup_ui(void)
48 {
49 	ui_method = UI_create_method("OpenSSL application user interface");
50 	UI_method_set_opener(ui_method, ui_open);
51 	UI_method_set_reader(ui_method, ui_read);
52 	UI_method_set_writer(ui_method, ui_write);
53 	UI_method_set_closer(ui_method, ui_close);
54 
55 	/*
56 	 * Set STDIO to binary
57 	 */
58 	_setmode(_fileno(stdin), _O_BINARY);
59 	_setmode(_fileno(stdout), _O_BINARY);
60 	_setmode(_fileno(stderr), _O_BINARY);
61 
62 	return 0;
63 }
64 
65 void
destroy_ui(void)66 destroy_ui(void)
67 {
68 	if (ui_method) {
69 		UI_destroy_method(ui_method);
70 		ui_method = NULL;
71 	}
72 }
73 
74 static void (*speed_alarm_handler)(int);
75 static HANDLE speed_thread;
76 static unsigned int speed_lapse;
77 static volatile unsigned int speed_schlock;
78 
79 void
speed_signal(int sigcatch,void (* func)(int sigraised))80 speed_signal(int sigcatch, void (*func)(int sigraised))
81 {
82 	speed_alarm_handler = func;
83 }
84 
85 static DWORD WINAPI
speed_timer(VOID * arg)86 speed_timer(VOID * arg)
87 {
88 	speed_schlock = 1;
89 	Sleep(speed_lapse);
90 	(*speed_alarm_handler)(0);
91 	return (0);
92 }
93 
94 unsigned int
speed_alarm(unsigned int seconds)95 speed_alarm(unsigned int seconds)
96 {
97 	DWORD err;
98 
99 	speed_lapse = seconds * 1000;
100 	speed_schlock = 0;
101 
102 	speed_thread = CreateThread(NULL, 4096, speed_timer, NULL, 0, NULL);
103 	if (speed_thread == NULL) {
104 		err = GetLastError();
105 		BIO_printf(bio_err, "CreateThread failed (%lu)", err);
106 		ExitProcess(err);
107 	}
108 
109 	while (!speed_schlock)
110 		Sleep(0);
111 
112 	return (seconds);
113 }
114 
115 void
speed_alarm_free(int run)116 speed_alarm_free(int run)
117 {
118 	DWORD err;
119 
120 	if (run) {
121 		if (TerminateThread(speed_thread, 0) == 0) {
122 			err = GetLastError();
123 			BIO_printf(bio_err, "TerminateThread failed (%lu)",
124 			    err);
125 			ExitProcess(err);
126 		}
127 	}
128 
129 	if (CloseHandle(speed_thread) == 0) {
130 		err = GetLastError();
131 		BIO_printf(bio_err, "CloseHandle failed (%lu)", err);
132 		ExitProcess(err);
133 	}
134 
135 	speed_thread = NULL;
136 	speed_lapse = 0;
137 	speed_schlock = 0;
138 }
139