Add wrappers to the UNICODE Win32 functions to translate the strings

from ANSI C strings to wchar_t strings.
pull/134/head
John Safranek 2019-01-24 17:23:02 -08:00
parent b8ae2fab59
commit 4f8623b9b6
3 changed files with 161 additions and 19 deletions

View File

@ -130,6 +130,133 @@ int wPread(WFD fd, unsigned char* buf, unsigned int sz, long ofst)
#endif
#endif /* !NO_FILESYSTEM */
#ifdef USE_WINDOWS_API
void* WS_CreateFileA(const char* fileName, unsigned long desiredAccess,
unsigned long shareMode, unsigned long creationDisposition,
unsigned long flags, void* heap)
{
HANDLE fileHandle;
wchar_t* unicodeFileName;
size_t unicodeFileNameSz = 0;
size_t returnSz = 0;
size_t fileNameSz = 0;
errno_t error;
fileNameSz = WSTRLEN(fileName);
error = mbstowcs_s(&unicodeFileNameSz, NULL, 0, fileName, 0);
if (error)
return INVALID_HANDLE_VALUE;
unicodeFileName = (wchar_t*)WMALLOC(unicodeFileNameSz, heap, 0);
if (unicodeFileName == NULL)
return INVALID_HANDLE_VALUE;
error = mbstowcs_s(&returnSz, unicodeFileName, unicodeFileNameSz,
fileName, fileNameSz);
if (!error)
fileHandle = CreateFileW(unicodeFileName, desiredAccess, shareMode,
NULL, creationDisposition, flags, NULL);
WFREE(unicodeFileName, heap, 0);
return (void*)(error ? INVALID_HANDLE_VALUE : fileHandle);
}
void* WS_FindFirstFileA(const char* fileName,
char* realFileName, size_t realFileNameSz, int* isDir, void* heap)
{
HANDLE findHandle;
WIN32_FIND_DATAW findFileData;
wchar_t* unicodeFileName;
size_t unicodeFileNameSz = 0;
size_t returnSz = 0;
size_t fileNameSz = 0;
errno_t error;
fileNameSz = WSTRLEN(fileName);
error = mbstowcs_s(&unicodeFileNameSz, NULL, 0, fileName, 0);
if (error)
return INVALID_HANDLE_VALUE;
unicodeFileName = (wchar_t*)WMALLOC(unicodeFileNameSz, heap, 0);
if (unicodeFileName == NULL)
return INVALID_HANDLE_VALUE;
error = mbstowcs_s(&returnSz, unicodeFileName, unicodeFileNameSz,
fileName, fileNameSz);
if (!error)
findHandle = FindFirstFileW(unicodeFileName, &findFileData);
WFREE(unicodeFileName, heap, 0);
error = wcstombs_s(NULL, realFileName, realFileNameSz,
findFileData.cFileName, realFileNameSz);
if (isDir != NULL) {
*isDir =
(findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
}
return (void*)findHandle;
}
int WS_FindNextFileA(void* findHandle,
char* realFileName, size_t realFileNameSz)
{
BOOL success;
WIN32_FIND_DATAW findFileData;
errno_t error;
success = FindNextFileW((HANDLE)findHandle, &findFileData);
if (success) {
error = wcstombs_s(NULL, realFileName, realFileNameSz,
findFileData.cFileName, realFileNameSz);
}
return (success != 0) && (error == 0);
}
int WS_GetFileAttributesExA(const char* fileName, void* fileInfo, void* heap)
{
BOOL success = 0;
wchar_t* unicodeFileName;
size_t unicodeFileNameSz = 0;
size_t returnSz = 0;
size_t fileNameSz = 0;
errno_t error;
fileNameSz = WSTRLEN(fileName);
error = mbstowcs_s(&unicodeFileNameSz, NULL, 0, fileName, 0);
if (error != 0)
return 0;
unicodeFileName = (wchar_t*)WMALLOC(unicodeFileNameSz, heap, 0);
if (unicodeFileName == NULL)
return 0;
error = mbstowcs_s(&returnSz, unicodeFileName, unicodeFileNameSz,
fileName, fileNameSz);
if (error == 0) {
success = GetFileAttributesExW(unicodeFileName,
GetFileExInfoStandard, fileInfo);
}
WFREE(unicodeFileName, heap, 0);
return success != 0;
}
#endif /* USE_WINDOWS_API */
#ifndef WSTRING_USER
char* wstrnstr(const char* s1, const char* s2, unsigned int n)

View File

@ -1637,8 +1637,8 @@ int wolfSSH_SFTP_RecvOpen(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
#endif
clean_path(dir);
fileHandle = CreateFileA(dir, desiredAccess, 0, NULL, creationDisp,
FILE_ATTRIBUTE_NORMAL, NULL);
fileHandle = WS_CreateFileA(dir, desiredAccess, 0, creationDisp,
FILE_ATTRIBUTE_NORMAL, ssh->ctx->heap);
if (fileHandle == INVALID_HANDLE_VALUE) {
WLOG(WS_LOG_SFTP, "Error opening file %s", dir);
res = oer;
@ -1808,7 +1808,8 @@ int wolfSSH_SFTP_RecvOpenDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
char* dirName;
word32 idx = 0;
HANDLE findHandle;
WIN32_FIND_DATAA findData;
char realName[MAX_PATH];
int isDir = 0;
int ret = WS_SUCCESS;
word32 outSz = sizeof(word64) + WOLFSSH_SFTP_HEADER + UINT32_SZ;
@ -1843,9 +1844,9 @@ int wolfSSH_SFTP_RecvOpenDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
clean_path(dirName);
/* get directory handle */
findHandle = FindFirstFileA(dirName, &findData);
if (findHandle == INVALID_HANDLE_VALUE ||
!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
findHandle = (HANDLE)WS_FindFirstFileA(dirName,
realName, sizeof(realName), &isDir, ssh->ctx->heap);
if (findHandle == INVALID_HANDLE_VALUE || !isDir) {
WLOG(WS_LOG_SFTP, "Error with opening directory");
WFREE(dirName, ssh->ctx->heap, DYNTYPE_BUFFER);
@ -2015,7 +2016,7 @@ static int wolfSSH_SFTPNAME_readdir(WOLFSSH* ssh, WDIR* dir, WS_SFTPNAME* out,
{
int sz;
HANDLE findHandle;
WIN32_FIND_DATAA findData;
char realFileName[MAX_PATH];
if (dir == NULL || ssh == NULL || out == NULL) {
return WS_BAD_ARGUMENT;
@ -2032,7 +2033,8 @@ static int wolfSSH_SFTPNAME_readdir(WOLFSSH* ssh, WDIR* dir, WS_SFTPNAME* out,
WSTRNCPY(name, dirName, MAX_PATH);
WSTRNCAT(name, "\\*", MAX_PATH);
findHandle = FindFirstFileA(name, &findData);
findHandle = (HANDLE)WS_FindFirstFileA(name,
realFileName, sizeof(realFileName), NULL, ssh->ctx->heap);
if (findHandle == INVALID_HANDLE_VALUE)
return WS_FATAL_ERROR;
@ -2041,12 +2043,13 @@ static int wolfSSH_SFTPNAME_readdir(WOLFSSH* ssh, WDIR* dir, WS_SFTPNAME* out,
}
else {
findHandle = *dir;
if (FindNextFileA(findHandle, &findData) == 0) {
if (WS_FindNextFileA(findHandle,
realFileName, sizeof(realFileName)) == 0) {
return WS_FATAL_ERROR;
}
}
sz = (int)WSTRLEN(findData.cFileName);
sz = (int)WSTRLEN(realFileName);
out->fName = (char*)WMALLOC(sz + 1, out->heap, DYNTYPE_SFTP);
if (out->fName == NULL) {
return WS_MEMORY_E;
@ -2057,8 +2060,8 @@ static int wolfSSH_SFTPNAME_readdir(WOLFSSH* ssh, WDIR* dir, WS_SFTPNAME* out,
return WS_MEMORY_E;
}
WMEMCPY(out->fName, findData.cFileName, sz);
WMEMCPY(out->lName, findData.cFileName, sz);
WMEMCPY(out->fName, realFileName, sz);
WMEMCPY(out->lName, realFileName, sz);
out->fName[sz] = '\0';
out->lName[sz] = '\0';
out->fSz = sz;
@ -3414,7 +3417,7 @@ int SFTP_GetAttributes(const char* fileName, WS_SFTP_FILEATRB* atr, byte link)
/* @TODO add proper Windows link support */
/* Note, for windows, we treat WSTAT and WLSTAT the same. */
error = !GetFileAttributesExA(fileName, GetFileExInfoStandard, &stats);
error = !WS_GetFileAttributesExA(fileName, &stats, NULL);
if (error)
return WS_BAD_FILE_E;
@ -6798,9 +6801,9 @@ int wolfSSH_SFTP_Get(WOLFSSH* ssh, char* from,
DWORD desiredAccess = GENERIC_WRITE;
if (state->gOfst > 0)
desiredAccess |= FILE_APPEND_DATA;
state->fileHandle = CreateFileA(to, desiredAccess,
0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
state->fileHandle = WS_CreateFileA(to, desiredAccess,
0, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, ssh->ctx->heap);
}
if (resume) {
WMEMSET(&state->offset, 0, sizeof(OVERLAPPED));
@ -6997,9 +7000,9 @@ int wolfSSH_SFTP_Put(WOLFSSH* ssh, char* from, char* to, byte resume,
WFSEEK(state->fl, state->pOfst, 0);
}
#else /* USE_WINDOWS_API */
state->fileHandle = CreateFileA(from, GENERIC_READ,
FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
state->fileHandle = WS_CreateFileA(from, GENERIC_READ,
FILE_SHARE_READ, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, ssh->ctx->heap);
if (state->fileHandle == INVALID_HANDLE_VALUE) {
ssh->error = WS_SFTP_FILE_DNE;
ret = WS_FATAL_ERROR;

View File

@ -146,6 +146,18 @@ extern "C" {
!defined(WOLFSSH_SCP_USER_CALLBACKS)
#ifdef USE_WINDOWS_API
WOLFSSH_LOCAL void* WS_CreateFileA(const char* fileName,
unsigned long desiredAccess, unsigned long shareMode,
unsigned long creationDisposition, unsigned long flags,
void* heap);
WOLFSSH_LOCAL void* WS_FindFirstFileA(const char* fileName,
char* realFileName, size_t realFileNameSz, int* isDir,
void* heap);
WOLFSSH_LOCAL int WS_FindNextFileA(void* findHandle,
char* realFileName, size_t realFileNameSz);
WOLFSSH_LOCAL int WS_GetFileAttributesExA(const char* fileName,
void* fileInfo, void* heap);
#ifndef _WIN32_WCE
#include <direct.h>
#define WCHDIR(p) _chdir((p))