GNU Emacs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
} MEMORY_STATUS_EX,*LPMEMORY_STATUS_EX;
/* These are here so that GDB would know about these data types. This
- allows to attach GDB to Emacs when a fatal exception is triggered
+ allows attaching GDB to Emacs when a fatal exception is triggered
and Windows pops up the "application needs to be closed" dialog.
At that point, _gnu_exception_handler, the top-level exception
handler installed by the MinGW startup code, is somewhere on the
#include <iphlpapi.h> /* should be after winsock2.h */
+#include <wincrypt.h>
+
#include <c-strcase.h>
#include "w32.h"
int (WINAPI *pMultiByteToWideChar)(UINT,DWORD,LPCSTR,int,LPWSTR,int);
int (WINAPI *pWideCharToMultiByte)(UINT,DWORD,LPCWSTR,int,LPSTR,int,LPCSTR,LPBOOL);
+DWORD multiByteToWideCharFlags;
/* ** A utility function ** */
static BOOL
int
filename_to_utf16 (const char *fn_in, wchar_t *fn_out)
{
- int result = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, fn_in, -1,
- fn_out, MAX_PATH);
+ int result = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags, fn_in,
+ -1, fn_out, MAX_PATH);
if (!result)
{
{
wchar_t fn_utf16[MAX_PATH];
int codepage = codepage_for_filenames (NULL);
- int result = pMultiByteToWideChar (codepage, MB_ERR_INVALID_CHARS, fn_in, -1,
- fn_utf16, MAX_PATH);
+ int result = pMultiByteToWideChar (codepage, multiByteToWideCharFlags, fn_in,
+ -1, fn_utf16, MAX_PATH);
if (!result)
{
CloseHandle (token);
}
+static HCRYPTPROV w32_crypto_hprov;
+static int
+w32_init_crypt_random (void)
+{
+ if (!CryptAcquireContext (&w32_crypto_hprov, NULL, NULL, PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
+ {
+ DebPrint (("CryptAcquireContext failed with error %x\n",
+ GetLastError ()));
+ w32_crypto_hprov = 0;
+ return -1;
+ }
+ return 0;
+}
+
+int
+w32_init_random (void *buf, ptrdiff_t buflen)
+{
+ if (!w32_crypto_hprov)
+ w32_init_crypt_random ();
+ if (w32_crypto_hprov)
+ {
+ if (CryptGenRandom (w32_crypto_hprov, buflen, (BYTE *)buf))
+ return 0;
+ }
+ return -1;
+}
+
int
random (void)
{
case STATUS_READ_READY:
case STATUS_READ_IN_PROGRESS:
- DebPrint (("sys_read called when read is in progress\n"));
+#if 0
+ /* This happens all the time during GnuTLS handshake
+ with the remote, evidently because GnuTLS waits for
+ the read to complete by retrying the read operation
+ upon EAGAIN. So I'm disabling the DebPrint to avoid
+ wasting cycles on something that is not a real
+ problem. Enable if you need to debug something that
+ bumps into this. */
+ DebPrint (("sys_read called when read is in progress %d\n",
+ current_status));
+#endif
errno = EWOULDBLOCK;
return -1;
"not unpacked properly.\nSee the README.W32 file in the "
"top-level Emacs directory for more information.",
init_file_name, load_path);
- needed = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, buffer,
- -1, NULL, 0);
+ needed = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
+ buffer, -1, NULL, 0);
if (needed > 0)
{
wchar_t *msg_w = alloca ((needed + 1) * sizeof (wchar_t));
- pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, buffer, -1,
- msg_w, needed);
+ pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags, buffer,
+ -1, msg_w, needed);
needed = pWideCharToMultiByte (CP_ACP, 0, msg_w, -1,
NULL, 0, NULL, NULL);
if (needed > 0)
(MultiByteToWideChar_Proc)GetProcAddress (ret, "MultiByteToWideChar");
pWideCharToMultiByte =
(WideCharToMultiByte_Proc)GetProcAddress (ret, "WideCharToMultiByte");
+ multiByteToWideCharFlags = MB_ERR_INVALID_CHARS;
return ret;
}
else
pointers; no need for the LoadLibrary dance. */
pMultiByteToWideChar = MultiByteToWideChar;
pWideCharToMultiByte = WideCharToMultiByte;
+ /* On NT 4.0, though, MB_ERR_INVALID_CHARS is not supported. */
+ if (w32_major_version < 5)
+ multiByteToWideCharFlags = 0;
+ else
+ multiByteToWideCharFlags = MB_ERR_INVALID_CHARS;
return LoadLibrary ("Gdi32.dll");
}
}
extern void dynlib_reset_last_error (void);
dynlib_reset_last_error ();
#endif
+
+ w32_crypto_hprov = (HCRYPTPROV)0;
}
/* For make-serial-process */