mirror of
https://gitlab.com/mbunkus/mkvtoolnix.git
synced 2025-01-01 15:56:59 +00:00
Fixed random number generation on Windows. On 9x/ME UuidCreate returns the same value in UUID.Data4 on each call meaning that the numbers generated are always the same, too. In such cases srand() and rand() is used instead of UuidCreate. The loop for the "UuidCreate failed" case was broken as well.
This commit is contained in:
parent
528890fe47
commit
770ba0b9f3
@ -1,3 +1,10 @@
|
||||
2006-09-29 Moritz Bunkus <moritz@bunkus.org>
|
||||
|
||||
* mkvmerge: bug fix: Fixed the random number generation on
|
||||
Windows. On Windows 9x/ME mkvmerge would simply hang. On newer
|
||||
versions the function was accessing invalid memory and was
|
||||
generally buggy.
|
||||
|
||||
2006-09-26 Moritz Bunkus <moritz@bunkus.org>
|
||||
|
||||
* mkvmerge: bug fix: SSA/ASS subtitles with comments before the
|
||||
|
@ -29,34 +29,63 @@ bool random_c::m_seeded = false;
|
||||
|
||||
#if defined(SYS_WINDOWS)
|
||||
|
||||
bool random_c::m_tried_uuidcreate = false;
|
||||
bool random_c::m_use_uuidcreate = false;
|
||||
|
||||
void
|
||||
random_c::generate_bytes(void *destination,
|
||||
int num_bytes) {
|
||||
int i, num_left;
|
||||
int num_written, num_left;
|
||||
UUID uuid;
|
||||
RPC_STATUS status;
|
||||
|
||||
i = 0;
|
||||
while (num_bytes > 0) {
|
||||
UUID uuid;
|
||||
RPC_STATUS status;
|
||||
if (!m_seeded) {
|
||||
srand(GetTickCount());
|
||||
m_seeded = true;
|
||||
}
|
||||
|
||||
status = UuidCreate(&uuid);
|
||||
if ((RPC_S_OK != status) && (RPC_S_UUID_LOCAL_ONLY != status)) {
|
||||
if (!m_seeded) {
|
||||
srand(GetTickCount());
|
||||
m_seeded = true;
|
||||
if (!m_tried_uuidcreate) {
|
||||
// Find out whether UuidCreate returns different
|
||||
// data in Data4 on each call by comparing up to five
|
||||
// results. If not use srand() and rand().
|
||||
UUID first_uuid;
|
||||
int i;
|
||||
|
||||
m_use_uuidcreate = true;
|
||||
status = UuidCreate(&first_uuid);
|
||||
if ((RPC_S_OK == status) || (RPC_S_UUID_LOCAL_ONLY == status)) {
|
||||
for (i = 0; i < 5; ++i) {
|
||||
status = UuidCreate(&uuid);
|
||||
if (((RPC_S_OK != status) && (RPC_S_UUID_LOCAL_ONLY != status)) ||
|
||||
!memcmp(first_uuid.Data4, uuid.Data4, sizeof(uuid.Data4))) {
|
||||
m_use_uuidcreate = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else
|
||||
m_use_uuidcreate = false;
|
||||
|
||||
m_tried_uuidcreate = true;
|
||||
}
|
||||
|
||||
num_written = 0;
|
||||
while (num_written < num_bytes) {
|
||||
if (m_use_uuidcreate) {
|
||||
status = UuidCreate(&uuid);
|
||||
if ((RPC_S_OK != status) && (RPC_S_UUID_LOCAL_ONLY != status)) {
|
||||
m_use_uuidcreate = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
while (0 > num_bytes) {
|
||||
((unsigned char *)destination)[i + num_bytes] =
|
||||
num_left = (num_bytes - num_written) > 8 ? 8 :
|
||||
(num_written - num_bytes);
|
||||
memcpy((unsigned char *)destination + num_written, &uuid.Data4, num_left);
|
||||
num_written += num_left;
|
||||
|
||||
} else
|
||||
for (; num_written < num_bytes; ++num_written)
|
||||
((unsigned char *)destination)[num_written] =
|
||||
(unsigned char)(256.0 * rand() / (RAND_MAX + 1.0));
|
||||
--num_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
num_left = num_bytes > 8 ? 8 : num_bytes;
|
||||
memcpy((unsigned char *)destination + i, &uuid.Data4, num_left);
|
||||
num_bytes -= num_left;
|
||||
i += num_left;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,8 @@ private:
|
||||
#if !defined(SYS_WINDOWS)
|
||||
static auto_ptr<mm_file_io_c> m_dev_urandom;
|
||||
static bool m_tried_dev_urandom;
|
||||
#else
|
||||
static bool m_tried_uuidcreate, m_use_uuidcreate;
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user