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