#include "php.h"
#include "winutil.h"
#include <wincrypt.h>
#include <lmcons.h>
PHP_WINUTIL_API char *php_win32_error_to_msg(HRESULT error)
{
char *buf = NULL;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&buf, 0, NULL
);
return (buf ? (char *) buf : "");
}
int php_win32_check_trailing_space(const char * path, const int path_len) {
if (path_len < 1) {
return 1;
}
if (path) {
if (path[0] == ' ' || path[path_len - 1] == ' ') {
return 0;
} else {
return 1;
}
} else {
return 0;
}
}
HCRYPTPROV hCryptProv;
unsigned int has_crypto_ctx = 0;
#ifdef ZTS
MUTEX_T php_lock_win32_cryptoctx;
void php_win32_init_rng_lock()
{
php_lock_win32_cryptoctx = tsrm_mutex_alloc();
}
void php_win32_free_rng_lock()
{
tsrm_mutex_lock(php_lock_win32_cryptoctx);
if (has_crypto_ctx == 1) {
CryptReleaseContext(hCryptProv, 0);
has_crypto_ctx = 0;
}
tsrm_mutex_unlock(php_lock_win32_cryptoctx);
tsrm_mutex_free(php_lock_win32_cryptoctx);
}
#else
#define php_win32_init_rng_lock();
#define php_win32_free_rng_lock();
#endif
PHP_WINUTIL_API int php_win32_get_random_bytes(unsigned char *buf, size_t size) {
BOOL ret;
#ifdef ZTS
tsrm_mutex_lock(php_lock_win32_cryptoctx);
#endif
if (has_crypto_ctx == 0) {
if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET|CRYPT_VERIFYCONTEXT )) {
if (GetLastError() == NTE_BAD_KEYSET) {
if (CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET | CRYPT_MACHINE_KEYSET | CRYPT_VERIFYCONTEXT )) {
has_crypto_ctx = 1;
} else {
has_crypto_ctx = 0;
}
}
} else {
has_crypto_ctx = 1;
}
}
#ifdef ZTS
tsrm_mutex_unlock(php_lock_win32_cryptoctx);
#endif
if (has_crypto_ctx == 0) {
return FAILURE;
}
ret = CryptGenRandom(hCryptProv, (DWORD)size, buf);
if (ret) {
return SUCCESS;
} else {
return FAILURE;
}
}
PHP_WINUTIL_API int php_win32_code_to_errno(unsigned long w32Err)
{
size_t i;
struct code_to_errno_map
{
unsigned long w32Err;
int eerrno;
};
static const struct code_to_errno_map errmap[] =
{
{ ERROR_INVALID_FUNCTION , EINVAL }
, { ERROR_FILE_NOT_FOUND , ENOENT }
, { ERROR_PATH_NOT_FOUND , ENOENT }
, { ERROR_TOO_MANY_OPEN_FILES , EMFILE }
, { ERROR_ACCESS_DENIED , EACCES }
, { ERROR_INVALID_HANDLE , EBADF }
, { ERROR_ARENA_TRASHED , ENOMEM }
, { ERROR_NOT_ENOUGH_MEMORY , ENOMEM }
, { ERROR_INVALID_BLOCK , ENOMEM }
, { ERROR_BAD_ENVIRONMENT , E2BIG }
, { ERROR_BAD_FORMAT , ENOEXEC }
, { ERROR_INVALID_ACCESS , EINVAL }
, { ERROR_INVALID_DATA , EINVAL }
, { ERROR_OUTOFMEMORY , ENOMEM }
, { ERROR_INVALID_DRIVE , ENOENT }
, { ERROR_CURRENT_DIRECTORY , ECURDIR }
, { ERROR_NOT_SAME_DEVICE , EXDEV }
, { ERROR_NO_MORE_FILES , ENOENT }
, { ERROR_WRITE_PROTECT , EROFS }
, { ERROR_BAD_UNIT , ENXIO }
, { ERROR_NOT_READY , EBUSY }
, { ERROR_BAD_COMMAND , EIO }
, { ERROR_CRC , EIO }
, { ERROR_BAD_LENGTH , EIO }
, { ERROR_SEEK , EIO }
, { ERROR_NOT_DOS_DISK , EIO }
, { ERROR_SECTOR_NOT_FOUND , ENXIO }
, { ERROR_OUT_OF_PAPER , EBUSY }
, { ERROR_WRITE_FAULT , EIO }
, { ERROR_READ_FAULT , EIO }
, { ERROR_GEN_FAILURE , EIO }
, { ERROR_SHARING_VIOLATION , EAGAIN }
, { ERROR_LOCK_VIOLATION , EACCES }
, { ERROR_WRONG_DISK , ENXIO }
, { 35 , ENFILE }
, { ERROR_SHARING_BUFFER_EXCEEDED , ENFILE }
, { ERROR_HANDLE_EOF , EINVAL }
, { ERROR_HANDLE_DISK_FULL , ENOSPC }
#if 0
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
#endif
, { ERROR_NOT_SUPPORTED , ENOSYS }
#if 0
, { 0 , 0 }
, { 0 , 0 }
#endif
, { ERROR_BAD_NETPATH , ENOENT }
#if 0
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
#endif
, { ERROR_NETWORK_ACCESS_DENIED , EACCES }
#if 0
, { 0 , 0 }
#endif
, { ERROR_BAD_NET_NAME , ENOENT }
#if 0
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
#endif
, { ERROR_FILE_EXISTS , EEXIST }
#if 0
, { 0 , 0 }
#endif
, { ERROR_CANNOT_MAKE , EACCES }
, { ERROR_FAIL_I24 , EACCES }
#if 0
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
#endif
, { ERROR_INVALID_PARAMETER , EINVAL }
#if 0
, { 0 , 0 }
#endif
, { ERROR_NO_PROC_SLOTS , EAGAIN }
#if 0
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
#endif
, { ERROR_DRIVE_LOCKED , EACCES }
, { ERROR_BROKEN_PIPE , EPIPE }
#if 0
, { 0 , 0 }
#endif
, { ERROR_BUFFER_OVERFLOW , ENAMETOOLONG }
, { ERROR_DISK_FULL , ENOSPC }
#if 0
, { 0 , 0 }
#endif
, { ERROR_INVALID_TARGET_HANDLE , EBADF }
#if 0
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
#endif
, { ERROR_INSUFFICIENT_BUFFER , ERANGE }
, { ERROR_INVALID_NAME , ENOENT }
, { ERROR_INVALID_HANDLE , EINVAL }
#if 0
, { 0 , 0 }
#endif
, { ERROR_MOD_NOT_FOUND , ENOENT }
, { ERROR_PROC_NOT_FOUND , ENOENT }
, { ERROR_WAIT_NO_CHILDREN , ECHILD }
, { ERROR_CHILD_NOT_COMPLETE , ECHILD }
, { ERROR_DIRECT_ACCESS_HANDLE , EBADF }
, { ERROR_NEGATIVE_SEEK , EINVAL }
, { ERROR_SEEK_ON_DEVICE , EACCES }
#if 0
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
#endif
, { ERROR_DIR_NOT_EMPTY , ENOTEMPTY }
#if 0
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
#endif
, { ERROR_NOT_LOCKED , EACCES }
#if 0
, { 0 , 0 }
, { 0 , 0 }
#endif
, { ERROR_BAD_PATHNAME , ENOENT }
#if 0
, { 0 , 0 }
, { 0 , 0 }
#endif
, { ERROR_MAX_THRDS_REACHED , EAGAIN }
#if 0
, { 0 , 0 }
, { 0 , 0 }
#endif
, { ERROR_LOCK_FAILED , EACCES }
#if 0
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
#endif
, { ERROR_ALREADY_EXISTS , EEXIST }
#if 0
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
, { 0 , 0 }
#endif
, { ERROR_FILENAME_EXCED_RANGE , ENAMETOOLONG }
, { ERROR_NESTING_NOT_ALLOWED , EAGAIN }
, { WAIT_TIMEOUT, ETIME}
, { ERROR_DIRECTORY , ENOTDIR }
, { ERROR_IO_INCOMPLETE , EAGAIN }
, { ERROR_IO_PENDING , EAGAIN }
, { ERROR_INVALID_FLAGS , EINVAL }
, { ERROR_NO_UNICODE_TRANSLATION , EINVAL }
, { ERROR_NOT_FOUND , ENOENT }
, { ERROR_USER_MAPPED_FILE , EACCES }
, { ERROR_NOT_ENOUGH_QUOTA , ENOMEM }
, { ERROR_ABANDONED_WAIT_0 , EIO }
};
for(i = 0; i < sizeof(errmap)/sizeof(struct code_to_errno_map); ++i)
{
if(w32Err == errmap[i].w32Err)
{
return errmap[i].eerrno;
}
}
assert(!"Unrecognised value");
return EINVAL;
}
PHP_WINUTIL_API char *php_win32_get_username(void)
{
wchar_t unamew[UNLEN + 1];
size_t uname_len;
char *uname;
DWORD unsize = UNLEN;
GetUserNameW(unamew, &unsize);
uname = php_win32_cp_conv_w_to_any(unamew, unsize - 1, &uname_len);
if (!uname) {
return NULL;
}
if (uname_len > UNLEN) {
uname[uname_len] = '\0';
}
return uname;
}