diff options
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/Makefile.am | 4 | ||||
-rw-r--r-- | src/util/crypto_rsa.c | 16 | ||||
-rw-r--r-- | src/util/disk.c | 2 | ||||
-rw-r--r-- | src/util/network.c | 36 | ||||
-rw-r--r-- | src/util/os_priority.c | 81 | ||||
-rw-r--r-- | src/util/scheduler.c | 2 | ||||
-rw-r--r-- | src/util/server.c | 3 | ||||
-rw-r--r-- | src/util/time.c | 2 | ||||
-rw-r--r-- | src/util/win.cc | 828 | ||||
-rw-r--r-- | src/util/winproc.c | 254 |
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 | ||
5 | if MINGW | 5 | if 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 | ||
7 | endif | 8 | endif |
8 | 9 | ||
9 | if USE_COVERAGE | 10 | if 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 | ||
51 | libgnunetutil_la_LIBADD = \ | 53 | libgnunetutil_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) | |||
559 | struct GNUNET_CRYPTO_RsaPrivateKey * | 559 | struct GNUNET_CRYPTO_RsaPrivateKey * |
560 | GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename) | 560 | GNUNET_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)); |
812 | RETRY: | 820 | RETRY: |
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) | |||
1086 | RETRY: | 1101 | RETRY: |
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, | |||
123 | pid_t | 123 | pid_t |
124 | GNUNET_OS_start_process (const char *filename, ...) | 124 | GNUNET_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, ...) | |||
164 | pid_t | 202 | pid_t |
165 | GNUNET_OS_start_process_v (const char *filename, char *const argv[]) | 203 | GNUNET_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> | ||
36 | using namespace std; | ||
37 | #include <ntdef.h> | ||
38 | |||
39 | #ifndef INHERITED_ACE | ||
40 | #define INHERITED_ACE 0x10 | ||
41 | #endif | ||
42 | |||
43 | extern "C" { | ||
44 | |||
45 | typedef list<WSAOVERLAPPED *> TOLList; | ||
46 | |||
47 | static HANDLE hOLLock; | ||
48 | static TOLList lstOL; | ||
49 | |||
50 | int plibc_conv_to_win_path(const char *pszUnix, char *pszWindows); | ||
51 | |||
52 | void __attribute__ ((constructor)) gnunet_win_init() { | ||
53 | hOLLock = CreateMutex(NULL, FALSE, NULL); | ||
54 | } | ||
55 | |||
56 | void __attribute__ ((destructor)) gnunet_win_fini() { | ||
57 | CloseHandle(hOLLock); | ||
58 | } | ||
59 | |||
60 | /** | ||
61 | * Enumerate all network adapters | ||
62 | */ | ||
63 | void 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 | */ | ||
224 | int 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 | */ | ||
269 | int 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 | |||
290 | closeSCM: | ||
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 | */ | ||
301 | void _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 | */ | ||
325 | NTSTATUS _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 | */ | ||
358 | BOOL _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 | |||
404 | end: | ||
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 | */ | ||
425 | NTSTATUS _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 | */ | ||
464 | int 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 | */ | ||
520 | BOOL 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 | |||
784 | end: | ||
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 | |||
804 | char *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 | |||
34 | static HINSTANCE hNTDLL, hIphlpapi, hAdvapi, hNetapi; | ||
35 | |||
36 | TNtQuerySystemInformation GNNtQuerySystemInformation; | ||
37 | TGetIfEntry GNGetIfEntry; | ||
38 | TGetIpAddrTable GNGetIpAddrTable; | ||
39 | TGetIfTable GNGetIfTable; | ||
40 | TOpenSCManager GNOpenSCManager; | ||
41 | TCreateService GNCreateService; | ||
42 | TCloseServiceHandle GNCloseServiceHandle; | ||
43 | TDeleteService GNDeleteService; | ||
44 | TRegisterServiceCtrlHandler GNRegisterServiceCtrlHandler; | ||
45 | TSetServiceStatus GNSetServiceStatus; | ||
46 | TStartServiceCtrlDispatcher GNStartServiceCtrlDispatcher; | ||
47 | TControlService GNControlService; | ||
48 | TOpenService GNOpenService; | ||
49 | TGetBestInterface GNGetBestInterface; | ||
50 | TGetAdaptersInfo GGetAdaptersInfo; | ||
51 | TNetUserAdd GNNetUserAdd; | ||
52 | TNetUserSetInfo GNNetUserSetInfo; | ||
53 | TLsaOpenPolicy GNLsaOpenPolicy; | ||
54 | TLsaAddAccountRights GNLsaAddAccountRights; | ||
55 | TLsaRemoveAccountRights GNLsaRemoveAccountRights; | ||
56 | TLsaClose GNLsaClose; | ||
57 | TLookupAccountName GNLookupAccountName; | ||
58 | TGetFileSecurity GNGetFileSecurity; | ||
59 | TInitializeSecurityDescriptor GNInitializeSecurityDescriptor; | ||
60 | TGetSecurityDescriptorDacl GNGetSecurityDescriptorDacl; | ||
61 | TGetAclInformation GNGetAclInformation; | ||
62 | TInitializeAcl GNInitializeAcl; | ||
63 | TGetAce GNGetAce; | ||
64 | TEqualSid GNEqualSid; | ||
65 | TAddAce GNAddAce; | ||
66 | TAddAccessAllowedAce GNAddAccessAllowedAce; | ||
67 | TSetNamedSecurityInfo GNSetNamedSecurityInfo; | ||
68 | |||
69 | /** | ||
70 | * Log (panic) messages from PlibC | ||
71 | */ | ||
72 | void | ||
73 | plibc_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 | */ | ||
85 | int | ||
86 | InitWinEnv () | ||
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 | */ | ||
233 | void | ||
234 | ShutdownWinEnv () | ||
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 | ||
249 | long long | ||
250 | atoll (const char *nptr) | ||
251 | { | ||
252 | return atol (nptr); | ||
253 | } | ||
254 | #endif | ||