aboutsummaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/util')
-rw-r--r--src/util/Makefile.am4
-rw-r--r--src/util/crypto_rsa.c16
-rw-r--r--src/util/disk.c2
-rw-r--r--src/util/network.c36
-rw-r--r--src/util/os_priority.c81
-rw-r--r--src/util/scheduler.c2
-rw-r--r--src/util/server.c3
-rw-r--r--src/util/time.c2
-rw-r--r--src/util/win.cc828
-rw-r--r--src/util/winproc.c254
10 files changed, 1217 insertions, 11 deletions
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index a90b2b793..9ecb3e469 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -4,6 +4,7 @@ plugindir = $(libdir)/gnunet
4 4
5if MINGW 5if MINGW
6 WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols -lole32 -lshell32 -luuid -liconv -lstdc++ -lcomdlg32 -lgdi32 6 WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols -lole32 -lshell32 -luuid -liconv -lstdc++ -lcomdlg32 -lgdi32
7 WINSRC = win.cc winproc.c
7endif 8endif
8 9
9if USE_COVERAGE 10if USE_COVERAGE
@@ -45,7 +46,8 @@ libgnunetutil_la_SOURCES = \
45 service.c \ 46 service.c \
46 signal.c \ 47 signal.c \
47 strings.c \ 48 strings.c \
48 time.c 49 time.c \
50 $(WINSRC)
49 51
50 52
51libgnunetutil_la_LIBADD = \ 53libgnunetutil_la_LIBADD = \
diff --git a/src/util/crypto_rsa.c b/src/util/crypto_rsa.c
index c5a6140f6..650df814e 100644
--- a/src/util/crypto_rsa.c
+++ b/src/util/crypto_rsa.c
@@ -559,7 +559,10 @@ rsa_decode_key (const struct RsaPrivateKeyBinaryEncoded *encoding)
559struct GNUNET_CRYPTO_RsaPrivateKey * 559struct GNUNET_CRYPTO_RsaPrivateKey *
560GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename) 560GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
561{ 561{
562#ifndef MINGW
563 // FIXME NILS
562 struct flock fl; 564 struct flock fl;
565#endif
563 struct GNUNET_CRYPTO_RsaPrivateKey *ret; 566 struct GNUNET_CRYPTO_RsaPrivateKey *ret;
564 struct RsaPrivateKeyBinaryEncoded *enc; 567 struct RsaPrivateKeyBinaryEncoded *enc;
565 struct stat sbuf; 568 struct stat sbuf;
@@ -581,11 +584,13 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
581 "open", filename); 584 "open", filename);
582 return NULL; 585 return NULL;
583 } 586 }
587#ifndef MINGW
584 memset (&fl, 0, sizeof (struct flock)); 588 memset (&fl, 0, sizeof (struct flock));
585 fl.l_type = F_WRLCK; 589 fl.l_type = F_WRLCK;
586 fl.l_whence = SEEK_SET; 590 fl.l_whence = SEEK_SET;
587 fl.l_len = sizeof (struct RsaPrivateKeyBinaryEncoded); 591 fl.l_len = sizeof (struct RsaPrivateKeyBinaryEncoded);
588 cnt = 0; 592 cnt = 0;
593
589 while (0 != fcntl (fd, F_SETLK, &fl)) 594 while (0 != fcntl (fd, F_SETLK, &fl))
590 { 595 {
591 sleep (1); 596 sleep (1);
@@ -604,6 +609,7 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
604 fl.l_whence = SEEK_SET; 609 fl.l_whence = SEEK_SET;
605 fl.l_len = sizeof (struct RsaPrivateKeyBinaryEncoded); 610 fl.l_len = sizeof (struct RsaPrivateKeyBinaryEncoded);
606 } 611 }
612#endif
607 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 613 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
608 _("Creating a new private key. This may take a while.\n")); 614 _("Creating a new private key. This may take a while.\n"));
609 ret = GNUNET_CRYPTO_rsa_key_create (); 615 ret = GNUNET_CRYPTO_rsa_key_create ();
@@ -612,6 +618,7 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
612 GNUNET_assert (enc != NULL); 618 GNUNET_assert (enc != NULL);
613 GNUNET_assert (ntohs (enc->len) == WRITE (fd, enc, ntohs (enc->len))); 619 GNUNET_assert (ntohs (enc->len) == WRITE (fd, enc, ntohs (enc->len)));
614 GNUNET_free (enc); 620 GNUNET_free (enc);
621#ifndef MINGW
615 fdatasync (fd); 622 fdatasync (fd);
616 memset (&fl, 0, sizeof (struct flock)); 623 memset (&fl, 0, sizeof (struct flock));
617 fl.l_type = F_UNLCK; 624 fl.l_type = F_UNLCK;
@@ -621,6 +628,7 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
621 if (0 != fcntl (fd, F_SETLK, &fl)) 628 if (0 != fcntl (fd, F_SETLK, &fl))
622 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, 629 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
623 "fcntl", filename); 630 "fcntl", filename);
631#endif
624 GNUNET_assert (0 == CLOSE (fd)); 632 GNUNET_assert (0 == CLOSE (fd));
625 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 633 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
626 _("Stored new private key in `%s'.\n"), filename); 634 _("Stored new private key in `%s'.\n"), filename);
@@ -636,6 +644,7 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
636 cnt = 0; 644 cnt = 0;
637 while (1) 645 while (1)
638 { 646 {
647#ifndef MINGW
639 memset (&fl, 0, sizeof (struct flock)); 648 memset (&fl, 0, sizeof (struct flock));
640 fl.l_type = F_RDLCK; 649 fl.l_type = F_RDLCK;
641 fl.l_whence = SEEK_SET; 650 fl.l_whence = SEEK_SET;
@@ -658,11 +667,13 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
658 sleep (1); 667 sleep (1);
659 continue; 668 continue;
660 } 669 }
670#endif
661 if (0 != STAT (filename, &sbuf)) 671 if (0 != STAT (filename, &sbuf))
662 { 672 {
663 /* eh, what!? File we opened is now gone!? */ 673 /* eh, what!? File we opened is now gone!? */
664 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, 674 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
665 "stat", filename); 675 "stat", filename);
676#ifndef MINGW
666 memset (&fl, 0, sizeof (struct flock)); 677 memset (&fl, 0, sizeof (struct flock));
667 fl.l_type = F_UNLCK; 678 fl.l_type = F_UNLCK;
668 fl.l_whence = SEEK_SET; 679 fl.l_whence = SEEK_SET;
@@ -671,10 +682,12 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
671 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, 682 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
672 "fcntl", filename); 683 "fcntl", filename);
673 GNUNET_assert (0 == CLOSE (fd)); 684 GNUNET_assert (0 == CLOSE (fd));
685#endif
674 return NULL; 686 return NULL;
675 } 687 }
676 if (sbuf.st_size < sizeof (struct RsaPrivateKeyBinaryEncoded)) 688 if (sbuf.st_size < sizeof (struct RsaPrivateKeyBinaryEncoded))
677 { 689 {
690#ifndef MINGW
678 /* maybe we got the read lock before the hostkey generating 691 /* maybe we got the read lock before the hostkey generating
679 process had a chance to get the write lock; give it up! */ 692 process had a chance to get the write lock; give it up! */
680 memset (&fl, 0, sizeof (struct flock)); 693 memset (&fl, 0, sizeof (struct flock));
@@ -698,6 +711,7 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
698 } 711 }
699 sleep (2); /* wait a bit longer! */ 712 sleep (2); /* wait a bit longer! */
700 continue; 713 continue;
714#endif
701 } 715 }
702 break; 716 break;
703 } 717 }
@@ -713,12 +727,14 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
713 filename); 727 filename);
714 GNUNET_free (enc); 728 GNUNET_free (enc);
715 } 729 }
730#ifndef MINGW
716 memset (&fl, 0, sizeof (struct flock)); 731 memset (&fl, 0, sizeof (struct flock));
717 fl.l_type = F_UNLCK; 732 fl.l_type = F_UNLCK;
718 fl.l_whence = SEEK_SET; 733 fl.l_whence = SEEK_SET;
719 fl.l_len = sizeof (struct RsaPrivateKeyBinaryEncoded); 734 fl.l_len = sizeof (struct RsaPrivateKeyBinaryEncoded);
720 if (0 != fcntl (fd, F_SETLK, &fl)) 735 if (0 != fcntl (fd, F_SETLK, &fl))
721 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); 736 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
737#endif
722 GNUNET_assert (0 == CLOSE (fd)); 738 GNUNET_assert (0 == CLOSE (fd));
723 return ret; 739 return ret;
724} 740}
diff --git a/src/util/disk.c b/src/util/disk.c
index f0fe9341b..5042f0867 100644
--- a/src/util/disk.c
+++ b/src/util/disk.c
@@ -157,7 +157,7 @@ GNUNET_DISK_get_blocks_available (const char *part)
157 szDrive[3] = 0; 157 szDrive[3] = 0;
158 if (!GetDiskFreeSpace (szDrive, &dwDummy, &dwDummy, &dwBlocks, &dwDummy)) 158 if (!GetDiskFreeSpace (szDrive, &dwDummy, &dwDummy, &dwBlocks, &dwDummy))
159 { 159 {
160 GNUNET_GE_LOG (GNUNET_ERROR_TYPE_WARNING, 160 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
161 _("`%s' failed for drive `%s': %u\n"), 161 _("`%s' failed for drive `%s': %u\n"),
162 "GetDiskFreeSpace", szDrive, GetLastError ()); 162 "GetDiskFreeSpace", szDrive, GetLastError ());
163 163
diff --git a/src/util/network.c b/src/util/network.c
index b6cce5462..890b4c573 100644
--- a/src/util/network.c
+++ b/src/util/network.c
@@ -249,9 +249,12 @@ GNUNET_NETWORK_socket_create_from_accept (struct GNUNET_SCHEDULER_Handle
249 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "accept"); 249 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "accept");
250 return NULL; 250 return NULL;
251 } 251 }
252#ifndef MINGW
253 // FIXME NILS
252 if (0 != fcntl (fd, F_SETFD, fcntl (fd, F_GETFD) | FD_CLOEXEC)) 254 if (0 != fcntl (fd, F_SETFD, fcntl (fd, F_GETFD) | FD_CLOEXEC))
253 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 255 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
254 "fcntl"); 256 "fcntl");
257#endif
255 if (addrlen > sizeof (addr)) 258 if (addrlen > sizeof (addr))
256 { 259 {
257 GNUNET_break (0); 260 GNUNET_break (0);
@@ -287,7 +290,7 @@ GNUNET_NETWORK_socket_create_from_accept (struct GNUNET_SCHEDULER_Handle
287 if (aret == GNUNET_NO) 290 if (aret == GNUNET_NO)
288 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 291 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
289 _("Access denied to `%s'\n"), 292 _("Access denied to `%s'\n"),
290 GNUNET_a2s(uaddr, addrlen)); 293 GNUNET_a2s(uaddr, addrlen));
291 GNUNET_break (0 == SHUTDOWN (fd, SHUT_RDWR)); 294 GNUNET_break (0 == SHUTDOWN (fd, SHUT_RDWR));
292 GNUNET_break (0 == CLOSE (fd)); 295 GNUNET_break (0 == CLOSE (fd));
293 GNUNET_free (uaddr); 296 GNUNET_free (uaddr);
@@ -432,9 +435,12 @@ try_connect (struct GNUNET_NETWORK_SocketHandle *sock)
432 sock->ai_pos = sock->ai_pos->ai_next; 435 sock->ai_pos = sock->ai_pos->ai_next;
433 continue; 436 continue;
434 } 437 }
438#ifndef MINGW
439 // FIXME NILS
435 if (0 != fcntl (s, F_SETFD, fcntl (s, F_GETFD) | FD_CLOEXEC)) 440 if (0 != fcntl (s, F_SETFD, fcntl (s, F_GETFD) | FD_CLOEXEC))
436 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 441 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
437 "fcntl"); 442 "fcntl");
443#endif
438 if (GNUNET_SYSERR == socket_set_blocking (s, GNUNET_NO)) 444 if (GNUNET_SYSERR == socket_set_blocking (s, GNUNET_NO))
439 { 445 {
440 /* we'll treat this one as fatal */ 446 /* we'll treat this one as fatal */
@@ -524,7 +530,7 @@ connect_continuation (void *cls,
524 } 530 }
525 /* connect succeeded! clean up "ai" */ 531 /* connect succeeded! clean up "ai" */
526#if DEBUG_NETWORK 532#if DEBUG_NETWORK
527 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 533 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
528 "Connection to `%s' succeeded!\n", 534 "Connection to `%s' succeeded!\n",
529 GNUNET_a2s(sock->addr, sock->addrlen)); 535 GNUNET_a2s(sock->addr, sock->addrlen));
530#endif 536#endif
@@ -619,9 +625,11 @@ GNUNET_NETWORK_socket_create_from_sockaddr (struct GNUNET_SCHEDULER_Handle
619 GNUNET_ERROR_TYPE_BULK, "socket"); 625 GNUNET_ERROR_TYPE_BULK, "socket");
620 return NULL; 626 return NULL;
621 } 627 }
628#ifndef MINGW
622 if (0 != fcntl (s, F_SETFD, fcntl (s, F_GETFD) | FD_CLOEXEC)) 629 if (0 != fcntl (s, F_SETFD, fcntl (s, F_GETFD) | FD_CLOEXEC))
623 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 630 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
624 "fcntl"); 631 "fcntl");
632#endif
625 if (GNUNET_SYSERR == socket_set_blocking (s, GNUNET_NO)) 633 if (GNUNET_SYSERR == socket_set_blocking (s, GNUNET_NO))
626 { 634 {
627 /* we'll treat this one as fatal */ 635 /* we'll treat this one as fatal */
@@ -712,7 +720,7 @@ destroy_continuation (void *cls,
712 } 720 }
713 } 721 }
714 if (sock->sock != -1) 722 if (sock->sock != -1)
715 GNUNET_break (0 == CLOSE (sock->sock)); 723 GNUNET_break (0 == CLOSE (sock->sock));
716 GNUNET_free_non_null (sock->addr); 724 GNUNET_free_non_null (sock->addr);
717 if (sock->ai != NULL) 725 if (sock->ai != NULL)
718 freeaddrinfo (sock->ai); 726 freeaddrinfo (sock->ai);
@@ -810,7 +818,14 @@ receive_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
810 } 818 }
811 GNUNET_assert (FD_ISSET (sh->sock, tc->read_ready)); 819 GNUNET_assert (FD_ISSET (sh->sock, tc->read_ready));
812RETRY: 820RETRY:
813 ret = RECV (sh->sock, buffer, sh->max, MSG_DONTWAIT); 821 ret = RECV (sh->sock, buffer, sh->max,
822#ifndef MINGW
823 // FIXME MINGW
824 MSG_DONTWAIT
825#else
826 0
827#endif
828 );
814 if (ret == -1) 829 if (ret == -1)
815 { 830 {
816 if (errno == EINTR) 831 if (errno == EINTR)
@@ -825,7 +840,7 @@ RETRY:
825#if DEBUG_NETWORK 840#if DEBUG_NETWORK
826 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 841 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
827 "receive_ready read %u/%u bytes from `%s'!\n", 842 "receive_ready read %u/%u bytes from `%s'!\n",
828 (unsigned int) ret, 843 (unsigned int) ret,
829 sh->max, 844 sh->max,
830 GNUNET_a2s(sh->addr, sh->addrlen)); 845 GNUNET_a2s(sh->addr, sh->addrlen));
831#endif 846#endif
@@ -889,7 +904,7 @@ receive_again (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
889 GNUNET_TIME_absolute_get_remaining 904 GNUNET_TIME_absolute_get_remaining
890 (sh->receive_timeout), 905 (sh->receive_timeout),
891 sh->sock, &receive_ready, 906 sh->sock, &receive_ready,
892 sh); 907 sh);
893} 908}
894 909
895 910
@@ -1086,7 +1101,14 @@ transmit_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1086RETRY: 1101RETRY:
1087 ret = SEND (sock->sock, 1102 ret = SEND (sock->sock,
1088 &sock->write_buffer[sock->write_buffer_pos], 1103 &sock->write_buffer[sock->write_buffer_pos],
1089 have, MSG_DONTWAIT | MSG_NOSIGNAL); 1104 have,
1105#ifndef MINGW
1106 // FIXME NILS
1107 MSG_DONTWAIT | MSG_NOSIGNAL
1108#else
1109 0
1110#endif
1111 );
1090 if (ret == -1) 1112 if (ret == -1)
1091 { 1113 {
1092 if (errno == EINTR) 1114 if (errno == EINTR)
diff --git a/src/util/os_priority.c b/src/util/os_priority.c
index 7862d68e9..f74bd9266 100644
--- a/src/util/os_priority.c
+++ b/src/util/os_priority.c
@@ -123,9 +123,11 @@ GNUNET_OS_set_process_priority (pid_t proc,
123pid_t 123pid_t
124GNUNET_OS_start_process (const char *filename, ...) 124GNUNET_OS_start_process (const char *filename, ...)
125{ 125{
126 va_list ap;
127
128#ifndef MINGW
126 pid_t ret; 129 pid_t ret;
127 char **argv; 130 char **argv;
128 va_list ap;
129 int argc; 131 int argc;
130 132
131 ret = fork (); 133 ret = fork ();
@@ -149,6 +151,42 @@ GNUNET_OS_start_process (const char *filename, ...)
149 execvp (filename, argv); 151 execvp (filename, argv);
150 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "execvp", filename); 152 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "execvp", filename);
151 exit (1); 153 exit (1);
154#else
155 char *arg;
156 unsigned int cmdlen;
157 char *cmd, *idx;
158 STARTUPINFO start;
159 PROCESS_INFORMATION proc;
160
161 cmdlen = 0;
162 va_start (ap, filename);
163 while (NULL != (arg = va_arg (ap, char *)))
164 cmdlen = cmdlen + strlen (arg) + 3;
165 va_end (ap);
166
167 cmd = idx = GNUNET_malloc (sizeof(char) * cmdlen);
168 va_start (ap, filename);
169 while (NULL != (arg = va_arg (ap, char *)))
170 idx += sprintf (idx, "\"%s\" ", arg);
171 va_end (ap);
172
173 memset (&start, 0, sizeof(start));
174 start.cb = sizeof(start);
175
176 if (!CreateProcess (filename, cmd, NULL, NULL, FALSE, DETACHED_PROCESS, NULL,
177 NULL, &start, &proc))
178 {
179 SetErrnoFromWinError (GetLastError ());
180 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "fork");
181 return -1;
182 }
183 CloseHandle (proc.hProcess);
184 CloseHandle (proc.hThread);
185
186 GNUNET_free(cmd);
187
188 return proc.dwProcessId;
189#endif
152} 190}
153 191
154 192
@@ -164,6 +202,7 @@ GNUNET_OS_start_process (const char *filename, ...)
164pid_t 202pid_t
165GNUNET_OS_start_process_v (const char *filename, char *const argv[]) 203GNUNET_OS_start_process_v (const char *filename, char *const argv[])
166{ 204{
205#ifndef MINGW
167 pid_t ret; 206 pid_t ret;
168 207
169 ret = fork (); 208 ret = fork ();
@@ -176,6 +215,46 @@ GNUNET_OS_start_process_v (const char *filename, char *const argv[])
176 execvp (filename, argv); 215 execvp (filename, argv);
177 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "execvp", filename); 216 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "execvp", filename);
178 exit (1); 217 exit (1);
218#else
219 char **arg;
220 unsigned int cmdlen;
221 char *cmd, *idx;
222 STARTUPINFO start;
223 PROCESS_INFORMATION proc;
224
225 cmdlen = 0;
226 arg = argv;
227 while (*arg)
228 {
229 cmdlen = cmdlen + strlen (*arg) + 3;
230 arg++;
231 }
232
233 cmd = idx = GNUNET_malloc (sizeof(char) * cmdlen);
234 arg = argv;
235 while (*arg)
236 {
237 idx += sprintf (idx, "\"%s\" ", *arg);
238 arg++;
239 }
240
241 memset (&start, 0, sizeof(start));
242 start.cb = sizeof(start);
243
244 if (!CreateProcess (filename, cmd, NULL, NULL, FALSE, DETACHED_PROCESS, NULL,
245 NULL, &start, &proc))
246 {
247 SetErrnoFromWinError (GetLastError ());
248 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "fork");
249 return -1;
250 }
251 CloseHandle (proc.hProcess);
252 CloseHandle (proc.hThread);
253
254 GNUNET_free(cmd);
255
256 return proc.dwProcessId;
257#endif
179} 258}
180 259
181 260
diff --git a/src/util/scheduler.c b/src/util/scheduler.c
index a20b3da06..4872eee41 100644
--- a/src/util/scheduler.c
+++ b/src/util/scheduler.c
@@ -470,10 +470,12 @@ GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_Task task, void *cls)
470 struct Task *tpos; 470 struct Task *tpos;
471 471
472 sig_shutdown = 0; 472 sig_shutdown = 0;
473#ifndef MINGW
473 shc_int = GNUNET_SIGNAL_handler_install (SIGINT, &sighandler_shutdown); 474 shc_int = GNUNET_SIGNAL_handler_install (SIGINT, &sighandler_shutdown);
474 shc_term = GNUNET_SIGNAL_handler_install (SIGTERM, &sighandler_shutdown); 475 shc_term = GNUNET_SIGNAL_handler_install (SIGTERM, &sighandler_shutdown);
475 shc_quit = GNUNET_SIGNAL_handler_install (SIGQUIT, &sighandler_shutdown); 476 shc_quit = GNUNET_SIGNAL_handler_install (SIGQUIT, &sighandler_shutdown);
476 shc_hup = GNUNET_SIGNAL_handler_install (SIGHUP, &sighandler_shutdown); 477 shc_hup = GNUNET_SIGNAL_handler_install (SIGHUP, &sighandler_shutdown);
478#endif
477 memset (&sched, 0, sizeof (sched)); 479 memset (&sched, 0, sizeof (sched));
478 sched.current_priority = GNUNET_SCHEDULER_PRIORITY_DEFAULT; 480 sched.current_priority = GNUNET_SCHEDULER_PRIORITY_DEFAULT;
479 GNUNET_SCHEDULER_add_continuation (&sched, 481 GNUNET_SCHEDULER_add_continuation (&sched,
diff --git a/src/util/server.c b/src/util/server.c
index 939814725..282e036e8 100644
--- a/src/util/server.c
+++ b/src/util/server.c
@@ -379,9 +379,12 @@ open_listen_socket (const struct sockaddr *serverAddr, socklen_t socklen)
379 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket"); 379 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket");
380 return -1; 380 return -1;
381 } 381 }
382#ifndef MINGW
383 // FIXME NILS
382 if (0 != fcntl (fd, F_SETFD, fcntl (fd, F_GETFD) | FD_CLOEXEC)) 384 if (0 != fcntl (fd, F_SETFD, fcntl (fd, F_GETFD) | FD_CLOEXEC))
383 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 385 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
384 "fcntl"); 386 "fcntl");
387#endif
385 if (SETSOCKOPT (fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0) 388 if (SETSOCKOPT (fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
386 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 389 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
387 "setsockopt"); 390 "setsockopt");
diff --git a/src/util/time.c b/src/util/time.c
index 3ae472561..c8f408841 100644
--- a/src/util/time.c
+++ b/src/util/time.c
@@ -39,7 +39,7 @@ GNUNET_TIME_absolute_get ()
39 struct GNUNET_TIME_Absolute ret; 39 struct GNUNET_TIME_Absolute ret;
40 struct timeval tv; 40 struct timeval tv;
41 41
42 gettimeofday (&tv, NULL); 42 GETTIMEOFDAY (&tv, NULL);
43 ret.value = tv.tv_sec * 1000 + tv.tv_usec / 1000; 43 ret.value = tv.tv_sec * 1000 + tv.tv_usec / 1000;
44 return ret; 44 return ret;
45} 45}
diff --git a/src/util/win.cc b/src/util/win.cc
new file mode 100644
index 000000000..f3e4bd98c
--- /dev/null
+++ b/src/util/win.cc
@@ -0,0 +1,828 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2005, 2006 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file util/win/win.cc
23 * @brief Helper functions for MS Windows in C++
24 * @author Nils Durner
25 **/
26
27#ifndef _WIN_CC
28#define _WIN_CC
29
30#include "winproc.h"
31#include "platform.h"
32#include "gnunet_common.h"
33#include "gnunet_network_lib.h"
34
35#include <list>
36using namespace std;
37#include <ntdef.h>
38
39#ifndef INHERITED_ACE
40#define INHERITED_ACE 0x10
41#endif
42
43extern "C" {
44
45typedef list<WSAOVERLAPPED *> TOLList;
46
47static HANDLE hOLLock;
48static TOLList lstOL;
49
50int plibc_conv_to_win_path(const char *pszUnix, char *pszWindows);
51
52void __attribute__ ((constructor)) gnunet_win_init() {
53 hOLLock = CreateMutex(NULL, FALSE, NULL);
54}
55
56void __attribute__ ((destructor)) gnunet_win_fini() {
57 CloseHandle(hOLLock);
58}
59
60/**
61 * Enumerate all network adapters
62 */
63void EnumNICs(PMIB_IFTABLE *pIfTable, PMIB_IPADDRTABLE *pAddrTable)
64{
65 DWORD dwSize, dwRet;
66
67 *pIfTable = NULL;
68
69 if (pAddrTable)
70 *pAddrTable = NULL;
71
72 if (GNGetIfTable)
73 {
74 dwSize = dwRet = 0;
75
76 *pIfTable = (MIB_IFTABLE *) GlobalAlloc(GPTR, sizeof(MIB_IFTABLE));
77
78 /* Get size of table */
79 if (GNGetIfTable(*pIfTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER)
80 {
81 GlobalFree(*pIfTable);
82 *pIfTable = (MIB_IFTABLE *) GlobalAlloc(GPTR, dwSize);
83 }
84
85 if ((dwRet = GNGetIfTable(*pIfTable, &dwSize, 0)) == NO_ERROR &&
86 pAddrTable)
87 {
88 DWORD dwIfIdx, dwSize = sizeof(MIB_IPADDRTABLE);
89 *pAddrTable = (MIB_IPADDRTABLE *) GlobalAlloc(GPTR, dwSize);
90
91 /* Make an initial call to GetIpAddrTable to get the
92 necessary size */
93 if (GNGetIpAddrTable(*pAddrTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER)
94 {
95 GlobalFree(*pAddrTable);
96 *pAddrTable = (MIB_IPADDRTABLE *) GlobalAlloc(GPTR, dwSize);
97 }
98 GNGetIpAddrTable(*pAddrTable, &dwSize, 0);
99 }
100 }
101}
102
103/**
104 * Lists all network interfaces in a combo box
105 * Used by the basic GTK configurator
106 * @param callback
107 */
108 int ListNICs(void (*callback) (const char *, int, void *), void * cls)
109{
110 PMIB_IFTABLE pTable;
111 PMIB_IPADDRTABLE pAddrTable;
112 DWORD dwIfIdx, dwExternalNIC;
113 IPAddr theIP;
114
115 /* Determine our external NIC */
116 theIP = inet_addr("192.0.34.166"); /* www.example.com */
117 if ((! GNGetBestInterface) ||
118 (GNGetBestInterface(theIP, &dwExternalNIC) != NO_ERROR))
119 {
120 dwExternalNIC = 0;
121 }
122
123 /* Enumerate NICs */
124 EnumNICs(&pTable, &pAddrTable);
125
126 if (pTable)
127 {
128 for(dwIfIdx=0; dwIfIdx <= pTable->dwNumEntries; dwIfIdx++)
129 {
130 char szEntry[1001];
131 DWORD dwIP = 0;
132 int iItm;
133 PIP_ADAPTER_INFO pAdapterInfo;
134 PIP_ADAPTER_INFO pAdapter = NULL;
135 DWORD dwRetVal = 0;
136
137 /* Get IP-Address */
138 int i;
139 for(i = 0; i < pAddrTable->dwNumEntries; i++)
140 {
141 if (pAddrTable->table[i].dwIndex == pTable->table[dwIfIdx].dwIndex)
142 {
143 dwIP = pAddrTable->table[i].dwAddr;
144 break;
145 }
146 }
147
148 if (dwIP)
149 {
150 BYTE bPhysAddr[MAXLEN_PHYSADDR];
151 char *pszIfName = NULL;
152 char dst[INET_ADDRSTRLEN];
153
154 /* Get friendly interface name */
155 pAdapterInfo = (IP_ADAPTER_INFO *) malloc(sizeof(IP_ADAPTER_INFO));
156 ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);
157
158 /* Make an initial call to GetAdaptersInfo to get
159 the necessary size into the ulOutBufLen variable */
160 if (GGetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
161 free(pAdapterInfo);
162 pAdapterInfo = (IP_ADAPTER_INFO *) malloc (ulOutBufLen);
163 }
164
165 if ((dwRetVal = GGetAdaptersInfo( pAdapterInfo, &ulOutBufLen)) == NO_ERROR) {
166 pAdapter = pAdapterInfo;
167 while (pAdapter) {
168 if (pTable->table[dwIfIdx].dwIndex == pAdapter->Index)
169 {
170 char szKey[251];
171 long lLen = 250;
172
173 sprintf(szKey, "SYSTEM\\CurrentControlSet\\Control\\Network\\"
174 "{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection",
175 pAdapter->AdapterName);
176 pszIfName = (char *) malloc(251);
177 if (QueryRegistry(HKEY_LOCAL_MACHINE, szKey, "Name", pszIfName,
178 &lLen) != ERROR_SUCCESS)
179 {
180 free(pszIfName);
181 pszIfName = NULL;
182 }
183 }
184 pAdapter = pAdapter->Next;
185 }
186 }
187 free(pAdapterInfo);
188
189 /* Set entry */
190 memset(bPhysAddr, 0, MAXLEN_PHYSADDR);
191 memcpy(bPhysAddr,
192 pTable->table[dwIfIdx].bPhysAddr,
193 pTable->table[dwIfIdx].dwPhysAddrLen);
194
195 snprintf(szEntry, 1000, "%s (%s - %I64u)",
196 pszIfName ? pszIfName : (char *) pTable->table[dwIfIdx].bDescr,
197 inet_ntop (AF_INET, &dwIP, dst, INET_ADDRSTRLEN),
198 *((unsigned long long *) bPhysAddr));
199 szEntry[1000] = 0;
200
201 if (pszIfName)
202 free(pszIfName);
203
204 callback(szEntry, pAddrTable->table[dwIfIdx].dwIndex == dwExternalNIC, cls);
205 }
206 }
207 GlobalFree(pAddrTable);
208 GlobalFree(pTable);
209 }
210
211 return GNUNET_YES;
212}
213
214/**
215 * @brief Installs the Windows service
216 * @param servicename name of the service as diplayed by the SCM
217 * @param application path to the application binary
218 * @param username the name of the service's user account
219 * @returns 0 on success
220 * 1 if the Windows version doesn't support services
221 * 2 if the SCM could not be opened
222 * 3 if the service could not be created
223 */
224int InstallAsService(char *servicename, char *application, char *username)
225{
226 SC_HANDLE hManager, hService;
227 char szEXE[_MAX_PATH + 17] = "\"";
228 char *user = NULL;
229
230 if (! GNOpenSCManager)
231 return 1;
232
233 plibc_conv_to_win_path(application, szEXE + 1);
234 strcat(szEXE, "\" --win-service");
235 hManager = GNOpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
236 if (! hManager)
237 return 2;
238
239 if (username)
240 {
241 user = (char *) malloc(strlen(username) + 3);
242 sprintf(user, ".\\%s", username);
243 }
244
245 hService = GNCreateService(hManager, (LPCTSTR) servicename, (LPCTSTR) servicename, 0,
246 SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, (LPCTSTR) szEXE,
247 NULL, NULL, NULL, (LPCTSTR) user, (LPCTSTR) username);
248
249 if (user)
250 free(user);
251
252 if (! hService)
253 return 3;
254
255 GNCloseServiceHandle(hService);
256
257 return 0;
258}
259
260/**
261 * @brief Uninstall Windows service
262 * @param servicename name of the service to delete
263 * @returns 0 on success
264 * 1 if the Windows version doesn't support services
265 * 2 if the SCM could not be openend
266 * 3 if the service cannot be accessed
267 * 4 if the service cannot be deleted
268 */
269int UninstallService(char *servicename)
270{
271 SC_HANDLE hManager, hService;
272
273 if (! GNOpenSCManager)
274 return 1;
275
276 hManager = GNOpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
277 if (! hManager)
278 return 2;
279
280 if (! (hService = GNOpenService(hManager, (LPCTSTR) servicename, DELETE)))
281 if (GetLastError() != ERROR_SERVICE_DOES_NOT_EXIST)
282 return 3;
283 else
284 goto closeSCM;
285
286 if (! GNDeleteService(hService))
287 if (GetLastError() != ERROR_SERVICE_MARKED_FOR_DELETE)
288 return 4;
289
290closeSCM:
291 GNCloseServiceHandle(hService);
292
293 return 0;
294}
295
296/**
297 * @author Scott Field, Microsoft
298 * @see http://support.microsoft.com/?scid=kb;en-us;132958
299 * @date 12-Jul-95
300 */
301void _InitLsaString(PLSA_UNICODE_STRING LsaString, LPWSTR String)
302{
303 DWORD StringLength;
304
305 if(String == NULL)
306 {
307 LsaString->Buffer = NULL;
308 LsaString->Length = 0;
309 LsaString->MaximumLength = 0;
310 return;
311 }
312
313 StringLength = wcslen(String);
314 LsaString->Buffer = String;
315 LsaString->Length = (USHORT) StringLength *sizeof(WCHAR);
316 LsaString->MaximumLength = (USHORT) (StringLength + 1) * sizeof(WCHAR);
317}
318
319
320/**
321 * @author Scott Field, Microsoft
322 * @see http://support.microsoft.com/?scid=kb;en-us;132958
323 * @date 12-Jul-95
324 */
325NTSTATUS _OpenPolicy(LPWSTR ServerName, DWORD DesiredAccess, PLSA_HANDLE PolicyHandle)
326{
327 LSA_OBJECT_ATTRIBUTES ObjectAttributes;
328 LSA_UNICODE_STRING ServerString;
329 PLSA_UNICODE_STRING Server = NULL;
330
331 /* Always initialize the object attributes to all zeroes. */
332 ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
333
334 if(ServerName != NULL)
335 {
336 /* Make a LSA_UNICODE_STRING out of the LPWSTR passed in */
337 _InitLsaString(&ServerString, ServerName);
338 Server = &ServerString;
339 }
340
341 /* Attempt to open the policy. */
342 return GNLsaOpenPolicy(Server,
343 &ObjectAttributes, DesiredAccess, PolicyHandle);
344}
345
346/**
347 * @brief Obtain a SID representing the supplied account on the supplied system
348 * @return TRUE on success, FALSE on failure
349 * @author Scott Field, Microsoft
350 * @date 12-Jul-95
351 * @remarks A buffer is allocated which contains the SID representing the
352 * supplied account. This buffer should be freed when it is no longer
353 * needed by calling\n
354 * HeapFree(GetProcessHeap(), 0, buffer)
355 * @remarks Call GetLastError() to obtain extended error information.
356 * @see http://support.microsoft.com/?scid=kb;en-us;132958
357 */
358BOOL _GetAccountSid(LPTSTR SystemName, LPTSTR AccountName, PSID * Sid)
359{
360 LPTSTR ReferencedDomain = NULL;
361 DWORD cbSid = 128; /* initial allocation attempt */
362 DWORD cchReferencedDomain = 16; /* initial allocation size */
363 SID_NAME_USE peUse;
364 BOOL bSuccess = FALSE; /* assume this function will fail */
365
366 /* initial memory allocations */
367 if ((*Sid = HeapAlloc (GetProcessHeap (), 0, cbSid)) == NULL)
368 return FALSE;
369
370 if ((ReferencedDomain = (LPTSTR) HeapAlloc (GetProcessHeap (),
371 0,
372 cchReferencedDomain *
373 sizeof (TCHAR))) == NULL)
374 return FALSE;
375
376 /* Obtain the SID of the specified account on the specified system. */
377 while (!GNLookupAccountName(SystemName, /* machine to lookup account on */
378 AccountName, /* account to lookup */
379 *Sid, /* SID of interest */
380 &cbSid, /* size of SID */
381 ReferencedDomain, /* domain account was found on */
382 &cchReferencedDomain, &peUse))
383 {
384 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
385 {
386 /* reallocate memory */
387 if ((*Sid = HeapReAlloc (GetProcessHeap (), 0, *Sid, cbSid)) == NULL)
388 return FALSE;
389
390 if ((ReferencedDomain = (LPTSTR) HeapReAlloc (GetProcessHeap (),
391 0,
392 ReferencedDomain,
393 cchReferencedDomain
394 * sizeof (TCHAR))) == NULL)
395 return FALSE;
396 }
397 else
398 goto end;
399 }
400
401 /* Indicate success. */
402 bSuccess = TRUE;
403
404end:
405 /* Cleanup and indicate failure, if appropriate. */
406 HeapFree (GetProcessHeap (), 0, ReferencedDomain);
407
408 if (!bSuccess)
409 {
410 if (*Sid != NULL)
411 {
412 HeapFree (GetProcessHeap (), 0, *Sid);
413 *Sid = NULL;
414 }
415 }
416
417 return bSuccess;
418}
419
420/**
421 * @author Scott Field, Microsoft
422 * @see http://support.microsoft.com/?scid=kb;en-us;132958
423 * @date 12-Jul-95
424 */
425NTSTATUS _SetPrivilegeOnAccount(LSA_HANDLE PolicyHandle,/* open policy handle */
426 PSID AccountSid, /* SID to grant privilege to */
427 LPWSTR PrivilegeName, /* privilege to grant (Unicode) */
428 BOOL bEnable /* enable or disable */
429 )
430{
431 LSA_UNICODE_STRING PrivilegeString;
432
433 /* Create a LSA_UNICODE_STRING for the privilege name. */
434 _InitLsaString(&PrivilegeString, PrivilegeName);
435
436 /* grant or revoke the privilege, accordingly */
437 if(bEnable)
438 {
439 NTSTATUS i;
440
441 i = GNLsaAddAccountRights(PolicyHandle, /* open policy handle */
442 AccountSid, /* target SID */
443 &PrivilegeString, /* privileges */
444 1 /* privilege count */
445 );
446 }
447 else
448 {
449 return GNLsaRemoveAccountRights(PolicyHandle, /* open policy handle */
450 AccountSid, /* target SID */
451 FALSE, /* do not disable all rights */
452 &PrivilegeString, /* privileges */
453 1 /* privilege count */
454 );
455 }
456}
457
458/**
459 * @brief Create a Windows service account
460 * @return 0 on success, > 0 otherwise
461 * @param pszName the name of the account
462 * @param pszDesc description of the account
463 */
464int CreateServiceAccount(char *pszName, char *pszDesc)
465{
466 USER_INFO_1 ui;
467 USER_INFO_1008 ui2;
468 NET_API_STATUS nStatus;
469 wchar_t wszName[MAX_NAME_LENGTH], wszDesc[MAX_NAME_LENGTH];
470 DWORD dwErr;
471 LSA_HANDLE hPolicy;
472 PSID pSID;
473
474 if (! GNNetUserAdd)
475 return 1;
476 mbstowcs(wszName, pszName, strlen(pszName) + 1);
477 mbstowcs(wszDesc, pszDesc, strlen(pszDesc) + 1);
478
479 memset(&ui, 0, sizeof(ui));
480 ui.usri1_name = wszName;
481 ui.usri1_password = wszName; /* account is locked anyway */
482 ui.usri1_priv = USER_PRIV_USER;
483 ui.usri1_comment = wszDesc;
484 ui.usri1_flags = UF_SCRIPT;
485
486 nStatus = GNNetUserAdd(NULL, 1, (LPBYTE)&ui, NULL);
487
488 if (nStatus != NERR_Success && nStatus != NERR_UserExists)
489 return 2;
490
491 ui2.usri1008_flags = UF_PASSWD_CANT_CHANGE | UF_DONT_EXPIRE_PASSWD;
492 GNNetUserSetInfo(NULL, wszName, 1008, (LPBYTE)&ui2, NULL);
493
494 if (_OpenPolicy(NULL, POLICY_ALL_ACCESS, &hPolicy) !=
495 STATUS_SUCCESS)
496 return 3;
497
498 _GetAccountSid(NULL, (LPTSTR) pszName, &pSID);
499
500 if (_SetPrivilegeOnAccount(hPolicy, pSID, L"SeServiceLogonRight", TRUE) != STATUS_SUCCESS)
501 return 4;
502
503 _SetPrivilegeOnAccount(hPolicy, pSID, L"SeDenyInteractiveLogonRight", TRUE);
504 _SetPrivilegeOnAccount(hPolicy, pSID, L"SeDenyBatchLogonRight", TRUE);
505 _SetPrivilegeOnAccount(hPolicy, pSID, L"SeDenyNetworkLogonRight", TRUE);
506
507 GNLsaClose(hPolicy);
508
509 return 0;
510}
511
512/**
513 * @brief Grant permission to a file
514 * @param lpszFileName the name of the file or directory
515 * @param lpszAccountName the user account
516 * @param the desired access (e.g. GENERIC_ALL)
517 * @return TRUE on success
518 * @remark based on http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q102102&
519 */
520BOOL AddPathAccessRights(char *lpszFileName, char *lpszAccountName,
521 DWORD dwAccessMask)
522{
523 /* SID variables. */
524 SID_NAME_USE snuType;
525 TCHAR * szDomain = NULL;
526 DWORD cbDomain = 0;
527 LPVOID pUserSID = NULL;
528 DWORD cbUserSID = 0;
529
530 /* File SD variables. */
531 PSECURITY_DESCRIPTOR pFileSD = NULL;
532 DWORD cbFileSD = 0;
533
534 /* New SD variables. */
535 SECURITY_DESCRIPTOR newSD;
536
537 /* ACL variables. */
538 PACL pACL = NULL;
539 BOOL fDaclPresent;
540 BOOL fDaclDefaulted;
541 ACL_SIZE_INFORMATION AclInfo;
542
543 /* New ACL variables. */
544 PACL pNewACL = NULL;
545 DWORD cbNewACL = 0;
546
547 /* Temporary ACE. */
548 LPVOID pTempAce = NULL;
549 UINT CurrentAceIndex = 0;
550
551 UINT newAceIndex = 0;
552
553 /* Assume function will fail. */
554 BOOL fResult = FALSE;
555 BOOL fAPISuccess;
556
557 SECURITY_INFORMATION secInfo = DACL_SECURITY_INFORMATION;
558
559 /**
560 * STEP 1: Get SID of the account name specified.
561 */
562 fAPISuccess = GNLookupAccountName(NULL, (LPCTSTR) lpszAccountName,
563 pUserSID, &cbUserSID, (LPTSTR) szDomain, &cbDomain, &snuType);
564
565 /* API should have failed with insufficient buffer. */
566 if (fAPISuccess)
567 goto end;
568 else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
569 goto end;
570 }
571
572 pUserSID = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbUserSID);
573 if (!pUserSID) {
574 goto end;
575 }
576
577 szDomain = (TCHAR *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbDomain * sizeof(TCHAR));
578 if (!szDomain) {
579 goto end;
580 }
581
582 fAPISuccess = GNLookupAccountName(NULL, (LPCTSTR) lpszAccountName,
583 pUserSID, &cbUserSID, (LPTSTR) szDomain, &cbDomain, &snuType);
584 if (!fAPISuccess) {
585 goto end;
586 }
587
588 /**
589 * STEP 2: Get security descriptor (SD) of the file specified.
590 */
591 fAPISuccess = GNGetFileSecurity((LPCTSTR) lpszFileName,
592 secInfo, pFileSD, 0, &cbFileSD);
593
594 /* API should have failed with insufficient buffer. */
595 if (fAPISuccess)
596 goto end;
597 else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
598 goto end;
599 }
600
601 pFileSD = (PSECURITY_DESCRIPTOR) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
602 cbFileSD);
603 if (!pFileSD) {
604 goto end;
605 }
606
607 fAPISuccess = GNGetFileSecurity((LPCTSTR) lpszFileName,
608 secInfo, pFileSD, cbFileSD, &cbFileSD);
609 if (!fAPISuccess) {
610 goto end;
611 }
612
613 /**
614 * STEP 3: Initialize new SD.
615 */
616 if (!GNInitializeSecurityDescriptor(&newSD,
617 SECURITY_DESCRIPTOR_REVISION)) {
618 goto end;
619 }
620
621 /**
622 * STEP 4: Get DACL from the old SD.
623 */
624 if (!GNGetSecurityDescriptorDacl(pFileSD, &fDaclPresent, &pACL,
625 &fDaclDefaulted)) {
626 goto end;
627 }
628
629 /**
630 * STEP 5: Get size information for DACL.
631 */
632 AclInfo.AceCount = 0; // Assume NULL DACL.
633 AclInfo.AclBytesFree = 0;
634 AclInfo.AclBytesInUse = sizeof(ACL);
635
636 if (pACL == NULL)
637 fDaclPresent = FALSE;
638
639 /* If not NULL DACL, gather size information from DACL. */
640 if (fDaclPresent) {
641
642 if (!GNGetAclInformation(pACL, &AclInfo,
643 sizeof(ACL_SIZE_INFORMATION), AclSizeInformation)) {
644 goto end;
645 }
646 }
647
648 /**
649 * STEP 6: Compute size needed for the new ACL.
650 */
651 cbNewACL = AclInfo.AclBytesInUse + sizeof(ACCESS_ALLOWED_ACE)
652 + GetLengthSid(pUserSID) - sizeof(DWORD);
653
654 /**
655 * STEP 7: Allocate memory for new ACL.
656 */
657 pNewACL = (PACL) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbNewACL);
658 if (!pNewACL) {
659 goto end;
660 }
661
662 /**
663 * STEP 8: Initialize the new ACL.
664 */
665 if (!GNInitializeAcl(pNewACL, cbNewACL, ACL_REVISION2)) {
666 goto end;
667 }
668
669 /**
670 * STEP 9 If DACL is present, copy all the ACEs from the old DACL
671 * to the new DACL.
672 *
673 * The following code assumes that the old DACL is
674 * already in Windows 2000 preferred order. To conform
675 * to the new Windows 2000 preferred order, first we will
676 * copy all non-inherited ACEs from the old DACL to the
677 * new DACL, irrespective of the ACE type.
678 */
679
680 newAceIndex = 0;
681
682 if (fDaclPresent && AclInfo.AceCount) {
683
684 for (CurrentAceIndex = 0;
685 CurrentAceIndex < AclInfo.AceCount;
686 CurrentAceIndex++) {
687
688 /**
689 * TEP 10: Get an ACE.
690 */
691 if (!GNGetAce(pACL, CurrentAceIndex, &pTempAce)) {
692 goto end;
693 }
694
695 /**
696 * STEP 11: Check if it is a non-inherited ACE.
697 * If it is an inherited ACE, break from the loop so
698 * that the new access allowed non-inherited ACE can
699 * be added in the correct position, immediately after
700 * all non-inherited ACEs.
701 */
702 if (((ACCESS_ALLOWED_ACE *)pTempAce)->Header.AceFlags
703 & INHERITED_ACE)
704 break;
705
706 /**
707 * STEP 12: Skip adding the ACE, if the SID matches
708 * with the account specified, as we are going to
709 * add an access allowed ACE with a different access
710 * mask.
711 */
712 if (GNEqualSid(pUserSID,
713 &(((ACCESS_ALLOWED_ACE *)pTempAce)->SidStart)))
714 continue;
715
716 /**
717 * STEP 13: Add the ACE to the new ACL.
718 */
719 if (!GNAddAce(pNewACL, ACL_REVISION, MAXDWORD, pTempAce,
720 ((PACE_HEADER) pTempAce)->AceSize)) {
721 goto end;
722 }
723
724 newAceIndex++;
725 }
726 }
727
728 /**
729 * STEP 14: Add the access-allowed ACE to the new DACL.
730 * The new ACE added here will be in the correct position,
731 * immediately after all existing non-inherited ACEs.
732 */
733 if (!GNAddAccessAllowedAce(pNewACL, ACL_REVISION2, dwAccessMask,
734 pUserSID)) {
735 goto end;
736 }
737
738 /**
739 * STEP 14.5: Make new ACE inheritable
740 */
741 if (!GetAce(pNewACL, newAceIndex, &pTempAce))
742 goto end;
743 ((ACCESS_ALLOWED_ACE *)pTempAce)->Header.AceFlags |=
744 (CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE);
745
746 /**
747 * STEP 15: To conform to the new Windows 2000 preferred order,
748 * we will now copy the rest of inherited ACEs from the
749 * old DACL to the new DACL.
750 */
751 if (fDaclPresent && AclInfo.AceCount) {
752
753 for (;
754 CurrentAceIndex < AclInfo.AceCount;
755 CurrentAceIndex++) {
756
757 /**
758 * STEP 16: Get an ACE.
759 */
760 if (!GNGetAce(pACL, CurrentAceIndex, &pTempAce)) {
761 goto end;
762 }
763
764 /**
765 * STEP 17: Add the ACE to the new ACL.
766 */
767 if (!GNAddAce(pNewACL, ACL_REVISION, MAXDWORD, pTempAce,
768 ((PACE_HEADER) pTempAce)->AceSize)) {
769 goto end;
770 }
771 }
772 }
773
774 /**
775 * STEP 18: Set permissions
776 */
777 if (GNSetNamedSecurityInfo((LPTSTR) lpszFileName, SE_FILE_OBJECT,
778 DACL_SECURITY_INFORMATION, NULL, NULL, pNewACL, NULL) != ERROR_SUCCESS) {
779 goto end;
780 }
781
782 fResult = TRUE;
783
784end:
785
786 /**
787 * STEP 19: Free allocated memory
788 */
789 if (pUserSID)
790 HeapFree(GetProcessHeap(), 0, pUserSID);
791
792 if (szDomain)
793 HeapFree(GetProcessHeap(), 0, szDomain);
794
795 if (pFileSD)
796 HeapFree(GetProcessHeap(), 0, pFileSD);
797
798 if (pNewACL)
799 HeapFree(GetProcessHeap(), 0, pNewACL);
800
801 return fResult;
802}
803
804char *winErrorStr(const char *prefix, int dwErr)
805{
806 char *err, *ret;
807 int mem;
808
809 if (! FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
810 NULL, (DWORD) dwErr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &err,
811 0, NULL ))
812 {
813 err = "";
814 }
815
816 mem = strlen(err) + strlen(prefix) + 20;
817 ret = (char *) malloc(mem);
818
819 snprintf(ret, mem, "%s: %s (#%u)", prefix, err, dwErr);
820
821 LocalFree(err);
822
823 return ret;
824}
825
826} /* extern "C" */
827
828#endif
diff --git a/src/util/winproc.c b/src/util/winproc.c
new file mode 100644
index 000000000..469e1fb41
--- /dev/null
+++ b/src/util/winproc.c
@@ -0,0 +1,254 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2005, 2006 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file util/win/winproc.c
23 * @brief Functions for MS Windows
24 * @author Nils Durner
25 */
26
27#include "platform.h"
28#include "gnunet_common.h"
29
30#define DEBUG_WINPROC 0
31
32#ifdef MINGW
33
34static HINSTANCE hNTDLL, hIphlpapi, hAdvapi, hNetapi;
35
36TNtQuerySystemInformation GNNtQuerySystemInformation;
37TGetIfEntry GNGetIfEntry;
38TGetIpAddrTable GNGetIpAddrTable;
39TGetIfTable GNGetIfTable;
40TOpenSCManager GNOpenSCManager;
41TCreateService GNCreateService;
42TCloseServiceHandle GNCloseServiceHandle;
43TDeleteService GNDeleteService;
44TRegisterServiceCtrlHandler GNRegisterServiceCtrlHandler;
45TSetServiceStatus GNSetServiceStatus;
46TStartServiceCtrlDispatcher GNStartServiceCtrlDispatcher;
47TControlService GNControlService;
48TOpenService GNOpenService;
49TGetBestInterface GNGetBestInterface;
50TGetAdaptersInfo GGetAdaptersInfo;
51TNetUserAdd GNNetUserAdd;
52TNetUserSetInfo GNNetUserSetInfo;
53TLsaOpenPolicy GNLsaOpenPolicy;
54TLsaAddAccountRights GNLsaAddAccountRights;
55TLsaRemoveAccountRights GNLsaRemoveAccountRights;
56TLsaClose GNLsaClose;
57TLookupAccountName GNLookupAccountName;
58TGetFileSecurity GNGetFileSecurity;
59TInitializeSecurityDescriptor GNInitializeSecurityDescriptor;
60TGetSecurityDescriptorDacl GNGetSecurityDescriptorDacl;
61TGetAclInformation GNGetAclInformation;
62TInitializeAcl GNInitializeAcl;
63TGetAce GNGetAce;
64TEqualSid GNEqualSid;
65TAddAce GNAddAce;
66TAddAccessAllowedAce GNAddAccessAllowedAce;
67TSetNamedSecurityInfo GNSetNamedSecurityInfo;
68
69/**
70 * Log (panic) messages from PlibC
71 */
72void
73plibc_panic (int err, char *msg)
74{
75 GNUNET_log (((err ==
76 INT_MAX) ? GNUNET_ERROR_TYPE_DEBUG : GNUNET_ERROR_TYPE_ERROR),
77 "%s", msg);
78}
79
80/**
81 * @brief Initialize PlibC and set up Windows environment
82 * @param logging context, NULL means stderr
83 * @return Error code from winerror.h, ERROR_SUCCESS on success
84*/
85int
86InitWinEnv ()
87{
88 int ret;
89
90 plibc_initialized ();
91 plibc_set_panic_proc (plibc_panic);
92 ret = plibc_init ("GNU", PACKAGE);
93
94 /* don't load other DLLs twice */
95 if (hNTDLL)
96 return ret;
97
98 hNTDLL = LoadLibrary ("ntdll.dll");
99
100 /* Function to get CPU usage under Win NT */
101 if (hNTDLL)
102 {
103 GNNtQuerySystemInformation = (TNtQuerySystemInformation)
104 GetProcAddress (hNTDLL, "NtQuerySystemInformation");
105 }
106 else
107 {
108 GNNtQuerySystemInformation = NULL;
109 }
110
111 /* Functions to get information about a network adapter */
112 hIphlpapi = LoadLibrary ("iphlpapi.dll");
113 if (hIphlpapi)
114 {
115 GNGetIfEntry = (TGetIfEntry) GetProcAddress (hIphlpapi, "GetIfEntry");
116 GNGetIpAddrTable = (TGetIpAddrTable) GetProcAddress (hIphlpapi,
117 "GetIpAddrTable");
118 GNGetIfTable = (TGetIfTable) GetProcAddress (hIphlpapi, "GetIfTable");
119 GNGetBestInterface = (TGetBestInterface) GetProcAddress (hIphlpapi,
120 "GetBestInterface");
121 GGetAdaptersInfo = (TGetAdaptersInfo) GetProcAddress (hIphlpapi,
122 "GetAdaptersInfo");
123 }
124 else
125 {
126 GNGetIfEntry = NULL;
127 GNGetIpAddrTable = NULL;
128 GNGetIfTable = NULL;
129 GNGetBestInterface = NULL;
130 GGetAdaptersInfo = NULL;
131 }
132
133 /* Service & Account functions */
134 hAdvapi = LoadLibrary ("advapi32.dll");
135 if (hAdvapi)
136 {
137 GNOpenSCManager = (TOpenSCManager)
138 GetProcAddress (hAdvapi, "OpenSCManagerA");
139 GNCreateService = (TCreateService)
140 GetProcAddress (hAdvapi, "CreateServiceA");
141 GNCloseServiceHandle = (TCloseServiceHandle)
142 GetProcAddress (hAdvapi, "CloseServiceHandle");
143 GNDeleteService = (TDeleteService)
144 GetProcAddress (hAdvapi, "DeleteService");
145 GNRegisterServiceCtrlHandler = (TRegisterServiceCtrlHandler)
146 GetProcAddress (hAdvapi, "RegisterServiceCtrlHandlerA");
147 GNSetServiceStatus = (TSetServiceStatus)
148 GetProcAddress (hAdvapi, "SetServiceStatus");
149 GNStartServiceCtrlDispatcher = (TStartServiceCtrlDispatcher)
150 GetProcAddress (hAdvapi, "StartServiceCtrlDispatcherA");
151 GNControlService = (TControlService)
152 GetProcAddress (hAdvapi, "ControlService");
153 GNOpenService = (TOpenService) GetProcAddress (hAdvapi, "OpenServiceA");
154
155 GNLsaOpenPolicy = (TLsaOpenPolicy)
156 GetProcAddress (hAdvapi, "LsaOpenPolicy");
157 GNLsaAddAccountRights = (TLsaAddAccountRights)
158 GetProcAddress (hAdvapi, "LsaAddAccountRights");
159 GNLsaRemoveAccountRights = (TLsaRemoveAccountRights)
160 GetProcAddress (hAdvapi, "LsaRemoveAccountRights");
161 GNLsaClose = (TLsaClose) GetProcAddress (hAdvapi, "LsaClose");
162 GNLookupAccountName = (TLookupAccountName)
163 GetProcAddress (hAdvapi, "LookupAccountNameA");
164
165 GNGetFileSecurity = (TGetFileSecurity)
166 GetProcAddress (hAdvapi, "GetFileSecurityA");
167 GNInitializeSecurityDescriptor = (TInitializeSecurityDescriptor)
168 GetProcAddress (hAdvapi, "InitializeSecurityDescriptor");
169 GNGetSecurityDescriptorDacl = (TGetSecurityDescriptorDacl)
170 GetProcAddress (hAdvapi, "GetSecurityDescriptorDacl");
171 GNGetAclInformation = (TGetAclInformation)
172 GetProcAddress (hAdvapi, "GetAclInformation");
173 GNInitializeAcl = (TInitializeAcl)
174 GetProcAddress (hAdvapi, "InitializeAcl");
175 GNGetAce = (TGetAce) GetProcAddress (hAdvapi, "GetAce");
176 GNEqualSid = (TEqualSid) GetProcAddress (hAdvapi, "EqualSid");
177 GNAddAce = (TAddAce) GetProcAddress (hAdvapi, "AddAce");
178 GNAddAccessAllowedAce = (TAddAccessAllowedAce)
179 GetProcAddress (hAdvapi, "AddAccessAllowedAce");
180 GNSetNamedSecurityInfo = (TSetNamedSecurityInfo)
181 GetProcAddress (hAdvapi, "SetNamedSecurityInfoA");
182 }
183 else
184 {
185 GNOpenSCManager = NULL;
186 GNCreateService = NULL;
187 GNCloseServiceHandle = NULL;
188 GNDeleteService = NULL;
189 GNRegisterServiceCtrlHandler = NULL;
190 GNSetServiceStatus = NULL;
191 GNStartServiceCtrlDispatcher = NULL;
192 GNControlService = NULL;
193 GNOpenService = NULL;
194
195 GNLsaOpenPolicy = NULL;
196 GNLsaAddAccountRights = NULL;
197 GNLsaRemoveAccountRights = NULL;
198 GNLsaClose = NULL;
199 GNLookupAccountName = NULL;
200
201 GNGetFileSecurity = NULL;
202 GNInitializeSecurityDescriptor = NULL;
203 GNGetSecurityDescriptorDacl = NULL;
204 GNGetAclInformation = NULL;
205 GNInitializeAcl = NULL;
206 GNGetAce = NULL;
207 GNEqualSid = NULL;
208 GNAddAce = NULL;
209 GNAddAccessAllowedAce = NULL;
210 GNSetNamedSecurityInfo = NULL;
211 }
212
213 /* Account function */
214 hNetapi = LoadLibrary ("netapi32.dll");
215 if (hNetapi)
216 {
217 GNNetUserAdd = (TNetUserAdd) GetProcAddress (hNetapi, "NetUserAdd");
218 GNNetUserSetInfo = (TNetUserSetInfo)
219 GetProcAddress (hNetapi, "NetUserSetInfo");
220 }
221 else
222 {
223 GNNetUserAdd = NULL;
224 GNNetUserSetInfo = NULL;
225 }
226
227 return ret;
228}
229
230/**
231 * Clean up Windows environment
232 */
233void
234ShutdownWinEnv ()
235{
236 plibc_shutdown ();
237
238 FreeLibrary (hNTDLL);
239 FreeLibrary (hIphlpapi);
240 FreeLibrary (hAdvapi);
241 FreeLibrary (hNetapi);
242
243 CoUninitialize ();
244}
245
246#endif /* MINGW */
247
248#if !HAVE_ATOLL
249long long
250atoll (const char *nptr)
251{
252 return atol (nptr);
253}
254#endif