patch 9.1.0518: initialize the random buffer can be improved

Problem:  initialize the random buffer can be improved
Solution: refactor init_srand() function, move machine-specific parts to
          os_mswin and os_unix, implement a fallback for Windows 10 and
          later (LemonBoy)

closes: #15125

Signed-off-by: LemonBoy <thatlemon@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/src/os_mswin.c b/src/os_mswin.c
index 9d0e1a0..df760fd 100644
--- a/src/os_mswin.c
+++ b/src/os_mswin.c
@@ -830,6 +830,40 @@
 						  0, mch_icon_load_cb, iconp);
 }
 
+/*
+ * Fill the buffer 'buf' with 'len' random bytes.
+ * Returns FAIL if the OS PRNG is not available or something went wrong.
+ */
+    int
+mch_get_random(char_u *buf, int len)
+{
+    static int		initialized = NOTDONE;
+    static HINSTANCE	hInstLib;
+    static BOOL (WINAPI *pProcessPrng)(PUCHAR, ULONG);
+
+    if (initialized == NOTDONE)
+    {
+	hInstLib = vimLoadLib("bcryptprimitives.dll");
+	if (hInstLib != NULL)
+	    pProcessPrng = (void *)GetProcAddress(hInstLib, "ProcessPrng");
+	if (hInstLib == NULL || pProcessPrng == NULL)
+	{
+	    FreeLibrary(hInstLib);
+	    initialized = FAIL;
+	}
+	else
+	    initialized = OK;
+    }
+
+    if (initialized == FAIL)
+	return FAIL;
+
+    // According to the documentation this call cannot fail.
+    pProcessPrng(buf, len);
+
+    return OK;
+}
+
     int
 mch_libcall(
     char_u	*libname,