1/*
2 * wpa_supplicant/hostapd / OS specific functions for Win32 systems
3 * Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi>
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8
9#include "includes.h"
10#include <time.h>
11#include <winsock2.h>
12#include <wincrypt.h>
13
14#include "os.h"
15
16void os_sleep(os_time_t sec, os_time_t usec)
17{
18	if (sec)
19		Sleep(sec * 1000);
20	if (usec)
21		Sleep(usec / 1000);
22}
23
24
25int os_get_time(struct os_time *t)
26{
27#define EPOCHFILETIME (116444736000000000ULL)
28	FILETIME ft;
29	LARGE_INTEGER li;
30	ULONGLONG tt;
31
32#ifdef _WIN32_WCE
33	SYSTEMTIME st;
34
35	GetSystemTime(&st);
36	SystemTimeToFileTime(&st, &ft);
37#else /* _WIN32_WCE */
38	GetSystemTimeAsFileTime(&ft);
39#endif /* _WIN32_WCE */
40	li.LowPart = ft.dwLowDateTime;
41	li.HighPart = ft.dwHighDateTime;
42	tt = (li.QuadPart - EPOCHFILETIME) / 10;
43	t->sec = (os_time_t) (tt / 1000000);
44	t->usec = (os_time_t) (tt % 1000000);
45
46	return 0;
47}
48
49
50int os_mktime(int year, int month, int day, int hour, int min, int sec,
51	      os_time_t *t)
52{
53	struct tm tm, *tm1;
54	time_t t_local, t1, t2;
55	os_time_t tz_offset;
56
57	if (year < 1970 || month < 1 || month > 12 || day < 1 || day > 31 ||
58	    hour < 0 || hour > 23 || min < 0 || min > 59 || sec < 0 ||
59	    sec > 60)
60		return -1;
61
62	memset(&tm, 0, sizeof(tm));
63	tm.tm_year = year - 1900;
64	tm.tm_mon = month - 1;
65	tm.tm_mday = day;
66	tm.tm_hour = hour;
67	tm.tm_min = min;
68	tm.tm_sec = sec;
69
70	t_local = mktime(&tm);
71
72	/* figure out offset to UTC */
73	tm1 = localtime(&t_local);
74	if (tm1) {
75		t1 = mktime(tm1);
76		tm1 = gmtime(&t_local);
77		if (tm1) {
78			t2 = mktime(tm1);
79			tz_offset = t2 - t1;
80		} else
81			tz_offset = 0;
82	} else
83		tz_offset = 0;
84
85	*t = (os_time_t) t_local - tz_offset;
86	return 0;
87}
88
89
90int os_gmtime(os_time_t t, struct os_tm *tm)
91{
92	struct tm *tm2;
93	time_t t2 = t;
94
95	tm2 = gmtime(&t2);
96	if (tm2 == NULL)
97		return -1;
98	tm->sec = tm2->tm_sec;
99	tm->min = tm2->tm_min;
100	tm->hour = tm2->tm_hour;
101	tm->day = tm2->tm_mday;
102	tm->month = tm2->tm_mon + 1;
103	tm->year = tm2->tm_year + 1900;
104	return 0;
105}
106
107
108int os_daemonize(const char *pid_file)
109{
110	/* TODO */
111	return -1;
112}
113
114
115void os_daemonize_terminate(const char *pid_file)
116{
117}
118
119
120int os_get_random(unsigned char *buf, size_t len)
121{
122	HCRYPTPROV prov;
123	BOOL ret;
124
125	if (!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
126				 CRYPT_VERIFYCONTEXT))
127		return -1;
128
129	ret = CryptGenRandom(prov, len, buf);
130	CryptReleaseContext(prov, 0);
131
132	return ret ? 0 : -1;
133}
134
135
136unsigned long os_random(void)
137{
138	return rand();
139}
140
141
142char * os_rel2abs_path(const char *rel_path)
143{
144	return _strdup(rel_path);
145}
146
147
148int os_program_init(void)
149{
150#ifdef CONFIG_NATIVE_WINDOWS
151	WSADATA wsaData;
152	if (WSAStartup(MAKEWORD(2, 0), &wsaData)) {
153		printf("Could not find a usable WinSock.dll\n");
154		return -1;
155	}
156#endif /* CONFIG_NATIVE_WINDOWS */
157	return 0;
158}
159
160
161void os_program_deinit(void)
162{
163#ifdef CONFIG_NATIVE_WINDOWS
164	WSACleanup();
165#endif /* CONFIG_NATIVE_WINDOWS */
166}
167
168
169int os_setenv(const char *name, const char *value, int overwrite)
170{
171	return -1;
172}
173
174
175int os_unsetenv(const char *name)
176{
177	return -1;
178}
179
180
181char * os_readfile(const char *name, size_t *len)
182{
183	FILE *f;
184	char *buf;
185
186	f = fopen(name, "rb");
187	if (f == NULL)
188		return NULL;
189
190	fseek(f, 0, SEEK_END);
191	*len = ftell(f);
192	fseek(f, 0, SEEK_SET);
193
194	buf = malloc(*len);
195	if (buf == NULL) {
196		fclose(f);
197		return NULL;
198	}
199
200	fread(buf, 1, *len, f);
201	fclose(f);
202
203	return buf;
204}
205
206
207void * os_zalloc(size_t size)
208{
209	return calloc(1, size);
210}
211
212
213size_t os_strlcpy(char *dest, const char *src, size_t siz)
214{
215	const char *s = src;
216	size_t left = siz;
217
218	if (left) {
219		/* Copy string up to the maximum size of the dest buffer */
220		while (--left != 0) {
221			if ((*dest++ = *s++) == '\0')
222				break;
223		}
224	}
225
226	if (left == 0) {
227		/* Not enough room for the string; force NUL-termination */
228		if (siz != 0)
229			*dest = '\0';
230		while (*s++)
231			; /* determine total src string length */
232	}
233
234	return s - src - 1;
235}
236