diff --git a/dlls/msvcrt/misc.c b/dlls/msvcrt/misc.c index 83f798dcda3..6455e397684 100644 --- a/dlls/msvcrt/misc.c +++ b/dlls/msvcrt/misc.c @@ -38,12 +38,26 @@ void _beep( unsigned int freq, unsigned int duration) Beep(freq, duration); } +/********************************************************************* + * srand (MSVCRT.@) + */ +void MSVCRT_srand( unsigned int seed ) +{ + thread_data_t *data = msvcrt_get_thread_data(); + data->random_seed = seed; +} + /********************************************************************* * rand (MSVCRT.@) */ int MSVCRT_rand(void) { - return (rand() & 0x7fff); + thread_data_t *data = msvcrt_get_thread_data(); + + /* this is the algorithm used by MSVC, according to + * http://en.wikipedia.org/wiki/List_of_pseudorandom_number_generators */ + data->random_seed = data->random_seed * 214013 + 2531011; + return (data->random_seed >> 16) & MSVCRT_RAND_MAX; } /********************************************************************* diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h index 9923deff459..2502d4b213c 100644 --- a/dlls/msvcrt/msvcrt.h +++ b/dlls/msvcrt/msvcrt.h @@ -93,6 +93,7 @@ extern DWORD msvcrt_tls_index; struct __thread_data { int thread_errno; unsigned long thread_doserrno; + unsigned int random_seed; /* seed for rand() */ char *strtok_next; /* next ptr for strtok() */ unsigned char *mbstok_next; /* next ptr for mbstok() */ MSVCRT_wchar_t *wcstok_next; /* next ptr for wcstok() */ @@ -375,6 +376,7 @@ struct MSVCRT__stati64 { #define MSVCRT_WEOF (MSVCRT_wint_t)(0xFFFF) #define MSVCRT_EOF (-1) #define MSVCRT_TMP_MAX 0x7fff +#define MSVCRT_RAND_MAX 0x7fff #define MSVCRT_BUFSIZ 512 #define MSVCRT_STDIN_FILENO 0 diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index 4620dff955c..a24f11b49e2 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -695,7 +695,7 @@ @ cdecl sinh(double) @ varargs sprintf(ptr str) MSVCRT_sprintf @ cdecl sqrt(double) -@ cdecl srand(long) +@ cdecl srand(long) MSVCRT_srand @ varargs sscanf(str str) MSVCRT_sscanf @ cdecl strcat(str str) @ cdecl strchr(str long) diff --git a/dlls/msvcrt/tests/headers.c b/dlls/msvcrt/tests/headers.c index a25ce01517c..840212af13a 100644 --- a/dlls/msvcrt/tests/headers.c +++ b/dlls/msvcrt/tests/headers.c @@ -303,6 +303,7 @@ static void test_defines(void) CHECK_DEF(WEOF); CHECK_DEF(EOF); CHECK_DEF(TMP_MAX); + CHECK_DEF(RAND_MAX); CHECK_DEF(BUFSIZ); CHECK_DEF(STDIN_FILENO); CHECK_DEF(STDOUT_FILENO); diff --git a/dlls/msvcrt/thread.c b/dlls/msvcrt/thread.c index 262aa5753f0..3362b4f66df 100644 --- a/dlls/msvcrt/thread.c +++ b/dlls/msvcrt/thread.c @@ -44,6 +44,7 @@ thread_data_t *msvcrt_get_thread_data(void) if (!(ptr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ptr) ))) _amsg_exit( _RT_THREAD ); if (!TlsSetValue( msvcrt_tls_index, ptr )) _amsg_exit( _RT_THREAD ); + ptr->random_seed = 1; } SetLastError( err ); return ptr;