diff --git a/trunk/configure b/trunk/configure index b29d709cb..1bd51abbc 100755 --- a/trunk/configure +++ b/trunk/configure @@ -299,8 +299,9 @@ END GDBDebug=" -g -O0" # the warning level. WarnLevel=" -Wall" -# the compile standard. -CppStd="-ansi" +# the compile in c++ standard. +# @remark, donot specifies it for mingw. +CppStd="-ansi" && echo $MSYSTEM|grep "MINGW">/dev/null && CppStd="" # for library compile LibraryCompile=" -fPIC" # performance of gprof @@ -355,7 +356,7 @@ if [ $SRS_MIPS_UBUNTU12 = YES ]; then SrsLinkOptions="${SrsLinkOptions} -lgcc_eh MODULE_ID="CORE" MODULE_DEPENDS=() ModuleLibIncs=(${SRS_OBJS_DIR}) -MODULE_FILES=("srs_core" "srs_core_autofree") +MODULE_FILES=("srs_core" "srs_core_autofree" "srs_platform") CORE_INCS="src/core"; MODULE_DIR=${CORE_INCS} . auto/modules.sh CORE_OBJS="${MODULE_OBJS[@]}" # diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index 3e2db170d..bffedbbb3 100644 --- a/trunk/src/core/srs_core.hpp +++ b/trunk/src/core/srs_core.hpp @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // current release version #define VERSION_MAJOR 2 #define VERSION_MINOR 0 -#define VERSION_REVISION 32 +#define VERSION_REVISION 33 // server info. #define RTMP_SIG_SRS_KEY "SRS" #define RTMP_SIG_SRS_ROLE "origin/edge server" @@ -110,5 +110,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. className(const className&); \ className& operator= (const className&) +// for windows to compile srs-librtmp +// @see: https://github.com/winlinvip/simple-rtmp-server/issues/213 +#include + #endif diff --git a/trunk/src/core/srs_platform.cpp b/trunk/src/core/srs_platform.cpp new file mode 100644 index 000000000..9e3f5fba9 --- /dev/null +++ b/trunk/src/core/srs_platform.cpp @@ -0,0 +1,373 @@ +/* +The MIT License (MIT) + +Copyright (c) 2014 allspace + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include + +#include +#include +#include + +#if defined(_WIN32) && !defined(__CYGWIN__) +int socket_setup() +{ + WORD wVersionRequested; + WSADATA wsaData; + int err; + + /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */ + wVersionRequested = MAKEWORD(2, 2); + + err = WSAStartup(wVersionRequested, &wsaData); + if (err != 0) { + /* Tell the user that we could not find a usable */ + /* Winsock DLL. */ + //printf("WSAStartup failed with error: %d\n", err); + return -1; + } + return 0; +} + +int socket_cleanup() +{ + WSACleanup(); + return 0; +} + +int gettimeofday(struct timeval* tv, struct timezone* tz) +{ + time_t clock; + struct tm tm; + SYSTEMTIME win_time; + + GetLocalTime(&win_time); + + tm.tm_year = win_time.wYear - 1900; + tm.tm_mon = win_time.wMonth - 1; + tm.tm_mday = win_time.wDay; + tm.tm_hour = win_time.wHour; + tm.tm_min = win_time.wMinute; + tm.tm_sec = win_time.wSecond; + tm.tm_isdst = -1; + + clock = mktime(&tm); + + tv->tv_sec = (long)clock; + tv->tv_usec = win_time.wMilliseconds * 1000; + + return 0; +} + +pid_t getpid(void) +{ + return (pid_t)GetCurrentProcessId(); +} + +int usleep(useconds_t usec) +{ + Sleep((DWORD)(usec / 1000)); + return 0; +} + +ssize_t writev(int fd, const struct iovec *iov, int iovcnt) +{ + ssize_t nwrite = 0; + for (int i = 0; i < iovcnt; i++) { + const struct iovec* current = iov + i; + + int nsent = ::send(fd, (char*)current->iov_base, current->iov_len, 0); + if (nsent < 0) { + return nsent; + } + + nwrite += nsent; + if (nsent == 0) { + return nwrite; + } + } + return nwrite; +} + +//////////////////////// strlcpy.c (modified) ////////////////////////// + +/* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */ + +/*- + * Copyright (c) 1998 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +//#include // **** +//#include // **** +// __FBSDID("$FreeBSD: stable/9/sys/libkern/strlcpy.c 243811 2012-12-03 18:08:44Z delphij $"); // **** + +// #include // **** +// #include // **** + +/* + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ + +//#define __restrict // **** + +size_t strlcpy(char * __restrict dst, const char * __restrict src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0) { + while (--n != 0) { + if ((*d++ = *s++) == '\0') + break; + } + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} + +// http://www.cplusplus.com/forum/general/141779///////////////////////// inet_ntop.c (modified) ////////////////////////// +/* + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 1996-1999 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +// #if defined(LIBC_SCCS) && !defined(lint) // **** +//static const char rcsid[] = "$Id: inet_ntop.c,v 1.3.18.2 2005/11/03 23:02:22 marka Exp $"; +// #endif /* LIBC_SCCS and not lint */ // **** +// #include // **** +// __FBSDID("$FreeBSD: stable/9/sys/libkern/inet_ntop.c 213103 2010-09-24 15:01:45Z attilio $"); // **** + +//#define _WIN32_WINNT _WIN32_WINNT_WIN8 // **** +//#include // **** +//#pragma comment(lib, "Ws2_32.lib") // **** +//#include // **** + +// #include // **** +// #include // **** +// #include // **** + +// #include // **** + +/*% + * WARNING: Don't even consider trying to compile this on a system where + * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. + */ + +static char *inet_ntop4(const u_char *src, char *dst, socklen_t size); +static char *inet_ntop6(const u_char *src, char *dst, socklen_t size); + +/* char * + * inet_ntop(af, src, dst, size) + * convert a network format address to presentation format. + * return: + * pointer to presentation format address (`dst'), or NULL (see errno). + * author: + * Paul Vixie, 1996. + */ +const char* inet_ntop(int af, const void *src, char *dst, socklen_t size) +{ + switch (af) { + case AF_INET: + return (inet_ntop4( (unsigned char*)src, (char*)dst, size)); // **** +#ifdef AF_INET6 + //#error "IPv6 not supported" + //case AF_INET6: + // return (char*)(inet_ntop6( (unsigned char*)src, (char*)dst, size)); // **** +#endif + default: + // return (NULL); // **** + return 0 ; // **** + } + /* NOTREACHED */ +} + +/* const char * + * inet_ntop4(src, dst, size) + * format an IPv4 address + * return: + * `dst' (as a const) + * notes: + * (1) uses no statics + * (2) takes a u_char* not an in_addr as input + * author: + * Paul Vixie, 1996. + */ +static char * inet_ntop4(const u_char *src, char *dst, socklen_t size) +{ + static const char fmt[128] = "%u.%u.%u.%u"; + char tmp[sizeof "255.255.255.255"]; + int l; + + l = snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]); // **** + if (l <= 0 || (socklen_t) l >= size) { + return (NULL); + } + strlcpy(dst, tmp, size); + return (dst); +} + +/* const char * + * inet_ntop6(src, dst, size) + * convert IPv6 binary address into presentation (printable) format + * author: + * Paul Vixie, 1996. + */ +static char * inet_ntop6(const u_char *src, char *dst, socklen_t size) +{ + /* + * Note that int32_t and int16_t need only be "at least" large enough + * to contain a value of the specified size. On some systems, like + * Crays, there is no such thing as an integer variable with 16 bits. + * Keep this in mind if you think this function should have been coded + * to use pointer overlays. All the world's not a VAX. + */ + char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; + struct { int base, len; } best, cur; +#define NS_IN6ADDRSZ 16 +#define NS_INT16SZ 2 + u_int words[NS_IN6ADDRSZ / NS_INT16SZ]; + int i; + + /* + * Preprocess: + * Copy the input (bytewise) array into a wordwise array. + * Find the longest run of 0x00's in src[] for :: shorthanding. + */ + memset(words, '\0', sizeof words); + for (i = 0; i < NS_IN6ADDRSZ; i++) + words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); + best.base = -1; + best.len = 0; + cur.base = -1; + cur.len = 0; + for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { + if (words[i] == 0) { + if (cur.base == -1) + cur.base = i, cur.len = 1; + else + cur.len++; + } else { + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + cur.base = -1; + } + } + } + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + } + if (best.base != -1 && best.len < 2) + best.base = -1; + + /* + * Format the result. + */ + tp = tmp; + for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { + /* Are we inside the best run of 0x00's? */ + if (best.base != -1 && i >= best.base && + i < (best.base + best.len)) { + if (i == best.base) + *tp++ = ':'; + continue; + } + /* Are we following an initial run of 0x00s or any real hex? */ + if (i != 0) + *tp++ = ':'; + /* Is this address an encapsulated IPv4? */ + if (i == 6 && best.base == 0 && (best.len == 6 || + (best.len == 7 && words[7] != 0x0001) || + (best.len == 5 && words[5] == 0xffff))) { + if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) + return (NULL); + tp += strlen(tp); + break; + } + tp += sprintf(tp, "%x", words[i]); // **** + } + /* Was it a trailing run of 0x00's? */ + if (best.base != -1 && (best.base + best.len) == + (NS_IN6ADDRSZ / NS_INT16SZ)) + *tp++ = ':'; + *tp++ = '\0'; + + /* + * Check for overflow, copy, and we're done. + */ + if ((socklen_t)(tp - tmp) > size) { + return (NULL); + } + strcpy(dst, tmp); + return (dst); +} + +#define Set_errno(num) SetLastError((num)) + +/* INVALID_SOCKET == INVALID_HANDLE_VALUE == (unsigned int)(~0) */ +/* SOCKET_ERROR == -1 */ +//#define ENOTSOCK WSAENOTSOCK +//#define EINTR WSAEINTR +//#define ENOBUFS WSAENOBUFS +//#define EWOULDBLOCK WSAEWOULDBLOCK +#define EAFNOSUPPORT WSAEAFNOSUPPORT +/* from public\sdk\inc\crt\errno.h */ +#define ENOSPC 28 + +#endif + diff --git a/trunk/src/core/srs_platform.hpp b/trunk/src/core/srs_platform.hpp new file mode 100644 index 000000000..1bd61d124 --- /dev/null +++ b/trunk/src/core/srs_platform.hpp @@ -0,0 +1,115 @@ +/* +The MIT License (MIT) + +Copyright (c) 2014 allspace + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef SRS_WIN_PORTING_H +#define SRS_WIN_PORTING_H + +// for srs-librtmp, @see https://github.com/winlinvip/simple-rtmp-server/issues/213 +#if defined(_WIN32) + #include +#endif + +/** +* for linux like, +* for example, not on windows or it's cygwin. +* while the _WIN32 includes both 32-bit and 64-bit +*/ +#if !defined(_WIN32) || defined(__CYGWIN__) + #define SOCKET_ETIME ETIME + #define SOCKET_ECONNRESET ECONNRESET + + #define SOCKET int + #define SOCKET_ERRNO() errno + #define SOCKET_RESET(fd) fd = -1; (void)0 + #define SOCKET_CLOSE(fd) \ + if (fd > 0) {\ + ::close(fd); \ + fd = -1; \ + } \ + (void)0 + #define SOCKET_VALID(x) (x > 0) + #define SOCKET_SETUP() (void)0 + #define SOCKET_CLEANUP() (void)0 +#else /*on windows, but not on cygwin*/ + #include + #include + #include + #include + + #ifdef _MSC_VER //for VS2010 + #include + #include + #define S_IRUSR _S_IREAD + #define S_IWUSR _S_IWRITE + #define open _open + #define close _close + #define lseek _lseek + #define write _write + #define read _read + + typedef int ssize_t; + typedef int pid_t; + typedef int mode_t; + typedef int64_t useconds_t; + #endif + + #define S_IRGRP 0 + #define S_IWGRP 0 + #define S_IXGRP 0 + #define S_IRWXG 0 + #define S_IROTH 0 + #define S_IWOTH 0 + #define S_IXOTH 0 + #define S_IRWXO 0 + + #define PRId64 "lld" + + #define SOCKET_ETIME WSAETIMEDOUT + #define SOCKET_ECONNRESET WSAECONNRESET + #define SOCKET_ERRNO() WSAGetLastError() + #define SOCKET_RESET(x) x=INVALID_SOCKET + #define SOCKET_CLOSE(x) if(x!=INVALID_SOCKET){::closesocket(x);x=INVALID_SOCKET;} + #define SOCKET_VALID(x) (x!=INVALID_SOCKET) + #define SOCKET_BUFF(x) ((char*)x) + #define SOCKET_SETUP() socket_setup() + #define SOCKET_CLEANUP() socket_cleanup() + + typedef uint32_t u_int32_t; + typedef uint8_t u_int8_t; + typedef int socklen_t; + struct iovec { + void* iov_base; /* Starting address */ + size_t iov_len; /* Length in bytes */ + }; + + #define snprintf _snprintf + ssize_t writev(int fd, const struct iovec *iov, int iovcnt); + const char* inet_ntop(int af, const void *src, char *dst, socklen_t size); + int gettimeofday(struct timeval* tv, struct timezone* tz); + pid_t getpid(void); + int usleep(useconds_t usec); + int socket_setup(); + int socket_cleanup(); +#endif + +#endif //SRS_WIN_PORTING_H diff --git a/trunk/src/kernel/srs_kernel_error.hpp b/trunk/src/kernel/srs_kernel_error.hpp index 14e94378b..aa6aa4109 100644 --- a/trunk/src/kernel/srs_kernel_error.hpp +++ b/trunk/src/kernel/srs_kernel_error.hpp @@ -30,8 +30,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include -// success, ok +// for srs-librtmp, @see https://github.com/winlinvip/simple-rtmp-server/issues/213 +#ifndef _WIN32 #define ERROR_SUCCESS 0 +#endif /////////////////////////////////////////////////////// // system error. diff --git a/trunk/src/libs/srs_lib_simple_socket.cpp b/trunk/src/libs/srs_lib_simple_socket.cpp index e7346b6a0..08096e714 100644 --- a/trunk/src/libs/srs_lib_simple_socket.cpp +++ b/trunk/src/libs/srs_lib_simple_socket.cpp @@ -45,22 +45,22 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. SimpleSocketStream::SimpleSocketStream() { - fd = -1; + SOCKET_RESET(fd); send_timeout = recv_timeout = ST_UTIME_NO_TIMEOUT; recv_bytes = send_bytes = 0; + SOCKET_SETUP(); } SimpleSocketStream::~SimpleSocketStream() { - if (fd != -1) { - ::close(fd); - fd = -1; - } + SOCKET_CLOSE(fd); + SOCKET_CLEANUP(); } int SimpleSocketStream::create_socket() { - if((fd = ::socket(AF_INET, SOCK_STREAM, 0)) < 0){ + fd = ::socket(AF_INET, SOCK_STREAM, 0); + if (!SOCKET_VALID(fd)) { return ERROR_SOCKET_CREATE; } @@ -95,12 +95,12 @@ int SimpleSocketStream::read(void* buf, size_t size, ssize_t* nread) // On success a non-negative integer indicating the number of bytes actually read is returned // (a value of 0 means the network connection is closed or end of file is reached). if (nb_read <= 0) { - if (nb_read < 0 && errno == ETIME) { + if (nb_read < 0 && SOCKET_ERRNO() == SOCKET_ETIME) { return ERROR_SOCKET_TIMEOUT; } if (nb_read == 0) { - errno = ECONNRESET; + errno = SOCKET_ECONNRESET; } return ERROR_SOCKET_READ; @@ -158,7 +158,7 @@ int SimpleSocketStream::writev(const iovec *iov, int iov_size, ssize_t* nwrite) // returned, and errno is set appropriately. if (nb_write <= 0) { // @see https://github.com/winlinvip/simple-rtmp-server/issues/200 - if (nb_write < 0 && errno == ETIME) { + if (nb_write < 0 && SOCKET_ERRNO() == SOCKET_ETIME) { return ERROR_SOCKET_TIMEOUT; } @@ -215,7 +215,7 @@ int SimpleSocketStream::write(void* buf, size_t size, ssize_t* nwrite) if (nb_write <= 0) { // @see https://github.com/winlinvip/simple-rtmp-server/issues/200 - if (nb_write < 0 && errno == ETIME) { + if (nb_write < 0 && SOCKET_ERRNO() == SOCKET_ETIME) { return ERROR_SOCKET_TIMEOUT; } diff --git a/trunk/src/libs/srs_lib_simple_socket.hpp b/trunk/src/libs/srs_lib_simple_socket.hpp index 2aa32bd39..90628a093 100644 --- a/trunk/src/libs/srs_lib_simple_socket.hpp +++ b/trunk/src/libs/srs_lib_simple_socket.hpp @@ -43,7 +43,7 @@ private: int64_t send_timeout; int64_t recv_bytes; int64_t send_bytes; - int fd; + SOCKET fd; public: SimpleSocketStream(); virtual ~SimpleSocketStream(); diff --git a/trunk/src/libs/srs_librtmp.cpp b/trunk/src/libs/srs_librtmp.cpp index d1ad3513b..e2ca37a3b 100644 --- a/trunk/src/libs/srs_librtmp.cpp +++ b/trunk/src/libs/srs_librtmp.cpp @@ -34,6 +34,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include using namespace std; +#include #include #include #include @@ -107,356 +108,6 @@ struct Context } }; -// for srs-librtmp, @see https://github.com/winlinvip/simple-rtmp-server/issues/213 -#ifdef _WIN32 - int gettimeofday(struct timeval* tv, struct timezone* tz) - { - time_t clock; - struct tm tm; - SYSTEMTIME win_time; - - GetLocalTime(&win_time); - - tm.tm_year = win_time.wYear - 1900; - tm.tm_mon = win_time.wMonth - 1; - tm.tm_mday = win_time.wDay; - tm.tm_hour = win_time.wHour; - tm.tm_min = win_time.wMinute; - tm.tm_sec = win_time.wSecond; - tm.tm_isdst = -1; - - clock = mktime(&tm); - - tv->tv_sec = (long)clock; - tv->tv_usec = win_time.wMilliseconds * 1000; - - return 0; - } - - int open(const char *pathname, int flags) - { - return open(pathname, flags, 0); - } - - int open(const char *pathname, int flags, mode_t mode) - { - FILE* file = NULL; - - if ((flags & O_RDONLY) == O_RDONLY) { - file = fopen(pathname, "r"); - } else { - file = fopen(pathname, "w+"); - } - - if (file == NULL) { - return -1; - } - - return (int)file; - } - - int close(int fd) - { - FILE* file = (FILE*)fd; - return fclose(file); - } - - off_t lseek(int fd, off_t offset, int whence) - { - return (off_t)fseek((FILE*)fd, offset, whence); - } - - ssize_t write(int fd, const void *buf, size_t count) - { - return (ssize_t)fwrite(buf, count, 1, (FILE*)fd); - } - - ssize_t read(int fd, void *buf, size_t count) - { - return (ssize_t)fread(buf, count, 1, (FILE*)fd); - } - - pid_t getpid(void) - { - return (pid_t)GetCurrentProcessId(); - } - - int usleep(useconds_t usec) - { - Sleep((DWORD)(usec / 1000)); - return 0; - } - - ssize_t writev(int fd, const struct iovec *iov, int iovcnt) - { - ssize_t nwrite = 0; - for (int i = 0; i < iovcnt; i++) { - const struct iovec* current = iov + i; - - int nsent = ::send(fd, (char*)current->iov_base, current->iov_len, 0); - if (nsent < 0) { - return nsent; - } - - nwrite += nsent; - if (nsent == 0) { - return nwrite; - } - } - return nwrite; - } - - //////////////////////// strlcpy.c (modified) ////////////////////////// - - /* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */ - - /*- - * Copyright (c) 1998 Todd C. Miller - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - - //#include // **** - //#include // **** - // __FBSDID("$FreeBSD: stable/9/sys/libkern/strlcpy.c 243811 2012-12-03 18:08:44Z delphij $"); // **** - - // #include // **** - // #include // **** - - /* - * Copy src to string dst of size siz. At most siz-1 characters - * will be copied. Always NUL terminates (unless siz == 0). - * Returns strlen(src); if retval >= siz, truncation occurred. - */ - - //#define __restrict // **** - - std::size_t strlcpy(char * __restrict dst, const char * __restrict src, size_t siz) - { - char *d = dst; - const char *s = src; - size_t n = siz; - - /* Copy as many bytes as will fit */ - if (n != 0) { - while (--n != 0) { - if ((*d++ = *s++) == '\0') - break; - } - } - - /* Not enough room in dst, add NUL and traverse rest of src */ - if (n == 0) { - if (siz != 0) - *d = '\0'; /* NUL-terminate dst */ - while (*s++) - ; - } - - return(s - src - 1); /* count does not include NUL */ - } - - // http://www.cplusplus.com/forum/general/141779///////////////////////// inet_ntop.c (modified) ////////////////////////// - /* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Copyright (c) 1996-1999 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - - // #if defined(LIBC_SCCS) && !defined(lint) // **** - //static const char rcsid[] = "$Id: inet_ntop.c,v 1.3.18.2 2005/11/03 23:02:22 marka Exp $"; - // #endif /* LIBC_SCCS and not lint */ // **** - // #include // **** - // __FBSDID("$FreeBSD: stable/9/sys/libkern/inet_ntop.c 213103 2010-09-24 15:01:45Z attilio $"); // **** - - //#define _WIN32_WINNT _WIN32_WINNT_WIN8 // **** - //#include // **** - #pragma comment(lib, "Ws2_32.lib") // **** - //#include // **** - - // #include // **** - // #include // **** - // #include // **** - - // #include // **** - - /*% - * WARNING: Don't even consider trying to compile this on a system where - * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. - */ - - static char *inet_ntop4(const u_char *src, char *dst, socklen_t size); - static char *inet_ntop6(const u_char *src, char *dst, socklen_t size); - - /* char * - * inet_ntop(af, src, dst, size) - * convert a network format address to presentation format. - * return: - * pointer to presentation format address (`dst'), or NULL (see errno). - * author: - * Paul Vixie, 1996. - */ - const char* inet_ntop(int af, const void *src, char *dst, socklen_t size) - { - switch (af) { - case AF_INET: - return (inet_ntop4( (unsigned char*)src, (char*)dst, size)); // **** - #ifdef AF_INET6 - #error "IPv6 not supported" - //case AF_INET6: - // return (char*)(inet_ntop6( (unsigned char*)src, (char*)dst, size)); // **** - #endif - default: - // return (NULL); // **** - return 0 ; // **** - } - /* NOTREACHED */ - } - - /* const char * - * inet_ntop4(src, dst, size) - * format an IPv4 address - * return: - * `dst' (as a const) - * notes: - * (1) uses no statics - * (2) takes a u_char* not an in_addr as input - * author: - * Paul Vixie, 1996. - */ - static char * inet_ntop4(const u_char *src, char *dst, socklen_t size) - { - static const char fmt[128] = "%u.%u.%u.%u"; - char tmp[sizeof "255.255.255.255"]; - int l; - - l = snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]); // **** - if (l <= 0 || (socklen_t) l >= size) { - return (NULL); - } - strlcpy(dst, tmp, size); - return (dst); - } - - /* const char * - * inet_ntop6(src, dst, size) - * convert IPv6 binary address into presentation (printable) format - * author: - * Paul Vixie, 1996. - */ - static char * inet_ntop6(const u_char *src, char *dst, socklen_t size) - { - /* - * Note that int32_t and int16_t need only be "at least" large enough - * to contain a value of the specified size. On some systems, like - * Crays, there is no such thing as an integer variable with 16 bits. - * Keep this in mind if you think this function should have been coded - * to use pointer overlays. All the world's not a VAX. - */ - char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; - struct { int base, len; } best, cur; - #define NS_IN6ADDRSZ 16 - #define NS_INT16SZ 2 - u_int words[NS_IN6ADDRSZ / NS_INT16SZ]; - int i; - - /* - * Preprocess: - * Copy the input (bytewise) array into a wordwise array. - * Find the longest run of 0x00's in src[] for :: shorthanding. - */ - memset(words, '\0', sizeof words); - for (i = 0; i < NS_IN6ADDRSZ; i++) - words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); - best.base = -1; - best.len = 0; - cur.base = -1; - cur.len = 0; - for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { - if (words[i] == 0) { - if (cur.base == -1) - cur.base = i, cur.len = 1; - else - cur.len++; - } else { - if (cur.base != -1) { - if (best.base == -1 || cur.len > best.len) - best = cur; - cur.base = -1; - } - } - } - if (cur.base != -1) { - if (best.base == -1 || cur.len > best.len) - best = cur; - } - if (best.base != -1 && best.len < 2) - best.base = -1; - - /* - * Format the result. - */ - tp = tmp; - for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { - /* Are we inside the best run of 0x00's? */ - if (best.base != -1 && i >= best.base && - i < (best.base + best.len)) { - if (i == best.base) - *tp++ = ':'; - continue; - } - /* Are we following an initial run of 0x00s or any real hex? */ - if (i != 0) - *tp++ = ':'; - /* Is this address an encapsulated IPv4? */ - if (i == 6 && best.base == 0 && (best.len == 6 || - (best.len == 7 && words[7] != 0x0001) || - (best.len == 5 && words[5] == 0xffff))) { - if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) - return (NULL); - tp += strlen(tp); - break; - } - tp += std::sprintf(tp, "%x", words[i]); // **** - } - /* Was it a trailing run of 0x00's? */ - if (best.base != -1 && (best.base + best.len) == - (NS_IN6ADDRSZ / NS_INT16SZ)) - *tp++ = ':'; - *tp++ = '\0'; - - /* - * Check for overflow, copy, and we're done. - */ - if ((socklen_t)(tp - tmp) > size) { - return (NULL); - } - strcpy(dst, tmp); - return (dst); - } -#endif - int srs_librtmp_context_parse_uri(Context* context) { int ret = ERROR_SUCCESS; diff --git a/trunk/src/libs/srs_librtmp.hpp b/trunk/src/libs/srs_librtmp.hpp index 58d2c4c8a..fb39ddd32 100644 --- a/trunk/src/libs/srs_librtmp.hpp +++ b/trunk/src/libs/srs_librtmp.hpp @@ -30,47 +30,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include -// for srs-librtmp, @see https://github.com/winlinvip/simple-rtmp-server/issues/213 -#ifdef _WIN32 - #define _CRT_SECURE_NO_WARNINGS - typedef unsigned long long u_int64_t; - typedef long long int64_t; - typedef unsigned int u_int32_t; - typedef int int32_t; - typedef unsigned char u_int8_t; - typedef char int8_t; - typedef unsigned short u_int16_t; - typedef short int16_t; - typedef int64_t ssize_t; - struct iovec { - void *iov_base; /* Starting address */ - size_t iov_len; /* Number of bytes to transfer */ - }; - #include - #include - int gettimeofday(struct timeval* tv, struct timezone* tz); - #define PRId64 "lld" - typedef int socklen_t; - const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); - typedef int mode_t; - #define S_IRUSR 0 - #define S_IWUSR 0 - #define S_IRGRP 0 - #define S_IWGRP 0 - #define S_IROTH 0 - int open(const char *pathname, int flags); - int open(const char *pathname, int flags, mode_t mode); - int close(int fd); - off_t lseek(int fd, off_t offset, int whence); - ssize_t write(int fd, const void *buf, size_t count); - ssize_t read(int fd, void *buf, size_t count); - typedef int pid_t; - pid_t getpid(void); - #define snprintf _snprintf - ssize_t writev(int fd, const struct iovec *iov, int iovcnt); - typedef int64_t useconds_t; - int usleep(useconds_t usec); -#endif /** * srs-librtmp is a librtmp like library, diff --git a/trunk/src/srs/srs.upp b/trunk/src/srs/srs.upp index 94f0fd339..d2f18d7c0 100755 --- a/trunk/src/srs/srs.upp +++ b/trunk/src/srs/srs.upp @@ -15,6 +15,8 @@ file ..\core\srs_core.cpp, ..\core\srs_core_autofree.hpp, ..\core\srs_core_autofree.cpp, + ..\core\srs_platform.hpp, + ..\core\srs_platform.cpp, kernel readonly separator, ..\kernel\srs_kernel_buffer.hpp, ..\kernel\srs_kernel_buffer.cpp, diff --git a/trunk/winbuild/srs-librtmp.def b/trunk/winbuild/srs-librtmp.def new file mode 100644 index 000000000..b35612186 --- /dev/null +++ b/trunk/winbuild/srs-librtmp.def @@ -0,0 +1,46 @@ +LIBRARY +EXPORTS +srs_rtmp_create +srs_rtmp_create2 +srs_rtmp_destroy +srs_rtmp_handshake +srs_rtmp_connect_app +srs_rtmp_connect_app2 +srs_rtmp_play_stream +srs_rtmp_publish_stream +srs_rtmp_read_packet +srs_rtmp_write_packet +srs_version_major +srs_version_minor +srs_version_revision +srs_utils_parse_timestamp +srs_human_format_time +srs_human_print_rtmp_packet +srs_rtmp_bandwidth_check +; +__srs_rtmp_do_simple_handshake +__srs_rtmp_connect_server +__srs_rtmp_dns_resolve + +;;;;;;;;for flv read/write;;;;;;;; +srs_flv_open_read +srs_flv_open_write +srs_flv_close +srs_flv_read_header +srs_flv_read_tag_header +srs_flv_read_tag_data +srs_flv_write_header +srs_flv_write_tag +srs_flv_size_tag +srs_flv_tellg +srs_flv_lseek +srs_flv_is_eof +srs_flv_is_sequence_header +srs_flv_is_keyframe + +;;;;;;;;for h264 read/write;;;;;;;; +srs_h264_write_raw_frames +srs_h264_is_dvbsp_error +srs_h264_is_duplicated_sps_error +srs_h264_is_duplicated_pps_error +srs_h264_startswith_annexb diff --git a/trunk/winbuild/srs-librtmp_vs2010.sln b/trunk/winbuild/srs-librtmp_vs2010.sln new file mode 100644 index 000000000..204bf81ac --- /dev/null +++ b/trunk/winbuild/srs-librtmp_vs2010.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "srs-librtmp", "srs-librtmp_vs2010.vcxproj", "{051CC3D8-5A99-4534-90EE-AED40EDDEEB2}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "srs_play", "srs_play.vcxproj", "{5149B9A9-5085-4A10-AD6F-23FBE6854390}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {051CC3D8-5A99-4534-90EE-AED40EDDEEB2}.Debug|Win32.ActiveCfg = Debug|Win32 + {051CC3D8-5A99-4534-90EE-AED40EDDEEB2}.Debug|Win32.Build.0 = Debug|Win32 + {051CC3D8-5A99-4534-90EE-AED40EDDEEB2}.Release|Win32.ActiveCfg = Release|Win32 + {051CC3D8-5A99-4534-90EE-AED40EDDEEB2}.Release|Win32.Build.0 = Release|Win32 + {5149B9A9-5085-4A10-AD6F-23FBE6854390}.Debug|Win32.ActiveCfg = Debug|Win32 + {5149B9A9-5085-4A10-AD6F-23FBE6854390}.Debug|Win32.Build.0 = Debug|Win32 + {5149B9A9-5085-4A10-AD6F-23FBE6854390}.Release|Win32.ActiveCfg = Release|Win32 + {5149B9A9-5085-4A10-AD6F-23FBE6854390}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/trunk/winbuild/srs-librtmp_vs2010.vcxproj b/trunk/winbuild/srs-librtmp_vs2010.vcxproj new file mode 100644 index 000000000..08cc6ead0 --- /dev/null +++ b/trunk/winbuild/srs-librtmp_vs2010.vcxproj @@ -0,0 +1,137 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {051CC3D8-5A99-4534-90EE-AED40EDDEEB2} + Win32Proj + srslibrtmp + srs-librtmp + + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + + + + + + + + + + + true + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;SRSLIBRTMP_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\src\rtmp;..\src\libs;..\src\kernel;..\src\core;.\;%(AdditionalIncludeDirectories) + + + Windows + true + ws2_32.lib;%(AdditionalDependencies) + srs-librtmp.def + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;SRSLIBRTMP_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\src\rtmp;..\src\libs;..\src\kernel;..\src\core;.\;%(AdditionalIncludeDirectories) + + + Windows + true + true + true + srs-librtmp.def + ws2_32.lib;%(AdditionalDependencies) + + + + + + \ No newline at end of file diff --git a/trunk/winbuild/srs-librtmp_vs2010.vcxproj.filters b/trunk/winbuild/srs-librtmp_vs2010.vcxproj.filters new file mode 100644 index 000000000..5c3da3219 --- /dev/null +++ b/trunk/winbuild/srs-librtmp_vs2010.vcxproj.filters @@ -0,0 +1,156 @@ + + + + + {8e33c6db-7a35-4d09-92d0-cc28491abbd6} + + + {eac81f26-3b4f-4905-85c5-2c0b915107b0} + + + {cbb45db3-c682-48bd-9a8c-1ae081aeddbf} + + + {6a284cec-b287-4aeb-b991-e11ebb4be6ec} + + + + + core + + + core + + + core + + + kernel + + + kernel + + + kernel + + + kernel + + + kernel + + + kernel + + + kernel + + + kernel + + + kernel + + + libs + + + libs + + + libs + + + rtmp + + + rtmp + + + rtmp + + + rtmp + + + rtmp + + + rtmp + + + rtmp + + + + + core + + + core + + + core + + + kernel + + + kernel + + + kernel + + + kernel + + + kernel + + + kernel + + + kernel + + + kernel + + + kernel + + + libs + + + libs + + + libs + + + rtmp + + + rtmp + + + rtmp + + + rtmp + + + rtmp + + + rtmp + + + rtmp + + + + + + \ No newline at end of file diff --git a/trunk/winbuild/srs_auto_headers.hpp b/trunk/winbuild/srs_auto_headers.hpp new file mode 100644 index 000000000..4ebef350b --- /dev/null +++ b/trunk/winbuild/srs_auto_headers.hpp @@ -0,0 +1,56 @@ +// auto generated by configure +#ifndef SRS_AUTO_HEADER_HPP +#define SRS_AUTO_HEADER_HPP + +#define SRS_AUTO_BUILD_TS "1416731672" +#define SRS_AUTO_BUILD_DATE "2014-11-23 16:34:32" +#define SRS_AUTO_UNAME "WIN_NT-6.1 WZY-PC2 1.0.18(0.48/3/2) 2012-11-21 22:34 i686 WINNT" +#define SRS_AUTO_USER_CONFIGURE "--x86-x64 --export-librtmp-project=../srs-librtmp" +#define SRS_AUTO_CONFIGURE "--prefix=/usr/local/srs --without-hls --without-dvr --without-nginx --without-ssl --without-ffmpeg --without-transcode --without-ingest --without-stat --without-http-callback --without-http-server --without-http-api --with-librtmp --with-research --without-utest --without-gperf --without-gmc --without-gmp --without-gcp --without-gprof --without-arm-ubuntu12 --without-mips-ubuntu12 --log-trace" + +#define SRS_AUTO_EMBEDED_TOOL_CHAIN "normal x86/x64 gcc" + +#undef SRS_AUTO_HTTP_PARSER +#undef SRS_AUTO_HTTP_SERVER +#undef SRS_AUTO_HTTP_API +#undef SRS_AUTO_NGINX +#undef SRS_AUTO_DVR +#undef SRS_AUTO_HLS +#undef SRS_AUTO_HTTP_CALLBACK +#undef SRS_AUTO_SSL +#undef SRS_AUTO_FFMPEG_TOOL +#undef SRS_AUTO_FFMPEG_STUB +#undef SRS_AUTO_TRANSCODE +#undef SRS_AUTO_INGEST +#undef SRS_AUTO_STAT +#undef SRS_AUTO_GPERF +#undef SRS_AUTO_GPERF_MC +#undef SRS_AUTO_GPERF_MP +#undef SRS_AUTO_GPERF_CP +#undef SRS_AUTO_EMBEDED_CPU +#undef SRS_AUTO_ARM_UBUNTU12 +#undef SRS_AUTO_MIPS_UBUNTU12 + +#undef SRS_AUTO_VERBOSE +#undef SRS_AUTO_INFO +#define SRS_AUTO_TRACE + +#define SRS_AUTO_PREFIX "/usr/local/srs" + +#define SRS_AUTO_CONSTRIBUTORS "\ +winlin \ +wenjie.zhao<740936897@qq.com> \ +xiangcheng.liu \ +naijia.liu \ +alcoholyi \ +byteman \ +chad.wang \ +suhetao \ +Johnny \ +karthikeyan \ +StevenLiu \ +zhengfl \ +" + +#endif + diff --git a/trunk/winbuild/srs_play.vcxproj b/trunk/winbuild/srs_play.vcxproj new file mode 100644 index 000000000..0480153df --- /dev/null +++ b/trunk/winbuild/srs_play.vcxproj @@ -0,0 +1,85 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {5149B9A9-5085-4A10-AD6F-23FBE6854390} + Win32Proj + srs_play + + + + Application + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + true + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + ..\src\core;..\src\libs;%(AdditionalIncludeDirectories) + + + Console + true + srs-librtmp.lib;%(AdditionalDependencies) + ./debug;%(AdditionalLibraryDirectories) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + true + true + + + + + + + + + diff --git a/trunk/winbuild/srs_play.vcxproj.filters b/trunk/winbuild/srs_play.vcxproj.filters new file mode 100644 index 000000000..f6123616d --- /dev/null +++ b/trunk/winbuild/srs_play.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + +